def test_csv_export_only_allowed_fields_should_be_exported(self, user): resp = self.get(self.USER_API_URL, headers={ 'HTTP_ACCEPT': 'text/csv', 'HTTP_X_FIELDS': 'id,email,invalid' }) assert_equal(len(resp.content.split(b'\n')[0].split(b';')), 2)
def test_html_is_auto_escaped(self): issue = IssueFactory(name='<html>') resp = self.get('{}{}/'.format(self.ISSUE_API_URL, issue.pk)) output_data = self.deserialize(resp) assert_equal(output_data['name'], '<html>') assert_equal(output_data.get('_obj_name'), 'issue: <b><html></b>')
def test_atomic_add_delete_and_set_issues_with_errors(self, number, issue_data, user_data): user_data['createdIssues'] = {'set': (None, '', None, {}, [None])} resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in('set', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = {'add': (None, '', None, [], {}, {'id': 500}), 'remove': (None, '', None, {}, {'id': 500}, [])} resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in('add', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) assert_in('remove', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = {'add': None, 'remove': None} resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in('add', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) assert_in('remove', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = (self.get_issue_data(), self.get_issue_data(), 'invalid') resp = self.post(self.USER_API_URL, data=user_data) assert_equal( self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues')[0]['_index'], 2 ) assert_http_bad_request(resp)
def test_reverse_with_defined_field_created_issues_renamed(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['created_issues_renamed'] = (self.get_issue_data(), self.get_issue_data(), self.get_issue_data()) resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count + 3, Issue.objects.all().count())
def test_atomic_set_issue_with_user_reverse(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['createdIssues'] = {'set': (issue_data, )} resp = self.post(self.USER_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count + 1, Issue.objects.all().count())
def test_create_issue_via_user_one_to_one_renamed(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['leading_issue_renamed'] = self.get_issue_data() resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count + 1, Issue.objects.all().count())
def test_typemapper_settings_of_resource_should_define_related_obj_serializer( self, number, issue_data, user_data): issue_data['created_by'] = self.get_user_data() issue_data['leader'] = self.get_user_data() resp = self.post(self.ISSUE_WITH_FORM_API_URL, data=issue_data) assert_equal(resp.json()['creator']['user_email'], issue_data['created_by']['email'])
def test_resource_with_serializable_result(self): [IssueFactory(solver=UserFactory()) for _ in range(10)] resp_data = self.deserialize(self.get(self.COUNT_ISSUES_PER_USER)) assert_equal(len(resp_data), 10 * 3) for row in resp_data: assert_equal(set(row.keys()), {'email', 'created_issues_count'})
def test_create_user(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) pk = self.deserialize(resp)['id'] resp = self.get(self.USER_API_URL) assert_equal(len(self.deserialize(resp)), 1) assert_valid_JSON_response(self.get('%s%s/' % (self.USER_API_URL, pk)))
def test_read_extra_field_header_user(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) headers = {'HTTP_X_FIELDS': 'email'} resp = self.get(self.USER_API_URL, headers=headers) for item_data in self.deserialize(resp): assert_equal(set(item_data.keys()), {'email'})
def test_create_user_via_renamed_field(self, number, issue_data, user_data): users_before_count = User.objects.all().count() issue_data['created_by'] = self.get_user_data() issue_data['leader'] = self.get_user_data() resp = self.post(self.ISSUE_WITH_FORM_API_URL, data=issue_data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 2, User.objects.all().count())
def test_reverse_with_defined_field_created_issues_renamed_fail(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['created_issues_renamed'] = {'add': (self.get_issue_data(), self.get_issue_data(), self.get_issue_data())} resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_http_bad_request(resp) assert_in('created_issues_renamed', self.deserialize(resp).get('messages', {}).get('errors')) assert_equal(issues_before_count + 0, Issue.objects.all().count())
def test_read_user_general_fields_set_with_metaclass(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) resp = self.get(self.USER_API_URL) output_data = self.deserialize(resp) assert_equal(set(output_data[0].keys()), {'id', '_obj_name', 'email', 'firstName', 'lastName', 'watchedIssues', 'manualCreatedDate', 'watchedIssuesCount'})
def test_atomic_add_and_delete_issues_with_auto_reverse_fields_turned_off(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['createdIssues'] = {'add': (self.get_issue_data(), self.get_issue_data(), self.get_issue_data())} resp = self.post(self.USER_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count, Issue.objects.all().count())
def test_create_user_via_renamed_field(self, number, issue_data, user_data): users_before_count = User.objects.all().count() issue_data['created_by'] = self.get_user_data() issue_data['leader'] = self.get_user_data() resp = self.post(self.ISSUE_WITH_FORM_API_URL, data=issue_data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 2, User.objects.all().count())
def test_order_by_decorator(self): [IssueFactory(description=str(i)) for i in range(10)] data = self.deserialize(self.get(build_url(self.ISSUE_API_URL, order='short_description'))) assert_equal([v['short_description'] for v in data], [str(i) for i in range(10)]) data = self.deserialize(self.get(build_url(self.ISSUE_API_URL, order='-short_description'))) assert_equal([v['short_description'] for v in data], [str(i) for i in range(10)][::-1]) assert_valid_JSON_response(self.get(build_url(self.USER_API_URL, order='solving_issue__short_description'))) assert_valid_JSON_response(self.get(build_url(self.USER_API_URL, order='-solving_issue__short_description'))) assert_http_bad_request(self.get(build_url(self.ISSUE_API_URL, order='description')))
def test_csv_export_column_labels_should_be_able_to_set_in_resource( self, user): resp = self.get(self.USER_API_URL, headers={ 'HTTP_ACCEPT': 'text/csv', 'HTTP_X_FIELDS': 'email' }) assert_equal( resp.content.split(b'\n')[0], b'\xef\xbb\xbf"E-mail address"\r')
def test_create_issue_should_tags_be_parsed_as_a_list(self): issue_data = self.get_issue_data() issue_data['created_by'] = self.get_user_data() issue_data['leader'] = self.get_user_data() issue_data['tags_list'] = ['taga', 'tagb'] resp = self.post(self.ISSUE_WITH_FORM_API_URL, data=issue_data) assert_valid_JSON_created_response(resp) assert_equal(Issue.objects.last().tags, 'taga|tagb')
def test_read_user(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) pk = self.get_pk(resp) resp = self.get('%s%s/' % (self.USER_API_URL, pk),) output_data = self.deserialize(resp) assert_equal(output_data.get('email'), data.get('email')) assert_equal(output_data.get('id'), pk)
def test_head_requests(self, number, data): resp = self.post(self.USER_API_URL, data=data) pk = self.get_pk(resp) resp = self.head(self.USER_API_URL) assert_equal(resp.content.decode('utf-8'), '') resp = self.head('%s%s/' % (self.USER_API_URL, pk)) assert_equal(resp.content.decode('utf-8'), '')
def test_camel_snake_case_nested(self): resp = self.get(self.TEST_CC_API_URL) assert_valid_JSON_response(resp) data = { 'fooBar': 'foo bar', 'connected': {'fizBaz': 'test object property content'} } assert_equal(data, self.deserialize(resp))
def test_read_user_extra_fields_set_with_metaclass(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) headers = {'HTTP_X_FIELDS': 'is_superuser'} resp = self.get(self.USER_API_URL, headers=headers) output_data = self.deserialize(resp) assert_equal(set(output_data[0].keys()), {'isSuperuser'})
def test_create_issue_should_tags_be_parsed_as_a_list(self): issue_data = self.get_issue_data() issue_data['created_by'] = self.get_user_data() issue_data['leader'] = self.get_user_data() issue_data['tags_list'] = ['taga', 'tagb'] resp = self.post(self.ISSUE_WITH_FORM_API_URL, data=issue_data) assert_valid_JSON_created_response(resp) assert_equal(Issue.objects.last().tags, 'taga|tagb')
def test_create_user_with_file_url(self, number, data): resp = self.get_file_url_response(data) assert_valid_JSON_created_response(resp) data = self.deserialize(resp) assert_not_equal(data['contract'], None) assert_in('filename', data['contract']) assert_in('url', data['contract']) assert_equal(data['contract']['content_type'], 'application/pdf')
def test_create_user_with_file_url(self, number, data): resp = self.get_file_url_response(data) assert_valid_JSON_created_response(resp) data = self.deserialize(resp) assert_not_equal(data['contract'], None) assert_in('filename', data['contract']) assert_in('url', data['contract']) assert_equal(data['contract']['content_type'], 'application/pdf')
def test_reverse_with_defined_field_created_issues_renamed( self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['created_issues_renamed'] = (self.get_issue_data(), self.get_issue_data(), self.get_issue_data()) resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count + 3, Issue.objects.all().count())
def test_should_raise_bad_request_if_url_is_not_valid(self, number, data): data['contract'] = { 'filename': 'testfile.pdf', 'url': 'hs://foo.bar/testfile.pdf', } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['url'], ugettext('Enter a valid URL.'))
def test_read_user_detailed_fields_set_with_metaclass(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) pk = self.get_pk(resp) resp = self.get('%s%s/' % (self.USER_API_URL, pk),) output_data = self.deserialize(resp) assert_equal(set(output_data.keys()), {'id', 'createdAt', '_obj_name', 'email', 'contract', 'solvingIssue', 'firstName', 'lastName', 'watchedIssues', 'manualCreatedDate'})
def test_should_raise_bad_request_if_url_is_not_valid(self, number, data): data['contract'] = { 'filename': 'testfile.pdf', 'url': 'hs://foo.bar/testfile.pdf', } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['url'], ugettext('Enter a valid URL.'))
def test_should_raise_bad_request_if_file_is_unreachable(self, number, data): url = 'http://foo.bar/testfile.pdf' data['contract'] = { 'filename': 'testfile.pdf', 'url': url, } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['url'], ugettext('File is unreachable on the URL address'))
def test_should_raise_bad_request_if_file_content_is_not_in_base64(self, number, data): data['contract'] = { 'content_type': 'text/plain', 'filename': 'contract.txt', 'content': 'abc', } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['content'], ugettext('File content must be in base64 format'))
def test_reverse_with_defined_field_created_issues_renamed_invalid_issue_name(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() users_before_count = Issue.objects.all().count() user_data['created_issues_renamed'] = ( self.get_issue_data(), self.get_issue_data(name='invalid'), self.get_issue_data() ) resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_http_bad_request(resp) assert_equal(issues_before_count, Issue.objects.all().count()) assert_equal(users_before_count, User.objects.all().count())
def test_rename_fields_should_not_be_nested(self): resp = self.get(self.TEST_CC_API_URL) assert_valid_JSON_response(resp) data = { 'fooBar': 'foo bar', 'connected': { 'fiz_baz': 'test object property content' } } assert_equal(data, self.deserialize(resp))
def test_atomic_update_issue_with_user(self, number, data): users_before_count = User.objects.all().count() resp = self.post(self.ISSUE_API_URL, data=data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 2, User.objects.all().count()) data['created_by'] = self.get_user_data() data['created_by']['id'] = self.deserialize(resp)['created_by']['id'] data['leader'] = self.get_user_data() resp = self.post(self.ISSUE_API_URL, data=data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 3, User.objects.all().count())
def test_cors_allow_headers(self, number, data): resp = self.options(self.USER_API_URL, headers={'HTTP_ORIGIN': FOO_DOMAIN}) assert_equal(resp[ACCESS_CONTROL_ALLOW_HEADERS], ', '.join(('X-Base', 'X-Offset', 'X-Fields', 'Origin', 'Content-Type', 'Accept'))) resp = self.options(self.USER_API_URL, headers={'HTTP_ORIGIN': BAR_DOMAIN}) assert_equal(resp[ACCESS_CONTROL_ALLOW_HEADERS], ', '.join(('X-Base', 'X-Offset', 'X-Fields', 'Origin', 'Content-Type', 'Accept'))) resp = self.options(self.USER_API_URL) assert_false(ACCESS_CONTROL_ALLOW_HEADERS in resp)
def test_atomic_update_issue_with_user(self, number, data): users_before_count = User.objects.all().count() resp = self.post(self.ISSUE_API_URL, data=data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 2, User.objects.all().count()) data['created_by'] = self.get_user_data() data['created_by']['id'] = self.deserialize(resp)['created_by']['id'] data['leader'] = self.get_user_data() resp = self.post(self.ISSUE_API_URL, data=data) assert_valid_JSON_created_response(resp) assert_equal(users_before_count + 3, User.objects.all().count())
def test_atomic_add_and_delete_issues_with_auto_reverse_fields_turned_off( self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['createdIssues'] = { 'add': (self.get_issue_data(), self.get_issue_data(), self.get_issue_data()) } resp = self.post(self.USER_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count, Issue.objects.all().count())
def test_update_user(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) pk = self.get_pk(resp) data['email'] = 'updated_%s' % data['email'] resp = self.put('%s%s/' % (self.USER_API_URL, pk), data=data) assert_valid_JSON_response(resp) assert_equal(self.deserialize(resp).get('email'), data['email']) resp = self.get(self.USER_API_URL) assert_equal(len(self.deserialize(resp)), 1)
def test_atomic_add_delete_and_set_issues_with_errors( self, number, issue_data, user_data): user_data['createdIssues'] = {'set': (None, '', None, {}, [None])} resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in( 'set', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = { 'add': (None, '', None, [], {}, { 'id': 500 }), 'remove': (None, '', None, {}, { 'id': 500 }, []) } resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in( 'add', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) assert_in( 'remove', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = {'add': None, 'remove': None} resp = self.post(self.USER_API_URL, data=user_data) assert_http_bad_request(resp) assert_in( 'add', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) assert_in( 'remove', self.deserialize(resp).get('messages', {}).get('errors', {}).get('createdIssues', {})) user_data['createdIssues'] = (self.get_issue_data(), self.get_issue_data(), 'invalid') resp = self.post(self.USER_API_URL, data=user_data) assert_equal( self.deserialize(resp).get('messages', {}).get( 'errors', {}).get('createdIssues')[0]['_index'], 2) assert_http_bad_request(resp)
def test_should_raise_bad_request_if_required_items_are_not_provided( self, number, data): REQUIRED_ITEMS = {'content'} REQUIRED_URL_ITEMS = {'url'} data['contract'] = {} resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) msg = ugettext('File data item must contains {} or {}').format( ', '.join(REQUIRED_ITEMS), ', '.join(REQUIRED_URL_ITEMS)) assert_equal(errors['contract'], msg)
def test_reverse_with_defined_field_created_issues_renamed_fail( self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['created_issues_renamed'] = { 'add': (self.get_issue_data(), self.get_issue_data(), self.get_issue_data()) } resp = self.post(self.USER_WITH_FORM_API_URL, data=user_data) assert_http_bad_request(resp) assert_in('created_issues_renamed', self.deserialize(resp).get('messages', {}).get('errors')) assert_equal(issues_before_count + 0, Issue.objects.all().count())
def test_should_raise_bad_request_if_required_items_are_not_provided(self, number, data): REQUIRED_ITEMS = {'content'} REQUIRED_URL_ITEMS = {'url'} data['contract'] = {} resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) msg = ugettext('File data item must contains {} or {}').format( ', '.join(REQUIRED_ITEMS), ', '.join(REQUIRED_URL_ITEMS) ) assert_equal(errors['contract'], msg)
def test_should_raise_bad_request_if_file_content_is_not_in_base64( self, number, data): data['contract'] = { 'content_type': 'text/plain', 'filename': 'contract.txt', 'content': 'abc', } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['content'], ugettext('File content must be in base64 format'))
def test_should_raise_bad_request_if_file_is_unreachable( self, number, data): url = 'http://foo.bar/testfile.pdf' data['contract'] = { 'filename': 'testfile.pdf', 'url': url, } resp = self.post(self.USER_API_URL, data=data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) assert_equal(errors['contract']['url'], ugettext('File is unreachable on the URL address'))
def test_delete_user(self, number, data): resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) pk = self.get_pk(resp) resp = self.delete('%s%s/' % (self.USER_API_URL, pk)) assert_http_accepted(resp) resp = self.get(self.USER_API_URL) assert_equal(len(self.deserialize(resp)), 0) resp = self.delete('%s%s/' % (self.USER_API_URL, pk)) assert_http_not_found(resp)
def test_should_raise_bad_request_if_response_is_too_large(self, number, data): data['contract'] = { 'content_type': 'text/plain', 'filename': 'contract.txt', 'content': base64.b64encode( ('Contract of %s code: šří+áýšé' % data['email']).encode('utf-8') ).decode('utf-8') } resp = self.get_file_url_response(data) assert_http_bad_request(resp) errors = self.deserialize(resp).get('messages', {}).get('errors') assert_in('contract', errors) msg = ugettext('Response too large, maximum size is {} bytes').format(pyston_settings.FILE_SIZE_LIMIT) assert_equal(errors['contract']['url'], msg)
def test_create_user_with_file_and_not_defined_content_type(self, number, data): data['contract'] = { 'filename': 'contract.txt', 'content': base64.b64encode( ('Contract of %s code: šří+áýšé' % data['email']).encode('utf-8') ).decode('utf-8') } resp = self.post(self.USER_API_URL, data=data) assert_valid_JSON_created_response(resp) data = self.deserialize(resp) assert_not_equal(data['contract'], None) assert_in('filename', data['contract']) assert_in('url', data['contract']) assert_equal(data['contract']['content_type'], 'text/plain')
def test_atomic_add_and_delete_issues_with_reverse(self, number, issue_data, user_data): issues_before_count = Issue.objects.all().count() user_data['createdIssues'] = {'add': (self.get_issue_data(), self.get_issue_data(), self.get_issue_data())} resp = self.post(self.USER_API_URL, data=user_data) assert_valid_JSON_created_response(resp) assert_equal(issues_before_count + 3, Issue.objects.all().count()) user_pk = self.get_pk(resp) first_issue_data = self.get_issue_data() first_issue_data['solver'] = {'email': '*****@*****.**', 'createdIssues': [self.get_issue_data()]} user_data['createdIssues'] = {'set': (first_issue_data, self.get_issue_data(), self.get_issue_data())} resp = self.put('%s%s/' % (self.USER_API_URL, user_pk), data=user_data) assert_equal(issues_before_count + 4, Issue.objects.all().count()) assert_valid_JSON_response(resp) user_data['createdIssues'] = {'remove': list(Issue.objects.filter(created_by=user_pk). values_list('pk', flat=True))} resp = self.put('%s%s/' % (self.USER_API_URL, self.get_pk(resp)), data=user_data) assert_valid_JSON_response(resp) assert_equal(issues_before_count + 1, Issue.objects.all().count()) user_data['createdIssues'] = (self.get_issue_data(), self.get_issue_data(), self.get_issue_data()) resp = self.put('%s%s/' % (self.USER_API_URL, user_pk), data=user_data) assert_equal(issues_before_count + 4, Issue.objects.all().count()) assert_valid_JSON_response(resp)
def test_custom_method_filter(self): user1 = UserFactory() user2 = UserFactory() issue1 = IssueFactory() issue2 = IssueFactory() issue1.watched_by.add(user1, user2) issue2.watched_by.add(user1) assert_http_bad_request(self.get(build_url(self.USER_API_URL, watched_issues_count='invalid'))) data = self.deserialize( self.get( build_url( self.USER_API_URL, watched_issues_count=2 ) ) ) assert_equal(len(data), 1) assert_equal(data[0]['id'], user1.pk) data = self.deserialize( self.get( build_url( self.USER_API_URL, watched_issues_count=1 ) ) ) assert_equal(len(data), 1) assert_equal(data[0]['id'], user2.pk)