diff --git a/core/common/checksums.py b/core/common/checksums.py index 87f542e6..59a4596f 100644 --- a/core/common/checksums.py +++ b/core/common/checksums.py @@ -88,7 +88,7 @@ def _calculate_standard_checksum(self): return self.generate_checksum('standard') def _calculate_smart_checksum(self): - return self.generate_checksum('standard') + return self.generate_checksum('smart') def _calculate_checksums(self): return self.get_all_checksums() diff --git a/core/common/tests.py b/core/common/tests.py index ce8cc247..b1086259 100644 --- a/core/common/tests.py +++ b/core/common/tests.py @@ -1165,7 +1165,7 @@ def test_generate(self): ) # datatype - self.assertNotEqual(Checksum.generate({'a': 1}), Checksum.generate({'a': 1.0})) + self.assertEqual(Checksum.generate({'a': 1}), Checksum.generate({'a': 1.0})) self.assertEqual(Checksum.generate({'a': 1.1}), Checksum.generate({'a': 1.10})) # value order @@ -1226,14 +1226,15 @@ def test_post_400(self, checksum_generate_mock): ) self.assertEqual(response.status_code, 400) + self.assertEqual(response.data, {'error': 'Invalid resource: foobar'}) checksum_generate_mock.assert_not_called() - @patch('core.common.checksums.Checksum.generate') + @patch('core.common.checksums.ChecksumBase.generate') def test_post_200_concept(self, checksum_generate_mock): checksum_generate_mock.return_value = 'checksum' response = self.client.post( - '/$checksum/standard/?resource=concept_version', + '/$checksum/standard/?resource=concept', data={'foo': 'bar', 'concept_class': 'foobar', 'extras': {}}, HTTP_AUTHORIZATION=f"Token {self.token}", format='json' @@ -1241,140 +1242,3 @@ def test_post_200_concept(self, checksum_generate_mock): self.assertEqual(response.status_code, 200) self.assertEqual(response.data, 'checksum') - checksum_generate_mock.assert_called_once_with( - { - 'concept_class': 'foobar', - } - ) - - @patch('core.common.checksums.Checksum.generate') - def test_post_200_mapping_standard(self, checksum_generate_mock): - checksum_generate_mock.side_effect = ['checksum1', 'checksum2', 'checksum3'] - - response = self.client.post( - '/$checksum/standard/?resource=mapping', - data=[ - { - 'id': 'bar', - 'map_type': 'foobar', - 'from_concept_url': '/foo/', - 'to_source_url': '/bar/', - 'from_concept_code': 'foo', - 'to_concept_code': 'bar', - 'from_concept_name': 'fooName', - 'to_concept_name': 'barName', - 'retired': False, - 'external_id': 'EX123', - 'extras': { - 'foo': 'bar' - } - }, - { - 'id': 'barbara', - 'map_type': 'foobarbara', - 'from_concept_url': '/foobara/', - 'to_source_url': '/barbara/', - 'from_concept_code': 'foobara', - 'to_concept_code': 'barbara', - 'from_concept_name': 'foobaraName', - 'to_concept_name': 'barbaraName', - 'retired': True, - 'extras': { - 'foo': 'barbara' - } - } - ], - HTTP_AUTHORIZATION=f"Token {self.token}", - format='json' - ) - - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data, 'checksum3') - self.assertEqual(checksum_generate_mock.call_count, 3) - self.assertEqual( - checksum_generate_mock.mock_calls, - [ - call({ - 'map_type': 'foobar', - 'from_concept_code': 'foo', - 'to_concept_code': 'bar', - 'from_concept_name': 'fooName', - 'to_concept_name': 'barName', - 'extras': {'foo': 'bar'}, - 'external_id': 'EX123', - 'to_source_url': '/bar/' - }), - call({ - 'map_type': 'foobarbara', - 'from_concept_code': 'foobara', - 'to_concept_code': 'barbara', - 'from_concept_name': 'foobaraName', - 'to_concept_name': 'barbaraName', - 'extras': {'foo': 'barbara'}, - 'retired': True, - 'to_source_url': '/barbara/', - }), - call(['checksum1', 'checksum2']) - ] - ) - - @patch('core.common.checksums.Checksum.generate') - def test_post_200_mapping_smart(self, checksum_generate_mock): - checksum_generate_mock.side_effect = ['checksum1', 'checksum2', 'checksum3'] - - response = self.client.post( - '/$checksum/smart/?resource=mapping', - data=[ - { - 'id': 'bar', - 'map_type': 'foobar', - 'from_concept_url': '/foo/', - 'to_source_url': '/bar/', - 'from_concept_code': 'foo', - 'to_concept_code': 'bar', - 'from_concept_name': 'fooName', - 'to_concept_name': 'barName', - 'retired': False, - 'extras': {'foo': 'bar'} - }, - { - 'id': 'barbara', - 'map_type': 'foobarbara', - 'from_concept_url': '/foobara/', - 'to_source_url': '/barbara/', - 'from_concept_code': 'foobara', - 'to_concept_code': 'barbara', - 'from_concept_name': 'foobaraName', - 'to_concept_name': 'barbaraName', - 'retired': True, - 'extras': {'foo': 'barbara'} - } - ], - HTTP_AUTHORIZATION=f"Token {self.token}", - format='json' - ) - - self.assertEqual(response.status_code, 200) - self.assertEqual(response.data, 'checksum3') - self.assertEqual(checksum_generate_mock.call_count, 3) - self.assertEqual( - checksum_generate_mock.mock_calls, - [ - call({ - 'map_type': 'foobar', - 'from_concept_code': 'foo', - 'to_concept_code': 'bar', - 'from_concept_name': 'fooName', - 'to_concept_name': 'barName' - }), - call({ - 'map_type': 'foobarbara', - 'from_concept_code': 'foobara', - 'to_concept_code': 'barbara', - 'from_concept_name': 'foobaraName', - 'to_concept_name': 'barbaraName', - 'retired': True - }), - call(['checksum1', 'checksum2']) - ] - ) diff --git a/core/common/views.py b/core/common/views.py index c6ce7f52..5642d2af 100644 --- a/core/common/views.py +++ b/core/common/views.py @@ -1123,8 +1123,12 @@ def post(self, request): if not resource or not data: return Response({'error': 'resource and data are both required.'}, status=status.HTTP_400_BAD_REQUEST) - return Response( - ChecksumModel.generate_checksum_from_many(resource, request.data, 'smart' if self.smart else 'standard')) + try: + checksum = ChecksumModel.generate_checksum_from_many( + resource, request.data, 'smart' if self.smart else 'standard') + except ValueError as ex: + return Response({'error': str(ex)}, status=status.HTTP_400_BAD_REQUEST) + return Response(checksum) class StandardChecksumView(AbstractChecksumView): diff --git a/core/concepts/tests/tests.py b/core/concepts/tests/tests.py index 802d72ab..4c62f492 100644 --- a/core/concepts/tests/tests.py +++ b/core/concepts/tests/tests.py @@ -389,14 +389,14 @@ def test_hierarchy_one_parent_child(self): def test_hierarchy(self): # pylint: disable=too-many-statements # Av1 parent_concept = ConceptFactory( - names=[ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)]) + mnemonic='A', names=[ConceptNameFactory.build(locale='en', name='Av1', locale_preferred=True)]) self.assertEqual(parent_concept.versions.count(), 1) source = parent_concept.parent # Av1 -> None and Av2 -> Bv1 child_concept = Concept.persist_new({ - **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c1', 'parent': source, - 'names': [ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)], + **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'B', 'parent': source, + 'names': [ConceptNameFactory.build(locale='en', name='Bv1', locale_preferred=True)], 'parent_concept_urls': [parent_concept.uri] }) @@ -413,8 +413,8 @@ def test_hierarchy(self): # pylint: disable=too-many-statements # Av1 -> None and Av2 -> Bv1,Bv2 and Bv2 -> Cv1 child_child_concept = Concept.persist_new({ - **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c2', 'parent': source, - 'names': [ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)], + **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'C', 'parent': source, + 'names': [ConceptNameFactory.build(locale='en', name='Cv1', locale_preferred=True)], 'parent_concept_urls': [child_concept.uri] }) @@ -436,7 +436,7 @@ def test_hierarchy(self): # pylint: disable=too-many-statements instance=child_child_concept.clone(), data={ 'parent_concept_urls': [parent_concept.uri], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv2', 'locale_preferred': True}] }, user=child_child_concept.created_by ) @@ -473,7 +473,7 @@ def test_hierarchy(self): # pylint: disable=too-many-statements instance=child_child_concept.clone(), data={ 'parent_concept_urls': [child_concept.uri], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv3', 'locale_preferred': True}] }, user=child_child_concept.created_by ) @@ -534,7 +534,7 @@ def test_hierarchy(self): # pylint: disable=too-many-statements instance=child_child_concept.clone(), data={ 'parent_concept_urls': [], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv4', 'locale_preferred': True}] }, user=child_child_concept.created_by ) @@ -597,16 +597,16 @@ def test_hierarchy(self): # pylint: disable=too-many-statements def test_hierarchy_without_multiple_parent_versions(self): # pylint: disable=too-many-statements # Av1 - parent_concept = ConceptFactory( - names=[ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)]) + parent_concept = ConceptFactory(mnemonic='A', + names=[ConceptNameFactory.build(locale='en', name='Av1', locale_preferred=True)]) self.assertEqual(parent_concept.versions.count(), 1) self.assertEqual(list(parent_concept.get_latest_version().child_concept_urls), []) source = parent_concept.parent # Av1 to Av1 -> Bv1 child_concept = Concept.persist_new(data={ - **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c1', 'parent': source, - 'names': [ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)], + **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'B', 'parent': source, + 'names': [ConceptNameFactory.build(locale='en', name='Bv1', locale_preferred=True)], 'parent_concept_urls': [parent_concept.uri] }, create_parent_version=False) @@ -622,8 +622,8 @@ def test_hierarchy_without_multiple_parent_versions(self): # pylint: disable=to # Av1 to Av1 -> Bv1 to Av1 -> Bv1 -> Cv1 child_child_concept = Concept.persist_new(data={ - **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c2', 'parent': source, - 'names': [ConceptNameFactory.build(locale='en', name='English', locale_preferred=True)], + **factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'C', 'parent': source, + 'names': [ConceptNameFactory.build(locale='en', name='Cv1', locale_preferred=True)], 'parent_concept_urls': [child_concept.uri] }, create_parent_version=False) @@ -646,7 +646,7 @@ def test_hierarchy_without_multiple_parent_versions(self): # pylint: disable=to instance=child_child_concept.clone(), data={ 'parent_concept_urls': [parent_concept.uri], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv2', 'locale_preferred': True}] }, user=child_child_concept.created_by, create_parent_version=False @@ -681,7 +681,7 @@ def test_hierarchy_without_multiple_parent_versions(self): # pylint: disable=to instance=child_child_concept.clone(), data={ 'parent_concept_urls': [child_concept.uri], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv3', 'locale_preferred': True}] }, user=child_child_concept.created_by, create_parent_version=False @@ -727,7 +727,7 @@ def test_hierarchy_without_multiple_parent_versions(self): # pylint: disable=to instance=child_child_concept.clone(), data={ 'parent_concept_urls': [], - 'names': [{'locale': 'en', 'name': 'English', 'locale_preferred': True}] + 'names': [{'locale': 'en', 'name': 'Cv4', 'locale_preferred': True}] }, user=child_child_concept.created_by, create_parent_version=False @@ -1341,7 +1341,7 @@ def test_cascade_as_hierarchy_reverse(self): root.url ) - @patch('core.common.checksums.Checksum.generate') + @patch('core.common.checksums.ChecksumBase.generate') def test_checksum(self, checksum_generate_mock): checksum_generate_mock.side_effect = [ 'standard-checksum', 'smart-checksum'