diff --git a/swh/web/ui/converters.py b/swh/web/ui/converters.py --- a/swh/web/ui/converters.py +++ b/swh/web/ui/converters.py @@ -165,6 +165,7 @@ return from_swh(revision, hashess=set(['id', 'directory', 'parents', 'children']), bytess=set(['name', + 'fullname', 'email', 'message']), dates={'date', 'committer_date'}) diff --git a/swh/web/ui/tests/views/test_api.py b/swh/web/ui/tests/views/test_api.py --- a/swh/web/ui/tests/views/test_api.py +++ b/swh/web/ui/tests/views/test_api.py @@ -716,6 +716,119 @@ @patch('swh.web.ui.views.api.service') @istest + def api_revision_raw_ok(self, mock_service): + # given + stub_revision = { + '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': ['8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'], + 'type': 'tar', + 'synthetic': True, + 'metadata': { + 'original_artifact': [{ + 'archive_type': 'tar', + 'name': 'webbase-5.7.0.tar.gz', + 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', + 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', + 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' + '309d36484e7edf7bb912' + }] + }, + } + + mock_service.lookup_revision.return_value = stub_revision + + # when + rv = self.app.get('/api/1/revision/' + '18d8be353ed3480476f032475e7c233eff7371d5/raw/') + + # then + self.assertEquals(rv.status_code, 200) + self.assertEquals(rv.mimetype, 'application/json') + + response_data = json.loads(rv.data.decode('utf-8')) + self.assertEquals(response_data, + {'message': 'synthetic revision message'}) + + mock_service.lookup_revision.assert_called_once_with( + '18d8be353ed3480476f032475e7c233eff7371d5') + + @patch('swh.web.ui.views.api.service') + @istest + def api_revision_raw_ko_no_msg(self, mock_service): + # given + stub_revision = { + 'id': '18d8be353ed3480476f032475e7c233eff7371d5', + 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', + 'author_name': 'Software Heritage', + 'author_email': 'robot@softwareheritage.org', + 'committer_name': 'Software Heritage', + 'committer_email': 'robot@softwareheritage.org', + 'date_offset': 0, + 'committer_date_offset': 0, + 'parents': ['8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'], + 'type': 'tar', + 'synthetic': True, + 'metadata': { + 'original_artifact': [{ + 'archive_type': 'tar', + 'name': 'webbase-5.7.0.tar.gz', + 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', + 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', + 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' + '309d36484e7edf7bb912' + }] + }, + } + + mock_service.lookup_revision.return_value = stub_revision + + # when + rv = self.app.get('/api/1/revision/' + '18d8be353ed3480476f032475e7c233eff7371d5/raw/') + + # then + self.assertEquals(rv.status_code, 404) + self.assertEquals(rv.mimetype, 'application/json') + + response_data = json.loads(rv.data.decode('utf-8')) + self.assertEquals(response_data, { + 'error': 'No message for revision with sha1_git ' + '18d8be353ed3480476f032475e7c233eff7371d5.'}) + + mock_service.lookup_revision.assert_called_once_with( + '18d8be353ed3480476f032475e7c233eff7371d5') + + @patch('swh.web.ui.views.api.service') + @istest + def api_revision_raw_ko_no_rev(self, mock_service): + # given + mock_service.lookup_revision.side_effect = NotFoundExc('not found') + + # when + rv = self.app.get('/api/1/revision/' + '18d8be353ed3480476f032475e7c233eff7371d5/raw/') + + # then + self.assertEquals(rv.status_code, 404) + self.assertEquals(rv.mimetype, 'application/json') + + response_data = json.loads(rv.data.decode('utf-8')) + self.assertEquals(response_data, { + 'error': 'not found'}) + + mock_service.lookup_revision.assert_called_once_with( + '18d8be353ed3480476f032475e7c233eff7371d5') + + @patch('swh.web.ui.views.api.service') + @istest def api_revision_with_origin_not_found(self, mock_service): mock_service.lookup_revision_by.return_value = None diff --git a/swh/web/ui/views/api.py b/swh/web/ui/views/api.py --- a/swh/web/ui/views/api.py +++ b/swh/web/ui/views/api.py @@ -492,6 +492,36 @@ enrich_fn=utils.enrich_revision) +@app.route('/api/1/revision//raw/') +def api_revision_raw_message(sha1_git): + """Return the raw data of the revision's message + + Args: + sha1_git: the revision's hash + + Returns: + The raw revision message, possibly in an illegible + format for humans, decoded in utf-8 by default. + + Raises: + BadInputExc in case of unknown algo_hash or bad hash. + NotFoundExc if the revision is not found or the revision has no + message + + Example: + GET /api/1/revision/baf18f9fc50a0b6fef50460a76c33b2ddc57486e/raw/ + + """ + + rev = api_revision(sha1_git) + if 'message' in rev: + return {'message': rev['message']} + else: + raise NotFoundExc('No message for revision with sha1_git %s.' + % sha1_git) + # TODO: can do better than same as api_revision? + + @app.route('/api/1/revision//directory/') @app.route('/api/1/revision//directory//') def api_revision_directory(sha1_git,