iiif-presentation 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +8 -1
- data/.standard.yml +1 -0
- data/Gemfile +5 -5
- data/README.md +1 -1
- data/Rakefile +4 -2
- data/VERSION +1 -1
- data/bin/standardrb +16 -0
- data/iiif-presentation.gemspec +23 -23
- data/lib/iiif/hash_behaviours.rb +29 -33
- data/lib/iiif/ordered_hash.rb +33 -33
- data/lib/iiif/presentation/abstract_resource.rb +17 -22
- data/lib/iiif/presentation/annotation.rb +9 -11
- data/lib/iiif/presentation/annotation_list.rb +8 -10
- data/lib/iiif/presentation/canvas.rb +11 -13
- data/lib/iiif/presentation/collection.rb +7 -9
- data/lib/iiif/presentation/image_resource.rb +33 -35
- data/lib/iiif/presentation/layer.rb +8 -10
- data/lib/iiif/presentation/manifest.rb +9 -12
- data/lib/iiif/presentation/range.rb +8 -10
- data/lib/iiif/presentation/resource.rb +5 -7
- data/lib/iiif/presentation/sequence.rb +8 -11
- data/lib/iiif/presentation/service.rb +1 -2
- data/lib/iiif/presentation.rb +7 -7
- data/lib/iiif/service.rb +121 -102
- data/lib/iiif/v3/abstract_resource.rb +127 -130
- data/lib/iiif/v3/presentation/annotation.rb +20 -21
- data/lib/iiif/v3/presentation/annotation_collection.rb +7 -9
- data/lib/iiif/v3/presentation/annotation_page.rb +14 -15
- data/lib/iiif/v3/presentation/canvas.rb +21 -22
- data/lib/iiif/v3/presentation/choice.rb +14 -15
- data/lib/iiif/v3/presentation/collection.rb +7 -8
- data/lib/iiif/v3/presentation/image_resource.rb +21 -22
- data/lib/iiif/v3/presentation/manifest.rb +18 -19
- data/lib/iiif/v3/presentation/nav_place.rb +125 -29
- data/lib/iiif/v3/presentation/range.rb +10 -10
- data/lib/iiif/v3/presentation/resource.rb +4 -5
- data/lib/iiif/v3/presentation/sequence.rb +10 -11
- data/lib/iiif/v3/presentation/service.rb +12 -13
- data/lib/iiif/v3/presentation.rb +8 -8
- data/spec/integration/iiif/presentation/image_resource_spec.rb +54 -58
- data/spec/integration/iiif/service_spec.rb +76 -77
- data/spec/integration/iiif/v3/abstract_resource_spec.rb +72 -73
- data/spec/integration/iiif/v3/presentation/image_resource_spec.rb +53 -56
- data/spec/spec_helper.rb +56 -64
- data/spec/unit/iiif/hash_behaviours_spec.rb +384 -387
- data/spec/unit/iiif/ordered_hash_spec.rb +86 -91
- data/spec/unit/iiif/presentation/abstract_resource_spec.rb +64 -70
- data/spec/unit/iiif/presentation/annotation_list_spec.rb +1 -3
- data/spec/unit/iiif/presentation/annotation_spec.rb +1 -3
- data/spec/unit/iiif/presentation/canvas_spec.rb +11 -14
- data/spec/unit/iiif/presentation/collection_spec.rb +26 -33
- data/spec/unit/iiif/presentation/image_resource_spec.rb +4 -6
- data/spec/unit/iiif/presentation/layer_spec.rb +16 -20
- data/spec/unit/iiif/presentation/manifest_spec.rb +45 -48
- data/spec/unit/iiif/presentation/range_spec.rb +18 -22
- data/spec/unit/iiif/presentation/resource_spec.rb +3 -6
- data/spec/unit/iiif/presentation/sequence_spec.rb +58 -63
- data/spec/unit/iiif/presentation/shared_examples/abstract_resource_only_keys.rb +4 -10
- data/spec/unit/iiif/presentation/shared_examples/any_type_keys.rb +5 -9
- data/spec/unit/iiif/presentation/shared_examples/array_only_keys.rb +9 -17
- data/spec/unit/iiif/presentation/shared_examples/int_only_keys.rb +6 -14
- data/spec/unit/iiif/presentation/shared_examples/string_only_keys.rb +6 -13
- data/spec/unit/iiif/service_spec.rb +8 -13
- data/spec/unit/iiif/v3/abstract_resource_define_methods_for_spec.rb +39 -37
- data/spec/unit/iiif/v3/abstract_resource_spec.rb +124 -131
- data/spec/unit/iiif/v3/presentation/annotation_collection_spec.rb +14 -17
- data/spec/unit/iiif/v3/presentation/annotation_page_spec.rb +71 -69
- data/spec/unit/iiif/v3/presentation/annotation_spec.rb +249 -233
- data/spec/unit/iiif/v3/presentation/canvas_spec.rb +211 -193
- data/spec/unit/iiif/v3/presentation/choice_spec.rb +81 -77
- data/spec/unit/iiif/v3/presentation/collection_spec.rb +24 -29
- data/spec/unit/iiif/v3/presentation/image_resource_spec.rb +70 -71
- data/spec/unit/iiif/v3/presentation/manifest_spec.rb +248 -235
- data/spec/unit/iiif/v3/presentation/nav_place_spec.rb +249 -49
- data/spec/unit/iiif/v3/presentation/range_spec.rb +28 -29
- data/spec/unit/iiif/v3/presentation/resource_spec.rb +83 -82
- data/spec/unit/iiif/v3/presentation/sequence_spec.rb +125 -119
- data/spec/unit/iiif/v3/presentation/service_spec.rb +123 -124
- data/spec/unit/iiif/v3/presentation/shared_examples/abstract_resource_only_keys.rb +4 -8
- data/spec/unit/iiif/v3/presentation/shared_examples/any_type_keys.rb +5 -7
- data/spec/unit/iiif/v3/presentation/shared_examples/array_only_keys.rb +9 -13
- data/spec/unit/iiif/v3/presentation/shared_examples/hash_only_keys.rb +9 -13
- data/spec/unit/iiif/v3/presentation/shared_examples/int_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/numeric_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/string_only_keys.rb +6 -10
- data/spec/unit/iiif/v3/presentation/shared_examples/uri_only_keys.rb +9 -13
- metadata +26 -65
|
@@ -1,244 +1,254 @@
|
|
|
1
1
|
describe IIIF::V3::Presentation::Manifest do
|
|
2
|
-
|
|
3
|
-
describe '#required_keys' do
|
|
2
|
+
describe "#required_keys" do
|
|
4
3
|
# NOTE: relaxing requirement for items as Universal Viewer currently only accepts sequences
|
|
5
4
|
# see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
|
|
6
5
|
# %w{ type id label items }.each do |k|
|
|
7
|
-
%w
|
|
6
|
+
%w[type id label].each do |k|
|
|
8
7
|
it k do
|
|
9
8
|
expect(subject.required_keys).to include(k)
|
|
10
9
|
end
|
|
11
10
|
end
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
describe
|
|
15
|
-
it
|
|
13
|
+
describe "#prohibited_keys" do
|
|
14
|
+
it "contains the expected key names" do
|
|
16
15
|
keys = described_class::CONTENT_RESOURCE_PROPERTIES +
|
|
17
16
|
described_class::PAGING_PROPERTIES +
|
|
18
|
-
%w
|
|
17
|
+
%w[
|
|
19
18
|
start_canvas
|
|
20
19
|
content_annotation
|
|
21
|
-
|
|
20
|
+
]
|
|
22
21
|
expect(subject.prohibited_keys).to include(*keys)
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
describe
|
|
27
|
-
it
|
|
28
|
-
expect(subject.uri_only_keys).to include(
|
|
25
|
+
describe "#uri_only_keys" do
|
|
26
|
+
it "id" do
|
|
27
|
+
expect(subject.uri_only_keys).to include("id")
|
|
29
28
|
end
|
|
30
29
|
end
|
|
31
30
|
|
|
32
|
-
describe
|
|
31
|
+
describe "#array_only_keys" do
|
|
33
32
|
# NOTE: also allowing sequences as Universal Viewer currently only accepts sequences
|
|
34
33
|
# see https://github.com/sul-dlss/osullivan/issues/27, sul-dlss/purl/issues/167
|
|
35
|
-
%w
|
|
34
|
+
%w[items sequences structures].each do |k|
|
|
36
35
|
it k do
|
|
37
36
|
expect(subject.array_only_keys).to include(k)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
|
41
40
|
|
|
42
|
-
describe
|
|
43
|
-
it
|
|
44
|
-
expect(subject.legal_viewing_hint_values).to contain_exactly(
|
|
41
|
+
describe "#legal_viewing_hint_values" do
|
|
42
|
+
it "contains the expected values" do
|
|
43
|
+
expect(subject.legal_viewing_hint_values).to contain_exactly("individuals", "paged", "continuous", "auto-advance")
|
|
45
44
|
end
|
|
46
45
|
end
|
|
47
46
|
|
|
48
|
-
describe
|
|
49
|
-
it
|
|
50
|
-
expect(subject[
|
|
47
|
+
describe "#initialize" do
|
|
48
|
+
it "sets type to Manifest by default" do
|
|
49
|
+
expect(subject["type"]).to eq "Manifest"
|
|
51
50
|
end
|
|
52
|
-
it
|
|
51
|
+
it "allows subclasses to override type" do
|
|
53
52
|
subclass = Class.new(described_class) do
|
|
54
|
-
def initialize(
|
|
55
|
-
|
|
56
|
-
super(hsh)
|
|
53
|
+
def initialize(_hsh = {})
|
|
54
|
+
super({"type" => "a:SubClass"})
|
|
57
55
|
end
|
|
58
56
|
end
|
|
59
57
|
sub = subclass.new
|
|
60
|
-
expect(sub[
|
|
58
|
+
expect(sub["type"]).to eq "a:SubClass"
|
|
61
59
|
end
|
|
62
60
|
end
|
|
63
61
|
|
|
64
|
-
let(:manifest_id) {
|
|
62
|
+
let(:manifest_id) { "http://www.example.org/iiif/book1/manifest" }
|
|
65
63
|
|
|
66
|
-
describe
|
|
67
|
-
it
|
|
68
|
-
subject.label = {
|
|
69
|
-
subject[
|
|
70
|
-
subject[
|
|
64
|
+
describe "#validate" do
|
|
65
|
+
it "raises an IllegalValueError if id is not http" do
|
|
66
|
+
subject.label = {"en" => ["Book 1"]}
|
|
67
|
+
subject["id"] = "ftp://www.example.org"
|
|
68
|
+
subject["items"] = [IIIF::V3::Presentation::Sequence.new]
|
|
71
69
|
exp_err_msg = "id must be an http(s) URI for #{described_class}"
|
|
72
70
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
|
|
73
71
|
end
|
|
74
72
|
|
|
75
|
-
let(:item_list_err) {
|
|
76
|
-
let(:item_entry_err) {
|
|
73
|
+
let(:item_list_err) { "The items list must have at least one entry (and it must be a IIIF::V3::Presentation::Canvas)" }
|
|
74
|
+
let(:item_entry_err) { "All entries in the items list must be a IIIF::V3::Presentation::Canvas" }
|
|
77
75
|
|
|
78
|
-
it
|
|
79
|
-
subject[
|
|
80
|
-
subject.label = {
|
|
76
|
+
it "raises MissingRequiredKeyError if no items or sequences key" do
|
|
77
|
+
subject["id"] = manifest_id
|
|
78
|
+
subject.label = {"en" => ["Book 1"]}
|
|
81
79
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, item_list_err)
|
|
82
80
|
end
|
|
83
|
-
describe
|
|
84
|
-
it
|
|
85
|
-
subject[
|
|
86
|
-
subject.label = {
|
|
87
|
-
subject[
|
|
81
|
+
describe "items" do
|
|
82
|
+
it "raises MissingRequiredKeyError for items entry without values" do
|
|
83
|
+
subject["id"] = manifest_id
|
|
84
|
+
subject.label = {"en" => ["Book 1"]}
|
|
85
|
+
subject["items"] = []
|
|
88
86
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::MissingRequiredKeyError, item_list_err)
|
|
89
87
|
end
|
|
90
|
-
it
|
|
91
|
-
subject[
|
|
92
|
-
subject.label = {
|
|
93
|
-
subject[
|
|
88
|
+
it "raises IllegalValueError for items entry that is not a Sequence" do
|
|
89
|
+
subject["id"] = manifest_id
|
|
90
|
+
subject.label = {"en" => ["Book 1"]}
|
|
91
|
+
subject["items"] = [IIIF::V3::Presentation::Sequence.new, IIIF::V3::Presentation::Canvas.new]
|
|
94
92
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, item_entry_err)
|
|
95
93
|
end
|
|
96
|
-
it
|
|
97
|
-
subject[
|
|
98
|
-
subject[
|
|
99
|
-
subject.label = {
|
|
94
|
+
it "raises no error items populated with canvases" do
|
|
95
|
+
subject["items"] = [IIIF::V3::Presentation::Canvas.new]
|
|
96
|
+
subject["id"] = manifest_id
|
|
97
|
+
subject.label = {"en" => ["Book 1"]}
|
|
100
98
|
expect { subject.validate }.not_to raise_error
|
|
101
99
|
end
|
|
102
100
|
end
|
|
103
101
|
|
|
104
|
-
it
|
|
105
|
-
subject[
|
|
106
|
-
subject.label = {
|
|
107
|
-
subject[
|
|
108
|
-
subject[
|
|
102
|
+
it "raises IllegalValueError for structures entry that is not a Range" do
|
|
103
|
+
subject["id"] = manifest_id
|
|
104
|
+
subject.label = {"en" => ["Book 1"]}
|
|
105
|
+
subject["items"] = [IIIF::V3::Presentation::Canvas.new]
|
|
106
|
+
subject["structures"] = [IIIF::V3::Presentation::Sequence.new]
|
|
109
107
|
exp_err_msg = "All entries in the structures list must be a IIIF::V3::Presentation::Range"
|
|
110
108
|
expect { subject.validate }.to raise_error(IIIF::V3::Presentation::IllegalValueError, exp_err_msg)
|
|
111
109
|
end
|
|
112
|
-
it
|
|
113
|
-
subject[
|
|
114
|
-
subject.label = {
|
|
115
|
-
subject[
|
|
116
|
-
subject[
|
|
110
|
+
it "raises no error when structures entry is a Range" do
|
|
111
|
+
subject["id"] = manifest_id
|
|
112
|
+
subject.label = {"en" => ["Book 1"]}
|
|
113
|
+
subject["items"] = [IIIF::V3::Presentation::Canvas.new]
|
|
114
|
+
subject["structures"] = [IIIF::V3::Presentation::Range.new]
|
|
117
115
|
expect { subject.validate }.not_to raise_error
|
|
118
116
|
end
|
|
119
117
|
end
|
|
120
118
|
|
|
121
|
-
describe
|
|
122
|
-
let!(:canvas_object) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
119
|
+
describe "realistic examples" do
|
|
120
|
+
let!(:canvas_object) {
|
|
121
|
+
IIIF::V3::Presentation::Canvas.new({
|
|
122
|
+
"id" => "https://example.org/abc666/iiif3/canvas/0001",
|
|
123
|
+
"label" => {"en" => ["image"]},
|
|
124
|
+
"height" => 7579,
|
|
125
|
+
"width" => 10108,
|
|
126
|
+
"content" => []
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
describe "realistic(?) minimal manifest" do
|
|
130
|
+
let!(:manifest_object) {
|
|
131
|
+
described_class.new({
|
|
132
|
+
"@context" => [
|
|
133
|
+
"http://www.w3.org/ns/anno.jsonld",
|
|
134
|
+
"http://iiif.io/api/presentation/3/context.json"
|
|
135
|
+
],
|
|
136
|
+
"id" => "https://example.org/abc666/iiif3/manifest",
|
|
137
|
+
"label" => {"en" => ["blah"]},
|
|
138
|
+
"requiredStatement" => {
|
|
139
|
+
label: {en: ["Attribution"]},
|
|
140
|
+
value: {en: ["bleah"]}
|
|
141
|
+
},
|
|
142
|
+
"summary" => {"en" => ["blargh"]},
|
|
143
|
+
"items" => [canvas_object]
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
it "validates" do
|
|
147
|
+
expect { manifest_object.validate }.not_to raise_error
|
|
146
148
|
end
|
|
147
|
-
it
|
|
148
|
-
expect(manifest_object.type).to eq
|
|
149
|
+
it "has expected required values" do
|
|
150
|
+
expect(manifest_object.type).to eq "Manifest"
|
|
149
151
|
expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
|
|
150
|
-
expect(manifest_object.label[
|
|
152
|
+
expect(manifest_object.label["en"]).to include "blah"
|
|
151
153
|
expect(manifest_object.items.size).to be 1
|
|
152
154
|
expect(manifest_object.items.first).to eq canvas_object
|
|
153
155
|
end
|
|
154
|
-
it
|
|
155
|
-
expect(manifest_object[
|
|
156
|
-
expect(manifest_object[
|
|
156
|
+
it "has expected context" do
|
|
157
|
+
expect(manifest_object["@context"].size).to be 2
|
|
158
|
+
expect(manifest_object["@context"]).to include(*IIIF::V3::Presentation::CONTEXT)
|
|
157
159
|
end
|
|
158
|
-
it
|
|
159
|
-
expect(manifest_object[
|
|
160
|
-
expect(manifest_object.summary[
|
|
160
|
+
it "has other values" do
|
|
161
|
+
expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
|
|
162
|
+
expect(manifest_object.summary["en"].first).to eq "blargh"
|
|
161
163
|
end
|
|
162
164
|
end
|
|
163
165
|
|
|
164
|
-
describe
|
|
165
|
-
let!(:logo_service) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
"seeAlso" => {
|
|
195
|
-
"id" => "https://example.org/abc666.mods",
|
|
196
|
-
"format" => "application/mods+xml"
|
|
197
|
-
},
|
|
198
|
-
"viewingHint" => "paged",
|
|
199
|
-
"viewingDirection" => "right-to-left",
|
|
200
|
-
"metadata" => [
|
|
201
|
-
{
|
|
202
|
-
"label" => "Type",
|
|
203
|
-
"value" => "map"
|
|
166
|
+
describe "realistic example from Stanford purl manifests" do
|
|
167
|
+
let!(:logo_service) {
|
|
168
|
+
IIIF::V3::Presentation::Service.new({
|
|
169
|
+
"@id" => "https://example.org/logo",
|
|
170
|
+
"@type" => "ImageService2",
|
|
171
|
+
"id" => "https://example.org/logo",
|
|
172
|
+
"profile" => "http://iiif.io/api/image/2/level1.json"
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
let!(:thumbnail_image_service) {
|
|
176
|
+
IIIF::V3::Presentation::Service.new({
|
|
177
|
+
"@id" => "https://example.org/image/iiif/abc666_05_0001",
|
|
178
|
+
"id" => "https://example.org/image/iiif/abc666_05_0001",
|
|
179
|
+
"profile" => IIIF::V3::Presentation::Service::IIIF_IMAGE_V2_LEVEL1_PROFILE
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
let!(:thumbnail_image) {
|
|
183
|
+
IIIF::V3::Presentation::ImageResource.new({
|
|
184
|
+
"id" => "https://example.org/image/iiif/abc666_05_0001/full/!400,400/0/default.jpg",
|
|
185
|
+
"format" => "image/jpeg",
|
|
186
|
+
"service" => [thumbnail_image_service]
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
let!(:manifest_object) {
|
|
190
|
+
described_class.new({
|
|
191
|
+
"id" => "https://example.org/abc666/iiif3/manifest",
|
|
192
|
+
"label" => {"en" => ["blah"]},
|
|
193
|
+
"requiredStatement" => {
|
|
194
|
+
label: {en: ["Attribution"]},
|
|
195
|
+
value: {en: ["bleah"]}
|
|
204
196
|
},
|
|
205
|
-
{
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
197
|
+
"summary" => {"en" => ["blargh"]},
|
|
198
|
+
"items" => [canvas_object],
|
|
199
|
+
"logo" => {
|
|
200
|
+
"id" => "https://example.org/logo/full/400,/0/default.jpg",
|
|
201
|
+
"service" => [logo_service]
|
|
202
|
+
},
|
|
203
|
+
"seeAlso" => {
|
|
204
|
+
"id" => "https://example.org/abc666.mods",
|
|
205
|
+
"format" => "application/mods+xml"
|
|
206
|
+
},
|
|
207
|
+
"viewingHint" => "paged",
|
|
208
|
+
"viewingDirection" => "right-to-left",
|
|
209
|
+
"metadata" => [
|
|
210
|
+
{
|
|
211
|
+
"label" => "Type",
|
|
212
|
+
"value" => "map"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"label" => "Rights",
|
|
216
|
+
"value" => "stuff"
|
|
217
|
+
}
|
|
209
218
|
],
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
219
|
+
"thumbnail" => [thumbnail_image]
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
it "thumbnail image object validates" do
|
|
223
|
+
expect { thumbnail_image.validate }.not_to raise_error
|
|
214
224
|
end
|
|
215
|
-
it
|
|
216
|
-
expect{manifest_object.validate}.not_to raise_error
|
|
225
|
+
it "manifest validates" do
|
|
226
|
+
expect { manifest_object.validate }.not_to raise_error
|
|
217
227
|
end
|
|
218
|
-
it
|
|
219
|
-
expect(manifest_object.type).to eq
|
|
228
|
+
it "has expected required values" do
|
|
229
|
+
expect(manifest_object.type).to eq "Manifest"
|
|
220
230
|
expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
|
|
221
|
-
expect(manifest_object.label[
|
|
231
|
+
expect(manifest_object.label["en"]).to include "blah"
|
|
222
232
|
expect(manifest_object.items.size).to be 1
|
|
223
233
|
expect(manifest_object.items.first).to eq canvas_object
|
|
224
234
|
end
|
|
225
|
-
it
|
|
226
|
-
expect(manifest_object[
|
|
227
|
-
expect(manifest_object.summary[
|
|
235
|
+
it "has expected additional content" do
|
|
236
|
+
expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
|
|
237
|
+
expect(manifest_object.summary["en"].first).to eq "blargh"
|
|
228
238
|
expect(manifest_object.logo.keys.size).to be 2
|
|
229
239
|
expect(manifest_object.seeAlso.keys.size).to be 2
|
|
230
240
|
expect(manifest_object.metadata.size).to be 2
|
|
231
241
|
expect(manifest_object.thumbnail.size).to be 1
|
|
232
242
|
end
|
|
233
243
|
|
|
234
|
-
describe
|
|
244
|
+
describe "from stanford purl CODE" do
|
|
235
245
|
let!(:manifest_data) {
|
|
236
246
|
{
|
|
237
247
|
"id" => "https://example.org/abc666/iiif3/manifest",
|
|
238
248
|
"label" => {"en" => ["blah"]},
|
|
239
249
|
"requiredStatement" => {
|
|
240
|
-
|
|
241
|
-
|
|
250
|
+
label: {en: ["Attribution"]},
|
|
251
|
+
value: {en: ["bleah"]}
|
|
242
252
|
},
|
|
243
253
|
"logo" => {
|
|
244
254
|
"id" => "https://example.org/logo/full/400,/0/default.jpg",
|
|
@@ -252,29 +262,29 @@ describe IIIF::V3::Presentation::Manifest do
|
|
|
252
262
|
}
|
|
253
263
|
let!(:manifest_object) {
|
|
254
264
|
m = described_class.new manifest_data
|
|
255
|
-
m.viewingHint =
|
|
265
|
+
m.viewingHint = "paged"
|
|
256
266
|
m.metadata = [
|
|
257
|
-
{
|
|
258
|
-
{
|
|
267
|
+
{"label" => "title", "value" => "who wants to know?"},
|
|
268
|
+
{"label" => "PublishDate", "value" => "sometime"}
|
|
259
269
|
]
|
|
260
|
-
m.summary = {
|
|
270
|
+
m.summary = {"en" => ["blargh"]}
|
|
261
271
|
m.thumbnail = [thumbnail_image]
|
|
262
272
|
m.items << canvas_object
|
|
263
273
|
m
|
|
264
274
|
}
|
|
265
|
-
it
|
|
266
|
-
expect{manifest_object.validate}.not_to raise_error
|
|
275
|
+
it "manifest validates" do
|
|
276
|
+
expect { manifest_object.validate }.not_to raise_error
|
|
267
277
|
end
|
|
268
|
-
it
|
|
269
|
-
expect(manifest_object.type).to eq
|
|
278
|
+
it "has expected required values" do
|
|
279
|
+
expect(manifest_object.type).to eq "Manifest"
|
|
270
280
|
expect(manifest_object.id).to eq "https://example.org/abc666/iiif3/manifest"
|
|
271
|
-
expect(manifest_object.label[
|
|
281
|
+
expect(manifest_object.label["en"]).to include "blah"
|
|
272
282
|
expect(manifest_object.items.size).to be 1
|
|
273
283
|
expect(manifest_object.items.first).to eq canvas_object
|
|
274
284
|
end
|
|
275
|
-
it
|
|
276
|
-
expect(manifest_object[
|
|
277
|
-
expect(manifest_object.summary[
|
|
285
|
+
it "has expected additional content" do
|
|
286
|
+
expect(manifest_object["required_statement"][:value][:en].first).to eq "bleah"
|
|
287
|
+
expect(manifest_object.summary["en"].first).to eq "blargh"
|
|
278
288
|
expect(manifest_object.logo.keys.size).to be 2
|
|
279
289
|
expect(manifest_object.seeAlso.keys.size).to be 2
|
|
280
290
|
expect(manifest_object.metadata.size).to be 2
|
|
@@ -282,86 +292,89 @@ describe IIIF::V3::Presentation::Manifest do
|
|
|
282
292
|
end
|
|
283
293
|
end
|
|
284
294
|
end
|
|
285
|
-
describe
|
|
286
|
-
let!(:range_object) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
295
|
+
describe "example from http://prezi3.iiif.io/api/presentation/3.0" do
|
|
296
|
+
let!(:range_object) {
|
|
297
|
+
IIIF::V3::Presentation::Range.new({
|
|
298
|
+
"id" => "http://example.org/iiif/book1/range/top",
|
|
299
|
+
"label" => {"en" => ["home, home on the"]},
|
|
300
|
+
"viewingHint" => ["top"]
|
|
290
301
|
})
|
|
291
302
|
}
|
|
292
|
-
let!(:manifest_object) {
|
|
293
|
-
|
|
294
|
-
"
|
|
295
|
-
|
|
303
|
+
let!(:manifest_object) {
|
|
304
|
+
described_class.new({
|
|
305
|
+
"@context" => [
|
|
306
|
+
"http://www.w3.org/ns/anno.jsonld",
|
|
307
|
+
"http://iiif.io/api/presentation/3/context.json"
|
|
308
|
+
],
|
|
309
|
+
"id" => "http://example.org/iiif/book1/manifest",
|
|
310
|
+
"label" => {"en" => ["Book 1"]},
|
|
311
|
+
"metadata" => [
|
|
312
|
+
{"label" => {"en" => ["Author"]},
|
|
313
|
+
"value" => {"@none" => ["Anne Author"]}},
|
|
314
|
+
{"label" => {"en" => ["Published"]},
|
|
315
|
+
"value" => {
|
|
316
|
+
"en" => ["Paris, circa 1400"],
|
|
317
|
+
"fr" => ["Paris, environ 1400"]
|
|
318
|
+
}},
|
|
319
|
+
{"label" => {"en" => ["Notes"]},
|
|
320
|
+
"value" => {"en" => ["Text of note 1", "Text of note 2"]}},
|
|
321
|
+
{"label" => {"en" => ["Source"]},
|
|
322
|
+
"value" => {"@none" => ["<span>From: <a href=\"http://example.org/db/1.html\">Some Collection</a></span>"]}}
|
|
296
323
|
],
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
"
|
|
305
|
-
|
|
324
|
+
"summary" => {"en" => ["A longer description of this example book. It should give some real information."]},
|
|
325
|
+
"thumbnail" => [{
|
|
326
|
+
"id" => "http://example.org/images/book1-page1/full/80,100/0/default.jpg",
|
|
327
|
+
"type" => "Image",
|
|
328
|
+
"service" => {
|
|
329
|
+
"id" => "http://example.org/images/book1-page1",
|
|
330
|
+
"type" => "ImageService2",
|
|
331
|
+
"profile" => ["http://iiif.io/api/image/2/level1.json"]
|
|
332
|
+
}
|
|
333
|
+
}],
|
|
334
|
+
"viewingDirection" => "right-to-left",
|
|
335
|
+
"viewingHint" => ["paged"],
|
|
336
|
+
"navDate" => "1856-01-01T00:00:00Z",
|
|
337
|
+
"rights" => "http://example.org/license.html",
|
|
338
|
+
"requiredStatement" => {
|
|
339
|
+
label: {en: ["Attribution"]},
|
|
340
|
+
value: {en: ["bleah"]}
|
|
306
341
|
},
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
"value" => {"@none" => ["<span>From: <a href=\"http://example.org/db/1.html\">Some Collection</a></span>"]}}
|
|
311
|
-
],
|
|
312
|
-
"summary" => {"en" => ["A longer description of this example book. It should give some real information."]},
|
|
313
|
-
"thumbnail" => [{
|
|
314
|
-
"id" => "http://example.org/images/book1-page1/full/80,100/0/default.jpg",
|
|
315
|
-
"type" => "Image",
|
|
316
|
-
"service" => {
|
|
317
|
-
"id" => "http://example.org/images/book1-page1",
|
|
318
|
-
"type" => "ImageService2",
|
|
319
|
-
"profile" => ["http://iiif.io/api/image/2/level1.json"]
|
|
320
|
-
}
|
|
321
|
-
}],
|
|
322
|
-
"viewingDirection" => "right-to-left",
|
|
323
|
-
"viewingHint" => ["paged"],
|
|
324
|
-
"navDate" => "1856-01-01T00:00:00Z",
|
|
325
|
-
"rights" => "http://example.org/license.html",
|
|
326
|
-
"requiredStatement" => {
|
|
327
|
-
"label": { "en": [ "Attribution" ] },
|
|
328
|
-
"value": { "en": [ "bleah" ] },
|
|
329
|
-
},
|
|
330
|
-
"logo" => {
|
|
331
|
-
"id" => "http://example.org/logos/institution1.jpg",
|
|
332
|
-
"service" => {
|
|
342
|
+
"logo" => {
|
|
343
|
+
"id" => "http://example.org/logos/institution1.jpg",
|
|
344
|
+
"service" => {
|
|
333
345
|
"id" => "http://example.org/service/inst1",
|
|
334
346
|
"type" => "ImageService2",
|
|
335
347
|
"profile" => ["http://iiif.io/api/image/2/profiles/level2.json"]
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"related" => [{
|
|
351
|
+
"id" => "http://example.org/videos/video-book1.mpg",
|
|
352
|
+
"format" => "video/mpeg"
|
|
353
|
+
}],
|
|
354
|
+
"service" => [{
|
|
355
|
+
"id" => "http://example.org/service/example",
|
|
356
|
+
"profile" => ["http://example.org/docs/example-service.html"]
|
|
357
|
+
}],
|
|
358
|
+
"seeAlso" => [{
|
|
359
|
+
"id" => "http://example.org/library/catalog/book1.xml",
|
|
360
|
+
"format" => "text/xml",
|
|
361
|
+
"profile" => ["http://example.org/profiles/bibliographic"]
|
|
362
|
+
}],
|
|
363
|
+
"rendering" => [{
|
|
364
|
+
"id" => "http://example.org/iiif/book1.pdf",
|
|
365
|
+
"label" => {"en" => ["Download as PDF"]},
|
|
366
|
+
"format" => "application/pdf"
|
|
367
|
+
}],
|
|
368
|
+
"within" => [{
|
|
369
|
+
"id" => "http://example.org/collections/books/",
|
|
370
|
+
"type" => "Collection"
|
|
371
|
+
}],
|
|
372
|
+
"items" => [canvas_object],
|
|
373
|
+
"structures" => [range_object]
|
|
374
|
+
})
|
|
375
|
+
}
|
|
376
|
+
it "validates" do
|
|
377
|
+
expect { manifest_object.validate }.not_to raise_error
|
|
365
378
|
end
|
|
366
379
|
end
|
|
367
380
|
end
|