iiif_print 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/README.md +4 -0
  5. data/app/actors/iiif_print/actors/file_set_actor_decorator.rb +1 -1
  6. data/app/indexers/concerns/iiif_print/child_work_indexer.rb +27 -0
  7. data/app/indexers/concerns/iiif_print/file_set_indexer.rb +37 -22
  8. data/{lib → app/jobs}/iiif_print/jobs/application_job.rb +2 -1
  9. data/{lib → app/jobs}/iiif_print/jobs/child_works_from_pdf_job.rb +14 -9
  10. data/{lib → app/jobs}/iiif_print/jobs/create_relationships_job.rb +10 -20
  11. data/app/listeners/iiif_print/listener.rb +31 -0
  12. data/app/models/concerns/iiif_print/set_child_flag.rb +1 -1
  13. data/app/models/concerns/iiif_print/solr/document.rb +5 -3
  14. data/app/presenters/iiif_print/file_set_presenter_decorator.rb +11 -0
  15. data/app/presenters/iiif_print/iiif_manifest_presenter_factory_behavior.rb +1 -1
  16. data/app/presenters/iiif_print/work_show_presenter_decorator.rb +5 -2
  17. data/app/services/iiif_print/manifest_builder_service_behavior.rb +4 -2
  18. data/app/services/iiif_print/pluggable_derivative_service.rb +5 -1
  19. data/app/services/iiif_print/simple_schema_loader_decorator.rb +11 -0
  20. data/app/transactions/hyrax/transactions/iiif_print_container_decorator.rb +34 -0
  21. data/app/transactions/hyrax/transactions/steps/conditionally_destroy_children_from_split.rb +32 -0
  22. data/app/transactions/hyrax/transactions/steps/delete_all_file_sets_decorator.rb +35 -0
  23. data/app/views/hyrax/file_sets/_show_actions.html.erb +1 -1
  24. data/config/initializers/simple_schema_loader.rb +1 -0
  25. data/config/metadata/child_works_from_pdf_splitting.yaml +21 -0
  26. data/db/migrate/20181214181358_create_iiif_print_derivative_attachments.rb +8 -6
  27. data/db/migrate/20190107165909_create_iiif_print_ingest_file_relations.rb +7 -5
  28. data/db/migrate/20230109000000_create_iiif_print_pending_relationships.rb +8 -6
  29. data/db/migrate/20231110163052_add_model_details_to_iiif_print_pending_relationships.rb +3 -3
  30. data/iiif_print.gemspec +1 -1
  31. data/lib/iiif_print/base_derivative_service.rb +13 -2
  32. data/lib/iiif_print/blacklight_iiif_search/annotation_decorator.rb +2 -2
  33. data/lib/iiif_print/catalog_search_builder.rb +2 -2
  34. data/lib/iiif_print/configuration.rb +65 -5
  35. data/lib/iiif_print/data/fileset_helper.rb +2 -2
  36. data/lib/iiif_print/data/work_derivatives.rb +1 -1
  37. data/lib/iiif_print/engine.rb +46 -2
  38. data/lib/iiif_print/homepage_search_builder.rb +2 -2
  39. data/lib/iiif_print/jp2_derivative_service.rb +4 -1
  40. data/lib/iiif_print/lineage_service.rb +19 -6
  41. data/lib/iiif_print/pdf_derivative_service.rb +3 -1
  42. data/lib/iiif_print/persistence_layer/active_fedora_adapter.rb +189 -0
  43. data/lib/iiif_print/persistence_layer/valkyrie_adapter.rb +183 -0
  44. data/lib/iiif_print/persistence_layer.rb +118 -0
  45. data/lib/iiif_print/split_pdfs/base_splitter.rb +11 -0
  46. data/lib/iiif_print/split_pdfs/child_work_creation_from_pdf_service.rb +19 -9
  47. data/lib/iiif_print/split_pdfs/destroy_pdf_child_works_service.rb +5 -16
  48. data/lib/iiif_print/text_extraction_derivative_service.rb +4 -2
  49. data/lib/iiif_print/text_formats_from_alto_service.rb +3 -1
  50. data/lib/iiif_print/tiff_derivative_service.rb +3 -1
  51. data/lib/iiif_print/version.rb +1 -1
  52. data/lib/iiif_print.rb +79 -44
  53. metadata +18 -191
  54. data/app/indexers/concerns/iiif_print/child_indexer.rb +0 -40
  55. data/app/views/hyrax/file_sets/_actions.html.erb +0 -46
  56. data/bin/rails +0 -13
  57. data/spec/.keep.txt +0 -1
  58. data/spec/factories/ability.rb +0 -6
  59. data/spec/factories/newspaper_issue.rb +0 -7
  60. data/spec/factories/newspaper_page.rb +0 -7
  61. data/spec/factories/newspaper_page_solr_document.rb +0 -20
  62. data/spec/factories/newspaper_title.rb +0 -8
  63. data/spec/factories/uploaded_pdf_file.rb +0 -9
  64. data/spec/factories/uploaded_txt_file.rb +0 -9
  65. data/spec/factories/user.rb +0 -13
  66. data/spec/fixtures/authorities/licenses.yml +0 -4
  67. data/spec/fixtures/authorities/rights_statements.yml +0 -4
  68. data/spec/fixtures/files/4.1.07.jp2 +0 -0
  69. data/spec/fixtures/files/4.1.07.tiff +0 -0
  70. data/spec/fixtures/files/README.md +0 -7
  71. data/spec/fixtures/files/alto-2-0.xsd +0 -714
  72. data/spec/fixtures/files/broken-truncated.pdf +0 -0
  73. data/spec/fixtures/files/credits.md +0 -16
  74. data/spec/fixtures/files/lowres-gray-via-ndnp-sample.tiff +0 -0
  75. data/spec/fixtures/files/minimal-1-page.pdf +0 -0
  76. data/spec/fixtures/files/minimal-2-page.pdf +0 -0
  77. data/spec/fixtures/files/minimal-alto.xml +0 -31
  78. data/spec/fixtures/files/ndnp-alto-sample.xml +0 -24
  79. data/spec/fixtures/files/ndnp-sample1-json.json +0 -1
  80. data/spec/fixtures/files/ndnp-sample1-txt.txt +0 -1
  81. data/spec/fixtures/files/ndnp-sample1.pdf +0 -0
  82. data/spec/fixtures/files/ocr_alto.xml +0 -202
  83. data/spec/fixtures/files/ocr_alto_scaled_4pts_per_px.xml +0 -202
  84. data/spec/fixtures/files/ocr_color.tiff +0 -0
  85. data/spec/fixtures/files/ocr_gray.jp2 +0 -0
  86. data/spec/fixtures/files/ocr_gray.tiff +0 -0
  87. data/spec/fixtures/files/ocr_mono.tiff +0 -0
  88. data/spec/fixtures/files/ocr_mono_text_hocr.html +0 -78
  89. data/spec/fixtures/files/page1.tiff +0 -0
  90. data/spec/fixtures/files/sample-4page-issue.pdf +0 -0
  91. data/spec/fixtures/files/sample-color-newsletter.pdf +0 -0
  92. data/spec/fixtures/files/thumbnail.jpg +0 -0
  93. data/spec/helpers/hyrax/iiif_helper_spec.rb +0 -65
  94. data/spec/helpers/iiif_print_helper_spec.rb +0 -43
  95. data/spec/iiif_print/base_derivative_service_spec.rb +0 -28
  96. data/spec/iiif_print/blacklight_iiif_search/annotation_decorator_spec.rb +0 -59
  97. data/spec/iiif_print/catalog_search_builder_spec.rb +0 -60
  98. data/spec/iiif_print/configuration_spec.rb +0 -193
  99. data/spec/iiif_print/data/work_derivatives_spec.rb +0 -245
  100. data/spec/iiif_print/data/work_file_spec.rb +0 -99
  101. data/spec/iiif_print/data/work_files_spec.rb +0 -237
  102. data/spec/iiif_print/image_tool_spec.rb +0 -109
  103. data/spec/iiif_print/jobs/child_works_from_pdf_job_spec.rb +0 -35
  104. data/spec/iiif_print/jobs/create_relationships_job_spec.rb +0 -118
  105. data/spec/iiif_print/jp2_image_metadata_spec.rb +0 -37
  106. data/spec/iiif_print/lineage_service_spec.rb +0 -13
  107. data/spec/iiif_print/metadata_spec.rb +0 -249
  108. data/spec/iiif_print/split_pdfs/base_splitter_spec.rb +0 -27
  109. data/spec/iiif_print/split_pdfs/derivative_rodeo_splitter_spec.rb +0 -80
  110. data/spec/iiif_print/split_pdfs/destroy_pdf_child_works_service_spec.rb +0 -92
  111. data/spec/iiif_print/split_pdfs/pages_to_jpgs_splitter_spec.rb +0 -22
  112. data/spec/iiif_print/split_pdfs/pages_to_pngs_splitter_spec.rb +0 -18
  113. data/spec/iiif_print/split_pdfs/pages_to_tiffs_splitter_spec.rb +0 -19
  114. data/spec/iiif_print/text_extraction/alto_reader_spec.rb +0 -49
  115. data/spec/iiif_print/text_extraction/hocr_reader_spec.rb +0 -45
  116. data/spec/iiif_print/text_extraction/page_ocr_spec.rb +0 -84
  117. data/spec/iiif_print/text_extraction/render_alto_spec.rb +0 -54
  118. data/spec/iiif_print/text_extraction/word_coords_builder_spec.rb +0 -44
  119. data/spec/iiif_print_spec.rb +0 -171
  120. data/spec/misc_shared.rb +0 -111
  121. data/spec/models/iiif_print/derivative_attachment_spec.rb +0 -37
  122. data/spec/models/iiif_print/iiif_search_decorator_spec.rb +0 -27
  123. data/spec/models/iiif_print/ingest_file_relation_spec.rb +0 -56
  124. data/spec/models/solr_document_spec.rb +0 -14
  125. data/spec/presenters/iiif_print/iiif_manifest_presenter_behavior_spec.rb +0 -70
  126. data/spec/presenters/iiif_print/iiif_manifest_presenter_factory_behavior_spec.rb +0 -49
  127. data/spec/samvera/derivatives/configuration_spec.rb +0 -41
  128. data/spec/samvera/derivatives/hyrax_spec.rb +0 -62
  129. data/spec/samvera/derivatives_spec.rb +0 -54
  130. data/spec/services/iiif_print/derivative_rodeo_service_spec.rb +0 -103
  131. data/spec/services/iiif_print/jp2_derivative_service_spec.rb +0 -59
  132. data/spec/services/iiif_print/manifest_builder_service_behavior_spec.rb +0 -20
  133. data/spec/services/iiif_print/pdf_derivative_service_spec.rb +0 -66
  134. data/spec/services/iiif_print/pluggable_derivative_service_spec.rb +0 -175
  135. data/spec/services/iiif_print/text_extraction_derivative_service_spec.rb +0 -82
  136. data/spec/services/iiif_print/text_formats_from_alto_service_spec.rb +0 -127
  137. data/spec/services/iiif_print/tiff_derivative_service_spec.rb +0 -65
  138. data/spec/spec_helper.rb +0 -181
  139. data/spec/support/controller_level_helpers.rb +0 -28
  140. data/spec/support/iiif_print_models.rb +0 -127
  141. data/spec/test_app_templates/blacklight.yml +0 -9
  142. data/spec/test_app_templates/fedora.yml +0 -15
  143. data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -40
  144. data/spec/test_app_templates/redis.yml +0 -9
  145. data/spec/test_app_templates/solr/conf/schema.xml +0 -362
  146. data/spec/test_app_templates/solr/conf/solrconfig.xml +0 -322
  147. data/spec/test_app_templates/solr.yml +0 -7
  148. /data/{lib → app/jobs}/iiif_print/jobs/request_split_pdf_job.rb +0 -0
@@ -1,84 +0,0 @@
1
- require 'json'
2
- require 'nokogiri'
3
- require 'spec_helper'
4
-
5
- RSpec.describe IiifPrint::TextExtraction::PageOCR do
6
- let(:fixture_path) do
7
- File.join(
8
- IiifPrint::GEM_PATH, 'spec', 'fixtures', 'files'
9
- )
10
- end
11
-
12
- let(:altoxsd) do
13
- xsdpath = File.join(fixture_path, 'alto-2-0.xsd')
14
- Nokogiri::XML::Schema(File.read(xsdpath))
15
- end
16
-
17
- # sample "snippet" images for OCR testing:
18
- let(:example_gray_tiff) { File.join(fixture_path, 'ocr_gray.tiff') }
19
- let(:example_mono_tiff) { File.join(fixture_path, 'ocr_mono.tiff') }
20
- let(:example_color_tiff) { File.join(fixture_path, 'ocr_color.tiff') }
21
- let(:example_gray_jp2) { File.join(fixture_path, 'ocr_gray.jp2') }
22
- let(:ocr_from_gray_tiff) { described_class.new(example_gray_tiff) }
23
-
24
- describe "performs OCR" do
25
- def match_ocr_expectations(words)
26
- expect(words).to be_an(Array)
27
- expect(words).not_to be_empty
28
- expect(words[0]).to be_a(Hash)
29
- [:word, :coordinates].each do |key|
30
- expect(words[0].keys).to include key
31
- end
32
- end
33
-
34
- it "gets words and coordinates from grayscale source" do
35
- match_ocr_expectations(ocr_from_gray_tiff.words)
36
- end
37
-
38
- it "gets words and coordinates from one-bit source" do
39
- ocr = described_class.new(example_mono_tiff)
40
- match_ocr_expectations(ocr.words)
41
- end
42
-
43
- it "gets words and coordinates from color source" do
44
- ocr = described_class.new(example_color_tiff)
45
- match_ocr_expectations(ocr.words)
46
- end
47
-
48
- it "gets words and coordinates from jp2 source" do
49
- ocr = described_class.new(example_gray_jp2)
50
- match_ocr_expectations(ocr.words)
51
- end
52
- end
53
-
54
- describe "turns image into ALTO" do
55
- xit "takes grayscale tiff, outputs valid ALTO, geometry" do
56
- alto = ocr_from_gray_tiff.alto
57
- document = Nokogiri::XML(alto)
58
- errors = altoxsd.validate(document)
59
- expect(errors.length).to eq 0
60
- expect(document.at_css('PrintSpace')['WIDTH']).to eq "418"
61
- expect(document.at_css('PrintSpace')['HEIGHT']).to eq "1046"
62
- end
63
- end
64
-
65
- describe "plain text" do
66
- it "makes plain text available for image" do
67
- plain = ocr_from_gray_tiff.plain
68
- expect(plain.class).to be String
69
- expect(plain.length).to be > 0
70
- end
71
- end
72
-
73
- describe "JSON word coordinates" do
74
- it "passes properly formatted data to WordCoordsBuilder and receives output" do
75
- parsed = JSON.parse(ocr_from_gray_tiff.word_json)
76
- expect(parsed['coords'].length).to be > 1
77
- word = ocr_from_gray_tiff.words[0]
78
- word1 = parsed['coords'][word[:word]]
79
- word1_coords = word1[0]
80
- expect(word1_coords[2]).to eq word[:coordinates][2]
81
- expect(word1_coords[3]).to eq word[:coordinates][3]
82
- end
83
- end
84
- end
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe IiifPrint::TextExtraction::RenderAlto do
4
- let(:fixture_path) do
5
- File.join(
6
- IiifPrint::GEM_PATH, 'spec', 'fixtures', 'files'
7
- )
8
- end
9
-
10
- let(:altoxsd) do
11
- xsdpath = File.join(fixture_path, 'alto-2-0.xsd')
12
- Nokogiri::XML::Schema(File.read(xsdpath))
13
- end
14
-
15
- let(:page_prefix) { '<Page ID="ID1" PHYSICAL_IMG_NR="1"' }
16
-
17
- let(:words) do
18
- [
19
- { word: "If", coordinates: [52, 13, 11, 14] },
20
- { word: "you", coordinates: [69, 17, 31, 14] },
21
- { word: "are", coordinates: [108, 17, 28, 10] },
22
- { word: "a", coordinates: [143, 17, 8, 10] },
23
- { word: "friend,", coordinates: [158, 13, 56, 16] },
24
- { word: "you", coordinates: [51, 39, 31, 14] },
25
- { word: "speak", coordinates: [90, 35, 50, 18] },
26
- { word: "the", coordinates: [146, 35, 28, 14] },
27
- { word: "password,", coordinates: [182, 35, 85, 18] },
28
- { word: "and", coordinates: [51, 57, 30, 14] },
29
- { word: "the", coordinates: [89, 57, 28, 14] },
30
- { word: "doors", coordinates: [124, 57, 48, 14] },
31
- { word: "will", coordinates: [180, 57, 28, 14] },
32
- { word: "open.", coordinates: [216, 61, 47, 14] }
33
- ]
34
- end
35
-
36
- describe "renders alto" do
37
- it "creates alto given width, height, words" do
38
- renderer = described_class.new(12_000, 9600)
39
- output = renderer.to_alto(words)
40
- expect(output.class).to be String
41
- expect(output).to include '<alto'
42
- expect(output).to include '<String'
43
- expect(output).to include page_prefix + ' HEIGHT="9600" WIDTH="12000"'
44
- expect(Nokogiri::XML(output).errors.empty?).to be true
45
- end
46
-
47
- xit "makes alto 2.0 that validates" do
48
- renderer = described_class.new(12_000, 9600)
49
- output = renderer.to_alto(words)
50
- document = Nokogiri::XML(output)
51
- altoxsd.validate(document)
52
- end
53
- end
54
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe IiifPrint::TextExtraction::WordCoordsBuilder do
4
- let(:words) do
5
- [
6
- { word: "foo", coordinates: [1, 2, 3, 4] },
7
- { word: "bar", coordinates: [5, 6, 7, 8] },
8
- { word: "baz", coordinates: [9, 10, 11, 12] },
9
- { word: "foo", coordinates: [13, 14, 15, 16] }
10
- ]
11
- end
12
- let(:image_width) { 1_234 }
13
- let(:image_height) { 5_678 }
14
-
15
- describe '.json_coordinates_for' do
16
- let(:wcb_to_json) { JSON.parse(described_class.json_coordinates_for(words: words, width: image_width, height: image_height)) }
17
- it 'has the correct structure' do
18
- expect(wcb_to_json['height']).to eq image_height
19
- expect(wcb_to_json['width']).to eq image_width
20
- expect(wcb_to_json['coords'].length).to eq 3
21
- expect(wcb_to_json['coords']['foo']).not_to be_falsey
22
- end
23
-
24
- it 'combines coordinates for the same word' do
25
- expect(wcb_to_json['coords']['foo']).to eq [[1, 2, 3, 4], [13, 14, 15, 16]]
26
- end
27
- end
28
-
29
- describe '#to_json' do
30
- let(:wcb_to_json) { JSON.parse(wcb.to_json) }
31
- let(:wcb) { described_class.new(words, image_width, image_height) }
32
-
33
- it 'has the correct structure' do
34
- expect(wcb_to_json['height']).to eq image_height
35
- expect(wcb_to_json['width']).to eq image_width
36
- expect(wcb_to_json['coords'].length).to eq 3
37
- expect(wcb_to_json['coords']['foo']).not_to be_falsey
38
- end
39
-
40
- it 'combines coordinates for the same word' do
41
- expect(wcb_to_json['coords']['foo']).to eq [[1, 2, 3, 4], [13, 14, 15, 16]]
42
- end
43
- end
44
- end
@@ -1,171 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe IiifPrint do
4
- describe '.skip_splitting_pdf_files_that_end_with_these_texts' do
5
- subject { described_class }
6
- it { is_expected.to respond_to :skip_splitting_pdf_files_that_end_with_these_texts }
7
- end
8
-
9
- describe ".manifest_metadata_for" do
10
- let(:attributes) do
11
- { "id" => "abc123",
12
- "title_tesim" => ['My Awesome Title'] }
13
- end
14
- let(:solr_document) { SolrDocument.new(attributes) }
15
- let(:base_url) { "https://my.dev.test" }
16
-
17
- subject(:manifest_metadata) do
18
- described_class.manifest_metadata_for(work: solr_document, current_ability: double(Ability), base_url: base_url)
19
- end
20
- it { is_expected.not_to be_falsey }
21
- it "does not contain any nil values" do
22
- expect(subject).not_to include(nil)
23
- end
24
- end
25
-
26
- describe ".model_configuration" do
27
- context "default configuration" do
28
- let(:model) do
29
- Class.new do
30
- include IiifPrint.model_configuration(pdf_split_child_model: Class.new)
31
- end
32
- end
33
-
34
- subject(:record) { model.new }
35
-
36
- it { is_expected.to be_iiif_print_config }
37
-
38
- it "has a #pdf_splitter_job" do
39
- expect(record.iiif_print_config.pdf_splitter_job).to be(IiifPrint::Jobs::ChildWorksFromPdfJob)
40
- end
41
-
42
- it "has a #pdf_splitter_service" do
43
- expect(record.iiif_print_config.pdf_splitter_service).to be(IiifPrint::SplitPdfs::PagesToJpgsSplitter)
44
- end
45
-
46
- it "has #derivative_service_plugins" do
47
- expect(record.iiif_print_config.derivative_service_plugins).to eq(
48
- [IiifPrint::TextExtractionDerivativeService]
49
- )
50
- end
51
- end
52
- end
53
-
54
- describe ".fields_for_allinson_flex" do
55
- subject { described_class.fields_for_allinson_flex(fields: fields, sort_order: sort_order) }
56
- let(:sort_order) { [] }
57
-
58
- context "when the fields include an admin only indexing property" do
59
- let(:fields) do
60
- [
61
- IiifPrint::CollectionFieldShim.new(name: :title, value: "My Title"),
62
- IiifPrint::CollectionFieldShim.new(name: :creator, value: "Hyrax, Sam", indexing: ["admin_only"])
63
- ]
64
- end
65
-
66
- it "does not include the admin only field" do
67
- # We are mapping from one data structure to another
68
- expect(subject.map(&:name)).to eq([fields.first.name])
69
- end
70
- end
71
-
72
- context "when the fields include duplicate name properties" do
73
- let(:fields) do
74
- [
75
- IiifPrint::CollectionFieldShim.new(name: :title, value: "My Title"),
76
- IiifPrint::CollectionFieldShim.new(name: :title, value: "My Other Title")
77
- ]
78
- end
79
-
80
- it "does not include later duplicates" do
81
- expect(subject.map(&:label)).to eq([fields.first.value])
82
- end
83
- end
84
-
85
- context "when we provide a fields sort order" do
86
- let(:fields) do
87
- [
88
- IiifPrint::CollectionFieldShim.new(name: :title, value: "My Title"),
89
- IiifPrint::CollectionFieldShim.new(name: :creator, value: "Hyrax, Sam"),
90
- IiifPrint::CollectionFieldShim.new(name: :date_created, value: "2023-05-02")
91
- ]
92
- end
93
- let(:sort_order) { [:creator, :title] }
94
-
95
- it "returns the fields in the order specified and puts unspecified fields last" do
96
- expect(subject.map(&:name)).to eq([:creator, :title, :date_created])
97
- end
98
- end
99
- end
100
-
101
- describe ".sort_af_fields!" do
102
- let(:fields) { [:title, :creator, :date_created].map { |name| IiifPrint::Field.new(name: name) } }
103
- subject(:sort_af_fields) { described_class.sort_af_fields!(fields, sort_order: sort_order) }
104
-
105
- context "when the sort order is an empty array" do
106
- let(:sort_order) { [] }
107
-
108
- it "returns the fields in the order they were given" do
109
- expect(sort_af_fields).to eq(fields)
110
- end
111
- end
112
-
113
- context "when the sort order specifies some of the fields" do
114
- let(:sort_order) { [:date_created, :title] }
115
-
116
- it "returns the fields in the order specified and puts unspecified fields last" do
117
- expect(sort_af_fields).to eq([:date_created, :title, :creator].map { |name| IiifPrint::Field.new(name: name) })
118
- end
119
- end
120
- end
121
-
122
- describe '.conditionally_submit_split_for' do
123
- context 'when the file suffix is one that we skip' do
124
- subject do
125
- described_class.conditionally_submit_split_for(
126
- work: double,
127
- file_set: double,
128
- locations: ['hello.reader.pdf'],
129
- skip_these_endings: ['.reader.pdf'],
130
- user: double
131
- )
132
- end
133
-
134
- it { is_expected.to eq(:no_pdfs_for_splitting) }
135
- end
136
- end
137
-
138
- describe '.split_for_path_suffix?' do
139
- context 'with default .skip_splitting_pdf_files_that_end_with_these_texts' do
140
- subject { described_class.split_for_path_suffix?(path) }
141
- [
142
- ["hello.pdf", true],
143
- ["hello.PDF", true],
144
- ["hello.reader.pdf", true],
145
- ["hello.png", false],
146
- ["hello.pdf.png", false]
147
- ].each do |given_path, expected_value|
148
- context "with #{given_path.inspect}" do
149
- let(:path) { given_path }
150
- it { is_expected.to eq(expected_value) }
151
- end
152
- end
153
- end
154
-
155
- context 'with customized .skip_splitting_pdf_files_that_end_with_these_texts' do
156
- subject { described_class.split_for_path_suffix?(path, skip_these_endings: ['.READER.pdf']) }
157
- [
158
- ["hello.pdf", true],
159
- ["hello.PDF", true],
160
- ["hello.reader.pdf", false],
161
- ["hello.png", false],
162
- ["hello.pdf.png", false]
163
- ].each do |given_path, expected_value|
164
- context "with #{given_path.inspect}" do
165
- let(:path) { given_path }
166
- it { is_expected.to eq(expected_value) }
167
- end
168
- end
169
- end
170
- end
171
- end
data/spec/misc_shared.rb DELETED
@@ -1,111 +0,0 @@
1
- RSpec.shared_context "shared setup", shared_context: :metadata do
2
- let(:fixture_path) do
3
- path = File.join(
4
- IiifPrint::GEM_PATH, 'spec', 'fixtures', 'files'
5
- )
6
- # TODO: NOTE: this has potential timing issues in the specs, because we're adjusting the
7
- # configured value during the spec run.
8
- registered = Hyrax.config.registered_ingest_dirs
9
- registered.push(path) unless registered.include?(path)
10
- path
11
- end
12
-
13
- # shared date to be invariant across all tests in a run:
14
- date_static = Hyrax::TimeService.time_in_utc
15
- let(:static_date) { date_static }
16
-
17
- # path fixtures:
18
- let(:example_gray_jp2) { File.join(fixture_path, 'ocr_gray.jp2') }
19
- let(:txt_path) { File.join(fixture_path, 'credits.md') }
20
- let(:sample_thumbnail) { File.join(fixture_path, 'thumbnail.jpg') }
21
-
22
- # sample data:
23
- let(:sample_text) { 'even in a mythical Age there must be some enigmas' }
24
-
25
- let(:valid_file_set) do
26
- file_set = FileSet.new
27
- file_set.save!(validate: false)
28
- file_set
29
- end
30
-
31
- let(:sample_work) do
32
- work = MyWork.new
33
- work.title = ['Bombadil']
34
- work.members.push(valid_file_set)
35
- work.save!
36
- work
37
- end
38
-
39
- # sample objects:
40
- let(:work_with_file) do
41
- # we need a work with not just a valid (but empty) fileset, but also
42
- # a persisted file, so we use the shared work sample, and expand
43
- # on it with actual file data/metadata.
44
- work = sample_work
45
- fileset = work.members.first
46
- file = Hydra::PCDM::File.create
47
- fileset.original_file = file
48
- # Set binary content on file via ActiveFedora content= mutator method
49
- # which also makes .size method return valid result for content
50
- file.content = File.open(txt_path)
51
- # Set some metdata we would expect to otherwise be set upon an upload
52
- file.original_name = 'credits.md'
53
- file.mime_type = 'text/plain'
54
- file.date_modified = static_date
55
- file.date_created = static_date
56
- # saving fileset also saves file content
57
- fileset.save!
58
- work
59
- end
60
-
61
- def path_factory
62
- Hyrax::DerivativePath
63
- end
64
-
65
- def work_file_set(work)
66
- work.members.detect { |m| m.is_a? FileSet }
67
- end
68
-
69
- def text_path(work)
70
- path_factory.derivative_path_for_reference(work_file_set(work), 'txt')
71
- end
72
-
73
- def jp2_path(work)
74
- path_factory.derivative_path_for_reference(work_file_set(work), 'jp2')
75
- end
76
-
77
- def thumbnail_path(work)
78
- path_factory.derivative_path_for_reference(work_file_set(work), 'thumbnail')
79
- end
80
-
81
- def mkdir_derivative(work, name)
82
- # make shared path for derivatives to live, Hyrax ususally does this
83
- # for thumbnails, and iiif_print does this in its derivative
84
- # service plugins; here we do same.
85
- fsid = work_file_set(work).id
86
- path = path_factory.derivative_path_for_reference(fsid, name)
87
- dir = File.join(path.split('/')[0..-2])
88
- FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
89
- end
90
-
91
- def mk_jp2_derivative(work)
92
- mkdir_derivative(work, 'jp2')
93
- dst_path = jp2_path(work)
94
- FileUtils.copy(example_gray_jp2, dst_path)
95
- expect(File.exist?(dst_path)).to be true
96
- end
97
-
98
- def mk_txt_derivative(work)
99
- mkdir_derivative(work, 'txt')
100
- dst_path = text_path(work)
101
- File.open(dst_path, 'w') { |f| f.write(sample_text) }
102
- expect(File.exist?(dst_path)).to be true
103
- end
104
-
105
- def mk_thumbnail_derivative(work)
106
- mkdir_derivative(work, 'thumbnail')
107
- dst_path = thumbnail_path(work)
108
- FileUtils.copy(sample_thumbnail, dst_path)
109
- expect(File.exist?(dst_path)).to be true
110
- end
111
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module IiifPrint
4
- RSpec.describe DerivativeAttachment, type: :model do
5
- it "requires some columns to be considered complete" do
6
- model = described_class.create
7
- # attempt save without required data; expect failure
8
- expect { model.save! }.to raise_exception(ActiveRecord::RecordInvalid)
9
- end
10
-
11
- it "saves when constructed with all field values" do
12
- model = described_class.create(
13
- fileset_id: 'a1b2c3d4e5',
14
- path: '/path/to/somefile',
15
- destination_name: 'txt'
16
- )
17
- # attempt save without required data; expect failure
18
- expect { model.save! }.not_to raise_exception
19
- end
20
-
21
- it "saves when all fields completely set" do
22
- model = described_class.create
23
- model.fileset_id = 'someid123'
24
- model.path = '/path/to/somefile'
25
- model.destination_name = 'txt'
26
- expect { model.save! }.not_to raise_exception
27
- end
28
-
29
- it "saves when only path, destination_name set" do
30
- model = described_class.create
31
- model.fileset_id = nil
32
- model.path = '/path/to/somefile'
33
- model.destination_name = 'txt'
34
- expect { model.save! }.not_to raise_exception
35
- end
36
- end
37
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe IiifPrint::IiifSearchDecorator do
4
- let(:iiif_config) { { object_relation_field: 'is_page_of_ssim' } }
5
- let(:parent_document) { double(SolrDocument, id: 'abc123') }
6
- let(:iiif_search) { BlacklightIiifSearch::IiifSearch.new(params, iiif_config, parent_document) }
7
-
8
- describe '#solr_params' do
9
- subject { iiif_search.solr_params }
10
-
11
- context 'when q is nil' do
12
- let(:params) { { q: nil } }
13
-
14
- it 'returns nil:nil' do
15
- expect(subject).to eq({ q: 'nil:nil' })
16
- end
17
- end
18
-
19
- context 'when q is not nil' do
20
- let(:params) { { q: 'catscan' } }
21
-
22
- it 'returns a query with the search term and filters for child or parent id' do
23
- expect(subject).to eq({ q: "catscan AND (is_page_of_ssim:\"abc123\" OR id:\"abc123\")", rows: 50, page: nil })
24
- end
25
- end
26
- end
27
- end
@@ -1,56 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module IiifPrint
4
- RSpec.describe IngestFileRelation, type: :model do
5
- def make_test_records
6
- # two unique values
7
- described_class.create(
8
- file_path: '/some/path/to/this',
9
- derivative_path: '/some/path/to/that'
10
- )
11
- described_class.create(
12
- file_path: '/some/path/to/this',
13
- derivative_path: '/some/path/to/other_thing'
14
- )
15
- # a duplicate will save, presumption is that dupes are filtered on query:
16
- described_class.create(
17
- file_path: '/some/path/to/this',
18
- derivative_path: '/some/path/to/other_thing'
19
- )
20
- end
21
-
22
- it "will not save unless record is complete" do
23
- model = described_class.create
24
- # attempt save without required data; expect failure
25
- expect { model.save! }.to raise_exception(ActiveRecord::RecordInvalid)
26
- model2 = described_class.create
27
- model2.file_path = '/path/to/sourcefile.tiff'
28
- expect { model2.save! }.to raise_exception(ActiveRecord::RecordInvalid)
29
- model3 = described_class.create
30
- model3.derivative_path = '/path/to/sourcefile.tiff'
31
- expect { model3.save! }.to raise_exception(ActiveRecord::RecordInvalid)
32
- end
33
-
34
- it "will save sufficiently constructed record" do
35
- model = described_class.create(
36
- file_path: '/path/to/this',
37
- derivative_path: '/path/to/that'
38
- )
39
- expect { model.save! }.not_to raise_exception
40
- end
41
-
42
- it "will save when all fields completely set" do
43
- model = described_class.create
44
- model.file_path = '/path/to/sourcefile.tiff'
45
- model.derivative_path = '/path/to/derived.jp2'
46
- expect { model.save! }.not_to raise_exception
47
- end
48
-
49
- it "can query derivative paths for primary file" do
50
- make_test_records
51
- result = described_class.derivatives_for_file('/some/path/to/this')
52
- expect(result).to be_an Array
53
- expect(result.size).to eq 2
54
- end
55
- end
56
- end
@@ -1,14 +0,0 @@
1
- require 'spec_helper'
2
- RSpec.describe SolrDocument do
3
- let(:solr_doc) { described_class.new(id: 'foo', file_set_ids_ssim: ['bar']) }
4
-
5
- describe 'file_set_ids' do
6
- it 'responds to #file_set_ids' do
7
- expect(solr_doc).to respond_to(:file_set_ids)
8
- end
9
-
10
- it 'returns the correct value' do
11
- expect(solr_doc.file_set_ids).to eq(['bar'])
12
- end
13
- end
14
- end
@@ -1,70 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe IiifPrint::IiifManifestPresenterBehavior do
4
- let(:attributes) do
5
- { "id" => "abc123",
6
- "title_tesim" => ['Page the first'],
7
- "description_tesim" => ['A book or something'],
8
- "creator_tesim" => ['Arthur McAuthor'] }
9
- end
10
- let(:solr_document) { SolrDocument.new(attributes) }
11
- let(:presenter) { Hyrax::IiifManifestPresenter.new(solr_document) }
12
- let(:test_request) { ActionDispatch::TestRequest.new({}) }
13
-
14
- describe '#search_service' do
15
- it 'returns the correct URL for the IIIF Search service' do
16
- expect(presenter.search_service).to include("#{solr_document.id}/iiif_search")
17
- end
18
- end
19
-
20
- context 'with IIIF external support' do
21
- let(:presenter) { Hyrax::IiifManifestPresenter::DisplayImagePresenter.new(solr_document) }
22
- let(:id) { 'abc123' }
23
- let(:url) { 'external_iiif_url' }
24
- let(:iiif_info_url_builder) { ->(file_id, base_url) { "#{base_url}/#{file_id}" } }
25
-
26
- before { allow(solr_document).to receive(:image?).and_return(true) }
27
-
28
- context 'when external iiif is enabled' do
29
- before do
30
- allow(ENV).to receive(:[])
31
- allow(ENV).to receive(:[]).with('EXTERNAL_IIIF_URL').and_return(url)
32
- allow(presenter).to receive(:latest_file_id).and_return(id)
33
- end
34
-
35
- describe '#display_image' do
36
- it 'renders a external url' do
37
- expect(presenter.display_image.iiif_endpoint.url).to eq "#{url}/#{id}"
38
- expect(presenter.display_image.iiif_endpoint.profile).to eq "http://iiif.io/api/image/2/level2.json"
39
- end
40
- end
41
-
42
- describe '#display_content' do
43
- it 'renders a external url' do
44
- expect(presenter.display_content.iiif_endpoint.url).to eq "#{url}/#{id}"
45
- expect(presenter.display_content.iiif_endpoint.profile).to eq "http://iiif.io/api/image/2/level2.json"
46
- end
47
- end
48
- end
49
-
50
- context 'when external iiif is not enabled' do
51
- before do
52
- allow(presenter).to receive(:latest_file_id).and_return(id)
53
- allow(Hyrax.config).to receive(:iiif_image_server?).and_return(true)
54
- allow(Hyrax.config).to receive(:iiif_info_url_builder).and_return(iiif_info_url_builder)
55
- end
56
-
57
- describe '#display_image' do
58
- it 'does not render a external url' do
59
- expect(presenter.display_image.iiif_endpoint.url).to eq "localhost/#{id}"
60
- end
61
- end
62
-
63
- describe '#display_content' do
64
- it 'does not render a external url' do
65
- expect(presenter.display_content.iiif_endpoint.url).to eq "localhost/#{id}"
66
- end
67
- end
68
- end
69
- end
70
- end