diff --git a/swh/web/api/views/revision.py b/swh/web/api/views/revision.py --- a/swh/web/api/views/revision.py +++ b/swh/web/api/views/revision.py @@ -7,7 +7,6 @@ from swh.web.common import service from swh.web.common.utils import reverse -from swh.web.common.utils import parse_timestamp from swh.web.api import utils from swh.web.api.apidoc import api_doc from swh.web.api.apiurls import api_route @@ -45,234 +44,6 @@ return result -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/log/', - 'api-revision-origin-log') -@api_route(r'/revision/origin/(?P[0-9]+)/log/', - 'api-revision-origin-log') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/ts/(?P.+)/log/', - 'api-revision-origin-log') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)' - r'/ts/(?P.+)/log/', - 'api-revision-origin-log') -@api_doc('/revision/origin/log/') -def api_revision_log_by(request, origin_id, - branch_name='refs/heads/master', - ts=None): - """ - .. http:get:: /api/1/revision/origin/(origin_id)[/branch/(branch_name)][/ts/(timestamp)]/log - - Show the commit log for a revision, searching for it based on software origin, - branch name, and/or visit timestamp. - - This endpoint behaves like :http:get:`/api/1/revision/(sha1_git)[/prev/(prev_sha1s)]/log/`, - but operates on the revision that has been found at a given software origin, - close to a given point in time, pointed by a given branch. - - :param int origin_id: a software origin identifier - :param string branch_name: optional parameter specifying a fully-qualified branch name - associated to the software origin, e.g., "refs/heads/master". Defaults to the master branch. - :param string timestamp: optional parameter specifying a timestamp close to which the revision - pointed by the given branch should be looked up. The timestamp can be expressed either - as an ISO date or as a Unix one (in UTC). Defaults to now. - - :reqheader Accept: the requested response content type, - either ``application/json`` (default) or ``application/yaml`` - :resheader Content-Type: this depends on :http:header:`Accept` header of request - - :>jsonarr object author: information about the author of the revision - :>jsonarr string author_url: link to :http:get:`/api/1/person/(person_id)/` to get - information about the author of the revision - :>jsonarr object committer: information about the committer of the revision - :>jsonarr string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get - information about the committer of the revision - :>jsonarr string committer_date: ISO representation of the commit date (in UTC) - :>jsonarr string date: ISO representation of the revision date (in UTC) - :>jsonarr string directory: the unique identifier that revision points to - :>jsonarr string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]` - to get information about the directory associated to the revision - :>jsonarr string id: the revision unique identifier - :>jsonarr boolean merge: whether or not the revision corresponds to a merge commit - :>jsonarr string message: the message associated to the revision - :>jsonarr array parents: the parents of the revision, i.e. the previous revisions - that head directly to it, each entry of that array contains an unique parent - revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/` - to get more information about it - :>jsonarr string type: the type of the revision - - **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options` - - :statuscode 200: no error - :statuscode 404: no revision matching the given criteria could be found in the archive - - **Example:** - - .. parsed-literal:: - - :swh_web_api:`revision/origin/723566/ts/2016-01-17T00:00:00+00:00/log/` - """ # noqa - result = {} - per_page = int(request.query_params.get('per_page', '10')) - - if ts: - ts = parse_timestamp(ts) - - def lookup_revision_log_by_with_limit(o_id, br, ts, limit=per_page+1): - return service.lookup_revision_log_by(o_id, br, ts, limit) - - error_msg = 'No revision matching origin %s ' % origin_id - error_msg += ', branch name %s' % branch_name - error_msg += (' and time stamp %s.' % ts) if ts else '.' - - rev_get = api_lookup( - lookup_revision_log_by_with_limit, origin_id, branch_name, ts, - notfound_msg=error_msg, - enrich_fn=utils.enrich_revision) - - nb_rev = len(rev_get) - if nb_rev == per_page+1: - revisions = rev_get[:-1] - last_sha1_git = rev_get[-1]['id'] - - params = {k: v for k, v in {'origin_id': origin_id, - 'branch_name': branch_name, - 'ts': ts, - }.items() if v is not None} - - query_params = {} - query_params['sha1_git'] = last_sha1_git - - if request.query_params.get('per_page'): - query_params['per_page'] = per_page - - result['headers'] = { - 'link-next': reverse('api-revision-origin-log', url_args=params, - query_params=query_params) - } - - else: - revisions = rev_get - - result.update({'results': revisions}) - - return result - - -@api_route(r'/revision/origin/(?P[0-9]+)/directory/', - 'api-revision-origin-directory') -@api_route(r'/revision/origin/(?P[0-9]+)/directory/(?P.+)/', - 'api-revision-origin-directory') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/directory/', - 'api-revision-origin-directory') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/ts/(?P.+)/directory/', - 'api-revision-origin-directory') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/directory/(?P.+)/', - 'api-revision-origin-directory') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/ts/(?P.+)' - r'/directory/(?P.+)/', - 'api-revision-origin-directory') -@api_doc('/revision/origin/directory/', tags=['hidden']) -def api_directory_through_revision_origin(request, origin_id, - branch_name="refs/heads/master", - ts=None, - path=None, - with_data=False): - """ - Display directory or content information through a revision identified - by origin/branch/timestamp. - """ - if ts: - ts = parse_timestamp(ts) - - return _revision_directory_by({'origin_id': origin_id, - 'branch_name': branch_name, - 'ts': ts - }, - path, request.path, - with_data=with_data) - - -@api_route(r'/revision/origin/(?P[0-9]+)/', - 'api-revision-origin') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/', - 'api-revision-origin') -@api_route(r'/revision/origin/(?P[0-9]+)' - r'/branch/(?P.+)/ts/(?P.+)/', - 'api-revision-origin') -@api_route(r'/revision/origin/(?P[0-9]+)/ts/(?P.+)/', - 'api-revision-origin') -@api_doc('/revision/origin/') -def api_revision_with_origin(request, origin_id, - branch_name="refs/heads/master", - ts=None): - """ - .. http:get:: /api/1/revision/origin/(origin_id)/[branch/(branch_name)/][ts/(timestamp)/] - - Get information about a revision, searching for it based on software origin, - branch name, and/or visit timestamp. - - This endpoint behaves like :http:get:`/api/1/revision/(sha1_git)/`, - but operates on the revision that has been found at a given software origin, - close to a given point in time, pointed by a given branch. - - :param int origin_id: a software origin identifier - :param string branch_name: optional parameter specifying a fully-qualified branch name - associated to the software origin, e.g., "refs/heads/master". Defaults to the master branch. - :param string timestamp: optional parameter specifying a timestamp close to which the revision - pointed by the given branch should be looked up. The timestamp can be expressed either - as an ISO date or as a Unix one (in UTC). Defaults to now. - - :reqheader Accept: the requested response content type, - either ``application/json`` (default) or ``application/yaml`` - :resheader Content-Type: this depends on :http:header:`Accept` header of request - - :>json object author: information about the author of the revision - :>json string author_url: link to :http:get:`/api/1/person/(person_id)/` to get - information about the author of the revision - :>json object committer: information about the committer of the revision - :>json string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get - information about the committer of the revision - :>json string committer_date: ISO representation of the commit date (in UTC) - :>json string date: ISO representation of the revision date (in UTC) - :>json string directory: the unique identifier that revision points to - :>json string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]` - to get information about the directory associated to the revision - :>json string id: the revision unique identifier - :>json boolean merge: whether or not the revision corresponds to a merge commit - :>json string message: the message associated to the revision - :>json array parents: the parents of the revision, i.e. the previous revisions - that head directly to it, each entry of that array contains an unique parent - revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/` - to get more information about it - :>json string type: the type of the revision - - **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options` - - :statuscode 200: no error - :statuscode 404: no revision matching the given criteria could be found in the archive - - **Example:** - - .. parsed-literal:: - - :swh_web_api:`revision/origin/13706355/branch/refs/heads/2.7/` - """ # noqa - ts = parse_timestamp(ts) - return api_lookup( - service.lookup_revision_by, origin_id, branch_name, ts, - notfound_msg=('Revision with (origin_id: {}, branch_name: {}' - ', ts: {}) not found.'.format(origin_id, - branch_name, ts)), - enrich_fn=utils.enrich_revision) - - @api_route(r'/revision/(?P[0-9a-f]+)/prev/(?P[0-9a-f/]+)/', 'api-revision-context') @api_doc('/revision/prev/', tags=['hidden']) diff --git a/swh/web/common/service.py b/swh/web/common/service.py --- a/swh/web/common/service.py +++ b/swh/web/common/service.py @@ -459,37 +459,6 @@ return res -def lookup_revision_by(origin_id, - branch_name="refs/heads/master", - timestamp=None): - """Lookup revisions by origin_id, branch_name and timestamp. - - If: - - branch_name is not provided, lookup using 'refs/heads/master' as default. - - ts is not provided, use the most recent - - Args: - - origin_id: origin of the revision. - - branch_name: revision's branch. - - timestamp: revision's time frame. - - Yields: - The revisions matching the criterions. - - Raises: - NotFoundExc if no revision corresponds to the criterion - - """ - res = _first_element(storage.revision_get_by(origin_id, - branch_name, - timestamp=timestamp, - limit=1)) - if not res: - raise NotFoundExc('Revision for origin %s and branch %s not found.' - % (origin_id, branch_name)) - return converters.from_revision(res) - - def lookup_revision_log(rev_sha1_git, limit): """Return information about the revision with sha1 revision_sha1_git. @@ -539,47 +508,6 @@ return map(converters.from_revision, revision_entries) -def lookup_revision_with_context_by(origin_id, branch_name, ts, sha1_git, - limit=100): - """Return information about revision sha1_git, limited to the - sub-graph of all transitive parents of sha1_git_root. - sha1_git_root being resolved through the lookup of a revision by origin_id, - branch_name and ts. - - In other words, sha1_git is an ancestor of sha1_git_root. - - Args: - - origin_id: origin of the revision. - - branch_name: revision's branch. - - timestamp: revision's time frame. - - sha1_git: one of sha1_git_root's ancestors. - - limit: limit the lookup to 100 revisions back. - - Returns: - Pair of (root_revision, revision). - Information on sha1_git if it is an ancestor of sha1_git_root - including children leading to sha1_git_root - - Raises: - - BadInputExc in case of unknown algo_hash or bad hash. - - NotFoundExc if either revision is not found or if sha1_git is not an - ancestor of sha1_git_root. - - """ - rev_root = _first_element(storage.revision_get_by(origin_id, - branch_name, - timestamp=ts, - limit=1)) - if not rev_root: - raise NotFoundExc('Revision with (origin_id: %s, branch_name: %s' - ', ts: %s) not found.' % (origin_id, - branch_name, - ts)) - - return (converters.from_revision(rev_root), - lookup_revision_with_context(rev_root, sha1_git, limit)) - - def lookup_revision_with_context(sha1_git_root, sha1_git, limit=100): """Return information about revision sha1_git, limited to the sub-graph of all transitive parents of sha1_git_root. @@ -872,73 +800,6 @@ return converters.from_snapshot(snapshot) -def lookup_revision_through(revision, limit=100): - """Retrieve a revision from the criterion stored in revision dictionary. - - Args: - revision: Dictionary of criterion to lookup the revision with. - Here are the supported combination of possible values: - - origin_id, branch_name, ts, sha1_git - - origin_id, branch_name, ts - - sha1_git_root, sha1_git - - sha1_git - - Returns: - None if the revision is not found or the actual revision. - - """ - if 'origin_id' in revision and \ - 'branch_name' in revision and \ - 'ts' in revision and \ - 'sha1_git' in revision: - return lookup_revision_with_context_by(revision['origin_id'], - revision['branch_name'], - revision['ts'], - revision['sha1_git'], - limit) - if 'origin_id' in revision and \ - 'branch_name' in revision and \ - 'ts' in revision: - return lookup_revision_by(revision['origin_id'], - revision['branch_name'], - revision['ts']) - if 'sha1_git_root' in revision and \ - 'sha1_git' in revision: - return lookup_revision_with_context(revision['sha1_git_root'], - revision['sha1_git'], - limit) - if 'sha1_git' in revision: - return lookup_revision(revision['sha1_git']) - - # this should not happen - raise NotImplementedError('Should not happen!') - - -def lookup_directory_through_revision(revision, path=None, - limit=100, with_data=False): - """Retrieve the directory information from the revision. - - Args: - revision: dictionary of criterion representing a revision to lookup - path: directory's path to lookup. - limit: optional query parameter to limit the revisions log (default to - 100). For now, note that this limit could impede the transitivity - conclusion about sha1_git not being an ancestor of. - with_data: indicate to retrieve the content's raw data if path resolves - to a content. - - Returns: - The directory pointing to by the revision criterions at path. - - """ - rev = lookup_revision_through(revision, limit) - - if not rev: - raise NotFoundExc('Revision with criterion %s not found!' % revision) - return (rev['id'], - lookup_directory_with_revision(rev['id'], path, with_data)) - - def vault_cook(obj_type, obj_id, email=None): """Cook a vault bundle. """ diff --git a/swh/web/tests/api/views/test_revision.py b/swh/web/tests/api/views/test_revision.py --- a/swh/web/tests/api/views/test_revision.py +++ b/swh/web/tests/api/views/test_revision.py @@ -165,176 +165,6 @@ '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.revision.service') - def test_api_revision_with_origin_not_found(self, mock_service): - mock_service.lookup_revision_by.return_value = None - - rv = self.client.get('/api/1/revision/origin/123/') - - # then - self.assertEqual(rv.status_code, 404) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertIn('Revision with (origin_id: 123', rv.data['reason']) - self.assertIn('not found', rv.data['reason']) - self.assertEqual('NotFoundExc', rv.data['exception']) - - mock_service.lookup_revision_by.assert_called_once_with( - '123', - 'refs/heads/master', - None) - - @patch('swh.web.api.views.revision.service') - def test_api_revision_with_origin(self, mock_service): - mock_revision = { - 'id': '32', - 'directory': '21', - 'message': 'message 1', - 'type': 'deb', - } - expected_revision = { - 'id': '32', - 'url': '/api/1/revision/32/', - 'history_url': '/api/1/revision/32/log/', - 'directory': '21', - 'directory_url': '/api/1/directory/21/', - 'message': 'message 1', - 'type': 'deb', - } - mock_service.lookup_revision_by.return_value = mock_revision - - rv = self.client.get('/api/1/revision/origin/1/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_revision) - - mock_service.lookup_revision_by.assert_called_once_with( - '1', - 'refs/heads/master', - None) - - @patch('swh.web.api.views.revision.service') - def test_api_revision_with_origin_and_branch_name(self, mock_service): - mock_revision = { - 'id': '12', - 'directory': '23', - 'message': 'message 2', - 'type': 'tar', - } - mock_service.lookup_revision_by.return_value = mock_revision - - expected_revision = { - 'id': '12', - 'url': '/api/1/revision/12/', - 'history_url': '/api/1/revision/12/log/', - 'directory': '23', - 'directory_url': '/api/1/directory/23/', - 'message': 'message 2', - 'type': 'tar', - } - - rv = self.client.get('/api/1/revision/origin/1' - '/branch/refs/origin/dev/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_revision) - - mock_service.lookup_revision_by.assert_called_once_with( - '1', - 'refs/origin/dev', - None) - - @patch('swh.web.api.views.revision.parse_timestamp') - @patch('swh.web.api.views.revision.service') - @patch('swh.web.api.views.revision.utils') - def test_api_revision_with_origin_and_branch_name_and_timestamp(self, - mock_utils, - mock_service, - mock_parse_timestamp): # noqa - mock_revision = { - 'id': '123', - 'directory': '456', - 'message': 'message 3', - 'type': 'tar', - } - mock_service.lookup_revision_by.return_value = mock_revision - - expected_revision = { - 'id': '123', - 'url': '/api/1/revision/123/', - 'history_url': '/api/1/revision/123/log/', - 'directory': '456', - 'directory_url': '/api/1/directory/456/', - 'message': 'message 3', - 'type': 'tar', - } - - mock_parse_timestamp.return_value = 'parsed-date' - mock_utils.enrich_revision.return_value = expected_revision - - rv = self.client.get('/api/1/revision' - '/origin/1' - '/branch/refs/origin/dev' - '/ts/1452591542/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_revision) - - mock_service.lookup_revision_by.assert_called_once_with( - '1', - 'refs/origin/dev', - 'parsed-date') - mock_parse_timestamp.assert_called_once_with('1452591542') - mock_utils.enrich_revision.assert_called_once_with( - mock_revision) - - @patch('swh.web.api.views.revision.parse_timestamp') - @patch('swh.web.api.views.revision.service') - @patch('swh.web.api.views.revision.utils') - def test_api_revision_with_origin_and_branch_name_and_timestamp_escapes( - self, - mock_utils, - mock_service, - mock_parse_timestamp): - mock_revision = { - 'id': '999', - } - mock_service.lookup_revision_by.return_value = mock_revision - - expected_revision = { - 'id': '999', - 'url': '/api/1/revision/999/', - 'history_url': '/api/1/revision/999/log/', - } - - mock_parse_timestamp.return_value = 'parsed-date' - mock_utils.enrich_revision.return_value = expected_revision - - rv = self.client.get('/api/1/revision' - '/origin/1' - '/branch/refs%2Forigin%2Fdev' - '/ts/Today%20is%20' - 'January%201,%202047%20at%208:21:00AM/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_revision) - - mock_service.lookup_revision_by.assert_called_once_with( - '1', - 'refs/origin/dev', - 'parsed-date') - mock_parse_timestamp.assert_called_once_with( - 'Today is January 1, 2047 at 8:21:00AM') - mock_utils.enrich_revision.assert_called_once_with( - mock_revision) - - @patch('swh.web.api.views.revision.service') def test_revision_directory_by_ko_raise(self, mock_service): # given mock_service.lookup_directory_through_revision.side_effect = NotFoundExc('not') # noqa @@ -380,91 +210,6 @@ 'some/path', limit=100, with_data=False) @patch('swh.web.api.views.revision.service') - def test_revision_directory_by_type_file(self, mock_service): - # given - mock_service.lookup_directory_through_revision.return_value = ( - 'rev-id', - { - 'type': 'file', - 'revision': 'rev-id', - 'path': 'some/path', - 'content': {'blah': 'blah'} - }) - # when - actual_dir_content = _revision_directory_by( - {'sha1_git': 'sha1'}, - 'some/path', - '/api/1/revision/origin/2/directory/', - limit=1000, with_data=True) - - # then - self.assertEqual(actual_dir_content, { - 'type': 'file', - 'revision': 'rev-id', - 'path': 'some/path', - 'content': {'blah': 'blah'} - }) - - mock_service.lookup_directory_through_revision.assert_called_once_with( - {'sha1_git': 'sha1'}, - 'some/path', limit=1000, with_data=True) - - @patch('swh.web.api.views.revision.parse_timestamp') - @patch('swh.web.api.views.revision._revision_directory_by') - @patch('swh.web.api.views.revision.utils') - def test_api_directory_through_revision_origin_ko_not_found(self, - mock_utils, - mock_rev_dir, - mock_parse_timestamp): # noqa - mock_rev_dir.side_effect = NotFoundExc('not found') - mock_parse_timestamp.return_value = '2012-10-20 00:00:00' - - rv = self.client.get('/api/1/revision' - '/origin/10' - '/branch/refs/remote/origin/dev' - '/ts/2012-10-20' - '/directory/') - - # then - self.assertEqual(rv.status_code, 404) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, { - 'exception': 'NotFoundExc', - 'reason': 'not found'}) - - mock_rev_dir.assert_called_once_with( - {'origin_id': '10', - 'branch_name': 'refs/remote/origin/dev', - 'ts': '2012-10-20 00:00:00'}, None, - '/api/1/revision' - '/origin/10' - '/branch/refs/remote/origin/dev' - '/ts/2012-10-20' - '/directory/', - with_data=False) - - @patch('swh.web.api.views.revision._revision_directory_by') - def test_api_directory_through_revision_origin(self, - mock_revision_dir): - expected_res = [{ - 'id': '123' - }] - mock_revision_dir.return_value = expected_res - - rv = self.client.get('/api/1/revision/origin/3/directory/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_res) - - mock_revision_dir.assert_called_once_with({ - 'origin_id': '3', - 'branch_name': 'refs/heads/master', - 'ts': None}, None, '/api/1/revision/origin/3/directory/', - with_data=False) - - @patch('swh.web.api.views.revision.service') def test_api_revision_log(self, mock_service): # given stub_revisions = [{ @@ -668,106 +413,6 @@ ['21145781e26ad1f978e']) @patch('swh.web.api.views.revision.service') - def test_api_revision_log_by(self, mock_service): - # given - stub_revisions = [{ - 'id': '18d8be353ed3480476f032475e7c233eff7371d5', - 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', - 'author_name': 'Software Heritage', - 'author_email': 'robot@softwareheritage.org', - 'committer_name': 'Software Heritage', - 'committer_email': 'robot@softwareheritage.org', - 'message': 'synthetic revision message', - 'date_offset': 0, - 'committer_date_offset': 0, - 'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'], - 'type': 'tar', - 'synthetic': True, - }] - mock_service.lookup_revision_log_by.return_value = stub_revisions - - expected_revisions = [{ - 'id': '18d8be353ed3480476f032475e7c233eff7371d5', - 'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/', - 'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef' - 'f7371d5/log/', - 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', - 'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a' - '42b7e2a44e6/', - 'author_name': 'Software Heritage', - 'author_email': 'robot@softwareheritage.org', - 'committer_name': 'Software Heritage', - 'committer_email': 'robot@softwareheritage.org', - 'message': 'synthetic revision message', - 'date_offset': 0, - 'committer_date_offset': 0, - 'parents': [{ - 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345', - 'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/' # noqa - }], - 'type': 'tar', - 'synthetic': True, - }] - - # when - rv = self.client.get('/api/1/revision/origin/1/log/') - - # then - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEqual(rv.data, expected_revisions) - self.assertFalse(rv.has_header('Link')) - - mock_service.lookup_revision_log_by.assert_called_once_with( - '1', 'refs/heads/master', None, 11) - - @patch('swh.web.api.views.revision.service') - def test_api_revision_log_by_with_next(self, mock_service): - # given - stub_revisions = [] - for i in range(27): - stub_revisions.append({'id': str(i)}) - - mock_service.lookup_revision_log_by.return_value = stub_revisions[:26] - - expected_revisions = [x for x in stub_revisions if int(x['id']) < 25] - for e in expected_revisions: - e['url'] = '/api/1/revision/%s/' % e['id'] - e['history_url'] = '/api/1/revision/%s/log/' % e['id'] - - # when - rv = self.client.get('/api/1/revision/origin/1/log/?per_page=25') - - # then - self.assertEqual(rv.status_code, 200) - - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertIsNotNone(rv['Link']) - self.assertEqual(rv.data, expected_revisions) - - mock_service.lookup_revision_log_by.assert_called_once_with( - '1', 'refs/heads/master', None, 26) - - @patch('swh.web.api.views.revision.service') - def test_api_revision_log_by_norev(self, mock_service): - # given - mock_service.lookup_revision_log_by.side_effect = NotFoundExc( - 'No revision') - - # when - rv = self.client.get('/api/1/revision/origin/1/log/') - - # then - self.assertEqual(rv.status_code, 404) - self.assertEqual(rv['Content-Type'], 'application/json') - self.assertFalse(rv.has_header('Link')) - self.assertEqual(rv.data, {'exception': 'NotFoundExc', - 'reason': 'No revision'}) - - mock_service.lookup_revision_log_by.assert_called_once_with( - '1', 'refs/heads/master', None, 11) - - @patch('swh.web.api.views.revision.service') def test_api_revision_history(self, mock_service): # for readability purposes, we use: # - sha1 as 3 letters (url are way too long otherwise to respect pep8) diff --git a/swh/web/tests/common/test_service.py b/swh/web/tests/common/test_service.py --- a/swh/web/tests/common/test_service.py +++ b/swh/web/tests/common/test_service.py @@ -1678,271 +1678,3 @@ self.assertEqual(actual_directory_ls, []) self.assertFalse(mock_storage.directory_ls.called) - - @patch('swh.web.common.service.storage') - def test_lookup_revision_by_nothing_found(self, mock_storage): - # given - mock_storage.revision_get_by.return_value = None - - # when - with self.assertRaises(NotFoundExc): - service.lookup_revision_by(1) - - # then - mock_storage.revision_get_by.assert_called_with(1, 'refs/heads/master', # noqa - limit=1, - timestamp=None) - - @patch('swh.web.common.service.storage') - def test_lookup_revision_by(self, mock_storage): - # given - stub_rev = self.SAMPLE_REVISION_RAW - - expected_rev = self.SAMPLE_REVISION - - mock_storage.revision_get_by.return_value = [stub_rev] - - # when - actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') - - # then - self.assertEqual(actual_revision, expected_rev) - - mock_storage.revision_get_by.assert_called_with(10, 'master2', - limit=1, - timestamp='some-ts') - - @patch('swh.web.common.service.storage') - def test_lookup_revision_by_nomerge(self, mock_storage): - # given - stub_rev = self.SAMPLE_REVISION_RAW - stub_rev['parents'] = [ - hash_to_bytes('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc')] - - expected_rev = self.SAMPLE_REVISION - expected_rev['parents'] = ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'] - mock_storage.revision_get_by.return_value = [stub_rev] - - # when - actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') - - # then - self.assertEqual(actual_revision, expected_rev) - - mock_storage.revision_get_by.assert_called_with(10, 'master2', - limit=1, - timestamp='some-ts') - - @patch('swh.web.common.service.storage') - def test_lookup_revision_by_merge(self, mock_storage): - # given - stub_rev = self.SAMPLE_REVISION_RAW - stub_rev['parents'] = [ - hash_to_bytes('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'), - hash_to_bytes('ffff3b19e793491b1c6db0fd8b46cd9f32e592fc') - ] - - expected_rev = self.SAMPLE_REVISION - expected_rev['parents'] = [ - 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc', - 'ffff3b19e793491b1c6db0fd8b46cd9f32e592fc' - ] - expected_rev['merge'] = True - - mock_storage.revision_get_by.return_value = [stub_rev] - - # when - actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') - - # then - self.assertEqual(actual_revision, expected_rev) - - mock_storage.revision_get_by.assert_called_with(10, 'master2', - limit=1, - timestamp='some-ts') - - @patch('swh.web.common.service.storage') - def test_lookup_revision_with_context_by_ko(self, mock_storage): - # given - mock_storage.revision_get_by.return_value = None - - # when - origin_id = 1 - branch_name = 'master3' - ts = None - with self.assertRaises(NotFoundExc) as cm: - service.lookup_revision_with_context_by(origin_id, branch_name, ts, - 'sha1') - # then - self.assertIn( - 'Revision with (origin_id: %s, branch_name: %s' - ', ts: %s) not found.' % (origin_id, - branch_name, - ts), cm.exception.args[0]) - - mock_storage.revision_get_by.assert_called_once_with( - origin_id, branch_name, limit=1, timestamp=ts) - - @patch('swh.web.common.service.lookup_revision_with_context') - @patch('swh.web.common.service.storage') - def test_lookup_revision_with_context_by( - self, mock_storage, mock_lookup_revision_with_context, - ): - # given - stub_root_rev = {'id': 'root-rev-id'} - mock_storage.revision_get_by.return_value = [{'id': 'root-rev-id'}] - stub_rev = {'id': 'rev-found'} - mock_lookup_revision_with_context.return_value = stub_rev - - # when - origin_id = 1 - branch_name = 'master3' - ts = None - sha1_git = 'sha1' - actual_root_rev, actual_rev = service.lookup_revision_with_context_by( - origin_id, branch_name, ts, sha1_git) - - # then - self.assertEqual(actual_root_rev, stub_root_rev) - self.assertEqual(actual_rev, stub_rev) - - mock_storage.revision_get_by.assert_called_once_with( - origin_id, branch_name, limit=1, timestamp=ts) - mock_lookup_revision_with_context.assert_called_once_with( - stub_root_rev, sha1_git, 100) - - def test_lookup_revision_through_ko_not_implemented(self): - # then - with self.assertRaises(NotImplementedError): - service.lookup_revision_through({ - 'something-unknown': 10, - }) - - @patch('swh.web.common.service.lookup_revision_with_context_by') - def test_lookup_revision_through_with_context_by(self, mock_lookup): - # given - stub_rev = {'id': 'rev'} - mock_lookup.return_value = stub_rev - - # when - actual_revision = service.lookup_revision_through({ - 'origin_id': 1, - 'branch_name': 'master', - 'ts': None, - 'sha1_git': 'sha1-git' - }, limit=1000) - - # then - self.assertEqual(actual_revision, stub_rev) - - mock_lookup.assert_called_once_with( - 1, 'master', None, 'sha1-git', 1000) - - @patch('swh.web.common.service.lookup_revision_by') - def test_lookup_revision_through_with_revision_by(self, mock_lookup): - # given - stub_rev = {'id': 'rev'} - mock_lookup.return_value = stub_rev - - # when - actual_revision = service.lookup_revision_through({ - 'origin_id': 2, - 'branch_name': 'master2', - 'ts': 'some-ts', - }, limit=10) - - # then - self.assertEqual(actual_revision, stub_rev) - - mock_lookup.assert_called_once_with( - 2, 'master2', 'some-ts') - - @patch('swh.web.common.service.lookup_revision_with_context') - def test_lookup_revision_through_with_context(self, mock_lookup): - # given - stub_rev = {'id': 'rev'} - mock_lookup.return_value = stub_rev - - # when - actual_revision = service.lookup_revision_through({ - 'sha1_git_root': 'some-sha1-root', - 'sha1_git': 'some-sha1', - }) - - # then - self.assertEqual(actual_revision, stub_rev) - - mock_lookup.assert_called_once_with( - 'some-sha1-root', 'some-sha1', 100) - - @patch('swh.web.common.service.lookup_revision') - def test_lookup_revision_through_with_revision(self, mock_lookup): - # given - stub_rev = {'id': 'rev'} - mock_lookup.return_value = stub_rev - - # when - actual_revision = service.lookup_revision_through({ - 'sha1_git': 'some-sha1', - }) - - # then - self.assertEqual(actual_revision, stub_rev) - - mock_lookup.assert_called_once_with( - 'some-sha1') - - @patch('swh.web.common.service.lookup_revision_through') - def test_lookup_directory_through_revision_ko_not_found( - self, mock_lookup_rev): - # given - mock_lookup_rev.return_value = None - - # when - with self.assertRaises(NotFoundExc): - service.lookup_directory_through_revision( - {'id': 'rev'}, 'some/path', 100) - - mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 100) - - @patch('swh.web.common.service.lookup_revision_through') - @patch('swh.web.common.service.lookup_directory_with_revision') - def test_lookup_directory_through_revision_ok_with_data( - self, mock_lookup_dir, mock_lookup_rev): - # given - mock_lookup_rev.return_value = {'id': 'rev-id'} - mock_lookup_dir.return_value = {'type': 'dir', - 'content': []} - - # when - rev_id, dir_result = service.lookup_directory_through_revision( - {'id': 'rev'}, 'some/path', 100) - # then - self.assertEqual(rev_id, 'rev-id') - self.assertEqual(dir_result, {'type': 'dir', - 'content': []}) - - mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 100) - mock_lookup_dir.assert_called_once_with('rev-id', 'some/path', False) - - @patch('swh.web.common.service.lookup_revision_through') - @patch('swh.web.common.service.lookup_directory_with_revision') - def test_lookup_directory_through_revision_ok_with_content( - self, mock_lookup_dir, mock_lookup_rev): - # given - mock_lookup_rev.return_value = {'id': 'rev-id'} - stub_result = {'type': 'file', - 'revision': 'rev-id', - 'content': {'data': b'blah', - 'sha1': 'sha1'}} - mock_lookup_dir.return_value = stub_result - - # when - rev_id, dir_result = service.lookup_directory_through_revision( - {'id': 'rev'}, 'some/path', 10, with_data=True) - # then - self.assertEqual(rev_id, 'rev-id') - self.assertEqual(dir_result, stub_result) - - mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 10) - mock_lookup_dir.assert_called_once_with('rev-id', 'some/path', True)