Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing issue where multiple bodies in an annotation caused validation to fail. #112

Merged
merged 2 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
49 changes: 49 additions & 0 deletions fixtures/3/multi_bodies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "http://localhost:4000/recipe/0219-using-caption-file/manifest.json",
"type": "Manifest",
"label": {
"en": [
"Lunchroom Manners"
]
},
"items": [
{
"id": "http://localhost:4000/recipe/0219-using-caption-file/canvas",
"type": "Canvas",
"height": 360,
"width": 480,
"duration": 572.034,
"items": [
{
"id": "http://localhost:4000/recipe/0219-using-caption-file/canvas/page",
"type": "AnnotationPage",
"items": [
{
"id": "http://localhost:4000/recipe/0219-using-caption-file/canvas/page/annotation",
"type": "Annotation",
"motivation": "painting",
"body": [
{
"id": "https://fixtures.iiif.io/video/indiana/lunchroom_manners/high/lunchroom_manners_1024kb.mp4",
"type": "Video",
"height": 360,
"width": 480,
"duration": 572.034,
"format": "video/mp4"
},
{
"id": "https://fixtures.iiif.io/video/indiana/lunchroom_manners/lunchroom_manners.vtt",
"type": "Text",
"format": "text/vtt",
"language": "en"
}
],
"target": "http://localhost:4000/recipe/0219-using-caption-file/canvas"
}
]
}
]
}
]
}
23 changes: 16 additions & 7 deletions iiif-presentation-validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,22 @@ def check_manifest(self, data, version, url=None, warnings=[]):
if url and 'id' in mf and mf['id'] != url:
raise ValidationError("The manifest id ({}) should be the same as the URL it is published at ({}).".format(mf["id"], url))
except ValidationError as e:
infojson = {
'received': data,
'okay': 0,
'error': str(e),
'url': url,
'warnings': []
}
if infojson:
infojson['errorList'].append({
'title': 'Resolve Error',
'detail': str(e),
'description': '',
'path': '/id',
'context': '{ \'id\': \'...\'}'
})
else:
infojson = {
'received': data,
'okay': 0,
'error': str(e),
'url': url,
'warnings': []
}
except Exception as e:
traceback.print_exc()
infojson = {
Expand Down
10 changes: 9 additions & 1 deletion schema/error_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ def parse(self, error_path, schemaEl, iiif_asset, IIIFJsonPath, parent=None, jso
elif 'const' in option:
value.append(option['const'])
#print ('Using values: {}'.format(value))
elif 'anyOf' in schemaEl['type']:
value = []
for option in schemaEl['type']['anyOf']:
if 'pattern' in option:
value.append(option['pattern'])
elif 'const' in option:
value.append(option['const'])
#print ('Using values: {}'.format(value))

if not self.isTypeMatch(jsonPath + '.type', iiif_asset, value, IIIFJsonPath):
return False
# Check child type to see if its a match
Expand All @@ -273,7 +282,6 @@ def parse(self, error_path, schemaEl, iiif_asset, IIIFJsonPath, parent=None, jso


if isinstance(schemaEl[pathEl], dict) and "$ref" in schemaEl[pathEl]:

#print ('Found ref, trying to resolve: {}'.format(schemaEl[pathEl]['$ref']))
return self.parse(error_path, self.resolver.resolve(schemaEl[pathEl]['$ref'])[1], iiif_asset, IIIFJsonPath, pathEl, jsonPath)
else:
Expand Down
13 changes: 11 additions & 2 deletions schema/iiif_3_0.json
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,13 @@
]
},
"body": {
"oneOf": [
"anyOf": [
{
"type": "object",
"$ref": "#/classes/resource"
},
{
"type": "object",
"allOf":[
{ "$ref": "#/classes/choice" },
{
Expand All @@ -615,11 +617,18 @@
"required": ["items"]
}
]
},
{
"type": "array",
"items": {
"type": "object"
}
}

]
},
"target": {
"oneOf": [
"anyOf": [
{ "$ref": "#/classes/annoTarget" },
{
"type": "array",
Expand Down
8 changes: 5 additions & 3 deletions tests/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ def test07_check_manifest3(self):
'fixtures/3/annoPageMultipleMotivations.json',
'fixtures/3/old_cc_license.json',
'fixtures/3/rightsstatement_license.json',
'fixtures/3/extension_anno.json'
'fixtures/3/extension_anno.json',
'fixtures/3/multi_bodies.json'
]:
with open(good, 'r') as fh:
data = fh.read()
Expand Down Expand Up @@ -216,7 +217,7 @@ def test08_errortrees(self):
self.assertTrue(errorParser.isValid(path, iiifPath), 'Should have caught the service in thumbnail needs to be an array.')

# annotationPage
path = [u'allOf', 1, u'oneOf', 0, u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'body', u'oneOf']
path = [u'allOf', 1, u'oneOf', 0, u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'items', u'items', u'allOf', 1, u'properties', u'body', u'anyOf']
iiifPath = [u'items', 0, u'items', 0, u'items', 0, u'body']
self.assertTrue(errorParser.isValid(path, iiifPath), 'Should have caught the service in the canvas needs to be an array')

Expand All @@ -243,7 +244,7 @@ def test_version3errors(self):
filename = 'fixtures/3/broken_service.json'
errorPaths = [
'/thumbnail[0]/service',
'/body[0]/items[0]/items[0]/items/items[0]/items[0]/items[0]/body/service'
'/items[0]/items[0]/items[0]/body/'
]
response = self.helperRunValidation(v, filename)
self.helperTestValidationErrors(filename, response, errorPaths)
Expand All @@ -264,6 +265,7 @@ def test_lang_rights(self):
'/label',
'/items[0]/label[0]',
'/items[0]/',
'/items[0]/items[0]/items[0]/body/',
'/rights',
'/metadata[0]/label/',
'/metadata[0]/value/',
Expand Down