def test_api_add_field_to_repo(self, backend): repo = backend.create_repo() repo_name = repo.repo_name id_, params = build_data( self.apikey, 'add_field_to_repo', repoid=repo_name, key='extra_field', label='extra_field_label', description='extra_field_desc') response = api_call(self.app, params) expected = { 'msg': 'Added new repository field `extra_field`', 'success': True, } assert_ok(id_, expected, given=response.body) repo = Repository.get_by_repo_name(repo_name) repo_field = RepositoryField.get_by_key_name('extra_field', repo) _data = repo_field.get_dict() assert _data['field_desc'] == 'extra_field_desc' assert _data['field_key'] == 'extra_field' assert _data['field_label'] == 'extra_field_label' id_, params = build_data( self.apikey, 'add_field_to_repo', repoid=repo_name, key='extra_field', label='extra_field_label', description='extra_field_desc') response = api_call(self.app, params) expected = 'Field with key `extra_field` exists for repo `%s`' % ( repo_name) assert_error(id_, expected, given=response.body)
def test_api_create_repo_with_booleans(self, backend): repo_name = 'api-repo-2' id_, params = build_data(self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, enable_statistics=True, enable_locking=True, enable_downloads=True) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None ret = { 'msg': 'Created new repository `%s`' % (repo_name, ), 'success': True, 'task': None, } expected = ret assert_ok(id_, expected, given=response.body) id_, params = build_data(self.apikey, 'get_repo', repoid=repo_name) response = api_call(self.app, params) body = json.loads(response.body) assert body['result']['enable_downloads'] is True assert body['result']['enable_locking'] is True assert body['result']['enable_statistics'] is True fixture.destroy_repo(repo_name)
def test_api_merge_pull_request(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_2 = PullRequestModel().create( created_by=pull_request.author, source_repo=pull_request.source_repo, source_ref=pull_request.source_ref, target_repo=pull_request.target_repo, target_ref=pull_request.target_ref, revisions=pull_request.revisions, reviewers=(), title=pull_request.title, description=pull_request.description, ) author = pull_request.user_id repo = pull_request_2.target_repo.repo_id pull_request_2_id = pull_request_2.pull_request_id pull_request_2_repo = pull_request_2.target_repo.repo_name Session().commit() id_, params = build_data(self.apikey, 'merge_pull_request', repoid=pull_request_2_repo, pullrequestid=pull_request_2_id) response = api_call(self.app, params) expected = {'executed': True, 'failure_reason': 0, 'possible': True} response_json = response.json['result'] assert response_json['merge_commit_id'] response_json.pop('merge_commit_id') assert response_json == expected action = 'user_merged_pull_request:%d' % (pull_request_2_id, ) journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 1 id_, params = build_data(self.apikey, 'merge_pull_request', repoid=pull_request_2_repo, pullrequestid=pull_request_2_id) response = api_call(self.app, params) expected = 'pull request `%s` merge failed, pull request is closed' % ( pull_request_2_id) assert_error(id_, expected, given=response.body)
def test_api_get_repo( self, apikey_attr, expect_secrets, cache_param, backend, user_util): repo = backend.create_repo() usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) group = user_util.create_user_group(members=[usr]) user_util.grant_user_group_permission_to_repo( repo=repo, user_group=group, permission_name='repository.read') Session().commit() kwargs = { 'repoid': repo.repo_name, } if cache_param is not None: kwargs['cache'] = cache_param apikey = getattr(self, apikey_attr) id_, params = build_data(apikey, 'get_repo', **kwargs) response = api_call(self.app, params) ret = repo.get_api_data() permissions = expected_permissions(repo) followers = [] for user in repo.followers: followers.append(user.user.get_api_data( include_secrets=expect_secrets)) ret['members'] = permissions ret['permissions'] = permissions ret['followers'] = followers expected = ret assert_ok(id_, expected, given=response.body)
def test_api_get_repo_by_non_admin(self, grant_perm, backend): # TODO: Depending on which tests are running before this one, we # start with a different number of permissions in the database. repo = RepoModel().get_by_repo_name(backend.repo_name) permission_count = len(repo.repo_to_perm) RepoModel().grant_user_permission(repo=backend.repo_name, user=self.TEST_USER_LOGIN, perm=grant_perm) Session().commit() id_, params = build_data( self.apikey_regular, 'get_repo', repoid=backend.repo_name) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(backend.repo_name) ret = repo.get_api_data() assert permission_count + 1, len(repo.repo_to_perm) permissions = expected_permissions(repo) followers = [] for user in repo.followers: followers.append(user.user.get_api_data()) ret['members'] = permissions ret['permissions'] = permissions ret['followers'] = followers expected = ret try: assert_ok(id_, expected, given=response.body) finally: RepoModel().revoke_user_permission( backend.repo_name, self.TEST_USER_LOGIN)
def test_api_grant_user_permission_to_user_group_by_regular_user( self, name, perm, grant_admin, access_ok, user_util): api_user = UserModel().get_by_username(self.TEST_USER_LOGIN) user = user_util.create_user() group = user_util.create_user_group() # grant the user ability to at least read the group permission = 'usergroup.admin' if grant_admin else 'usergroup.read' user_util.grant_user_permission_to_user_group(group, api_user, permission) id_, params = build_data(self.apikey_regular, 'grant_user_permission_to_user_group', usergroupid=group.users_group_name, userid=user.username, perm=perm) response = api_call(self.app, params) if access_ok: ret = { 'msg': ('Granted perm: `%s` for user: `%s` in user group: `%s`' % (perm, user.username, group.users_group_name)), 'success': True } expected = ret assert_ok(id_, expected, given=response.body) else: expected = 'user group `%s` does not exist' % ( group.users_group_name) assert_error(id_, expected, given=response.body)
def test_api_get_gist_with_content(self, gist_util): mapping = { u'filename1.txt': {'content': u'hello world'}, u'filename1ą.txt': {'content': u'hello worldę'} } gist = gist_util.create_gist(gist_mapping=mapping) gist_id = gist.gist_access_id gist_created_on = gist.created_on gist_modified_at = gist.modified_at id_, params = build_data( self.apikey, 'get_gist', gistid=gist_id, content=True) response = api_call(self.app, params) expected = { 'access_id': gist_id, 'created_on': gist_created_on, 'modified_at': gist_modified_at, 'description': 'new-gist', 'expires': -1.0, 'gist_id': int(gist_id), 'type': 'public', 'url': 'http://test.example.com:80/_admin/gists/%s' % (gist_id,), 'acl_level': Gist.ACL_LEVEL_PUBLIC, 'content': { u'filename1.txt': u'hello world', u'filename1ą.txt': u'hello worldę' }, } assert_ok(id_, expected, given=response.body)
def test_api_revoke_user_group_permission_from_user_group( self, name, user_util): user = UserModel().get_by_username(self.TEST_USER_LOGIN) group = user_util.create_user_group() source_group = user_util.create_user_group() user_util.grant_user_permission_to_user_group(group, user, 'usergroup.read') user_util.grant_user_group_permission_to_user_group( source_group, group, 'usergroup.read') id_, params = build_data( self.apikey, 'revoke_user_group_permission_from_user_group', usergroupid=group.users_group_name, sourceusergroupid=source_group.users_group_name) response = api_call(self.app, params) expected = { 'msg': 'Revoked perm for user group: `%s` in user group: `%s`' % (source_group.users_group_name, group.users_group_name), 'success': True } assert_ok(id_, expected, given=response.body)
def test_api_create_user_group_regular_user(self): group_name = 'some_new_group' usr = UserModel().get_by_username(self.TEST_USER_LOGIN) usr.inherit_default_permissions = False Session().add(usr) UserModel().grant_perm(self.TEST_USER_LOGIN, 'hg.usergroup.create.true') Session().commit() id_, params = build_data(self.apikey_regular, 'create_user_group', group_name=group_name) response = api_call(self.app, params) expected = { 'msg': 'created new user group `%s`' % (group_name, ), 'user_group': jsonify(UserGroupModel().get_by_name(group_name).get_api_data()) } try: assert_ok(id_, expected, given=response.body) finally: self.fixture.destroy_user_group(group_name) UserModel().revoke_perm(self.TEST_USER_LOGIN, 'hg.usergroup.create.true') usr = UserModel().get_by_username(self.TEST_USER_LOGIN) usr.inherit_default_permissions = True Session().add(usr) Session().commit()
def test_create_repo_with_extra_slashes_in_name(self, backend, user_util): existing_repo_group = user_util.create_repo_group() dirty_repo_name = '//{}/repo_name//'.format( existing_repo_group.group_name) cleaned_repo_name = '{}/repo_name'.format( existing_repo_group.group_name) id_, params = build_data( self.apikey, 'create_repo', repo_name=dirty_repo_name, repo_type=backend.alias, owner=TEST_USER_ADMIN_LOGIN, ) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(cleaned_repo_name) assert repo is not None expected = { 'msg': 'Created new repository `%s`' % (cleaned_repo_name, ), 'success': True, 'task': None, } assert_ok(id_, expected, given=response.body) fixture.destroy_repo(cleaned_repo_name)
def test_api_create_repo_group_in_another_group(self): repo_group_name = 'api-repo-group' repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None # create the parent fixture.create_repo_group(repo_group_name) full_repo_group_name = repo_group_name + '/' + repo_group_name id_, params = build_data(self.apikey, 'create_repo_group', group_name=full_repo_group_name, owner=TEST_USER_ADMIN_LOGIN, copy_permissions=True) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(full_repo_group_name) assert repo_group is not None ret = { 'msg': 'Created new repo group `%s`' % (full_repo_group_name, ), 'repo_group': repo_group.get_api_data() } expected = ret assert_ok(id_, expected, given=response.body) fixture.destroy_repo_group(full_repo_group_name) fixture.destroy_repo_group(repo_group_name)
def test_api_grant_user_group_permission_to_user_group( self, name, perm, user_util): group = user_util.create_user_group() target_group = user_util.create_user_group() id_, params = build_data( self.apikey, 'grant_user_group_permission_to_user_group', usergroupid=target_group.users_group_name, sourceusergroupid=group.users_group_name, perm=perm) response = api_call(self.app, params) expected = { 'msg': ( 'Granted perm: `%s` for user group: `%s`' ' in user group: `%s`' % ( perm, group.users_group_name, target_group.users_group_name ) ), 'success': True } try: assert_ok(id_, expected, given=response.body) finally: UserGroupModel().revoke_user_group_permission( target_group.users_group_id, group.users_group_id)
def test_api_create_repo_in_group(self, backend): repo_group_name = 'my_gr' # create the parent fixture.create_repo_group(repo_group_name) repo_name = '%s/api-repo-gr' % (repo_group_name, ) id_, params = build_data( self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, ) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None assert repo.group is not None ret = { 'msg': 'Created new repository `%s`' % (repo_name, ), 'success': True, 'task': None, } expected = ret assert_ok(id_, expected, given=response.body) fixture.destroy_repo(repo_name) fixture.destroy_repo_group(repo_group_name)
def test_api_pull_error(self, backend): id_, params = build_data( self.apikey, 'pull', repoid=backend.repo_name) response = api_call(self.app, params) expected = 'Unable to pull changes from `%s`' % (backend.repo_name,) assert_error(id_, expected, given=response.body)
def test_api_revoke_user_permission_from_user_group_by_regular_user( self, name, grant_admin, access_ok, user_util): user = user_util.create_user() group = user_util.create_user_group() permission = 'usergroup.admin' if grant_admin else 'usergroup.read' user_util.grant_user_permission_to_user_group(group, user, permission) id_, params = build_data(self.apikey_regular, 'revoke_user_permission_from_user_group', usergroupid=group.users_group_name, userid=user.username) response = api_call(self.app, params) if access_ok: expected = { 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (user.username, group.users_group_name), 'success': True } assert_ok(id_, expected, given=response.body) else: expected = 'user group `%s` does not exist' % ( group.users_group_name) assert_error(id_, expected, given=response.body)
def test_api_revoke_user_group_permission_from_repo_group( self, name, apply_to_children, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() user_util.grant_user_group_permission_to_repo_group( repo_group, user_group, 'group.read') id_, params = build_data( self.apikey, 'revoke_user_group_permission_from_repo_group', repogroupid=repo_group.name, usergroupid=user_group.users_group_name, apply_to_children=apply_to_children,) response = api_call(self.app, params) expected = { 'msg': ( 'Revoked perm (recursive:%s) for user group: `%s`' ' in repo group: `%s`' % ( apply_to_children, user_group.users_group_name, repo_group.name ) ), 'success': True } assert_ok(id_, expected, given=response.body)
def test_api_update_repo(self, updates, expected, backend): repo_name = UPDATE_REPO_NAME repo = fixture.create_repo(repo_name, repo_type=backend.alias) if updates.get('group'): fixture.create_repo_group(updates['group']) expected_api_data = repo.get_api_data(include_secrets=True) if expected is SAME_AS_UPDATES: expected_api_data.update(updates) else: expected_api_data.update(expected) id_, params = build_data(self.apikey, 'update_repo', repoid=repo_name, **updates) response = api_call(self.app, params) if updates.get('name'): repo_name = updates['name'] if updates.get('group'): repo_name = '/'.join([updates['group'], repo_name]) try: expected = { 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name), 'repository': jsonify(expected_api_data) } assert_ok(id_, expected, given=response.body) finally: fixture.destroy_repo(repo_name) if updates.get('group'): fixture.destroy_repo_group(updates['group'])
def test_api_create_restricted_repo_type(self, backend): repo_name = 'api-repo-type-{0}'.format(backend.alias) id_, params = build_data( self.apikey, 'create_repo', repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, ) git_backend = settings.BACKENDS['git'] with mock.patch('rhodecode.lib.vcs.settings.BACKENDS', {'git': git_backend}): response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) if backend.alias == 'git': assert repo is not None expected = { 'msg': 'Created new repository `{0}`'.format(repo_name, ), 'success': True, 'task': None, } assert_ok(id_, expected, given=response.body) else: assert repo is None fixture.destroy_repo(repo_name)
def test_api_comment_pull_request(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id author = pull_request.user_id repo = pull_request.target_repo.repo_id id_, params = build_data(self.apikey, 'comment_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, message='test message') response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request.pull_request_id) comments = ChangesetCommentsModel().get_comments( pull_request.target_repo.repo_id, pull_request=pull_request) expected = { 'pull_request_id': pull_request.pull_request_id, 'comment_id': comments[-1].comment_id, 'status': None } assert_ok(id_, expected, response.body) action = 'user_commented_pull_request:%d' % pull_request_id journal = UserLog.query()\ .filter(UserLog.user_id == author)\ .filter(UserLog.repository_id == repo)\ .filter(UserLog.action == action)\ .all() assert len(journal) == 2
def test_create_fails_when_no_revisions(self, backend): data = self._prepare_data(backend, source_head='initial') id_, params = build_data(self.apikey_regular, 'create_pull_request', **data) response = api_call(self.app, params) expected_message = 'no commits found' assert_error(id_, expected_message, given=response.body)
def test_api_grant_user_permission_to_repo_group_by_regular_user( self, name, perm, apply_to_children, grant_admin, access_ok, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() if grant_admin: test_user = UserModel().get_by_username(self.TEST_USER_LOGIN) user_util.grant_user_permission_to_repo_group( repo_group, test_user, 'group.admin') id_, params = build_data( self.apikey_regular, 'grant_user_permission_to_repo_group', repogroupid=repo_group.name, userid=user.username, perm=perm, apply_to_children=apply_to_children) response = api_call(self.app, params) if access_ok: ret = { 'msg': ( 'Granted perm: `%s` (recursive:%s) for user: `%s`' ' in repo group: `%s`' % ( perm, apply_to_children, user.username, repo_group.name ) ), 'success': True } expected = ret assert_ok(id_, expected, given=response.body) else: expected = 'repository group `%s` does not exist' % ( repo_group.name, ) assert_error(id_, expected, given=response.body)
def test_api_grant_user_group_permission_to_repo_group( self, name, perm, apply_to_children, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() id_, params = build_data( self.apikey, 'grant_user_group_permission_to_repo_group', repogroupid=repo_group.name, usergroupid=user_group.users_group_name, perm=perm, apply_to_children=apply_to_children, ) response = api_call(self.app, params) ret = { 'msg': ('Granted perm: `%s` (recursive:%s) for user group: `%s`' ' in repo group: `%s`' % (perm, apply_to_children, user_group.users_group_name, repo_group.name)), 'success': True } expected = ret try: assert_ok(id_, expected, given=response.body) finally: RepoGroupModel().revoke_user_group_permission( repo_group.group_id, user_group.users_group_id)
def test_api_create_gist(self, lifetime, gist_type, gist_acl_level): id_, params = build_data(self.apikey_regular, 'create_gist', lifetime=lifetime, description='foobar-gist', gist_type=gist_type, acl_level=gist_acl_level, files={'foobar': { 'content': 'foo' }}) response = api_call(self.app, params) response_json = response.json gist = response_json['result']['gist'] expected = { 'gist': { 'access_id': gist['access_id'], 'created_on': gist['created_on'], 'modified_at': gist['modified_at'], 'description': 'foobar-gist', 'expires': gist['expires'], 'gist_id': gist['gist_id'], 'type': gist_type, 'url': gist['url'], # content is empty since we don't show it here 'content': None, 'acl_level': gist_acl_level, }, 'msg': 'created new gist' } try: assert_ok(id_, expected, given=response.body) finally: Fixture().destroy_gists()
def test_get_repo_changesets_commit_range_svn(self, details, backend_svn, start_rev, expected_revision): # TODO: johbo: SVN showed a problem here: The parameter "start_rev" # in our API allows to pass in a "Commit ID" as well as a # "Commit Index". In the case of Subversion it is not possible to # distinguish these cases. As a workaround we implemented this # behavior which gives a preference to see it as a "Commit ID". limit = 10 __, params = build_data( self.apikey, 'get_repo_changesets', repoid=backend_svn.repo_name, start_rev=start_rev, limit=limit, details=details, ) response = api_call(self.app, params) result = response.json['result'] assert result assert len(result) == limit for i in xrange(limit): assert result[i]['revision'] == int(expected_revision) + i
def test_api_delete_repo_group_regular_user(self, user_util): repo_group = user_util.create_repo_group(auto_cleanup=False) repo_group_name = repo_group.group_name repo_group_id = repo_group.group_id user = UserModel().get_by_username(self.TEST_USER_LOGIN) user_util.grant_user_permission_to_repo_group(repo_group, user, 'group.admin') id_, params = build_data( self.apikey, 'delete_repo_group', repogroupid=repo_group_name, ) response = api_call(self.app, params) ret = { 'msg': 'deleted repo group ID:%s %s' % (repo_group_id, repo_group_name), 'repo_group': None } expected = ret assert_ok(id_, expected, given=response.body) gr = RepoGroupModel()._get_repo_group(repo_group_name) assert gr is None
def test_api_update_change_reviewers( self, pr_util, silence_action_logger, no_notifications): users = [x.username for x in User.get_all()] new = [users.pop(0)] removed = sorted(new) added = sorted(users) pull_request = pr_util.create_pull_request(reviewers=new) id_, params = build_data( self.apikey, 'update_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, reviewers=added) response = api_call(self.app, params) expected = { "msg": "Updated pull request `{}`".format( pull_request.pull_request_id), "pull_request": response.json['result']['pull_request'], "updated_commits": {"added": [], "common": [], "removed": []}, "updated_reviewers": {"added": added, "removed": removed}, } response_json = response.json['result'] assert response_json == expected
def test_api_revoke_user_permission_from_repo_group_by_regular_user( self, name, apply_to_children, grant_admin, access_ok, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() permission = 'group.admin' if grant_admin else 'group.read' user_util.grant_user_permission_to_repo_group(repo_group, user, permission) id_, params = build_data( self.apikey_regular, 'revoke_user_permission_from_repo_group', repogroupid=repo_group.name, userid=user.username, apply_to_children=apply_to_children, ) response = api_call(self.app, params) if access_ok: expected = { 'msg': ('Revoked perm (recursive:%s) for user: `%s`' ' in repo group: `%s`' % (apply_to_children, user.username, repo_group.name)), 'success': True } assert_ok(id_, expected, given=response.body) else: expected = 'repository group `%s` does not exist' % ( repo_group.name) assert_error(id_, expected, given=response.body)
def test_api_update_pull_request_title_or_description( self, pr_util, silence_action_logger, no_notifications): pull_request = pr_util.create_pull_request() id_, params = build_data( self.apikey, 'update_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, title='New TITLE OF A PR', description='New DESC OF A PR', ) response = api_call(self.app, params) expected = { "msg": "Updated pull request `{}`".format( pull_request.pull_request_id), "pull_request": response.json['result']['pull_request'], "updated_commits": {"added": [], "common": [], "removed": []}, "updated_reviewers": {"added": [], "removed": []}, } response_json = response.json['result'] assert response_json == expected pr = response_json['pull_request'] assert pr['title'] == 'New TITLE OF A PR' assert pr['description'] == 'New DESC OF A PR'
def test_api_update_update_commits( self, pr_util, silence_action_logger, no_notifications): commits = [ {'message': 'a'}, {'message': 'b', 'added': [FileNode('file_b', 'test_content\n')]}, {'message': 'c', 'added': [FileNode('file_c', 'test_content\n')]}, ] pull_request = pr_util.create_pull_request( commits=commits, target_head='a', source_head='b', revisions=['b']) pr_util.update_source_repository(head='c') repo = pull_request.source_repo.scm_instance() commits = [x for x in repo.get_commits()] added_commit_id = commits[-1].raw_id # c commit common_commits = commits[1].raw_id # b commit is common ancestor id_, params = build_data( self.apikey, 'update_pull_request', repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, update_commits=True ) response = api_call(self.app, params) expected = { "msg": "Updated pull request `{}`".format( pull_request.pull_request_id), "pull_request": response.json['result']['pull_request'], "updated_commits": {"added": [added_commit_id], "common": [common_commits], "removed": []}, "updated_reviewers": {"added": [], "removed": []}, } response_json = response.json['result'] assert response_json == expected
def test_api_update_user_group_regular_user(self, changing_attr, updates, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name expected_api_data = user_group.get_api_data() expected_api_data.update(updates) # grant permission to this user user = UserModel().get_by_username(self.TEST_USER_LOGIN) user_util.grant_user_permission_to_user_group(user_group, user, 'usergroup.admin') id_, params = build_data(self.apikey_regular, 'update_user_group', usergroupid=group_name, **updates) response = api_call(self.app, params) expected = { 'msg': 'updated user group ID:%s %s' % (user_group.users_group_id, user_group.users_group_name), 'user_group': jsonify(expected_api_data) } assert_ok(id_, expected, given=response.body)