Changeset View
Changeset View
Standalone View
Standalone View
swh/web/tests/common/test_converters.py
# Copyright (C) 2015-2018 The Software Heritage developers | # Copyright (C) 2015-2018 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import datetime | import datetime | ||||
from nose.tools import istest | |||||
from swh.model import hashutil | from swh.model import hashutil | ||||
from swh.web.common import converters | from swh.web.common import converters | ||||
from swh.web.tests.testcase import SWHWebTestCase | from swh.web.tests.testcase import SWHWebTestCase | ||||
class ConvertersTestCase(SWHWebTestCase): | class ConvertersTestCase(SWHWebTestCase): | ||||
@istest | def test_fmap(self): | ||||
def fmap(self): | |||||
self.assertEquals([2, 3, None, 4], | self.assertEquals([2, 3, None, 4], | ||||
converters.fmap(lambda x: x+1, [1, 2, None, 3])) | converters.fmap(lambda x: x+1, [1, 2, None, 3])) | ||||
self.assertEquals([11, 12, 13], | self.assertEquals([11, 12, 13], | ||||
list(converters.fmap(lambda x: x+10, | list(converters.fmap(lambda x: x+10, | ||||
map(lambda x: x, [1, 2, 3])))) | map(lambda x: x, [1, 2, 3])))) | ||||
self.assertEquals({'a': 2, 'b': 4}, | self.assertEquals({'a': 2, 'b': 4}, | ||||
converters.fmap(lambda x: x*2, {'a': 1, 'b': 2})) | converters.fmap(lambda x: x*2, {'a': 1, 'b': 2})) | ||||
self.assertEquals(100, | self.assertEquals(100, | ||||
converters.fmap(lambda x: x*10, 10)) | converters.fmap(lambda x: x*10, 10)) | ||||
self.assertEquals({'a': [2, 6], 'b': 4}, | self.assertEquals({'a': [2, 6], 'b': 4}, | ||||
converters.fmap(lambda x: x*2, {'a': [1, 3], 'b': 2})) # noqa | converters.fmap(lambda x: x*2, {'a': [1, 3], 'b': 2})) # noqa | ||||
self.assertIsNone(converters.fmap(lambda x: x, None)) | self.assertIsNone(converters.fmap(lambda x: x, None)) | ||||
@istest | def test_from_swh(self): | ||||
def from_swh(self): | |||||
some_input = { | some_input = { | ||||
'a': 'something', | 'a': 'something', | ||||
'b': 'someone', | 'b': 'someone', | ||||
'c': b'sharp-0.3.4.tgz', | 'c': b'sharp-0.3.4.tgz', | ||||
'd': hashutil.hash_to_bytes( | 'd': hashutil.hash_to_bytes( | ||||
'b04caf10e9535160d90e874b45aa426de762f19f'), | 'b04caf10e9535160d90e874b45aa426de762f19f'), | ||||
'e': b'sharp.html/doc_002dS_005fISREG.html', | 'e': b'sharp.html/doc_002dS_005fISREG.html', | ||||
'g': [b'utf-8-to-decode', b'another-one'], | 'g': [b'utf-8-to-decode', b'another-one'], | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | def test_from_swh(self): | ||||
removables_if_empty={'t'}, | removables_if_empty={'t'}, | ||||
empty_dict={'u'}, | empty_dict={'u'}, | ||||
empty_list={'v'}, | empty_list={'v'}, | ||||
convert={'p', 'q', 'w'}, | convert={'p', 'q', 'w'}, | ||||
convert_fn=converters.convert_revision_metadata) | convert_fn=converters.convert_revision_metadata) | ||||
self.assertEquals(expected_output, actual_output) | self.assertEquals(expected_output, actual_output) | ||||
@istest | def test_from_swh_edge_cases_do_no_conversion_if_none_or_not_bytes(self): | ||||
def from_swh_edge_cases_do_no_conversion_if_none_or_not_bytes(self): | |||||
some_input = { | some_input = { | ||||
'a': 'something', | 'a': 'something', | ||||
'b': None, | 'b': None, | ||||
'c': 'someone', | 'c': 'someone', | ||||
'd': None, | 'd': None, | ||||
'e': None | 'e': None | ||||
} | } | ||||
expected_output = { | expected_output = { | ||||
'a': 'something', | 'a': 'something', | ||||
'b': None, | 'b': None, | ||||
'c': 'someone', | 'c': 'someone', | ||||
'd': None, | 'd': None, | ||||
'e': None | 'e': None | ||||
} | } | ||||
actual_output = converters.from_swh(some_input, | actual_output = converters.from_swh(some_input, | ||||
hashess={'a', 'b'}, | hashess={'a', 'b'}, | ||||
bytess={'c', 'd'}, | bytess={'c', 'd'}, | ||||
dates={'e'}) | dates={'e'}) | ||||
self.assertEquals(expected_output, actual_output) | self.assertEquals(expected_output, actual_output) | ||||
@istest | def test_from_swh_edge_cases_convert_invalid_utf8_bytes(self): | ||||
def from_swh_edge_cases_convert_invalid_utf8_bytes(self): | |||||
some_input = { | some_input = { | ||||
'a': 'something', | 'a': 'something', | ||||
'b': 'someone', | 'b': 'someone', | ||||
'c': b'a name \xff', | 'c': b'a name \xff', | ||||
'd': b'an email \xff', | 'd': b'an email \xff', | ||||
} | } | ||||
expected_output = { | expected_output = { | ||||
Show All 9 Lines | def test_from_swh_edge_cases_convert_invalid_utf8_bytes(self): | ||||
bytess={'c', 'd'}) | bytess={'c', 'd'}) | ||||
for v in ['a', 'b', 'c', 'd']: | for v in ['a', 'b', 'c', 'd']: | ||||
self.assertEqual(expected_output[v], actual_output[v]) | self.assertEqual(expected_output[v], actual_output[v]) | ||||
self.assertEqual(len(expected_output['decoding_failures']), | self.assertEqual(len(expected_output['decoding_failures']), | ||||
len(actual_output['decoding_failures'])) | len(actual_output['decoding_failures'])) | ||||
for v in expected_output['decoding_failures']: | for v in expected_output['decoding_failures']: | ||||
self.assertTrue(v in actual_output['decoding_failures']) | self.assertTrue(v in actual_output['decoding_failures']) | ||||
@istest | def test_from_swh_empty(self): | ||||
def from_swh_empty(self): | |||||
# when | # when | ||||
self.assertEquals({}, converters.from_swh({})) | self.assertEquals({}, converters.from_swh({})) | ||||
@istest | def test_from_swh_none(self): | ||||
def from_swh_none(self): | |||||
# when | # when | ||||
self.assertIsNone(converters.from_swh(None)) | self.assertIsNone(converters.from_swh(None)) | ||||
@istest | def test_from_provenance(self): | ||||
def from_provenance(self): | |||||
# given | # given | ||||
input_provenance = { | input_provenance = { | ||||
'origin': 10, | 'origin': 10, | ||||
'visit': 1, | 'visit': 1, | ||||
'content': hashutil.hash_to_bytes( | 'content': hashutil.hash_to_bytes( | ||||
'321caf10e9535160d90e874b45aa426de762f19f'), | '321caf10e9535160d90e874b45aa426de762f19f'), | ||||
'revision': hashutil.hash_to_bytes( | 'revision': hashutil.hash_to_bytes( | ||||
'123caf10e9535160d90e874b45aa426de762f19f'), | '123caf10e9535160d90e874b45aa426de762f19f'), | ||||
Show All 9 Lines | def test_from_provenance(self): | ||||
} | } | ||||
# when | # when | ||||
actual_provenance = converters.from_provenance(input_provenance) | actual_provenance = converters.from_provenance(input_provenance) | ||||
# then | # then | ||||
self.assertEqual(actual_provenance, expected_provenance) | self.assertEqual(actual_provenance, expected_provenance) | ||||
@istest | def test_from_origin(self): | ||||
def from_origin(self): | |||||
# given | # given | ||||
origin_input = { | origin_input = { | ||||
'id': 9, | 'id': 9, | ||||
'type': 'ftp', | 'type': 'ftp', | ||||
'url': 'rsync://ftp.gnu.org/gnu/octave', | 'url': 'rsync://ftp.gnu.org/gnu/octave', | ||||
} | } | ||||
expected_origin = { | expected_origin = { | ||||
'id': 9, | 'id': 9, | ||||
'type': 'ftp', | 'type': 'ftp', | ||||
'url': 'rsync://ftp.gnu.org/gnu/octave', | 'url': 'rsync://ftp.gnu.org/gnu/octave', | ||||
} | } | ||||
# when | # when | ||||
actual_origin = converters.from_origin(origin_input) | actual_origin = converters.from_origin(origin_input) | ||||
# then | # then | ||||
self.assertEqual(actual_origin, expected_origin) | self.assertEqual(actual_origin, expected_origin) | ||||
@istest | def test_from_origin_visit(self): | ||||
def from_origin_visit(self): | |||||
snap_hash = 'b5f0b7f716735ebffe38505c60145c4fd9da6ca3' | snap_hash = 'b5f0b7f716735ebffe38505c60145c4fd9da6ca3' | ||||
for snap in [snap_hash, None]: | for snap in [snap_hash, None]: | ||||
# given | # given | ||||
visit = { | visit = { | ||||
'date': { | 'date': { | ||||
'timestamp': datetime.datetime( | 'timestamp': datetime.datetime( | ||||
2015, 1, 1, 22, 0, 0, | 2015, 1, 1, 22, 0, 0, | ||||
Show All 18 Lines | def test_from_origin_visit(self): | ||||
} | } | ||||
# when | # when | ||||
actual_visit = converters.from_origin_visit(visit) | actual_visit = converters.from_origin_visit(visit) | ||||
# then | # then | ||||
self.assertEqual(actual_visit, expected_visit) | self.assertEqual(actual_visit, expected_visit) | ||||
@istest | def test_from_release(self): | ||||
def from_release(self): | |||||
release_input = { | release_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'aad23fa492a0c5fed0708a6703be875448c86884'), | 'aad23fa492a0c5fed0708a6703be875448c86884'), | ||||
'target': hashutil.hash_to_bytes( | 'target': hashutil.hash_to_bytes( | ||||
'5e46d564378afc44b31bb89f99d5675195fbdf67'), | '5e46d564378afc44b31bb89f99d5675195fbdf67'), | ||||
'target_type': 'revision', | 'target_type': 'revision', | ||||
'date': { | 'date': { | ||||
'timestamp': datetime.datetime( | 'timestamp': datetime.datetime( | ||||
Show All 29 Lines | def test_from_release(self): | ||||
} | } | ||||
# when | # when | ||||
actual_release = converters.from_release(release_input) | actual_release = converters.from_release(release_input) | ||||
# then | # then | ||||
self.assertEqual(actual_release, expected_release) | self.assertEqual(actual_release, expected_release) | ||||
@istest | def test_from_release_no_revision(self): | ||||
def from_release_no_revision(self): | |||||
release_input = { | release_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e'), | 'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e'), | ||||
'target': None, | 'target': None, | ||||
'date': { | 'date': { | ||||
'timestamp': datetime.datetime( | 'timestamp': datetime.datetime( | ||||
2016, 3, 2, 10, 0, 0, | 2016, 3, 2, 10, 0, 0, | ||||
tzinfo=datetime.timezone.utc).timestamp(), | tzinfo=datetime.timezone.utc).timestamp(), | ||||
Show All 26 Lines | def test_from_release_no_revision(self): | ||||
} | } | ||||
# when | # when | ||||
actual_release = converters.from_release(release_input) | actual_release = converters.from_release(release_input) | ||||
# then | # then | ||||
self.assertEqual(actual_release, expected_release) | self.assertEqual(actual_release, expected_release) | ||||
@istest | def test_from_revision(self): | ||||
def from_revision(self): | |||||
revision_input = { | revision_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'18d8be353ed3480476f032475e7c233eff7371d5'), | '18d8be353ed3480476f032475e7c233eff7371d5'), | ||||
'directory': hashutil.hash_to_bytes( | 'directory': hashutil.hash_to_bytes( | ||||
'7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | ||||
'author': { | 'author': { | ||||
'name': b'Software Heritage', | 'name': b'Software Heritage', | ||||
'fullname': b'robot robot@softwareheritage.org', | 'fullname': b'robot robot@softwareheritage.org', | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | def test_from_revision(self): | ||||
} | } | ||||
# when | # when | ||||
actual_revision = converters.from_revision(revision_input) | actual_revision = converters.from_revision(revision_input) | ||||
# then | # then | ||||
self.assertEqual(actual_revision, expected_revision) | self.assertEqual(actual_revision, expected_revision) | ||||
@istest | def test_from_revision_nomerge(self): | ||||
def from_revision_nomerge(self): | |||||
revision_input = { | revision_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'18d8be353ed3480476f032475e7c233eff7371d5'), | '18d8be353ed3480476f032475e7c233eff7371d5'), | ||||
'parents': [ | 'parents': [ | ||||
hashutil.hash_to_bytes( | hashutil.hash_to_bytes( | ||||
'29d8be353ed3480476f032475e7c244eff7371d5') | '29d8be353ed3480476f032475e7c244eff7371d5') | ||||
] | ] | ||||
} | } | ||||
expected_revision = { | expected_revision = { | ||||
'id': '18d8be353ed3480476f032475e7c233eff7371d5', | 'id': '18d8be353ed3480476f032475e7c233eff7371d5', | ||||
'parents': [ | 'parents': [ | ||||
'29d8be353ed3480476f032475e7c244eff7371d5' | '29d8be353ed3480476f032475e7c244eff7371d5' | ||||
], | ], | ||||
'merge': False | 'merge': False | ||||
} | } | ||||
# when | # when | ||||
actual_revision = converters.from_revision(revision_input) | actual_revision = converters.from_revision(revision_input) | ||||
# then | # then | ||||
self.assertEqual(actual_revision, expected_revision) | self.assertEqual(actual_revision, expected_revision) | ||||
@istest | def test_from_revision_noparents(self): | ||||
def from_revision_noparents(self): | |||||
revision_input = { | revision_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'18d8be353ed3480476f032475e7c233eff7371d5'), | '18d8be353ed3480476f032475e7c233eff7371d5'), | ||||
'directory': hashutil.hash_to_bytes( | 'directory': hashutil.hash_to_bytes( | ||||
'7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | ||||
'author': { | 'author': { | ||||
'name': b'Software Heritage', | 'name': b'Software Heritage', | ||||
'fullname': b'robot robot@softwareheritage.org', | 'fullname': b'robot robot@softwareheritage.org', | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | def test_from_revision_noparents(self): | ||||
} | } | ||||
# when | # when | ||||
actual_revision = converters.from_revision(revision_input) | actual_revision = converters.from_revision(revision_input) | ||||
# then | # then | ||||
self.assertEqual(actual_revision, expected_revision) | self.assertEqual(actual_revision, expected_revision) | ||||
@istest | def test_from_revision_invalid(self): | ||||
def from_revision_invalid(self): | |||||
revision_input = { | revision_input = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'18d8be353ed3480476f032475e7c233eff7371d5'), | '18d8be353ed3480476f032475e7c233eff7371d5'), | ||||
'directory': hashutil.hash_to_bytes( | 'directory': hashutil.hash_to_bytes( | ||||
'7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), | ||||
'author': { | 'author': { | ||||
'name': b'Software Heritage', | 'name': b'Software Heritage', | ||||
'fullname': b'robot robot@softwareheritage.org', | 'fullname': b'robot robot@softwareheritage.org', | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | def test_from_revision_invalid(self): | ||||
} | } | ||||
# when | # when | ||||
actual_revision = converters.from_revision(revision_input) | actual_revision = converters.from_revision(revision_input) | ||||
# then | # then | ||||
self.assertEqual(actual_revision, expected_revision) | self.assertEqual(actual_revision, expected_revision) | ||||
@istest | def test_from_content_none(self): | ||||
def from_content_none(self): | |||||
self.assertIsNone(converters.from_content(None)) | self.assertIsNone(converters.from_content(None)) | ||||
@istest | def test_from_content(self): | ||||
def from_content(self): | |||||
content_input = { | content_input = { | ||||
'sha1': hashutil.hash_to_bytes( | 'sha1': hashutil.hash_to_bytes( | ||||
'5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | ||||
'sha256': hashutil.hash_to_bytes( | 'sha256': hashutil.hash_to_bytes( | ||||
'39007420ca5de7cb3cfc15196335507e' | '39007420ca5de7cb3cfc15196335507e' | ||||
'e76c98930e7e0afa4d2747d3bf96c926'), | 'e76c98930e7e0afa4d2747d3bf96c926'), | ||||
'blake2s256': hashutil.hash_to_bytes( | 'blake2s256': hashutil.hash_to_bytes( | ||||
'49007420ca5de7cb3cfc15196335507e' | '49007420ca5de7cb3cfc15196335507e' | ||||
Show All 22 Lines | def test_from_content(self): | ||||
} | } | ||||
# when | # when | ||||
actual_content = converters.from_content(content_input) | actual_content = converters.from_content(content_input) | ||||
# then | # then | ||||
self.assertEqual(actual_content, expected_content) | self.assertEqual(actual_content, expected_content) | ||||
@istest | def test_from_person(self): | ||||
def from_person(self): | |||||
person_input = { | person_input = { | ||||
'id': 10, | 'id': 10, | ||||
'anything': 'else', | 'anything': 'else', | ||||
'name': b'bob', | 'name': b'bob', | ||||
'fullname': b'bob bob@alice.net', | 'fullname': b'bob bob@alice.net', | ||||
'email': b'bob@foo.alice', | 'email': b'bob@foo.alice', | ||||
} | } | ||||
expected_person = { | expected_person = { | ||||
'id': 10, | 'id': 10, | ||||
'anything': 'else', | 'anything': 'else', | ||||
'name': 'bob', | 'name': 'bob', | ||||
'fullname': 'bob bob@alice.net', | 'fullname': 'bob bob@alice.net', | ||||
'email': 'bob@foo.alice', | 'email': 'bob@foo.alice', | ||||
} | } | ||||
# when | # when | ||||
actual_person = converters.from_person(person_input) | actual_person = converters.from_person(person_input) | ||||
# then | # then | ||||
self.assertEqual(actual_person, expected_person) | self.assertEqual(actual_person, expected_person) | ||||
@istest | def test_from_directory_entries(self): | ||||
def from_directory_entries(self): | |||||
dir_entries_input = { | dir_entries_input = { | ||||
'sha1': hashutil.hash_to_bytes( | 'sha1': hashutil.hash_to_bytes( | ||||
'5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | ||||
'sha256': hashutil.hash_to_bytes( | 'sha256': hashutil.hash_to_bytes( | ||||
'39007420ca5de7cb3cfc15196335507e' | '39007420ca5de7cb3cfc15196335507e' | ||||
'e76c98930e7e0afa4d2747d3bf96c926'), | 'e76c98930e7e0afa4d2747d3bf96c926'), | ||||
'sha1_git': hashutil.hash_to_bytes( | 'sha1_git': hashutil.hash_to_bytes( | ||||
'40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), | '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), | ||||
Show All 26 Lines | def test_from_directory_entries(self): | ||||
} | } | ||||
# when | # when | ||||
actual_dir_entries = converters.from_directory_entry(dir_entries_input) | actual_dir_entries = converters.from_directory_entry(dir_entries_input) | ||||
# then | # then | ||||
self.assertEqual(actual_dir_entries, expected_dir_entries) | self.assertEqual(actual_dir_entries, expected_dir_entries) | ||||
@istest | def test_from_filetype(self): | ||||
def from_filetype(self): | |||||
content_filetype = { | content_filetype = { | ||||
'id': hashutil.hash_to_bytes( | 'id': hashutil.hash_to_bytes( | ||||
'5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), | ||||
'encoding': b'utf-8', | 'encoding': b'utf-8', | ||||
'mimetype': b'text/plain', | 'mimetype': b'text/plain', | ||||
} | } | ||||
expected_content_filetype = { | expected_content_filetype = { | ||||
Show All 10 Lines |