diff --git a/core/collections/serializers.py b/core/collections/serializers.py index e238d073..c7f0b038 100644 --- a/core/collections/serializers.py +++ b/core/collections/serializers.py @@ -199,10 +199,11 @@ def prepare_object(self, validated_data, instance=None): collection.full_name = validated_data.get('full_name', collection.full_name) or collection.name collection.autoexpand_head = validated_data.get('autoexpand_head', collection.autoexpand_head) collection.autoexpand = validated_data.get('autoexpand', collection.autoexpand) - collection.expansion_uri = validated_data.get('expansion_uri', collection.expansion_uri) - if collection.id and collection.expansion_uri and not collection.expansions.filter( - uri=collection.expansion_uri).exists(): - self._errors.update({'expansion_url': INVALID_EXPANSION_URL}) + # A new collection or version has no expansions yet, so only an update may name one. + if collection.id: + collection.expansion_uri = validated_data.get('expansion_uri', collection.expansion_uri) + if collection.expansion_uri and not collection.expansions.filter(uri=collection.expansion_uri).exists(): + self._errors.update({'expansion_url': INVALID_EXPANSION_URL}) return collection diff --git a/core/integration_tests/tests_collections.py b/core/integration_tests/tests_collections.py index 2cc5ba34..0cda6594 100644 --- a/core/integration_tests/tests_collections.py +++ b/core/integration_tests/tests_collections.py @@ -340,6 +340,32 @@ def test_post_201_with_autoexpand_head_false(self): ] ) + def test_post_201_ignores_expansion_uri(self): + org = OrganizationFactory(mnemonic='org') + user = UserProfileFactory(organizations=[org], username='user') + other_expansion = ExpansionFactory(collection_version=OrganizationCollectionFactory()) + + for collection_id, expansion_uri, autoexpand_head in [ + ('coll1', 'https://other.example/x/', True), ('coll2', other_expansion.uri, False)]: + with self.subTest(expansion_uri=expansion_uri): + response = self.client.post( + '/orgs/org/collections/', + { + 'id': collection_id, + 'name': 'Collection', + 'expansion_uri': expansion_uri, + 'autoexpand_head': autoexpand_head + }, + HTTP_AUTHORIZATION='Token ' + user.get_token(), + format='json' + ) + + self.assertEqual(response.status_code, 201) + collection = org.collection_set.get(mnemonic=collection_id, version='HEAD') + own_expansion = collection.expansions.first() + self.assertEqual(collection.expansion_uri, own_expansion.uri if autoexpand_head else None) + self.assertEqual(response.data['expansion_url'], collection.expansion_uri) + def test_post_400(self): org = OrganizationFactory(mnemonic='org') user = UserProfileFactory(organizations=[org]) @@ -2429,6 +2455,25 @@ def test_put_400(self): self.assertEqual(response.status_code, 400) self.assertEqual(response.data, {'version': [ErrorDetail(string='This field may not be null.', code='null')]}) + def test_put_expansion_url(self): + own_expansion = ExpansionFactory(collection_version=self.collection_v1) + other_expansion = ExpansionFactory(collection_version=self.collection) + + for expansion_url, status_code in [ + ('https://other.example/x/', 400), (other_expansion.uri, 400), (own_expansion.uri, 200)]: + with self.subTest(expansion_url=expansion_url): + response = self.client.put( + self.collection_v1.uri, + {'expansion_url': expansion_url}, + HTTP_AUTHORIZATION='Token ' + self.token, + format='json' + ) + + self.assertEqual(response.status_code, status_code) + + self.collection_v1.refresh_from_db() + self.assertEqual(self.collection_v1.expansion_uri, own_expansion.uri) + @patch('core.common.models.delete_s3_objects') def test_delete(self, delete_s3_objects_mock): response = self.client.delete( @@ -3169,6 +3214,24 @@ def test_post_201_autoexpand_false(self): self.assertEqual(last_created_version.expansions.count(), 0) self.assertEqual(last_created_version.references.count(), 1) + def test_post_201_ignores_expansion_uri(self): + other_expansion = ExpansionFactory(collection_version=UserCollectionFactory()) + + for version, expansion_uri, autoexpand in [ + ('v1', 'https://other.example/x/', True), ('v2', other_expansion.uri, False)]: + with self.subTest(expansion_uri=expansion_uri): + response = self.client.post( + self.collection.uri + 'versions/', + {'id': version, 'expansion_uri': expansion_uri, 'autoexpand': autoexpand}, + HTTP_AUTHORIZATION='Token ' + self.token, + format='json' + ) + + self.assertEqual(response.status_code, 201) + new_version = self.collection.versions.get(version=version) + own_expansion = new_version.expansions.first() + self.assertEqual(new_version.expansion_uri, own_expansion.uri if autoexpand else None) + class ExportCollectionTaskTest(OCLAPITestCase): @patch('core.common.utils.get_export_service')