def test_post(self): filename = 'pic.jpg' zoo = Zoo(name='Apenheul') zoo.save() response = self.client.post('/zoo/%s/binder_picture/' % zoo.id, data={ 'file': ContentFile(CONTENT, name=filename), }) self.assertEqual(response.status_code, 200) content = jsonloads(response.content) # Remove once Django 3 lands with: https://docs.djangoproject.com/en/3.1/howto/custom-file-storage/#django.core.files.storage.get_alternative_name zoo.refresh_from_db() filename = basename( zoo.binder_picture.name) # Without folders foo/bar/ self.assertEqual( content['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg&filename={}'. format(zoo.pk, HASH, filename), ) response = self.client.get('/zoo/{}/'.format(zoo.pk)) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual( data['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg&filename={}'. format(zoo.pk, HASH, filename), )
def test_remove_relation_through_backref(self): model_data = { 'data': [{ 'id': -1, 'name': 'Apenheul', 'animals': [-2, -3] }], 'with': { 'animal': [{ 'id': -2, 'name': 'Harambe', }, { 'id': -3, 'name': 'Bokito', }] } } response = self.client.put('/zoo/', data=json.dumps(model_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) zoo_id = returned_data['idmap']['zoo'][0][1] update_data = {'animals': []} response = self.client.put('/zoo/{}/?with=animals'.format(zoo_id), data=json.dumps(update_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['animals'], [])
def test_post_with_long_filename(self): filename = 'this_is_an_extremely_long_filename_which_should_be_over_200_chars_but_under_400_and_im_running_out_of_things_to_say_and_i_guess_we_just_keep_going_and_im_now_in_poznan_working_onsite_perhaps_thats_interesting_and_just_ordered_pizza_for_lunch.jpg' zoo = Zoo(name='Apenheul') zoo.save() response = self.client.post('/zoo/%s/binder_picture/' % zoo.id, data={ 'file': ContentFile(CONTENT, name=filename), }) self.assertEqual(response.status_code, 200) content = jsonloads(response.content) # Remove once Django 3 lands with: https://docs.djangoproject.com/en/3.1/howto/custom-file-storage/#django.core.files.storage.get_alternative_name zoo.refresh_from_db() filename = basename( zoo.binder_picture.name) # Without folders foo/bar/ self.assertEqual( content['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg&filename={}'. format(zoo.pk, HASH, filename), ) response = self.client.get('/zoo/{}/'.format(zoo.pk)) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual( data['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg&filename={}'. format(zoo.pk, HASH, filename), )
def test_limit_offset_filtering(self): response = self.client.get('/zoo/', data={ 'order_by': 'name', 'limit': 2, '.name:not': 'GaiaZOO' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(3, data['meta']['total_records']) self.assertEqual(2, len(data['data'])) self.assertEqual(self.artis.id, data['data'][0]['id']) self.assertEqual(self.harderwijk.id, data['data'][1]['id']) response = self.client.get('/zoo/', data={ 'order_by': 'name', 'limit': 2, 'offset': 1, '.name:not': 'GaiaZOO' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(3, data['meta']['total_records']) self.assertEqual(2, len(data['data'])) self.assertEqual(self.harderwijk.id, data['data'][0]['id']) self.assertEqual(self.wildlands.id, data['data'][1]['id'])
def test_post_allowed_extension_success(self): for filename in ['foobar.png', 'foobar.PNG', 'foobar.Png', 'foobar.pNg', 'foobar.pnG']: with self.subTest(filename=filename): zoo = Zoo(name='Apenheul') zoo.save() response = self.client.post('/zoo/%s/binder_picture_custom_extensions/' % zoo.id, data={ 'file': ContentFile(PNG_CONTENT, name=filename), }) self.assertEqual(response.status_code, 200) content = jsonloads(response.content) # Remove once Django 3 lands with: https://docs.djangoproject.com/en/3.1/howto/custom-file-storage/#django.core.files.storage.get_alternative_name zoo.refresh_from_db() filename = basename(zoo.binder_picture_custom_extensions.name) # Without folders foo/bar/ self.assertEqual( content['data']['binder_picture_custom_extensions'], '/zoo/{}/binder_picture_custom_extensions/?h={}&content_type=image/png&filename={}'.format(zoo.pk, PNG_HASH, filename), ) response = self.client.get('/zoo/{}/'.format(zoo.pk)) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual( data['data']['binder_picture_custom_extensions'], '/zoo/{}/binder_picture_custom_extensions/?h={}&content_type=image/png&filename={}'.format(zoo.pk, PNG_HASH, filename), )
def test_datetime_filter_syntax_variations(self): # Precise milliseconds response = self.client.get('/caretaker/', data={'.last_seen:gt': '2017-03-23T11:26:13.9999Z', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) # Implicitly we add T23:59:59Z here to make this correct. response = self.client.get('/caretaker/', data={'.last_seen:gt': '2017-03-23', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) # Same as above, but to the range start we add T00:00:00Z response = self.client.get('/caretaker/', data={'.last_seen:range': '2017-03-23,2017-03-23', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) # Just a sanity check response = self.client.get('/caretaker/', data={'.last_seen:range': '2017-03-23,2017-03-24', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) # You can't mix and match date and datetime syntax response = self.client.get('/caretaker/', data={'.last_seen:range': '2017-03-23T00:00:00Z,2017-03-24', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 418)
def test_get_collection_jsonfield_has_key(self): response = self.client.get('/feeding_schedule/', data={'.schedule_details:has_key': '10:30'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) # Embedded commas should not be parsed (see has_[any_]keys instead) response = self.client.get( '/feeding_schedule/', data={'.schedule_details:has_key': '10:30,16:00'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data'])) response = self.client.get('/feeding_schedule/', data={'.schedule_details:has_key': '15:00'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data'])) response = self.client.get('/feeding_schedule/', data={'.schedule_details:has_key': ''}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data']))
def test_get_uuidfield_startswith_filtering(self): response = self.client.get('/gate/', data={'.serial_number:startswith': '2e'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual(self.emmen.id, result['data'][0]['id']) response = self.client.get('/gate/', data={'.serial_number:startswith': '3e'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual(self.artis.id, result['data'][0]['id']) # OK, this is a bit weird and possibly unexpected: # uuid is case sensitive (in Postgres, at least) response = self.client.get('/gate/', data={'.serial_number:startswith': '2E'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data']))
def test_datetime_filter_gt_match(self): # One second before earliest "last seen" response = self.client.get('/caretaker/', data={'.last_seen:gt': '2017-03-23T11:26:13Z', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) self.assertEqual('Stefan', result['data'][0]['name']) self.assertEqual('Peter', result['data'][1]['name']) # One second later (exactly _on_ earliest "last seen") response = self.client.get('/caretaker/', data={'.last_seen:gt': '2017-03-23T11:26:14Z', 'order_by': 'last_seen'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Peter', result['data'][0]['name']) response = self.client.get('/caretaker/', data={'.last_seen:gt': '2017-03-25T00:00:00Z'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data']))
def test_datetime_filter_gte_match(self): response = self.client.get('/caretaker/', data={ '.last_seen:gte': '2017-03-23T11:26:14Z', 'order_by': 'last_seen' }) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) self.assertEqual('Marcel', result['data'][0]['name']) self.assertEqual('Peter', result['data'][1]['name']) response = self.client.get('/caretaker/', data={ '.last_seen:gte': '2017-03-23T12:00:00Z', 'order_by': 'last_seen' }) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Peter', result['data'][0]['name']) response = self.client.get( '/caretaker/', data={'.last_seen:gte': '2017-03-25T00:00:00Z'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data']))
def test_post(self): zoo = Zoo(name='Apenheul') zoo.save() response = self.client.post('/zoo/%s/binder_picture/' % zoo.id, data={ 'file': ContentFile(CONTENT, name='pic.jpg'), }) self.assertEqual(response.status_code, 200) content = jsonloads(response.content) self.assertEqual( content['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg'.format( zoo.pk, HASH), ) zoo.refresh_from_db() response = self.client.get('/zoo/{}/'.format(zoo.pk)) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual( data['data']['binder_picture'], '/zoo/{}/binder_picture/?h={}&content_type=image/jpeg'.format( zoo.pk, HASH), )
def test_filtering_on_ssn_throws_request_error(self): """ Make sure that filtering on hidden fields throws an exception that filter does not exist, otherwise it may leak information stored in hidden fields by doing a smart lookup """ res = self.client.get('/caretaker/', data={}) self.assertEqual(res.status_code, 200) res = jsonloads(res.content) # No filtering, every records is returned self.assertEqual(2, res['meta']['total_records']) self.assertEqual(2, len(res['data'])) # A normal where is filter res = self.client.get('/caretaker/', data={'.id': -4, '.ssn': 1234}) self.assertEqual(res.status_code, 418) res = jsonloads(res.content) # Filtering should throw an exception self.assertEqual('RequestError', res['code']) # A more complicated filter res = self.client.get('/caretaker/', data={'.ssn:startswith': '1234'}) self.assertEqual(res.status_code, 418) res = jsonloads(res.content) # Filtering should throw an exception self.assertEqual('RequestError', res['code'])
def test_get_model_shown_properties(self): """ Test that the properties under shown_properties are added to the result of a get model request """ gaia = Zoo(name='GaiaZOO') gaia.save() response = self.client.get('/zoo/{}/'.format(gaia.id)) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertTrue('animal_count' in result['data']) self.assertEqual(0, result['data']['animal_count']) coyote = Animal(name='Wile E. Coyote', zoo=gaia) coyote.save() response = self.client.get('/zoo/{}/'.format(gaia.id)) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertTrue('animal_count' in result['data']) self.assertEqual(1, result['data']['animal_count'])
def test_datetime_filter_range(self): response = self.client.get( '/caretaker/', data={ '.last_seen:range': '2017-03-24T14:44:54Z,2017-03-24T14:44:56Z' }) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Peter', result['data'][0]['name']) # Alt syntax response = self.client.get( '/caretaker/', data={ 'order_by': 'name', '.last_seen:range': '2017-03-23T10:00:00+0100,2017-03-25T00:00:00+0100' }) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) self.assertEqual('Marcel', result['data'][0]['name']) self.assertEqual('Peter', result['data'][1]['name'])
def test_time_filter_exact_match(self): response = self.client.get('/zoo/', data={'.opening_time': '09:00:00Z'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Artis', result['data'][0]['name']) response = self.client.get('/zoo/', data={'.opening_time': '11:00:00Z'}) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Burgers Zoo', result['data'][0]['name']) response = self.client.get( '/zoo/', data={'.opening_time': '09:00:00.000+00:00'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Artis', result['data'][0]['name']) response = self.client.get( '/zoo/', data={'.opening_time': '11:00:00.000000+0000'}) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Burgers Zoo', result['data'][0]['name'])
def test_get_collection_arrayfield_exact_filtering(self): response = self.client.get('/feeding_schedule/', data={'.foods': 'corn,bugs'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual(self.rr_feeding.id, result['data'][0]['id']) response = self.client.get('/feeding_schedule/', data={'.foods': 'corn'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data'])) response = self.client.get('/feeding_schedule/', data={'.foods': 'corn,bugs,meat'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(0, len(result['data'])) response = self.client.get('/feeding_schedule/', data={'.foods': 'meat'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual(self.coyote_feeding.id, result['data'][0]['id'])
def test_meta_options(self): zoo = Zoo(name='Apenheul') zoo.save() bokito = Animal(zoo=zoo, name='Bokito') bokito.save() Animal(zoo=zoo, name='Harambe').save() res = self.client.get('/zoo/') self.assertEqual(res.status_code, 200) res = jsonloads(res.content) assert_json( res, { 'data': [{ 'name': 'Apenheul', EXTRA(): None, # Other fields are dontcare }], 'meta': { 'total_records': 1 }, EXTRA(): None, # Debug, meta, with, etc }) res = self.client.get('/zoo/?include_meta=') self.assertEqual(res.status_code, 200) res = jsonloads(res.content) assert_json( res, { 'data': [{ 'name': 'Apenheul', EXTRA(): None, # Other fields are dontcare }], 'meta': {}, EXTRA(): None, # Debug, meta, with, etc }) # Explicitly requesting total_records is the same as the default res = self.client.get('/zoo/?include_meta=total_records') self.assertEqual(res.status_code, 200) res = jsonloads(res.content) assert_json( res, { 'data': [{ 'name': 'Apenheul', EXTRA(): None, # Other fields are dontcare }], 'meta': { 'total_records': 1 }, EXTRA(): None, # Debug, meta, with, etc })
def test_remove_relation_through_backref_non_nullable_soft_deletable(self): model_data = { 'data': [{ 'id': -1, 'name': 'Apenheul', 'zoo_employees': [-2, -3] }], 'with': { 'zoo_employee': [{ 'id': -2, 'name': 'Harambe', }, { 'id': -3, 'name': 'Bokito', }] } } response = self.client.put('/zoo/', data=json.dumps(model_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) zoo_id = returned_data['idmap']['zoo'][0][1] harambe_id = returned_data['idmap']['zoo_employee'][0][1] bokito_id = returned_data['idmap']['zoo_employee'][1][1] # Fixup if needed (gosh this format is FUBAR) if returned_data['idmap']['zoo_employee'][0][0] == -3: harambe_id, bokito_id = bokito_id, harambe_id update_data = {'zoo_employees': [bokito_id]} response = self.client.put('/zoo/{}/'.format(zoo_id), data=json.dumps(update_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertSetEqual(set(returned_data['zoo_employees']), set([bokito_id, harambe_id])) bokito = ZooEmployee.objects.get(id=bokito_id) harambe = ZooEmployee.objects.get(id=harambe_id) self.assertFalse(bokito.deleted) self.assertTrue(harambe.deleted) # Do it again, should not cause any problems due to duplicate deletion response = self.client.put('/zoo/{}/'.format(zoo_id), data=json.dumps(update_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertSetEqual(set(returned_data['zoo_employees']), set([bokito_id, harambe_id])) bokito = ZooEmployee.objects.get(id=bokito_id) harambe = ZooEmployee.objects.get(id=harambe_id) self.assertFalse(bokito.deleted) self.assertTrue(harambe.deleted)
def test_basic_limit_offset(self): response = self.client.get('/animal/', data={'order_by': 'name'}) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(5, data['meta']['total_records']) self.assertEqual(5, len(data['data'])) response = self.client.get('/animal/', data={ 'limit': 1, 'order_by': 'name' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(5, data['meta']['total_records']) self.assertEqual(1, len(data['data'])) self.assertEqual(self.donald.id, data['data'][0]['id']) response = self.client.get('/animal/', data={ 'limit': 1, 'offset': 1, 'order_by': 'name' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(5, data['meta']['total_records']) self.assertEqual(1, len(data['data'])) self.assertEqual(self.mickey.id, data['data'][0]['id']) response = self.client.get('/animal/', data={ 'limit': 2, 'offset': 1, 'order_by': 'name' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(5, data['meta']['total_records']) self.assertEqual(2, len(data['data'])) self.assertEqual(self.mickey.id, data['data'][0]['id']) self.assertEqual(self.minnie.id, data['data'][1]['id']) response = self.client.get('/animal/', data={ 'limit': 2, 'offset': 100, 'order_by': 'name' }) self.assertEqual(response.status_code, 200) data = jsonloads(response.content) self.assertEqual(5, data['meta']['total_records']) self.assertEqual(0, len(data['data']))
def test_get_collection_filtering(self): gaia = Zoo(name='GaiaZOO') gaia.save() emmen = Zoo(name='Wildlands Adventure Zoo Emmen') emmen.save() artis = Zoo(name='Artis') artis.save() coyote = Animal(name='Wile E. Coyote', zoo=gaia) coyote.save() roadrunner = Animal(name='Roadrunner', zoo=gaia) roadrunner.save() woody = Animal(name='Woody Woodpecker', zoo=emmen) woody.save() donald = Animal(name='Donald Duck', zoo=artis) donald.save() response = self.client.get('/animal/', data={'.name': 'Wile E. Coyote'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Wile E. Coyote', result['data'][0]['name']) response = self.client.get('/animal/', data={ '.name:startswith': 'W', 'order_by': 'name' }) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) self.assertEqual('Wile E. Coyote', result['data'][0]['name']) self.assertEqual('Woody Woodpecker', result['data'][1]['name']) # Filtering by relation response = self.client.get('/animal/', data={ '.zoo.name:in': 'Artis,Wildlands Adventure Zoo Emmen', 'order_by': 'name' }) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(2, len(result['data'])) self.assertEqual('Donald Duck', result['data'][0]['name']) self.assertEqual('Woody Woodpecker', result['data'][1]['name'])
def test_order_related_ids(self): z = Zoo(name='hoi') z.save() a9 = Animal.objects.create(zoo_id=z.id, name='a9').id a0 = Animal.objects.create(zoo_id=z.id, name='a0').id a2 = Animal.objects.create(zoo_id=z.id, name='a2').id a6 = Animal.objects.create(zoo_id=z.id, name='a6').id a7 = Animal.objects.create(zoo_id=z.id, name='a7').id a5 = Animal.objects.create(zoo_id=z.id, name='a5').id a4 = Animal.objects.create(zoo_id=z.id, name='a4').id a3 = Animal.objects.create(zoo_id=z.id, name='a3').id a8 = Animal.objects.create(zoo_id=z.id, name='a8').id a1 = Animal.objects.create(zoo_id=z.id, name='a1').id with CustomOrdering(Animal, 'name'): response = self.client.get('/zoo/{}/?with=animals'.format(z.id)) self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['data']['animals'], [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]) # Check ordering on complex OrderBy expression. with CustomOrdering(Animal, Upper('name').asc(), '-id'): response = self.client.get('/zoo/{}/?with=animals'.format(z.id)) self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['data']['animals'], [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]) # Complex order by with desc on an F field with an operation on it with CustomOrdering(Animal, OrderBy(Length(F('name')), descending=True), '-name'): response = self.client.get('/zoo/{}/?with=animals'.format(z.id)) self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['data']['animals'], [a9, a8, a7, a6, a5, a4, a3, a2, a1, a0]) # Nested complex order by with CustomOrdering(Animal, Reverse(Upper('name')), 'id'): response = self.client.get('/zoo/{}/?with=animals'.format(z.id)) self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['data']['animals'], [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]) with CustomOrdering(Animal, '-name'): response = self.client.get('/zoo/{}/?with=animals'.format(z.id)) self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertEqual(returned_data['data']['animals'], [a9, a8, a7, a6, a5, a4, a3, a2, a1, a0])
def test_writes_to_write_once_fields_are_blocked_for_updates(self): res = self.client.post('/caretaker/', data=jsondumps({ 'name': 'Fabby', 'first_seen': '2020-01-01T00:00:00Z' }), content_type='application/json') self.assertEqual(res.status_code, 200) data = jsonloads(res.content) self.assertEqual([], data['_meta']['ignored_fields']) dt = parse_datetime('2020-01-01T00:00:00Z') self.assertEqual(dt, parse_datetime(data['first_seen'])) caretaker = Caretaker.objects.get(id=data['id']) self.assertEqual(dt, caretaker.first_seen) self.assertEqual('Fabby', caretaker.name) res = self.client.put('/caretaker/%s/' % caretaker.id, data=jsondumps({ 'name': 'Mr Fabby', 'first_seen': '2020-02-01T00:00:00Z' }), content_type='application/json') self.assertEqual(res.status_code, 200) data = jsonloads(res.content) self.assertEqual(['first_seen'], data['_meta']['ignored_fields']) self.assertEqual(dt, parse_datetime(data['first_seen'])) caretaker.refresh_from_db() self.assertEqual(dt, caretaker.first_seen) self.assertEqual('Mr Fabby', caretaker.name) # A put without the field means it's not in ignored_fields res = self.client.put('/caretaker/%s/' % caretaker.id, data=jsondumps({'name': 'Mrs Fabby'}), content_type='application/json') self.assertEqual(res.status_code, 200) data = jsonloads(res.content) self.assertEqual([], data['_meta']['ignored_fields']) self.assertEqual(dt, parse_datetime(data['first_seen'])) caretaker.refresh_from_db() self.assertEqual(dt, caretaker.first_seen) self.assertEqual('Mrs Fabby', caretaker.name)
def test_get_collection_jsonfield_invalid_json_filtering_fails(self): response = self.client.get('/feeding_schedule/', data={'.schedule_details:contains': '{'}) self.assertEqual(response.status_code, 418) result = jsonloads(response.content) self.assertEqual('RequestError', result['code']) response = self.client.get( '/feeding_schedule/', data={'.schedule_details:contained_by': '{'}) self.assertEqual(response.status_code, 418) result = jsonloads(response.content) self.assertEqual('RequestError', result['code'])
def test_remove_relation_through_backref_with_custom_unsetter(self): model_data = { 'data': [{ 'id': -1, 'name': 'Apenheul', 'animals': [-2, -3] }], 'with': { 'animal': [{ 'id': -2, 'name': 'Harambe', }, { 'id': -3, 'name': 'Bokito', }] } } response = self.client.put('/caretaker/', data=json.dumps(model_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) caretaker_id = returned_data['idmap']['caretaker'][0][1] animal_ids = [new for old, new in returned_data['idmap']['animal']] update_data = {'animals': []} response = self.client.put('/caretaker/{}/'.format(caretaker_id), data=json.dumps(update_data), content_type='application/json') self.assertEqual(response.status_code, 400) returned_data = jsonloads(response.content) assert_json( returned_data, { 'errors': { 'animal': { str(animal_id): { 'caretaker': [{ 'code': 'cant_unset', MAYBE('message'): ANY(str) }] } for animal_id in animal_ids } }, 'code': 'ValidationError', MAYBE('debug'): ANY(), })
def test_datetime_filter_exact_match(self): response = self.client.get('/caretaker/', data={'.last_seen': '2017-03-24T14:44:55Z'}) self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Peter', result['data'][0]['name']) # Alt syntax response = self.client.get('/caretaker/', data={'.last_seen': '2017-03-23T12:26:14+0100'}) result = jsonloads(response.content) self.assertEqual(1, len(result['data'])) self.assertEqual('Stefan', result['data'][0]['name'])
def test_filter_on_animal_count(self): caretaker_2 = Caretaker(name='caretaker 2') caretaker_2.save() caretaker_3 = Caretaker(name='caretaker 3') caretaker_3.save() for i in range(3): Animal( name='animal 2 {}'.format(i), zoo=self.zoo, caretaker=caretaker_2, ).save() for i in range(2): Animal( name='animal 3 {}'.format(i), zoo=self.zoo, caretaker=caretaker_3, ).save() res = self.client.get('/caretaker/?.animal_count=2') self.assertEqual(res.status_code, 200) data = jsonloads(res.content) order = [ct['id'] for ct in data['data']] self.assertEqual(order, [caretaker_3.pk])
def test_get_collection_with_no_models_returns_empty_array(self): response = self.client.get('/animal/') self.assertEqual(response.status_code, 200) result = jsonloads(response.content) self.assertEqual([], result['data'])
def test_get_model_with_invalid_id_sets_correct_code(self): response = self.client.get('/animal/1234/') self.assertEqual(response.status_code, 404) result = jsonloads(response.content) self.assertEqual('NotFound', result['code'])
def test_post_new_model_with_reverse_foreign_key_multi_value(self): scooby = Animal(name='Scooby Doo') scooby.full_clean() scooby.save() scrappy = Animal(name='Scrappy Doo') scrappy.full_clean() scrappy.save() woody = Animal(name='Woody Woodpecker') woody.full_clean() woody.save() model_data = { 'name': 'Artis', 'animals': [scooby.pk, scrappy.pk], } response = self.client.post('/zoo/', data=json.dumps(model_data), content_type='application/json') self.assertEqual(response.status_code, 200) returned_data = jsonloads(response.content) self.assertIsNotNone(returned_data.get('id')) self.assertEqual('Artis', returned_data.get('name')) self.assertSetEqual(set([scooby.id, scrappy.id]), set(returned_data.get('animals'))) artis = Zoo.objects.get(id=returned_data.get('id')) self.assertEqual('Artis', artis.name) self.assertSetEqual(set([scooby.id, scrappy.id]), set([a.id for a in artis.animals.all()]))
def test_get_data(self): res = self.client.get('/caretaker/{}/'.format(self.caretaker.pk)) self.assertEqual(res.status_code, 200) data = jsonloads(res.content) self.assertEqual(data['data']['animal_count'], 1)