Skip to content

Commit c677a41

Browse files
committed
Fixes for Presentation 4 - hasPart
1 parent c946a86 commit c677a41

File tree

5 files changed

+497
-72
lines changed

5 files changed

+497
-72
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { describe, expect, test } from "vitest";
2+
import { HAS_PART, normalize, PART_OF } from "../../src/presentation-4";
3+
4+
describe("presentation-4 hasPart parity", () => {
5+
test("records framing metadata when the same resource diverges by parent context", () => {
6+
const manifest = {
7+
"@context": "http://iiif.io/api/presentation/4/context.json",
8+
id: "https://example.org/manifest/has-part",
9+
type: "Manifest",
10+
label: { en: ["has part parity"] },
11+
items: [
12+
{
13+
id: "https://example.org/canvas/1",
14+
type: "Canvas",
15+
width: 1000,
16+
height: 1000,
17+
thumbnail: [
18+
{
19+
id: "https://example.org/image/shared.jpg",
20+
type: "Image",
21+
format: "image/jpeg",
22+
},
23+
],
24+
},
25+
{
26+
id: "https://example.org/canvas/2",
27+
type: "Canvas",
28+
width: 1000,
29+
height: 1000,
30+
thumbnail: [
31+
{
32+
id: "https://example.org/image/shared.jpg",
33+
type: "Image",
34+
format: "image/jpeg",
35+
width: 6000,
36+
},
37+
],
38+
},
39+
],
40+
};
41+
42+
const result = normalize(manifest as any);
43+
const image = result.entities.ContentResource["https://example.org/image/shared.jpg"] as any;
44+
45+
expect(image).toBeTruthy();
46+
expect(Array.isArray(image[HAS_PART])).toBe(true);
47+
48+
const partOf = (image[HAS_PART] as any[]).map((item) => item[PART_OF]);
49+
expect(partOf).toContain("https://example.org/canvas/1");
50+
expect(partOf).toContain("https://example.org/canvas/2");
51+
});
52+
});
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { describe, expect, test } from "vitest";
2+
import { normalize } from "../../src/presentation-4";
3+
4+
describe("presentation-4 specific resource parity", () => {
5+
test("coerces start, range items, and annotation target for v3 input and keeps selectors", () => {
6+
const manifest = {
7+
"@context": "http://iiif.io/api/presentation/3/context.json",
8+
id: "https://example.org/manifest/p3-upgrade",
9+
type: "Manifest",
10+
label: { en: ["p3 specific resource parity"] },
11+
start: "https://example.org/canvas/1#t=5,15",
12+
items: [
13+
{
14+
id: "https://example.org/canvas/1",
15+
type: "Canvas",
16+
width: 1000,
17+
height: 1000,
18+
items: [
19+
{
20+
id: "https://example.org/canvas/1/page/1",
21+
type: "AnnotationPage",
22+
items: [
23+
{
24+
id: "https://example.org/canvas/1/annotation/1",
25+
type: "Annotation",
26+
motivation: "painting",
27+
body: {
28+
id: "https://example.org/image/1.jpg",
29+
type: "Image",
30+
format: "image/jpeg",
31+
},
32+
target: "https://example.org/canvas/1#xywh=10,20,30,40",
33+
},
34+
],
35+
},
36+
],
37+
},
38+
],
39+
structures: [
40+
{
41+
id: "https://example.org/range/1",
42+
type: "Range",
43+
items: ["https://example.org/canvas/1#t=0,10"],
44+
},
45+
],
46+
};
47+
48+
const result = normalize(manifest as any);
49+
const normalizedManifest = result.entities.Manifest["https://example.org/manifest/p3-upgrade"] as any;
50+
const normalizedRange = result.entities.Range["https://example.org/range/1"] as any;
51+
const normalizedAnnotation = result.entities.Annotation["https://example.org/canvas/1/annotation/1"] as any;
52+
const startSelector = Array.isArray(normalizedManifest.start.selector)
53+
? normalizedManifest.start.selector[0]
54+
: normalizedManifest.start.selector;
55+
const rangeSelector = Array.isArray(normalizedRange.items[0].selector)
56+
? normalizedRange.items[0].selector[0]
57+
: normalizedRange.items[0].selector;
58+
const targetSelector = Array.isArray(normalizedAnnotation.target[0].selector)
59+
? normalizedAnnotation.target[0].selector[0]
60+
: normalizedAnnotation.target[0].selector;
61+
62+
expect(normalizedManifest.start.type).toBe("SpecificResource");
63+
expect(normalizedManifest.start.source.id).toBe("https://example.org/canvas/1");
64+
expect(startSelector.type).toBe("FragmentSelector");
65+
expect(startSelector.value).toBe("t=5,15");
66+
67+
expect(normalizedRange.items[0].type).toBe("SpecificResource");
68+
expect(normalizedRange.items[0].source.id).toBe("https://example.org/canvas/1");
69+
expect(rangeSelector.type).toBe("FragmentSelector");
70+
expect(rangeSelector.value).toBe("t=0,10");
71+
72+
expect(normalizedAnnotation.target[0].type).toBe("SpecificResource");
73+
expect(normalizedAnnotation.target[0].source.id).toBe("https://example.org/canvas/1");
74+
expect(targetSelector.type).toBe("FragmentSelector");
75+
expect(targetSelector.value).toBe("xywh=10,20,30,40");
76+
77+
const selectorId = targetSelector.id;
78+
expect(selectorId).toBeTruthy();
79+
expect(result.entities.Selector[selectorId]).toBeTruthy();
80+
expect(result.mapping[selectorId]).toBe("Selector");
81+
});
82+
});

0 commit comments

Comments
 (0)