Skip to content

Commit 4e98db4

Browse files
authored
Merge pull request #11756 from adlius/handle-validation-remove-context
Remove non-required fields from payload @context; add tests
2 parents 6ac878f + 76ea4d1 commit 4e98db4

2 files changed

Lines changed: 60 additions & 2 deletions

File tree

osf/models/cedar_metadata.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
'pav:createdBy',
1313
'pav:lastUpdatedOn',
1414
'oslc:modifiedBy',
15+
'schema:isBasedOn',
16+
'schema:name',
17+
'schema:description',
1518
})
1619

1720

@@ -66,9 +69,22 @@ def clean(self):
6669
f for f in schema['required']
6770
if f not in CEDAR_SERVER_GENERATED_FIELDS
6871
]
69-
metadata = {k: v for k, v in self.metadata.items() if v != {}}
72+
# Workaround for a cedar-embeddable-editor bug that injects extra keys into
73+
# @context; strip it down to only the schema-required keys before saving.
74+
context = self.metadata.get('@context')
75+
if isinstance(context, dict):
76+
required_context = schema.get('properties', {}).get('@context', {}).get('required')
77+
if isinstance(required_context, list):
78+
filtered_context = {
79+
k: v for k, v in context.items()
80+
if k in required_context
81+
}
82+
if filtered_context:
83+
self.metadata['@context'] = filtered_context
84+
else:
85+
self.metadata.pop('@context', None)
7086
try:
71-
jsonschema_validate(metadata, schema)
87+
jsonschema_validate(self.metadata, schema)
7288
except JsonSchemaValidationError as e:
7389
raise ValidationError(
7490
f'CEDAR metadata does not validate against template "{self.template.schema_name}": {e.message}'

osf_tests/test_cedar_metadata.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import pytest
2+
3+
from osf.models import CedarMetadataRecord, CedarMetadataTemplate
4+
from osf_tests.factories import AuthUserFactory, ProjectFactory
5+
6+
7+
@pytest.mark.django_db
8+
class TestCedarMetadataRecordClean:
9+
10+
def test_clean_filters_context_items_not_in_schema_required(self):
11+
template = CedarMetadataTemplate.objects.create(
12+
schema_name='cedar_test_schema',
13+
cedar_id='cedar_test_id',
14+
template_version=1,
15+
template={
16+
'type': 'object',
17+
'properties': {
18+
'@context': {
19+
'type': 'object',
20+
'required': ['foo', 'bar'],
21+
'properties': {
22+
'foo': {'type': 'string'},
23+
'bar': {'type': 'string'},
24+
},
25+
'additionalProperties': False,
26+
},
27+
},
28+
'required': ['@context'],
29+
},
30+
active=True,
31+
)
32+
user = AuthUserFactory()
33+
project = ProjectFactory(creator=user)
34+
record = CedarMetadataRecord(
35+
guid=project.guids.first(),
36+
template=template,
37+
metadata={'@context': {'foo': 'value1', 'bar': 'value2', 'extra': 'drop'}},
38+
is_published=True,
39+
)
40+
41+
record.clean() # should not raise after filtering @context items
42+
assert record.metadata == {'@context': {'foo': 'value1', 'bar': 'value2'}}

0 commit comments

Comments
 (0)