Ejemplo n.º 1
0
    def test_bulk_edit_objects(self):
        sites = (
            Site(name='Site 1', slug='site-1'),
            Site(name='Site 2', slug='site-2'),
            Site(name='Site 3', slug='site-3'),
        )
        Site.objects.bulk_create(sites)

        data = (
            {
                'id': sites[0].pk,
                'name': 'Site A',
                'slug': 'site-A',
            },
            {
                'id': sites[1].pk,
                'name': 'Site B',
                'slug': 'site-b',
            },
            {
                'id': sites[2].pk,
                'name': 'Site C',
                'slug': 'site-c',
            },
        )
        self.assertEqual(ObjectChange.objects.count(), 0)
        url = reverse('dcim-api:site-list')
        self.add_permissions('dcim.change_site')

        response = self.client.patch(url, data, format='json', **self.header)
        self.assertHttpStatus(response, status.HTTP_200_OK)
        self.assertEqual(ObjectChange.objects.count(), 3)

        objectchange = ObjectChange.objects.get(
            changed_object_type=ContentType.objects.get_for_model(Site),
            changed_object_id=sites[0].pk
        )
        self.assertEqual(objectchange.changed_object, sites[0])
        self.assertEqual(objectchange.action, ObjectChangeActionChoices.ACTION_UPDATE)
        self.assertEqual(objectchange.prechange_data['name'], 'Site 1')
        self.assertEqual(objectchange.prechange_data['slug'], 'site-1')
        self.assertEqual(objectchange.postchange_data['name'], data[0]['name'])
        self.assertEqual(objectchange.postchange_data['slug'], data[0]['slug'])
Ejemplo n.º 2
0
    def test_bulk_update_objects(self):
        sites = (
            Site(name='Site 1',
                 slug='site-1',
                 status=SiteStatusChoices.STATUS_ACTIVE),
            Site(name='Site 2',
                 slug='site-2',
                 status=SiteStatusChoices.STATUS_ACTIVE),
            Site(name='Site 3',
                 slug='site-3',
                 status=SiteStatusChoices.STATUS_ACTIVE),
        )
        Site.objects.bulk_create(sites)

        form_data = {
            'pk': [site.pk for site in sites],
            '_apply': True,
            'status': SiteStatusChoices.STATUS_PLANNED,
            'description': 'New description',
        }

        request = {
            'path': self._get_url('bulk_edit'),
            'data': post_data(form_data),
        }
        self.add_permissions('dcim.view_site', 'dcim.change_site')
        response = self.client.post(**request)
        self.assertHttpStatus(response, 302)

        objectchange = ObjectChange.objects.get(
            changed_object_type=ContentType.objects.get_for_model(Site),
            changed_object_id=sites[0].pk)
        self.assertEqual(objectchange.changed_object, sites[0])
        self.assertEqual(objectchange.action,
                         ObjectChangeActionChoices.ACTION_UPDATE)
        self.assertEqual(objectchange.prechange_data['status'],
                         SiteStatusChoices.STATUS_ACTIVE)
        self.assertEqual(objectchange.prechange_data['description'], '')
        self.assertEqual(objectchange.postchange_data['status'],
                         form_data['status'])
        self.assertEqual(objectchange.postchange_data['description'],
                         form_data['description'])
Ejemplo n.º 3
0
    def setUp(self):
        user = create_test_user(permissions=['extras.view_objectchange'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ObjectChanges
        for i in range(1, 4):
            site.log_change(user=user, request_id=uuid.uuid4(), action=2)
Ejemplo n.º 4
0
    def setUpTestData(cls):

        sites = (
            Site(name='Site 1', slug='site-1'),
            Site(name='Site 2', slug='site-2'),
            Site(name='Site 3', slug='site-3'),
        )
        Site.objects.bulk_create(sites)
        provider = Provider.objects.create(name='Provider 1',
                                           slug='provider-1')
        circuittype = CircuitType.objects.create(name='Circuit Type 1',
                                                 slug='circuit-type-1')

        circuits = (
            Circuit(cid='Circuit 1', provider=provider, type=circuittype),
            Circuit(cid='Circuit 2', provider=provider, type=circuittype),
            Circuit(cid='Circuit 3', provider=provider, type=circuittype),
        )
        Circuit.objects.bulk_create(circuits)

        circuit_terminations = (
            CircuitTermination(circuit=circuits[0],
                               term_side='A',
                               site=sites[0]),
            CircuitTermination(circuit=circuits[0],
                               term_side='Z',
                               site=sites[1]),
            CircuitTermination(circuit=circuits[1],
                               term_side='A',
                               site=sites[0]),
            CircuitTermination(circuit=circuits[1],
                               term_side='Z',
                               site=sites[1]),
        )
        CircuitTermination.objects.bulk_create(circuit_terminations)

        cls.form_data = {
            'term_side': 'A',
            'site': sites[2].pk,
            'description': 'New description',
        }
Ejemplo n.º 5
0
    def setUpTestData(cls):

        providers = (
            Provider(name='Provider 1', slug='provider-1', asn=65001, account='1234'),
            Provider(name='Provider 2', slug='provider-2', asn=65002, account='2345'),
            Provider(name='Provider 3', slug='provider-3', asn=65003, account='3456'),
            Provider(name='Provider 4', slug='provider-4', asn=65004, account='4567'),
            Provider(name='Provider 5', slug='provider-5', asn=65005, account='5678'),
        )
        Provider.objects.bulk_create(providers)

        regions = (
            Region(name='Test Region 1', slug='test-region-1'),
            Region(name='Test Region 2', slug='test-region-2'),
        )
        # Can't use bulk_create for models with MPTT fields
        for r in regions:
            r.save()

        sites = (
            Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
            Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
        )
        Site.objects.bulk_create(sites)

        circuit_types = (
            CircuitType(name='Test Circuit Type 1', slug='test-circuit-type-1'),
            CircuitType(name='Test Circuit Type 2', slug='test-circuit-type-2'),
        )
        CircuitType.objects.bulk_create(circuit_types)

        circuits = (
            Circuit(provider=providers[0], type=circuit_types[0], cid='Test Circuit 1'),
            Circuit(provider=providers[1], type=circuit_types[1], cid='Test Circuit 1'),
        )
        Circuit.objects.bulk_create(circuits)

        CircuitTermination.objects.bulk_create((
            CircuitTermination(circuit=circuits[0], site=sites[0], term_side='A', port_speed=1000),
            CircuitTermination(circuit=circuits[1], site=sites[0], term_side='A', port_speed=1000),
        ))
Ejemplo n.º 6
0
    def setUpTestData(cls):

        regions = (
            Region(name='Test Region 1', slug='test-region-1'),
            Region(name='Test Region 2', slug='test-region-2'),
            Region(name='Test Region 3', slug='test-region-3'),
        )
        # Can't use bulk_create for models with MPTT fields
        for r in regions:
            r.save()

        sites = (
            Site(name='Test Site 1', slug='test-site-1', region=regions[0]),
            Site(name='Test Site 2', slug='test-site-2', region=regions[1]),
            Site(name='Test Site 3', slug='test-site-3', region=regions[2]),
        )
        Site.objects.bulk_create(sites)

        roles = (
            Role(name='Role 1', slug='role-1'),
            Role(name='Role 2', slug='role-2'),
            Role(name='Role 3', slug='role-3'),
        )
        Role.objects.bulk_create(roles)

        groups = (
            VLANGroup(name='VLAN Group 1', slug='vlan-group-1', site=sites[0]),
            VLANGroup(name='VLAN Group 2', slug='vlan-group-2', site=sites[1]),
            VLANGroup(name='VLAN Group 3', slug='vlan-group-3', site=None),
        )
        VLANGroup.objects.bulk_create(groups)

        vlans = (
            VLAN(vid=101, name='VLAN 101', site=sites[0], group=groups[0], role=roles[0], status=VLANStatusChoices.STATUS_ACTIVE),
            VLAN(vid=102, name='VLAN 102', site=sites[0], group=groups[0], role=roles[0], status=VLANStatusChoices.STATUS_ACTIVE),
            VLAN(vid=201, name='VLAN 201', site=sites[1], group=groups[1], role=roles[1], status=VLANStatusChoices.STATUS_DEPRECATED),
            VLAN(vid=202, name='VLAN 202', site=sites[1], group=groups[1], role=roles[1], status=VLANStatusChoices.STATUS_DEPRECATED),
            VLAN(vid=301, name='VLAN 301', site=sites[2], group=groups[2], role=roles[2], status=VLANStatusChoices.STATUS_RESERVED),
            VLAN(vid=302, name='VLAN 302', site=sites[2], group=groups[2], role=roles[2], status=VLANStatusChoices.STATUS_RESERVED),
        )
        VLAN.objects.bulk_create(vlans)
Ejemplo n.º 7
0
    def setUpTestData(cls):

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ObjectChanges
        user = User.objects.create_user(username='******')
        for i in range(1, 4):
            oc = site.to_objectchange(action=ObjectChangeActionChoices.ACTION_UPDATE)
            oc.user = user
            oc.request_id = uuid.uuid4()
            oc.save()
Ejemplo n.º 8
0
    def setUp(self):
        user = create_test_user(permissions=[
            'secrets.view_secret',
            'secrets.add_secret',
        ])

        # Set up a master key
        userkey = UserKey(user=user, public_key=PUBLIC_KEY)
        userkey.save()
        master_key = userkey.get_master_key(PRIVATE_KEY)
        self.session_key = SessionKey(userkey=userkey)
        self.session_key.save(master_key)

        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        manufacturer = Manufacturer(name='Manufacturer 1',
                                    slug='manufacturer-1')
        manufacturer.save()

        devicetype = DeviceType(manufacturer=manufacturer,
                                model='Device Type 1')
        devicetype.save()

        devicerole = DeviceRole(name='Device Role 1', slug='device-role-1')
        devicerole.save()

        device = Device(name='Device 1',
                        site=site,
                        device_type=devicetype,
                        device_role=devicerole)
        device.save()

        secretrole = SecretRole(name='Secret Role 1', slug='secret-role-1')
        secretrole.save()

        Secret.objects.bulk_create([
            Secret(device=device,
                   role=secretrole,
                   name='Secret 1',
                   ciphertext=b'1234567890'),
            Secret(device=device,
                   role=secretrole,
                   name='Secret 2',
                   ciphertext=b'1234567890'),
            Secret(device=device,
                   role=secretrole,
                   name='Secret 3',
                   ciphertext=b'1234567890'),
        ])
Ejemplo n.º 9
0
    def setUp(self):

        self.client = Client()

        site = Site(name='Site 1', slug='site-1')
        site.save()

        Rack.objects.bulk_create([
            Rack(name='Rack 1', site=site),
            Rack(name='Rack 2', site=site),
            Rack(name='Rack 3', site=site),
        ])
Ejemplo n.º 10
0
    def setUp(self):

        self.client = Client()

        site = Site(name='Site 1', slug='site-1')
        site.save()

        RackGroup.objects.bulk_create([
            RackGroup(name='Rack Group 1', slug='rack-group-1', site=site),
            RackGroup(name='Rack Group 2', slug='rack-group-2', site=site),
            RackGroup(name='Rack Group 3', slug='rack-group-3', site=site),
        ])
Ejemplo n.º 11
0
    def setUpTestData(cls):

        cls.sites = (
            Site(name='Site 1', slug='site-1'),
            Site(name='Site 2', slug='site-2'),
            Site(name='Site 3', slug='site-3'),
        )
        Site.objects.bulk_create(cls.sites)

        cls.prefixes = (
            Prefix(prefix=IPNetwork('10.0.0.0/24'), site=cls.sites[0]),
            Prefix(prefix=IPNetwork('10.0.1.0/24'), site=cls.sites[0]),
            Prefix(prefix=IPNetwork('10.0.2.0/24'), site=cls.sites[0]),
            Prefix(prefix=IPNetwork('10.0.3.0/24'), site=cls.sites[1]),
            Prefix(prefix=IPNetwork('10.0.4.0/24'), site=cls.sites[1]),
            Prefix(prefix=IPNetwork('10.0.5.0/24'), site=cls.sites[1]),
            Prefix(prefix=IPNetwork('10.0.6.0/24'), site=cls.sites[2]),
            Prefix(prefix=IPNetwork('10.0.7.0/24'), site=cls.sites[2]),
            Prefix(prefix=IPNetwork('10.0.8.0/24'), site=cls.sites[2]),
        )
        Prefix.objects.bulk_create(cls.prefixes)
Ejemplo n.º 12
0
    def setUp(self):
        user = create_test_user(permissions=['ipam.view_vlangroup'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        VLANGroup.objects.bulk_create([
            VLANGroup(name='VLAN Group 1', slug='vlan-group-1', site=site),
            VLANGroup(name='VLAN Group 2', slug='vlan-group-2', site=site),
            VLANGroup(name='VLAN Group 3', slug='vlan-group-3', site=site),
        ])
Ejemplo n.º 13
0
    def setUp(self):
        user = create_test_user(permissions=['dcim.view_rackgroup'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        RackGroup.objects.bulk_create([
            RackGroup(name='Rack Group 1', slug='rack-group-1', site=site),
            RackGroup(name='Rack Group 2', slug='rack-group-2', site=site),
            RackGroup(name='Rack Group 3', slug='rack-group-3', site=site),
        ])
Ejemplo n.º 14
0
    def setUp(self):
        user = create_test_user(permissions=['dcim.view_rack'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        Rack.objects.bulk_create([
            Rack(name='Rack 1', site=site),
            Rack(name='Rack 2', site=site),
            Rack(name='Rack 3', site=site),
        ])
Ejemplo n.º 15
0
    def test_bulk_delete_objects(self):
        sites = (
            Site(name='Site 1',
                 slug='site-1',
                 status=SiteStatusChoices.STATUS_ACTIVE),
            Site(name='Site 2',
                 slug='site-2',
                 status=SiteStatusChoices.STATUS_ACTIVE),
            Site(name='Site 3',
                 slug='site-3',
                 status=SiteStatusChoices.STATUS_ACTIVE),
        )
        Site.objects.bulk_create(sites)

        form_data = {
            'pk': [site.pk for site in sites],
            'confirm': True,
            '_confirm': True,
        }

        request = {
            'path': self._get_url('bulk_delete'),
            'data': post_data(form_data),
        }
        self.add_permissions('dcim.delete_site')
        response = self.client.post(**request)
        self.assertHttpStatus(response, 302)

        objectchange = ObjectChange.objects.get(
            changed_object_type=ContentType.objects.get_for_model(Site),
            changed_object_id=sites[0].pk)
        self.assertEqual(objectchange.changed_object_type,
                         ContentType.objects.get_for_model(Site))
        self.assertEqual(objectchange.changed_object_id, sites[0].pk)
        self.assertEqual(objectchange.action,
                         ObjectChangeActionChoices.ACTION_DELETE)
        self.assertEqual(objectchange.prechange_data['name'], sites[0].name)
        self.assertEqual(objectchange.prechange_data['slug'], sites[0].slug)
        self.assertEqual(objectchange.postchange_data, None)
Ejemplo n.º 16
0
    def setUp(self):
        user = create_test_user(permissions=['ipam.view_prefix'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        Prefix.objects.bulk_create([
            Prefix(family=4, prefix=IPNetwork('10.1.0.0/16'), site=site),
            Prefix(family=4, prefix=IPNetwork('10.2.0.0/16'), site=site),
            Prefix(family=4, prefix=IPNetwork('10.3.0.0/16'), site=site),
        ])
Ejemplo n.º 17
0
    def setUp(self):

        self.client = Client()

        user = User(username='******', email='*****@*****.**')
        user.save()

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ObjectChanges
        for i in range(1, 4):
            site.log_change(user=user, request_id=uuid.uuid4(), action=2)
Ejemplo n.º 18
0
    def setUp(self):

        self.client = Client()

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ConfigContexts
        for i in range(1, 4):
            configcontext = ConfigContext(name='Config Context {}'.format(i),
                                          data='{{"foo": {}}}'.format(i))
            configcontext.save()
            configcontext.sites.add(site)
Ejemplo n.º 19
0
    def test_bulk_delete_objects(self):
        sites = (
            Site(name='Site 1', slug='site-1'),
            Site(name='Site 2', slug='site-2'),
            Site(name='Site 3', slug='site-3'),
        )
        Site.objects.bulk_create(sites)

        data = (
            {
                'id': sites[0].pk,
            },
            {
                'id': sites[1].pk,
            },
            {
                'id': sites[2].pk,
            },
        )
        self.assertEqual(ObjectChange.objects.count(), 0)
        url = reverse('dcim-api:site-list')
        self.add_permissions('dcim.delete_site')

        response = self.client.delete(url, data, format='json', **self.header)
        self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
        self.assertEqual(ObjectChange.objects.count(), 3)

        objectchange = ObjectChange.objects.get(
            changed_object_type=ContentType.objects.get_for_model(Site),
            changed_object_id=sites[0].pk)
        self.assertEqual(objectchange.changed_object_type,
                         ContentType.objects.get_for_model(Site))
        self.assertEqual(objectchange.changed_object_id, sites[0].pk)
        self.assertEqual(objectchange.action,
                         ObjectChangeActionChoices.ACTION_DELETE)
        self.assertEqual(objectchange.prechange_data['name'], 'Site 1')
        self.assertEqual(objectchange.prechange_data['slug'], 'site-1')
        self.assertEqual(objectchange.postchange_data, None)
Ejemplo n.º 20
0
    def setUp(self):
        user = create_test_user(permissions=['extras.view_configcontext'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ConfigContexts
        for i in range(1, 4):
            configcontext = ConfigContext(name='Config Context {}'.format(i),
                                          data='{{"foo": {}}}'.format(i))
            configcontext.save()
            configcontext.sites.add(site)
Ejemplo n.º 21
0
    def setUp(self):
        user = create_test_user(permissions=['extras.view_objectchange'])
        self.client = Client()
        self.client.force_login(user)

        site = Site(name='Site 1', slug='site-1')
        site.save()

        # Create three ObjectChanges
        for i in range(1, 4):
            oc = site.to_objectchange(action=OBJECTCHANGE_ACTION_UPDATE)
            oc.user = user
            oc.request_id = uuid.uuid4()
            oc.save()
Ejemplo n.º 22
0
    def test_invalid_data(self):
        """
        Setting custom field data for a non-applicable (or non-existent) CustomField should raise a ValidationError.
        """
        site = Site(name='Test Site', slug='test-site')

        # Set custom field data
        site.cf['foo'] = 'abc'
        site.cf['bar'] = 'def'
        with self.assertRaises(ValidationError):
            site.clean()

        del(site.cf['bar'])
        site.clean()
Ejemplo n.º 23
0
    def mutate_and_get_payload(cls, input, context, info):
        region = input.get('region')
        tenant = input.get('tenant')

        temp = Site()

        if not_none(region):
            temp.region = Region.objects.get(pk=from_global_id(region)[1])

        if not_none(tenant):
            temp.tenant = Tenant.objects.get(pk=from_global_id(tenant)[1])

        fields = [ 'name', 'slug', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments' ]
        return NewSite(site=set_and_save(fields, input, temp))
Ejemplo n.º 24
0
    def test_view_object_with_custom_link(self):
        customlink = CustomLink(
            content_type=ContentType.objects.get_for_model(Site),
            name='Test',
            link_text='FOO {{ obj.name }} BAR',
            link_url='http://example.com/?site={{ obj.slug }}',
            new_window=False)
        customlink.save()

        site = Site(name='Test Site', slug='test-site')
        site.save()

        response = self.client.get(site.get_absolute_url(), follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertIn(f'FOO {site.name} BAR', str(response.content))
Ejemplo n.º 25
0
    def setUpTestData(cls):

        sites = (
            Site(name='Site 1', slug='site-1'),
            Site(name='Site 2', slug='site-2'),
        )
        Site.objects.bulk_create(sites)

        VLANGroup.objects.bulk_create([
            VLANGroup(name='VLAN Group 1', slug='vlan-group-1',
                      scope=sites[0]),
            VLANGroup(name='VLAN Group 2', slug='vlan-group-2',
                      scope=sites[0]),
            VLANGroup(name='VLAN Group 3', slug='vlan-group-3',
                      scope=sites[0]),
        ])

        tags = create_tags('Alpha', 'Bravo', 'Charlie')

        cls.form_data = {
            'name': 'VLAN Group X',
            'slug': 'vlan-group-x',
            'description': 'A new VLAN group',
            'tags': [t.pk for t in tags],
        }

        cls.csv_data = (
            f"name,slug,scope_type,scope_id,description",
            f"VLAN Group 4,vlan-group-4,,,Fourth VLAN group",
            f"VLAN Group 5,vlan-group-5,dcim.site,{sites[0].pk},Fifth VLAN group",
            f"VLAN Group 6,vlan-group-6,dcim.site,{sites[1].pk},Sixth VLAN group",
        )

        cls.bulk_edit_data = {
            'description': 'New description',
        }
Ejemplo n.º 26
0
    def test_cf_data(self):
        """
        Check that custom field data is present on the instance immediately after being set and after being fetched
        from the database.
        """
        site = Site(name='Test Site', slug='test-site')

        # Check custom field data on new instance
        site.cf['foo'] = 'abc'
        self.assertEqual(site.cf['foo'], 'abc')

        # Check custom field data from database
        site.save()
        site = Site.objects.get(name='Test Site')
        self.assertEqual(site.cf['foo'], 'abc')
Ejemplo n.º 27
0
    def test_missing_required_field(self):
        """
        Check that a ValidationError is raised if any required custom fields are not present.
        """
        cf3 = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='baz', required=True)
        cf3.save()
        cf3.content_types.set([ContentType.objects.get_for_model(Site)])

        site = Site(name='Test Site', slug='test-site')

        # Set custom field data with a required field omitted
        site.cf['foo'] = 'abc'
        with self.assertRaises(ValidationError):
            site.clean()

        site.cf['baz'] = 'def'
        site.clean()
Ejemplo n.º 28
0
    def test_delete_object(self):

        site = Site(name='Test Site 1', slug='test-site-1')
        site.save()

        self.assertEqual(ObjectChange.objects.count(), 0)

        url = reverse('dcim-api:site-detail', kwargs={'pk': site.pk})
        response = self.client.delete(url, **self.header)

        self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
        self.assertEqual(Site.objects.count(), 0)

        oc = ObjectChange.objects.first()
        self.assertEqual(oc.changed_object, None)
        self.assertEqual(oc.object_repr, site.name)
        self.assertEqual(oc.action, OBJECTCHANGE_ACTION_DELETE)
Ejemplo n.º 29
0
    def evaluate_ordering(self, names):

        # Create the Sites
        Site.objects.bulk_create(
            Site(name=name, slug=name.lower()) for name in names
        )

        # Validate forward ordering
        self.assertEqual(
            names,
            list(Site.objects.values_list('name', flat=True))
        )

        # Validate reverse ordering
        self.assertEqual(
            list(reversed(names)),
            list(Site.objects.reverse().values_list('name', flat=True))
        )
Ejemplo n.º 30
0
    def test_delete_object(self):
        site = Site(name='Test Site 1',
                    slug='test-site-1',
                    custom_field_data={'my_field': 'ABC'})
        site.save()
        site.tags.set(*Tag.objects.all()[:2])
        self.assertEqual(ObjectChange.objects.count(), 0)
        self.add_permissions('dcim.delete_site')
        url = reverse('dcim-api:site-detail', kwargs={'pk': site.pk})

        response = self.client.delete(url, **self.header)
        self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
        self.assertEqual(Site.objects.count(), 0)

        oc = ObjectChange.objects.first()
        self.assertEqual(oc.changed_object, None)
        self.assertEqual(oc.object_repr, site.name)
        self.assertEqual(oc.action, ObjectChangeActionChoices.ACTION_DELETE)
        self.assertEqual(oc.object_data['custom_fields'], {'my_field': 'ABC'})
        self.assertEqual(oc.object_data['tags'], ['Tag 1', 'Tag 2'])