예제 #1
0
 def create_attributes(self):
     self.attribute1 = CIAttribute(
         name='Attribute 1', attribute_type=CI_ATTRIBUTE_TYPES.INTEGER,
         choices='',
     )
     self.attribute1.save()
     self.attribute1.ci_types.add(self.types[0]),
     self.attribute_value1 = CIAttributeValue(
         ci=self.ci1, attribute=self.attribute1,
     )
     self.attribute_value1.value = 10
     self.attribute_value1.save()
예제 #2
0
 def create_attributes(self):
     self.attribute1 = CIAttribute(name="Attribute 1", attribute_type=CI_ATTRIBUTE_TYPES.INTEGER, choices="")
     self.attribute1.save()
     self.attribute1.ci_types.add(self.types[0]),
     self.attribute_value1 = CIAttributeValue(ci=self.ci1, attribute=self.attribute1)
     self.attribute_value1.value = 10
     self.attribute_value1.save()
예제 #3
0
class CMDBApiTest(TestCase):
    def setUp(self):
        self.user = create_user("api_user", "*****@*****.**", "password")
        self.layers = CILayer.objects.all()
        self.types = CIType.objects.all()
        self.create_owners()
        self.create_cis()
        self.create_ownerships()
        self.create_attributes()
        self.create_relations()
        self.headers = {
            "HTTP_ACCEPT": "application/json",
            "HTTP_AUTHORIZATION": "ApiKey {}:{}".format(self.user.username, self.user.api_key.key),
        }
        cache.delete("api_user_accesses")

    def create_owners(self):
        self.owner1 = CIOwner(
            first_name="first_name_owner1",
            last_name="last_name_owner1",
            email="*****@*****.**",
        )
        self.owner1.save()
        self.owner2 = CIOwner(
            first_name="first_name_owner2",
            last_name="last_name_owner2",
            email="*****@*****.**",
        )
        self.owner2.save()

    def create_cis(self):
        self.ci1 = CI(uid="uid-ci1", type=self.types[0], barcode="barcodeci1", name="ciname1")
        self.ci1.save()
        self.ci1.layers = [self.layers[0].id, self.layers[1].id]
        self.ci1.save()
        self.ci2 = CI(uid="uid-ci2", type=self.types[1], barcode="barcodeci2", name="ciname2")
        self.ci2.save()
        self.ci2.layers = [self.layers[0].id]
        self.ci2.save()
        self.ci3 = CI(uid="other-ci3", type=self.types[1], barcode="otherbarcodeci3", name="otherci")
        self.ci3.save()
        self.ci3.layers = [self.layers[1].id]
        self.ci3.save()

    def create_ownerships(self):
        self.ciownership1 = CIOwnership(ci=self.ci1, owner=self.owner1, type=CIOwnershipType.technical)
        self.ciownership1.save()
        self.ciownership2 = CIOwnership(ci=self.ci1, owner=self.owner2, type=CIOwnershipType.business)
        self.ciownership2.save()
        self.ciownership3 = CIOwnership(ci=self.ci2, owner=self.owner2, type=CIOwnershipType.business)
        self.ciownership3.save()

    def create_relations(self):
        self.relation1 = CIRelation(parent=self.ci1, child=self.ci2, type=CI_RELATION_TYPES.CONTAINS)
        self.relation1.save()
        self.relation2 = CIRelation(parent=self.ci2, child=self.ci3, type=CI_RELATION_TYPES.HASROLE)
        self.relation2.save()

    def create_attributes(self):
        self.attribute1 = CIAttribute(name="Attribute 1", attribute_type=CI_ATTRIBUTE_TYPES.INTEGER, choices="")
        self.attribute1.save()
        self.attribute1.ci_types.add(self.types[0]),
        self.attribute_value1 = CIAttributeValue(ci=self.ci1, attribute=self.attribute1)
        self.attribute_value1.value = 10
        self.attribute_value1.save()

    def test_layers(self):
        path = "/api/v0.9/cilayers/"
        response = self.client.get(path=path, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci_layer["resource_uri"] for ci_layer in json_data["objects"]]

        response = self.client.get(path=resource_uris[0], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["name"], self.layers[0].name)

        response = self.client.get(resource_uris[1], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["name"], self.layers[1].name)

    def test_types(self):
        path = "/api/v0.9/citypes/"
        response = self.client.get(path=path, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci_type["resource_uri"] for ci_type in json_data["objects"]]
        response = self.client.get(path=resource_uris[0], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)

        self.assertEqual(json_data["name"], self.types[0].name)

        response = self.client.get(resource_uris[1], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["name"], self.types[1].name)

    def test_ci(self):
        path = "/api/v0.9/ci/"
        response = self.client.get(path, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci["resource_uri"] for ci in json_data["objects"]]

        response = self.client.get(resource_uris[0], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["layers"][0]["name"], self.layers[0].name)
        self.assertEqual(json_data["layers"][1]["name"], self.layers[1].name)
        self.assertEqual(json_data["barcode"], self.ci1.barcode)
        self.assertEqual(json_data["name"], self.ci1.name)
        self.assertEqual(json_data["type"]["name"], self.ci1.type.name)
        self.assertEqual(json_data["uid"], self.ci1.uid)
        self.assertEqual(json_data["technical_owners"][0]["first_name"], self.owner1.first_name)
        self.assertEqual(json_data["business_owners"][0]["first_name"], self.owner2.first_name)

        response = self.client.get(resource_uris[1], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["layers"][0]["name"], self.layers[0].name)
        self.assertEqual(json_data["barcode"], self.ci2.barcode)
        self.assertEqual(json_data["name"], self.ci2.name)
        self.assertEqual(json_data["type"]["name"], self.ci2.type.name)
        self.assertEqual(json_data["uid"], self.ci2.uid)
        self.assertFalse(json_data["technical_owners"])
        self.assertEqual(json_data["business_owners"][0]["first_name"], self.owner2.first_name)

    def test_ownership(self):
        """Test the direct and effective ownerships."""
        path1 = "/api/v0.9/ci/{}/".format(self.ci1.id)
        path3 = "/api/v0.9/ci/{}/".format(self.ci3.id)
        ci1_data = json.loads(self.client.get(path1, **self.headers).content)
        ci3_data = json.loads(self.client.get(path3, **self.headers).content)
        # CI1 has its own owners
        self.assertListEqual(ci1_data["business_owners"], ci1_data["effective_business_owners"])
        # CI3 inherits owners from CI1
        self.assertListEqual(ci3_data["business_owners"], [])
        self.assertListEqual(ci3_data["effective_business_owners"], ci1_data["business_owners"])

    def test_post_ci(self):
        """POST to ci collection should create a new CI"""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps(
            {
                "uid": "uid-ci-api-1",
                "type": "/api/v0.9/citypes/{0}/".format(self.types[0].id),
                "barcode": "barcodeapi1",
                "name": "ciname from api 1",
                "layers": ["/api/v0.9/cilayers/5/"],
                "business_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner1.id)],
                "technical_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner2.id)],
                "attributes": [
                    {"name": "SLA value", "value": 0.7},
                    {
                        "name": "Documentation Link",
                        "value": "http://www.gutenberg.org/files/27827/" "27827-h/27827-h.htm",
                    },
                ],
            }
        )
        resp = self.client.post("/api/v0.9/ci/?", ci_data, content_type="application/json", **self.headers)
        self.assertEqual(CI.objects.count(), ci_count_before + 1)
        created_id = int(resp["Location"].split("/")[-2])
        created = CI.objects.get(pk=created_id)
        self.assertEqual(created.name, "ciname from api 1")
        self.assertSetEqual(set(created.business_owners.all()), {self.owner1})
        self.assertSetEqual(
            set(av.value for av in created.ciattributevalue_set.all()),
            {0.7, "http://www.gutenberg.org/files/27827/27827-h/27827-h.htm"},
        )

    def test_put_ci(self):
        """PUT should edit existing CI"""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps(
            {
                "uid": "uid-ci-api-1",
                "type": "/api/v0.9/citypes/{0}/".format(self.types[0].id),
                "barcode": "barcodeapi1",
                "name": "ciname from api 1",
                "layers": ["/api/v0.9/cilayers/5/"],
                "business_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner1.id)],
                "technical_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner2.id)],
                "attributes": [
                    {"name": "SLA value", "value": 0.7},
                    {
                        "name": "Documentation Link",
                        "value": "http://www.gutenberg.org/files/27827/" "27827-h/27827-h.htm",
                    },
                ],
            }
        )
        self.client.put(
            "/api/v0.9/ci/{0}/".format(self.ci1.id), ci_data, content_type="application/json", **self.headers
        )
        self.assertEqual(CI.objects.count(), ci_count_before)
        edited = CI.objects.get(pk=self.ci1.id)
        self.assertEqual(edited.name, "ciname from api 1")
        self.assertSetEqual(set(edited.business_owners.all()), {self.owner1})
        self.assertSetEqual(
            set(av.value for av in edited.ciattributevalue_set.all()),
            {0.7, "http://www.gutenberg.org/files/27827/27827-h/27827-h.htm"},
        )

    def test_patch(self):
        """PATCH should edit some attributes."""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps(
            {
                "business_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner1.id)],
                "technical_owners": ["/api/v0.9/ciowners/{0}/".format(self.owner2.id)],
                "attributes": [
                    {"name": "SLA value", "value": 0.7},
                    {
                        "name": "Documentation Link",
                        "value": "http://www.gutenberg.org/files/27827/" "27827-h/27827-h.htm",
                    },
                ],
            }
        )
        req_data = {
            "CONTENT_LENGTH": len(ci_data),
            "CONTENT_TYPE": "application/json",
            "PATH_INFO": "/api/v0.9/ci/{0}/".format(self.ci1.id),
            "REQUEST_METHOD": "PATCH",
            "wsgi.input": FakePayload(ci_data),
        }
        req_data.update(self.headers)
        self.client.request(**req_data)
        self.assertEqual(CI.objects.count(), ci_count_before)
        edited = CI.objects.get(pk=self.ci1.id)
        self.assertEqual(edited.name, "ciname1")
        self.assertEqual(edited.uid, "uid-ci1")
        self.assertSetEqual(set(edited.business_owners.all()), {self.owner1})
        self.assertSetEqual(
            set(av.value for av in edited.ciattributevalue_set.all()),
            {0.7, "http://www.gutenberg.org/files/27827/27827-h/27827-h.htm"},
        )

    def test_get_attribute(self):
        path = "/api/v0.9/ci/{0}/".format(self.ci1.id)
        response = self.client.get(path, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertListEqual(json_data["attributes"], [{"name": "Attribute 1", "value": 10}])

    def test_relations(self):
        path = "/api/v0.9/cirelation/"
        response = self.client.get(path, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci_relation["resource_uri"] for ci_relation in json_data["objects"]]

        response = self.client.get(resource_uris[0], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["parent"], self.ci1.id)
        self.assertEqual(json_data["child"], self.ci2.id)
        self.assertEqual(json_data["type"], CI_RELATION_TYPES.CONTAINS)

        response = self.client.get(resource_uris[1], **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["parent"], self.ci2.id)
        self.assertEqual(json_data["child"], self.ci3.id)
        self.assertEqual(json_data["type"], CI_RELATION_TYPES.HASROLE)

    def test_ci_filter_exact(self):
        path = "/api/v0.9/ci/"
        data = {"name__exact": "otherci"}
        response = self.client.get(path, data=data, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci["resource_uri"] for ci in json_data["objects"]]
        self.assertEqual(len(resource_uris), 1)
        response = self.client.get(resource_uris[0], data, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["layers"][0]["name"], self.layers[1].name)
        self.assertEqual(json_data["barcode"], self.ci3.barcode)
        self.assertEqual(json_data["name"], self.ci3.name)
        self.assertEqual(json_data["type"]["name"], self.ci3.type.name)
        self.assertEqual(json_data["uid"], self.ci3.uid)

    def test_ci_filter_startswith(self):
        path = "/api/v0.9/ci/"
        data = {"name__startswith": "ciname"}
        response = self.client.get(path=path, data=data, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci["resource_uri"] for ci in json_data["objects"]]
        self.assertEqual(len(resource_uris), 2)
        response = self.client.get(resource_uris[0], data=data, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["layers"][0]["name"], self.layers[0].name)
        self.assertEqual(json_data["barcode"], self.ci1.barcode)
        self.assertEqual(json_data["name"], self.ci1.name)
        self.assertEqual(json_data["type"]["name"], self.ci1.type.name)
        self.assertEqual(json_data["uid"], self.ci1.uid)

        response = self.client.get(resource_uris[1], data=data, **self.headers)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data["layers"][0]["name"], self.layers[0].name)
        self.assertEqual(json_data["barcode"], self.ci2.barcode)
        self.assertEqual(json_data["name"], self.ci2.name)
        self.assertEqual(json_data["type"]["name"], self.ci2.type.name)
        self.assertEqual(json_data["uid"], self.ci2.uid)
예제 #4
0
class CMDBApiTest(UserTestCase):

    def setUp(self):
        self.layers = CILayer.objects.all()
        self.types = CIType.objects.all()
        self.create_owners()
        self.create_cis()
        self.create_ownerships()
        self.create_attributes()
        self.create_relations()
        super(CMDBApiTest, self).setUp()

    def create_owners(self):
        self.owner1 = CIOwnerFactory()
        self.owner2 = CIOwnerFactory()

    def create_cis(self):
        self.ci1 = CI(
            uid='uid-ci1',
            type=self.types[0],
            barcode='barcodeci1',
            name='ciname1',
        )
        self.ci1.save()
        self.ci1.layers = [self.layers[0].id, self.layers[1].id]
        self.ci1.save()
        self.ci2 = CI(
            uid='uid-ci2',
            type=self.types[1],
            barcode='barcodeci2',
            name='ciname2',
        )
        self.ci2.save()
        self.ci2.layers = [self.layers[0].id]
        self.ci2.save()
        self.ci3 = CI(
            uid='other-ci3',
            type=self.types[1],
            barcode='otherbarcodeci3',
            name='otherci',
        )
        self.ci3.save()
        self.ci3.layers = [self.layers[1].id]
        self.ci3.save()

    def create_ownerships(self):
        self.ciownership1 = CIOwnership(
            ci=self.ci1,
            owner=self.owner1,
            type=CIOwnershipType.technical,
        )
        self.ciownership1.save()
        self.ciownership2 = CIOwnership(
            ci=self.ci1,
            owner=self.owner2,
            type=CIOwnershipType.business,
        )
        self.ciownership2.save()
        self.ciownership3 = CIOwnership(
            ci=self.ci2,
            owner=self.owner2,
            type=CIOwnershipType.business,
        )
        self.ciownership3.save()

    def create_relations(self):
        self.relation1 = CIRelation(
            parent=self.ci1,
            child=self.ci2,
            type=CI_RELATION_TYPES.CONTAINS,
        )
        self.relation1.save()
        self.relation2 = CIRelation(
            parent=self.ci2,
            child=self.ci3,
            type=CI_RELATION_TYPES.HASROLE,
        )
        self.relation2.save()

    def create_attributes(self):
        self.attribute1 = CIAttribute(
            name='Attribute 1', attribute_type=CI_ATTRIBUTE_TYPES.INTEGER,
            choices='',
        )
        self.attribute1.save()
        self.attribute1.ci_types.add(self.types[0]),
        self.attribute_value1 = CIAttributeValue(
            ci=self.ci1, attribute=self.attribute1,
        )
        self.attribute_value1.value = 10
        self.attribute_value1.save()

    def test_layers(self):
        path = "/api/v0.9/cilayers/"
        response = self.get(path)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [
            ci_layer['resource_uri'] for ci_layer in json_data['objects']
        ]
        response = self.get(resource_uris[0])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['name'], self.layers[0].name)

        response = self.get(resource_uris[1])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['name'], self.layers[1].name)

    def test_types(self):
        path = "/api/v0.9/citypes/"
        response = self.get(path=path)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [
            ci_type['resource_uri'] for ci_type in json_data['objects']
        ]
        response = self.get(path=resource_uris[0])
        json_string = response.content
        json_data = json.loads(json_string)

        self.assertEqual(json_data['name'], self.types[0].name)

        response = self.get(resource_uris[1])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['name'], self.types[1].name)

    def test_ci(self):
        path = "/api/v0.9/ci/"
        response = self.get(path)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci['resource_uri'] for ci in json_data['objects']]

        response = self.get(resource_uris[0])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['layers'][0]['name'], self.layers[0].name)
        self.assertEqual(json_data['layers'][1]['name'], self.layers[1].name)
        self.assertEqual(json_data['barcode'], self.ci1.barcode)
        self.assertEqual(json_data['name'], self.ci1.name)
        self.assertEqual(json_data['type']['name'], self.ci1.type.name)
        self.assertEqual(json_data['uid'], self.ci1.uid)
        self.assertEqual(
            json_data['technical_owners'][0]['first_name'],
            self.owner1.first_name,
        )
        self.assertEqual(
            json_data['business_owners'][0]['first_name'],
            self.owner2.first_name,
        )

        response = self.get(resource_uris[1])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['layers'][0]['name'], self.layers[0].name)
        self.assertEqual(json_data['barcode'], self.ci2.barcode)
        self.assertEqual(json_data['name'], self.ci2.name)
        self.assertEqual(json_data['type']['name'], self.ci2.type.name)
        self.assertEqual(json_data['uid'], self.ci2.uid)
        self.assertFalse(json_data['technical_owners'])
        self.assertEqual(
            json_data['business_owners'][0]['first_name'],
            self.owner2.first_name,
        )

    def test_ownership(self):
        """Test the direct and effective ownerships."""
        path1 = '/api/v0.9/ci/{}/'.format(self.ci1.id)
        path3 = '/api/v0.9/ci/{}/'.format(self.ci3.id)
        ci1_data = json.loads(self.get(path1).content)
        ci3_data = json.loads(self.get(path3).content)
        # CI1 has its own owners
        self.assertListEqual(
            ci1_data['business_owners'],
            ci1_data['effective_business_owners']
        )
        # CI3 inherits owners from CI1
        self.assertListEqual(ci3_data['business_owners'], [])
        self.assertListEqual(
            ci3_data['effective_business_owners'],
            ci1_data['business_owners']
        )

    def test_post_ci(self):
        """POST to ci collection should create a new CI"""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps({
            'uid': 'uid-ci-api-1',
            'type': '/api/v0.9/citypes/{0}/'.format(self.types[0].id),
            'barcode': 'barcodeapi1',
            'name': 'ciname from api 1',
            'layers': ['/api/v0.9/cilayers/5/'],
            'business_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner1.id)
            ],
            'technical_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner2.id)
            ],
            'attributes': [
                {
                    'name': 'SLA value',
                    'value': 0.7,
                }, {
                    'name': 'Documentation Link',
                    'value': 'http://www.gutenberg.org/files/27827/'
                    '27827-h/27827-h.htm',
                },
            ],
        })
        resp = self.post(
            '/api/v0.9/ci/?',
            ci_data,
            content_type='application/json',
        )
        self.assertEqual(CI.objects.count(), ci_count_before + 1)
        created_id = int(resp['Location'].split('/')[-2])
        created = CI.objects.get(pk=created_id)
        self.assertEqual(created.name, 'ciname from api 1')
        self.assertSetEqual(
            set(created.business_owners.all()),
            {self.owner1},
        )
        self.assertSetEqual(
            set(av.value for av in created.ciattributevalue_set.all()),
            {
                0.7,
                'http://www.gutenberg.org/files/27827/27827-h/27827-h.htm',
            },
        )

    def test_put_ci(self):
        """PUT should edit existing CI"""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps({
            'uid': 'uid-ci-api-1',
            'type': '/api/v0.9/citypes/{0}/'.format(self.types[0].id),
            'barcode': 'barcodeapi1',
            'name': 'ciname from api 1',
            'layers': ['/api/v0.9/cilayers/5/'],
            'business_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner1.id)
            ],
            'technical_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner2.id)
            ],
            'related': [],
            'attributes': [
                {
                    'name': 'SLA value',
                    'value': 0.7,
                }, {
                    'name': 'Documentation Link',
                    'value': 'http://www.gutenberg.org/files/27827/'
                    '27827-h/27827-h.htm',
                },
            ],
        })
        self.put(
            '/api/v0.9/ci/{0}/'.format(
                self.ci1.id,
            ),
            ci_data,
            content_type='application/json',
        )
        self.assertEqual(CI.objects.count(), ci_count_before)
        edited = CI.objects.get(pk=self.ci1.id)
        self.assertEqual(edited.name, 'ciname from api 1')
        self.assertSetEqual(
            set(edited.business_owners.all()),
            {self.owner1},
        )
        self.assertSetEqual(
            set(av.value for av in edited.ciattributevalue_set.all()),
            {
                0.7,
                'http://www.gutenberg.org/files/27827/27827-h/27827-h.htm',
            },
        )

    def test_patch(self):
        """PATCH should edit some attributes."""
        ci_count_before = CI.objects.count()
        ci_data = json.dumps({
            'business_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner1.id)
            ],
            'technical_owners': [
                '/api/v0.9/ciowners/{0}/'.format(self.owner2.id)
            ],
            'attributes': [
                {
                    'name': 'SLA value',
                    'value': 0.7,
                }, {
                    'name': 'Documentation Link',
                    'value': 'http://www.gutenberg.org/files/27827/'
                    '27827-h/27827-h.htm',
                },
            ],
        })
        self.patch(
            '/api/v0.9/ci/{0}/'.format(self.ci1.id),
            ci_data,
            CONTENT_TYPE='application/json'

        )
        self.assertEqual(CI.objects.count(), ci_count_before)
        edited = CI.objects.get(pk=self.ci1.id)
        self.assertEqual(edited.name, 'ciname1')
        self.assertEqual(edited.uid, 'uid-ci1')
        self.assertSetEqual(
            set(edited.business_owners.all()),
            {self.owner1},
        )
        self.assertSetEqual(
            set(av.value for av in edited.ciattributevalue_set.all()),
            {
                0.7,
                'http://www.gutenberg.org/files/27827/27827-h/27827-h.htm',
            },
        )

    def test_patch_relations(self):
        """A test for adding relations via 0.10 version of API."""
        ci_data = json.dumps({
            'related': [
                {
                    'dir': 'INCOMING',
                    'type': 'HASROLE',
                    'id': self.ci2.id,
                }, {
                    'dir': 'OUTGOING',
                    'type': 'CONTAINS',
                    'id': self.ci3.id,
                }
            ],
        })
        req_data = {
            'CONTENT_LENGTH': len(ci_data),
            'CONTENT_TYPE': 'application/json',
            'PATH_INFO': '/api/v0.10/ci/{0}/'.format(self.ci1.id),
            'REQUEST_METHOD': 'PATCH',
            'wsgi.input': FakePayload(ci_data),
        }
        req_data.update(self.headers)
        self.client.request(**req_data)
        rel1 = CIRelation.objects.get(
            child_id=self.ci1.id,
            parent_id=self.ci2.id,
            type=CI_RELATION_TYPES.HASROLE.id,
        )
        rel2 = CIRelation.objects.get(
            child_id=self.ci3.id,
            parent_id=self.ci1.id,
            type=CI_RELATION_TYPES.CONTAINS.id,
        )


    def test_get_attribute(self):
        path = "/api/v0.9/ci/{0}/".format(self.ci1.id)
        response = self.get(path)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertListEqual(json_data['attributes'], [
            {'name': 'Attribute 1', 'value': 10}
        ])

    def test_relations(self):
        path = "/api/v0.9/cirelation/"
        response = self.get(path)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [
            ci_relation['resource_uri'] for ci_relation in json_data['objects']
        ]

        response = self.get(resource_uris[0])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['parent'], self.ci1.id)
        self.assertEqual(json_data['child'], self.ci2.id)
        self.assertEqual(json_data['type'], CI_RELATION_TYPES.CONTAINS)

        response = self.get(resource_uris[1])
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['parent'], self.ci2.id)
        self.assertEqual(json_data['child'], self.ci3.id)
        self.assertEqual(json_data['type'], CI_RELATION_TYPES.HASROLE)

    def test_ci_filter_exact(self):
        path = "/api/v0.9/ci/"
        data = {'name__exact': 'otherci'}
        response = self.get(path, data=data)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci['resource_uri'] for ci in json_data['objects']]
        self.assertEqual(len(resource_uris), 1)
        response = self.get(resource_uris[0], data)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['layers'][0]['name'], self.layers[1].name)
        self.assertEqual(json_data['barcode'], self.ci3.barcode)
        self.assertEqual(json_data['name'], self.ci3.name)
        self.assertEqual(json_data['type']['name'], self.ci3.type.name)
        self.assertEqual(json_data['uid'], self.ci3.uid)

    def test_ci_filter_startswith(self):
        path = "/api/v0.9/ci/"
        data = {'name__startswith': 'ciname'}
        response = self.get(path=path, data=data)
        json_string = response.content
        json_data = json.loads(json_string)
        resource_uris = [ci['resource_uri'] for ci in json_data['objects']]
        self.assertEqual(len(resource_uris), 2)
        response = self.get(resource_uris[0], data=data)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['layers'][0]['name'], self.layers[0].name)
        self.assertEqual(json_data['barcode'], self.ci1.barcode)
        self.assertEqual(json_data['name'], self.ci1.name)
        self.assertEqual(json_data['type']['name'], self.ci1.type.name)
        self.assertEqual(json_data['uid'], self.ci1.uid)

        response = self.get(resource_uris[1], data=data)
        json_string = response.content
        json_data = json.loads(json_string)
        self.assertEqual(json_data['layers'][0]['name'], self.layers[0].name)
        self.assertEqual(json_data['barcode'], self.ci2.barcode)
        self.assertEqual(json_data['name'], self.ci2.name)
        self.assertEqual(json_data['type']['name'], self.ci2.type.name)
        self.assertEqual(json_data['uid'], self.ci2.uid)

    def test_filter_related(self):
        path = "/api/v0.10/ci/"
        data = {'parent': self.ci1.id, 'child': self.ci3.id}
        response = self.get(path=path, data=data)
        json_data = json.loads(response.content)
        self.assertEqual(len(json_data['objects']), 1)
        self.assertEqual(json_data['objects'][0]['id'], self.ci2.id)