Пример #1
0
    def test_one_to_one(self):
        """
        Test a related ToOne resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Company.objects.count(), 0)
        self.assertEqual(Address.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'company': {
                'name': 'Yum Yum Pie Factory!',
                'address': {
                    'line': 'Somewhere, Utah'
                }
            }
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.raw_post_data = json.dumps(data)
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content)
        self.assertEqual(person['name'], 'Joan Rivers')

        company = person['company']
        self.assertEqual(company['name'], 'Yum Yum Pie Factory!')

        address = company['address']
        self.assertEqual(address['line'], 'Somewhere, Utah')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        request.raw_post_data = resp.content
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #2
0
    def test_many_to_many(self):
        """
        Test a related ToMany resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(Bone.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [
                {
                    'name': 'Snoopy',
                    'bones': [
                        {
                            'color': 'white'
                        }
                    ]
                }
            ]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.path = reverse('api_dispatch_list', kwargs={'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(Bone.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')
        self.assertEqual(len(dog['bones']), 1)

        bone = dog['bones'][0]
        self.assertEqual(bone['color'], 'white')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.set_body(json.dumps(person))
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #3
0
    def test_many_to_many(self):
        """
        Test a related ToMany resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(Bone.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [
                {
                    'name': 'Snoopy',
                    'bones': [
                        {
                            'color': 'white'
                        }
                    ]
                }
            ]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.path = reverse('api_dispatch_list', kwargs={'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(Bone.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')
        self.assertEqual(len(dog['bones']), 1)

        bone = dog['bones'][0]
        self.assertEqual(bone['color'], 'white')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.set_body(json.dumps(person))
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #4
0
    def test_many_to_one_extra_data_ignored(self):
        """
        Test a related ToMany resource with a nested full ToOne resource
        
        FieldError would result when extra data is included on an embedded
        resource for an already saved object.
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {"name": "Joan Rivers", "dogs": [{"name": "Snoopy", "house": {"color": "Red"}}]}

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = "GET"
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(person["name"], "Joan Rivers")
        self.assertEqual(len(person["dogs"]), 1)

        dog = person["dogs"][0]
        self.assertEqual(dog["name"], "Snoopy")

        house = dog["house"]
        self.assertEqual(house["color"], "Red")

        # clients may include extra data, which should be ignored. Make extra data is ignored on the resource and sub resources.
        person["thisfieldshouldbeignored"] = "foobar"
        person["dogs"][0]["thisfieldshouldbeignored"] = "foobar"

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        request.set_body(json.dumps(person))
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #5
0
    def test_one_to_one(self):
        """
        Test a related ToOne resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Company.objects.count(), 0)
        self.assertEqual(Address.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'company': {
                'name': 'Yum Yum Pie Factory!',
                'address': {
                    'line': 'Somewhere, Utah'
                }
            }
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': pk,
            'resource_name': pr._meta.resource_name,
            'api_name': pr._meta.api_name
        })
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(person['name'], 'Joan Rivers')

        company = person['company']
        self.assertEqual(company['name'], 'Yum Yum Pie Factory!')

        address = company['address']
        self.assertEqual(address['line'], 'Somewhere, Utah')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': pk,
            'resource_name': pr._meta.resource_name,
            'api_name': pr._meta.api_name
        })
        request.set_body(resp.content.decode('utf-8'))
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #6
0
    def test_one_to_many(self):
        """
        Test a related ToOne resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Company.objects.count(), 0)
        self.assertEqual(Product.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'company': {
                'name': 'Yum Yum Pie Factory!',
                'products': [
                    {
                        'name': 'Tasty Pie'
                    }
                ]
            }
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        setattr(request, self.body_attr, json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Company.objects.count(), 1)
        self.assertEqual(Product.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content)
        self.assertEqual(person['name'], 'Joan Rivers')

        company = person['company']
        self.assertEqual(company['name'], 'Yum Yum Pie Factory!')
        self.assertEqual(len(company['products']), 1)

        product = company['products'][0]
        self.assertEqual(product['name'], 'Tasty Pie')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        setattr(request, self.body_attr, json.dumps(person))
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #7
0
    def test_many_to_one(self):
        """
        Test a related ToMany resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [
                {
                    'name': 'Snoopy',
                    'house': {
                        'color': 'Red'
                    }
                }
            ]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.raw_post_data = json.dumps(data)
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content)
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')

        house = dog['house']
        self.assertEqual(house['color'], 'Red')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.raw_post_data = json.dumps(person)
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #8
0
    def test_one_to_many(self):
        """
        Test a related ToOne resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Company.objects.count(), 0)
        self.assertEqual(Product.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'company': {
                'name': 'Yum Yum Pie Factory!',
                'products': [
                    {
                        'name': 'Tasty Pie'
                    }
                ]
            }
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        setattr(request, self.body_attr, json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Company.objects.count(), 1)
        self.assertEqual(Product.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content)
        self.assertEqual(person['name'], 'Joan Rivers')

        company = person['company']
        self.assertEqual(company['name'], 'Yum Yum Pie Factory!')
        self.assertEqual(len(company['products']), 1)

        product = company['products'][0]
        self.assertEqual(product['name'], 'Tasty Pie')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        setattr(request, self.body_attr, json.dumps(person))
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #9
0
    def test_many_to_one(self):
        """
        Test a related ToMany resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {"name": "Joan Rivers", "dogs": [{"name": "Snoopy", "house": {"color": "Red"}}]}

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = "GET"
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(person["name"], "Joan Rivers")
        self.assertEqual(len(person["dogs"]), 1)

        dog = person["dogs"][0]
        self.assertEqual(dog["name"], "Snoopy")

        house = dog["house"]
        self.assertEqual(house["color"], "Red")

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        request.set_body(json.dumps(person))
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #10
0
    def test_one_to_one(self):
        """
        Test a related ToOne resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Company.objects.count(), 0)
        self.assertEqual(Address.objects.count(), 0)

        pr = PersonResource()

        data = {
            "name": "Joan Rivers",
            "company": {"name": "Yum Yum Pie Factory!", "address": {"line": "Somewhere, Utah"}},
        }

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = "GET"
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(person["name"], "Joan Rivers")

        company = person["company"]
        self.assertEqual(company["name"], "Yum Yum Pie Factory!")

        address = company["address"]
        self.assertEqual(address["line"], "Somewhere, Utah")

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        request.set_body(resp.content.decode("utf-8"))
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #11
0
    def test_many_to_many_change_nested(self):
        """
        Test a related ToMany resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(Bone.objects.count(), 0)

        pr = PersonResource()

        person = Person.objects.create(name='Joan Rivers')
        dog = person.dogs.create(name='Snoopy')
        bone = dog.bones.create(color='white')

        pk = person.pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        data = json.loads(resp.content.decode('utf-8'))

        self.assertEqual(data['dogs'][0]['bones'][0]['color'], 'white')

        # Change just a nested resource via PUT
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        data['dogs'][0]['bones'][0]['color'] = 'gray'
        body = json.dumps(data)
        request.set_body(body)
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)

        self.assertEqual(Bone.objects.count(), 1)
        bone = Bone.objects.all()[0]
        self.assertEqual(bone.color, 'gray')
Пример #12
0
    def test_reverse_items_relationship(self):
        order_resource = OrderResource()

        data = {
            'name': 'order1',
            'items': [{
                'name': 'car',
            }, {
                'name': 'yacht',
            }]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'

        request.path = reverse('api_dispatch_list',
                               kwargs={
                                   'resource_name':
                                   order_resource._meta.resource_name,
                                   'api_name': order_resource._meta.api_name
                               })
        request.set_body(json.dumps(data))
        resp = order_resource.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Order.objects.count(), 1)
        self.assertEqual(OrderItem.objects.count(), 2)
Пример #13
0
    def test_m2m_put_prefetch(self):
        resource = api.canonical_resource_for("forum")
        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        forum = Forum.objects.create()
        user_data_1 = {"username": "******", "email": "*****@*****.**", "password": "******"}
        user_data_2 = {
            "username": "******",
            "email": "*****@*****.**",
            "password": "******",
        }
        user_data_3 = {"username": "******", "email": "*****@*****.**", "password": "******"}

        forum_data = {"members": [user_data_1, user_data_2], "moderators": [user_data_3]}
        request.set_body(json.dumps(forum_data))

        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": forum.pk, "resource_name": resource._meta.resource_name, "api_name": resource._meta.api_name},
        )

        response = resource.put_detail(request)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content.decode("utf-8"))

        # Check that the query does what it's supposed to and only the return value is wrong
        self.assertEqual(User.objects.count(), 3)

        self.assertEqual(len(data["members"]), 2)
        self.assertEqual(len(data["moderators"]), 1)
Пример #14
0
    def test_correct_setup(self):
        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "GET"

        # Verify the explicit 'through' relationships has been created correctly
        resource = api.canonical_resource_for("taggabletag")
        resp = resource.wrap_view("dispatch_detail")(request, pk=self.taggabletag_1.pk)
        data = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data["tag"], "/v1/tag/1/")
        self.assertEqual(data["taggable"], "/v1/taggable/1/")

        resource = api.canonical_resource_for("taggable")
        resp = resource.wrap_view("dispatch_detail")(request, pk=self.taggable_1.pk)
        data = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data["name"], "exam")

        resource = api.canonical_resource_for("tag")
        request.path = "/v1/tag/%(pk)s/" % {"pk": self.tag_1.pk}
        resp = resource.wrap_view("dispatch_detail")(request, pk=self.tag_1.pk)
        data = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data["name"], "important")

        # and check whether the extradata is present
        self.assertEqual(data["extradata"]["name"], u"additional")
Пример #15
0
    def test_patch_detail_dont_update_related_without_permission(self):
        """
        When fields are excluded the value of the field should not be set to a
        default value if updated by tastypie.
        """
        resource = NoteResource()
        note = Note.objects.create(author_id=1)
        user = User.objects.get(pk=1)

        self.assertEqual(user.password, 'this_is_not_a_valid_password_string')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PATCH'
        request.path = "/v1/note/%(pk)s/" % {'pk': note.pk}

        data = {
            'author': {
                'id': 1,
                'username': '******',
                'email': '*****@*****.**',
            }
        }

        request.set_body(json.dumps(data))

        resp = resource.patch_detail(request, pk=note.pk)

        self.assertEqual(resp.status_code, 202)

        user2 = User.objects.get(pk=1)

        self.assertEqual(user2.email, '*****@*****.**')
        self.assertEqual(user2.password, 'this_is_not_a_valid_password_string')
Пример #16
0
    def test_patch_to_one(self):
        resource = FullCategoryResource()
        cat1 = Category.objects.create(name='Dad')
        cat2 = Category.objects.create(parent=cat1, name='Child')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PATCH'
        request.path = "/v1/category/%(pk)s/" % {'pk': cat2.pk}

        data = {
            'name': 'Kid'
        }

        request.set_body(json.dumps(data))

        self.assertEqual(cat2.name, 'Child')

        resp = resource.patch_detail(request, pk=cat2.pk)

        self.assertEqual(resp.status_code, 202)

        cat2 = Category.objects.get(pk=2)

        self.assertEqual(cat2.name, 'Kid')
Пример #17
0
    def test_reverse_items_relationship(self):
        order_resource = OrderResource()

        data = {
            'name': 'order1',
            'items': [
                {
                    'name': 'car',
                },
                {
                    'name': 'yacht',
                }
            ]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'

        request.path = reverse('api_dispatch_list',
                               kwargs={'resource_name': order_resource._meta.resource_name,
                                       'api_name': order_resource._meta.api_name})
        request.set_body(json.dumps(data))
        resp = order_resource.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Order.objects.count(), 1)
        self.assertEqual(OrderItem.objects.count(), 2)
Пример #18
0
    def test_correct_setup(self):
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'GET'

        # Verify the explicit 'through' relationships has been created correctly
        resource = api.canonical_resource_for('taggabletag')
        resp = resource.wrap_view('dispatch_detail')(request, pk=self.taggabletag_1.pk)
        data = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['tag'], '/v1/tag/1/')
        self.assertEqual(data['taggable'], '/v1/taggable/1/')

        resource = api.canonical_resource_for('taggable')
        resp = resource.wrap_view('dispatch_detail')(request, pk=self.taggable_1.pk)
        data = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['name'], 'exam')

        resource = api.canonical_resource_for('tag')
        request.path = "/v1/tag/%(pk)s/" % {'pk': self.tag_1.pk}
        resp = resource.wrap_view('dispatch_detail')(request, pk=self.tag_1.pk)
        data = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['name'], 'important')

        # and check whether the extradata is present
        self.assertEqual(data['extradata']['name'], u'additional')
Пример #19
0
    def test_correct_setup(self):
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'GET'

        # Verify the explicit 'through' relationships has been created correctly
        resource = api.canonical_resource_for('taggabletag')
        resp = resource.wrap_view('dispatch_detail')(request,
                                                     pk=self.taggabletag_1.pk)
        data = json.loads(resp.content)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['tag'], '/v1/tag/1/')
        self.assertEqual(data['taggable'], '/v1/taggable/1/')

        resource = api.canonical_resource_for('taggable')
        resp = resource.wrap_view('dispatch_detail')(request,
                                                     pk=self.taggable_1.pk)
        data = json.loads(resp.content)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['name'], 'exam')

        resource = api.canonical_resource_for('tag')
        request.path = "/v1/tag/%(pk)s/" % {'pk': self.tag_1.pk}
        resp = resource.wrap_view('dispatch_detail')(request, pk=self.tag_1.pk)
        data = json.loads(resp.content)
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(data['name'], 'important')

        # and check whether the extradata is present
        self.assertEqual(data['extradata']['name'], u'additional')
Пример #20
0
    def test_patch_to_one(self):
        resource = FullCategoryResource()
        cat1 = Category.objects.create(name='Dad')
        cat2 = Category.objects.create(parent=cat1, name='Child')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PATCH'
        request.path = "/v1/category/%(pk)s/" % {'pk': cat2.pk}

        data = {
            'name': 'Kid'
        }

        request.set_body(json.dumps(data))

        self.assertEqual(cat2.name, 'Child')

        resp = resource.patch_detail(request, pk=cat2.pk)

        self.assertEqual(resp.status_code, 202)

        cat2 = Category.objects.get(pk=2)

        self.assertEqual(cat2.name, 'Kid')
Пример #21
0
    def test_patch_detail_dont_update_related_without_permission(self):
        """
        When fields are excluded the value of the field should not be set to a
        default value if updated by bmga.
        """
        resource = NoteResource()
        note = Note.objects.create(author_id=1)
        user = User.objects.get(pk=1)

        self.assertEqual(user.password, 'this_is_not_a_valid_password_string')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PATCH'
        request.path = "/v1/note/%(pk)s/" % {'pk': note.pk}

        data = {
            'author': {
                'id': 1,
                'username': '******',
                'email': '*****@*****.**',
            }
        }

        request.set_body(json.dumps(data))

        resp = resource.patch_detail(request, pk=note.pk)

        self.assertEqual(resp.status_code, 202)

        user2 = User.objects.get(pk=1)

        self.assertEqual(user2.email, '*****@*****.**')
        self.assertEqual(user2.password, 'this_is_not_a_valid_password_string')
Пример #22
0
    def test_many_to_many_change_nested(self):
        """
        Test a related ToMany resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(Bone.objects.count(), 0)

        pr = PersonResource()

        person = Person.objects.create(name='Joan Rivers')
        dog = person.dogs.create(name='Snoopy')
        bone = dog.bones.create(color='white')

        pk = person.pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        data = json.loads(resp.content.decode('utf-8'))

        self.assertEqual(data['dogs'][0]['bones'][0]['color'], 'white')

        # Change just a nested resource via PUT
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        data['dogs'][0]['bones'][0]['color'] = 'gray'
        body = json.dumps(data)
        request.set_body(body)
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)

        self.assertEqual(Bone.objects.count(), 1)
        bone = Bone.objects.all()[0]
        self.assertEqual(bone.color, 'gray')
Пример #23
0
    def test_m2m_put_prefetch(self):
        resource = api.canonical_resource_for('forum')
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        forum = Forum.objects.create()
        user_data_1 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }
        user_data_2 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }
        user_data_3 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }

        forum_data = {
            'members': [
                user_data_1,
                user_data_2,
            ],
            'moderators': [
                user_data_3,
            ]
        }
        request.set_body(json.dumps(forum_data))

        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': forum.pk,
                                   'resource_name':
                                   resource._meta.resource_name,
                                   'api_name': resource._meta.api_name
                               })

        response = resource.put_detail(request)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content.decode('utf-8'))

        # Check that the query does what it's supposed to and only the return value is wrong
        self.assertEqual(User.objects.count(), 3)

        self.assertEqual(len(data['members']), 2)
        self.assertEqual(len(data['moderators']), 1)
Пример #24
0
    def test_reverse_items_relationship(self):
        order_resource = OrderResource()

        data = {"name": "order1", "items": [{"name": "car"}, {"name": "yacht"}]}

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"

        request.path = reverse(
            "api_dispatch_list",
            kwargs={"resource_name": order_resource._meta.resource_name, "api_name": order_resource._meta.api_name},
        )
        request.set_body(json.dumps(data))
        resp = order_resource.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Order.objects.count(), 1)
        self.assertEqual(OrderItem.objects.count(), 2)
Пример #25
0
    def make_request(self, method):
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = method
        request.set_body(json.dumps({
            'members': [
                self.user_data[0],
                self.user_data[1],
            ],
            'moderators': [self.user_data[2]],
        }))
        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': self.forum.pk,
            'resource_name': self.resource._meta.resource_name,
            'api_name': self.resource._meta.api_name
        })

        return request
Пример #26
0
    def make_request(self, method):
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = method
        request.set_body(json.dumps({
            'members': [
                self.user_data[0],
                self.user_data[1],
            ],
            'moderators': [self.user_data[2]],
        }))
        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': self.forum.pk,
            'resource_name': self.resource._meta.resource_name,
            'api_name': self.resource._meta.api_name
        })

        return request
Пример #27
0
    def test_save_m2m_changed(self):
        """
        Posting a new or updated detail object with a related m2m object
        should save the m2m object if it's included inline.
        """
        resource = api.canonical_resource_for('tag')
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        body_dict = {
            'name': 'school',
            'taggabletags': [{'extra': 7}]
        }

        request.set_body(json.dumps(body_dict))

        with self.assertNumQueries(4):
            resp = resource.wrap_view('dispatch_list')(request)
        self.assertEqual(resp.status_code, 201)

        # 'extra' should have been set
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 7)

        body_dict['taggabletags'] = [{'extra': 1234}]

        request.set_body(json.dumps(body_dict))

        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': tag.pk,
            'resource_name': resource._meta.resource_name,
            'api_name': resource._meta.api_name
        })

        with self.assertNumQueries(5):
            resource.put_detail(request)

        # 'extra' should have changed
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 1234)
Пример #28
0
    def test_save_m2m_changed(self):
        """
        Posting a new or updated detail object with a related m2m object
        should save the m2m object if it's included inline.
        """
        resource = api.canonical_resource_for('tag')
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        body_dict = {
            'name': 'school',
            'taggabletags': [{'extra': 7}]
        }

        request.set_body(json.dumps(body_dict))

        with self.assertNumQueries(4):
            resp = resource.wrap_view('dispatch_list')(request)
        self.assertEqual(resp.status_code, 201)

        # 'extra' should have been set
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 7)

        body_dict['taggabletags'] = [{'extra': 1234}]

        request.set_body(json.dumps(body_dict))

        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': tag.pk,
            'resource_name': resource._meta.resource_name,
            'api_name': resource._meta.api_name
        })

        with self.assertNumQueries(5):
            resource.put_detail(request)

        # 'extra' should have changed
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 1234)
Пример #29
0
    def test_m2m_put_prefetch(self):
        resource = api.canonical_resource_for('forum')
        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        forum = Forum.objects.create()
        user_data_1 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }
        user_data_2 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }
        user_data_3 = {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
        }

        forum_data = {'members': [user_data_1, user_data_2, ],
                      'moderators': [user_data_3, ]}
        request.set_body(json.dumps(forum_data))

        request.path = reverse('api_dispatch_detail', kwargs={
            'pk': forum.pk,
            'resource_name': resource._meta.resource_name,
            'api_name': resource._meta.api_name
        })

        response = resource.put_detail(request)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content.decode('utf-8'))

        # Check that the query does what it's supposed to and only the return value is wrong
        self.assertEqual(User.objects.count(), 3)

        self.assertEqual(len(data['members']), 2)
        self.assertEqual(len(data['moderators']), 1)
Пример #30
0
    def test_save_m2m_changed(self):
        """
        Posting a new or updated detail object with a related m2m object
        should save the m2m object if it's included inline.
        """

        resource = api.canonical_resource_for("tag")
        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"
        body_dict = {"name": "school", "taggabletags": [{"extra": 7}]}

        request.set_body(json.dumps(body_dict))

        resp = resource.wrap_view("dispatch_list")(request)
        self.assertEqual(resp.status_code, 201)

        #'extra' should have been set
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 7)

        body_dict["taggabletags"] = [{"extra": 1234}]

        request.set_body(json.dumps(body_dict))

        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": tag.pk, "resource_name": resource._meta.resource_name, "api_name": resource._meta.api_name},
        )

        resource.put_detail(request)

        #'extra' should have changed
        tag = Tag.objects.all()[0]
        taggable_tag = tag.taggabletags.all()[0]
        self.assertEqual(taggable_tag.extra, 1234)
Пример #31
0
    def test_many_to_one(self):
        """
        Test a related ToMany resource with a nested full ToOne resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [{
                'name': 'Snoopy',
                'house': {
                    'color': 'Red'
                }
            }]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.raw_post_data = json.dumps(data)
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content)
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')

        house = dog['house']
        self.assertEqual(house['color'], 'Red')

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.raw_post_data = json.dumps(person)
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #32
0
    def test_many_to_many(self):
        """
        Test a related ToMany resource with a nested full ToMany resource
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(Bone.objects.count(), 0)

        pr = PersonResource()

        data = {"name": "Joan Rivers", "dogs": [{"name": "Snoopy", "bones": [{"color": "white"}]}]}

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "POST"
        request.path = reverse(
            "api_dispatch_list", kwargs={"resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name}
        )
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(Bone.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = "GET"
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode("utf-8"))
        self.assertEqual(person["name"], "Joan Rivers")
        self.assertEqual(len(person["dogs"]), 1)

        dog = person["dogs"][0]
        self.assertEqual(dog["name"], "Snoopy")
        self.assertEqual(len(dog["bones"]), 1)

        bone = dog["bones"][0]
        self.assertEqual(bone["color"], "white")

        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        request.set_body(json.dumps(person))
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)

        # Change just a nested resource via PUT
        request = MockRequest()
        request.GET = {"format": "json"}
        request.method = "PUT"
        person["dogs"][0]["bones"][0]["color"] = "gray"
        body = json.dumps(person)
        request.set_body(body)
        request.path = reverse(
            "api_dispatch_detail",
            kwargs={"pk": pk, "resource_name": pr._meta.resource_name, "api_name": pr._meta.api_name},
        )
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)

        self.assertEqual(Bone.objects.count(), 1)
        bone = Bone.objects.all()[0]
        self.assertEqual(bone.color, "gray")
Пример #33
0
    def test_many_to_one_extra_data_ignored(self):
        """
        Test a related ToMany resource with a nested full ToOne resource

        FieldError would result when extra data is included on an embedded
        resource for an already saved object.
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [{
                'name': 'Snoopy',
                'house': {
                    'color': 'Red'
                }
            }]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')

        house = dog['house']
        self.assertEqual(house['color'], 'Red')

        # clients may include extra data, which should be ignored. Make extra data is ignored on the resource and sub resources.
        person['thisfieldshouldbeignored'] = 'foobar'
        person['dogs'][0]['thisfieldshouldbeignored'] = 'foobar'

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.set_body(json.dumps(person))
        request.path = reverse('api_dispatch_detail',
                               kwargs={
                                   'pk': pk,
                                   'resource_name': pr._meta.resource_name,
                                   'api_name': pr._meta.api_name
                               })
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)
Пример #34
0
    def test_many_to_one_extra_data_ignored(self):
        """
        Test a related ToMany resource with a nested full ToOne resource

        FieldError would result when extra data is included on an embedded
        resource for an already saved object.
        """
        self.assertEqual(Person.objects.count(), 0)
        self.assertEqual(Dog.objects.count(), 0)
        self.assertEqual(DogHouse.objects.count(), 0)

        pr = PersonResource()

        data = {
            'name': 'Joan Rivers',
            'dogs': [
                {
                    'name': 'Snoopy',
                    'house': {
                        'color': 'Red'
                    }
                }
            ]
        }

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'POST'
        request.set_body(json.dumps(data))
        resp = pr.post_list(request)
        self.assertEqual(resp.status_code, 201)
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Dog.objects.count(), 1)
        self.assertEqual(DogHouse.objects.count(), 1)

        pk = Person.objects.all()[0].pk
        request = MockRequest()
        request.method = 'GET'
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.get_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 200)

        person = json.loads(resp.content.decode('utf-8'))
        self.assertEqual(person['name'], 'Joan Rivers')
        self.assertEqual(len(person['dogs']), 1)

        dog = person['dogs'][0]
        self.assertEqual(dog['name'], 'Snoopy')

        house = dog['house']
        self.assertEqual(house['color'], 'Red')

        # clients may include extra data, which should be ignored. Make extra data is ignored on the resource and sub resources.
        person['thisfieldshouldbeignored'] = 'foobar'
        person['dogs'][0]['thisfieldshouldbeignored'] = 'foobar'

        request = MockRequest()
        request.GET = {'format': 'json'}
        request.method = 'PUT'
        request.set_body(json.dumps(person))
        request.path = reverse('api_dispatch_detail', kwargs={'pk': pk, 'resource_name': pr._meta.resource_name, 'api_name': pr._meta.api_name})
        resp = pr.put_detail(request, pk=pk)
        self.assertEqual(resp.status_code, 204)