berkeley_library-av-core 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +391 -0
  3. data/.github/workflows/build.yml +30 -0
  4. data/.gitignore +388 -0
  5. data/.idea/av_core.iml +146 -0
  6. data/.idea/codeStyles/Project.xml +12 -0
  7. data/.idea/codeStyles/codeStyleConfig.xml +5 -0
  8. data/.idea/go.imports.xml +6 -0
  9. data/.idea/inspectionProfiles/Project_Default.xml +37 -0
  10. data/.idea/misc.xml +6 -0
  11. data/.idea/modules.xml +8 -0
  12. data/.idea/vcs.xml +6 -0
  13. data/.rubocop.yml +241 -0
  14. data/.ruby-version +1 -0
  15. data/.simplecov +8 -0
  16. data/CHANGES.md +38 -0
  17. data/Gemfile +3 -0
  18. data/Jenkinsfile +16 -0
  19. data/LICENSE.md +21 -0
  20. data/README.md +20 -0
  21. data/Rakefile +20 -0
  22. data/av_core.gemspec +49 -0
  23. data/lib/berkeley_library/av/config.rb +238 -0
  24. data/lib/berkeley_library/av/constants.rb +30 -0
  25. data/lib/berkeley_library/av/core/module_info.rb +18 -0
  26. data/lib/berkeley_library/av/core.rb +7 -0
  27. data/lib/berkeley_library/av/marc/util.rb +114 -0
  28. data/lib/berkeley_library/av/marc.rb +52 -0
  29. data/lib/berkeley_library/av/metadata/README.md +5 -0
  30. data/lib/berkeley_library/av/metadata/field.rb +110 -0
  31. data/lib/berkeley_library/av/metadata/fields.rb +130 -0
  32. data/lib/berkeley_library/av/metadata/link.rb +28 -0
  33. data/lib/berkeley_library/av/metadata/readers/alma.rb +54 -0
  34. data/lib/berkeley_library/av/metadata/readers/base.rb +53 -0
  35. data/lib/berkeley_library/av/metadata/readers/tind.rb +52 -0
  36. data/lib/berkeley_library/av/metadata/readers.rb +2 -0
  37. data/lib/berkeley_library/av/metadata/source.rb +93 -0
  38. data/lib/berkeley_library/av/metadata/tind_html_metadata_da.json +2076 -0
  39. data/lib/berkeley_library/av/metadata/value.rb +121 -0
  40. data/lib/berkeley_library/av/metadata.rb +103 -0
  41. data/lib/berkeley_library/av/record.rb +86 -0
  42. data/lib/berkeley_library/av/record_id.rb +121 -0
  43. data/lib/berkeley_library/av/record_not_found.rb +7 -0
  44. data/lib/berkeley_library/av/restrictions.rb +36 -0
  45. data/lib/berkeley_library/av/track.rb +132 -0
  46. data/lib/berkeley_library/av/types/duration.rb +67 -0
  47. data/lib/berkeley_library/av/types/file_type.rb +84 -0
  48. data/lib/berkeley_library/av/util.rb +65 -0
  49. data/rakelib/bundle.rake +8 -0
  50. data/rakelib/coverage.rake +11 -0
  51. data/rakelib/gem.rake +54 -0
  52. data/rakelib/rubocop.rake +18 -0
  53. data/rakelib/spec.rake +12 -0
  54. data/spec/.rubocop.yml +116 -0
  55. data/spec/data/10.23.19.JessieLaCavalier.02.mrc +3 -0
  56. data/spec/data/alma/991005939359706532-sru.xml +123 -0
  57. data/spec/data/alma/991034756419706532-sru.xml +162 -0
  58. data/spec/data/alma/991047179369706532-sru.xml +210 -0
  59. data/spec/data/alma/991054360089706532-sru.xml +186 -0
  60. data/spec/data/alma/b11082434-sru.xml +165 -0
  61. data/spec/data/alma/b18538031-sru.xml +123 -0
  62. data/spec/data/alma/b20786580-sru.xml +123 -0
  63. data/spec/data/alma/b22139647-sru.xml +171 -0
  64. data/spec/data/alma/b22139658-sru.xml +282 -0
  65. data/spec/data/alma/b23161018-sru.xml +182 -0
  66. data/spec/data/alma/b23305522-sru.xml +144 -0
  67. data/spec/data/alma/b24071548-sru.xml +136 -0
  68. data/spec/data/alma/b24659129-sru.xml +210 -0
  69. data/spec/data/alma/b25207857-sru.xml +217 -0
  70. data/spec/data/alma/b25716973-sru.xml +186 -0
  71. data/spec/data/alma/b25742488-sru.xml +246 -0
  72. data/spec/data/record-(cityarts)00002.xml +78 -0
  73. data/spec/data/record-(cityarts)00773.xml +94 -0
  74. data/spec/data/record-(clir)00020.xml +153 -0
  75. data/spec/data/record-(miscmat)00615.xml +45 -0
  76. data/spec/data/record-(pacradio)00107.xml +85 -0
  77. data/spec/data/record-(pacradio)01469.xml +82 -0
  78. data/spec/data/record-empty-result.xml +4 -0
  79. data/spec/data/record-multiple-998s-disordered.xml +178 -0
  80. data/spec/data/record-multiple-998s.xml +178 -0
  81. data/spec/data/record-physcolloquia-bk00169017b.xml +78 -0
  82. data/spec/data/record-ragged-998-subfields.xml +122 -0
  83. data/spec/data/record-ragged-998s-multiple-fields.xml +160 -0
  84. data/spec/data/record-redirect-to-login.html +288 -0
  85. data/spec/data/record_id/bibs_with_check_digits.txt +151 -0
  86. data/spec/data/search-1993.xml +158 -0
  87. data/spec/data/search-b23305516.xml +81 -0
  88. data/spec/lib/berkeley_library/av/av_spec.rb +12 -0
  89. data/spec/lib/berkeley_library/av/config_spec.rb +250 -0
  90. data/spec/lib/berkeley_library/av/marc/util_spec.rb +150 -0
  91. data/spec/lib/berkeley_library/av/marc_spec.rb +62 -0
  92. data/spec/lib/berkeley_library/av/metadata/field_spec.rb +81 -0
  93. data/spec/lib/berkeley_library/av/metadata/fields_spec.rb +180 -0
  94. data/spec/lib/berkeley_library/av/metadata/metadata_spec.rb +274 -0
  95. data/spec/lib/berkeley_library/av/metadata/source_spec.rb +261 -0
  96. data/spec/lib/berkeley_library/av/metadata/value_spec.rb +29 -0
  97. data/spec/lib/berkeley_library/av/record_id_spec.rb +72 -0
  98. data/spec/lib/berkeley_library/av/record_spec.rb +284 -0
  99. data/spec/lib/berkeley_library/av/track_spec.rb +335 -0
  100. data/spec/lib/berkeley_library/av/types/duration_spec.rb +91 -0
  101. data/spec/lib/berkeley_library/av/types/file_type_spec.rb +98 -0
  102. data/spec/lib/berkeley_library/av/util_spec.rb +30 -0
  103. data/spec/spec_helper.rb +63 -0
  104. metadata +499 -0
@@ -0,0 +1,180 @@
1
+ require 'spec_helper'
2
+
3
+ require 'marc'
4
+
5
+ module BerkeleyLibrary
6
+ module AV
7
+ class Metadata
8
+ describe Fields do
9
+
10
+ describe :standard_fields do
11
+ it 'parses the config' do
12
+ expected_fields = [
13
+ Field.new(order: 1, spec: '245$a', label: 'Title'),
14
+ Field.new(order: 2, spec: '520$a', label: 'Description'),
15
+ Field.new(order: 2, spec: '700', label: 'Creator'),
16
+ Field.new(order: 2, spec: '710', label: 'Creator'),
17
+ Field.new(order: 3, spec: '720$a', label: 'Contributor'),
18
+ Field.new(order: 4, spec: '711', label: 'Meeting Name', subfields_separator: ', ', subfield_order: %w[a n d c]),
19
+ Field.new(order: 6, spec: '246', label: 'Variant Title', subfields_separator: ', '),
20
+ Field.new(order: 9, spec: '260', label: 'Published', subfields_separator: ', '),
21
+ Field.new(order: 10, spec: '250', label: 'Edition', subfields_separator: ', '),
22
+ Field.new(order: 14, spec: '982$b', label: 'Full Collection Name', subfields_separator: ', '),
23
+ Field.new(order: 15, spec: '490$a', label: 'Series', subfields_separator: ', '),
24
+ Field.new(order: 16, spec: '020', label: 'ISBN'),
25
+ Field.new(order: 17, spec: '022', label: 'ISSN'),
26
+ Field.new(order: 20, spec: '024$a{^1=\8}{^2=\0}', label: 'Other Identifiers'),
27
+ Field.new(order: 21, spec: '600', label: 'Subject (Person)'),
28
+ Field.new(order: 22, spec: '610$a', label: 'Subject (Corporate)'),
29
+ Field.new(order: 23, spec: '650$a', label: 'Subject (Topic)'),
30
+ Field.new(order: 24, spec: '611$a', label: 'Subject (Meeting Name)'),
31
+ Field.new(order: 25, spec: '630$a', label: 'Subject (Uniform Title)'),
32
+ Field.new(order: 27, spec: '651$a', label: 'Geographic Coverage'),
33
+ Field.new(order: 28, spec: '508$a', label: 'Credits', subfields_separator: ', '),
34
+ Field.new(order: 29, spec: '255$a', label: 'Scale', subfields_separator: ', '),
35
+ Field.new(order: 30, spec: '255$b', label: 'Projection', subfields_separator: ', '),
36
+ Field.new(order: 31, spec: '255$c', label: 'Coordinates', subfields_separator: ', '),
37
+ Field.new(order: 32, spec: '392$c', label: 'Sheet Name', subfields_separator: ', '),
38
+ Field.new(order: 33, spec: '392$d', label: 'Sheet Number', subfields_separator: ', '),
39
+ Field.new(order: 34, spec: '336$a', label: 'Type', subfields_separator: ', '),
40
+ Field.new(order: 35, spec: '655$a', label: 'Format'),
41
+ Field.new(order: 36, spec: '300$a', label: 'Extent'),
42
+ Field.new(order: 37, spec: '300$b', label: 'Other Physical Details'),
43
+ Field.new(order: 38, spec: '300$c', label: 'Dimensions'),
44
+ Field.new(order: 39, spec: '306$a', label: 'Duration', subfields_separator: ', '),
45
+ Field.new(order: 40, spec: '340$a', label: 'Physical Medium'),
46
+ Field.new(order: 41, spec: '340$g', label: 'Colour/ B&W'),
47
+ Field.new(order: 42, spec: '340$i', label: 'Technical Specifications'),
48
+ Field.new(order: 43, spec: '546$a', label: 'Language'),
49
+ Field.new(order: 45, spec: '533$c', label: 'Repository'),
50
+ Field.new(order: 46, spec: '773', label: 'In', subfields_separator: ', '),
51
+ Field.new(order: 47, spec: '773$i{^2=\8}', label: 'Digital Collection'),
52
+ Field.new(order: 48, spec: '363$a', label: 'Volume'),
53
+ Field.new(order: 49, spec: '363$b', label: 'Issue'),
54
+ Field.new(order: 51, spec: '787$i{^2=\8}', label: 'Digital Exhibit'),
55
+ Field.new(order: 52, spec: '786$i{^2=\8}', label: 'Collection in Repository'),
56
+ Field.new(order: 53, spec: '740$a', label: 'Text on Picture', subfields_separator: ', '),
57
+ Field.new(order: 54, spec: '751$a', label: 'Mentioned Place', subfields_separator: ', '),
58
+ Field.new(order: 56, spec: '789', label: 'Related Resource'),
59
+ Field.new(order: 57, spec: '790$a', label: 'Contributing Institution'),
60
+ Field.new(order: 58, spec: '852', label: 'Archive', subfields_separator: '; ', subfield_order: %w[a b c h]),
61
+ Field.new(order: 60, spec: '500', label: 'Note', subfields_separator: ', '),
62
+ Field.new(order: 61, spec: '502$a', label: 'Dissertation/Thesis Note', subfields_separator: ', '),
63
+ Field.new(order: 63, spec: '522$a', label: 'Coverage', subfields_separator: ', '),
64
+ Field.new(order: 64, spec: '524$a', label: 'Preferred Citation', subfields_separator: ', '),
65
+ Field.new(order: 65, spec: '533$a', label: 'Reproduction Note', subfields_separator: ', '),
66
+ Field.new(order: 66, spec: '536', label: 'Grant Information', subfield_order: %w[a o m n]),
67
+ Field.new(order: 67, spec: '541$a', label: 'Provenance', subfields_separator: ', '),
68
+ Field.new(order: 68, spec: '541$c', label: 'Acquisition Method', subfields_separator: ', '),
69
+ Field.new(order: 69, spec: '541$d', label: 'Year of Admission', subfields_separator: ', '),
70
+ Field.new(order: 70, spec: '541$f', label: 'Owner', subfields_separator: ', '),
71
+ Field.new(order: 71, spec: '542$f', label: 'Standard Rights Statement'),
72
+ Field.new(order: 72, spec: '545$a', label: 'Note', subfields_separator: ', '),
73
+ Field.new(order: 73, spec: '542$u', label: 'Standard Rights Statement'),
74
+ Field.new(order: 85, spec: '540$a', label: 'Usage Statement', subfields_separator: ', '),
75
+ Field.new(order: 86, spec: '991$a', label: 'Access', subfields_separator: ', '),
76
+ Field.new(order: 89, spec: '982$a', label: 'Collection'),
77
+ Field.new(order: 99, spec: '998', label: 'Tracks', subfield_order: %w[g t a]),
78
+ Field.new(order: 999, spec: '856{^1=\4}{^2=\1}', label: 'Linked Resources')
79
+ ]
80
+
81
+ fields = Fields.default_fields
82
+ expect(fields).to eq(expected_fields)
83
+ end
84
+
85
+ it 'filters out duplicates' do
86
+ fields = Fields.default_fields
87
+ duplicates = []
88
+
89
+ fields.each_with_index do |f1, i|
90
+ fields[(i + 1)..].each do |f2|
91
+ if f1.same_metadata?(f2)
92
+ duplicates << [f1, f2]
93
+ elsif f2.same_metadata?(f1)
94
+ duplicates << [f2, f1]
95
+ end
96
+ end
97
+ end
98
+
99
+ expect(duplicates).to eq([]) # better reporting than be_empty?
100
+ end
101
+ end
102
+
103
+ describe :default_values_from do
104
+ it 'reads an Alma record' do
105
+ bib_number = 'b23305522'
106
+ marc_record = alma_marc_record_for(bib_number)
107
+
108
+ fields = Fields.default_fields.each_with_object({}) do |f, ff|
109
+ ff[f.spec] = f
110
+ end
111
+
112
+ expected = {
113
+ '245$a' => 'Title (245): Wanda Coleman',
114
+ '520$a' => 'Description (520): Poet Opal Palmer Adisa interviews writer/poet Wanda Coleman, author of Mad Dog, Black Lady, African Sleeping Sickness and Hand Dance, among other books. Coleman discusses when she found her poetic voice, talks about the function of poetry, her personal encounters with anti-Black discrimination, and about the reluctance of white liberals to discuss issues that affect the Black community. She also talks about the plight of the African American community in South Central Los Angeles. The poems Coleman reads are A civilized plague, David Polion, Notes of a cultural terrorist and Jazz wazz.',
115
+ '700' => 'Creator (700): Coleman, Wanda. interviewee. Adisa, Opal Palmer. interviewer.',
116
+ '710' => 'Creator (710): Pacifica Radio Archive. KPFA (Radio station : Berkeley, Calif.).',
117
+ '260' => 'Published (260): Los Angeles :, Pacifica Radio Archives,, 1993.',
118
+ '300$a' => 'Extent (300): 1 online resource.',
119
+ '533$c' => 'Repository (533): Pacifica Radio Archives.',
120
+ '533$a' => 'Reproduction Note (533): Electronic reproduction.',
121
+ '536' => "Grant Information (536): Sponsored by the National Historical Publications and Records Commission at the National Archives and Records Administration as part of Pacifica's American Women Making History and Culture: 1963-1982 grant preservation project.",
122
+ '540$a' => 'Usage Statement (540): RESTRICTED.',
123
+ '998' => 'Tracks (998): PRA_NHPRC1_AZ1084_00_000_00.mp3 00:54:03'
124
+ }.each_with_object({}) do |(k, v), x|
125
+ field = fields[k]
126
+ x[field] = v
127
+ end
128
+
129
+ actual = Fields.default_values_from(marc_record)
130
+ expect(actual.keys).to eq(expected.keys)
131
+
132
+ aggregate_failures do
133
+ expected.each do |f, xv|
134
+ actual_value = actual[f]
135
+ expect(actual_value.to_s).to eq(xv), "Wrong value for field #{f}: expected #{xv}, got #{actual_value}"
136
+ end
137
+ end
138
+ end
139
+
140
+ it 'reads a TIND record' do
141
+ marc_record = MARC::XMLReader.new('spec/data/record-(pacradio)01469.xml').first
142
+
143
+ fields = Fields.default_fields.each_with_object({}) do |f, ff|
144
+ ff[f.spec] = f
145
+ end
146
+
147
+ expected = {
148
+ '245$a' => 'Title (245): Wanda Coleman',
149
+ '520$a' => 'Description (520): Poet Opal Palmer Adisa interviews writer/poet Wanda Coleman, author of Mad Dog, Black Lady, African Sleeping Sickness and Hand Dance, among other books. Coleman discusses when she found her poetic voice, talks about the function of poetry, her personal encounters with anti-Black discrimination, and about the reluctance of white liberals to discuss issues that affect the Black community. She also talks about the plight of the African American community in South Central Los Angeles. The poems Coleman reads are A civilized plague, David Polion, Notes of a cultural terrorist and Jazz wazz.',
150
+ '700' => 'Creator (700): Coleman, Wanda. interviewee. Adisa, Opal Palmer. interviewer.',
151
+ '710' => 'Creator (710): Pacifica Radio Archive. KPFA (Radio station : Berkeley, Calif.).',
152
+ '260' => 'Published (260): Los Angeles, Pacifica Radio Archives, 1993.',
153
+ '982$b' => 'Full Collection Name (982): Pacifica Radio Archives Social Activism Sound Recording Project',
154
+ '336$a' => 'Type (336): Audio',
155
+ '300$a' => 'Extent (300): 1 online resource.',
156
+ '852' => 'Archive (852): The Library',
157
+ '536' => "Grant Information (536): Sponsored by the National Historical Publications and Records Commission at the National Archives and Records Administration as part of Pacifica's American Women Making History and Culture: 1963-1982 grant preservation project.",
158
+ '540$a' => 'Usage Statement (540): RESTRICTED. Permissions, licensing requests, and all other inquiries should be directed in writing to: Director of the Archives, Pacifica Radio Archives, 3729 Cahuenga Blvd. West, North Hollywood, CA 91604, 800-735-0230 x 263, fax 818-506-1084, info@pacificaradioarchives.org, http://www.pacificaradioarchives.org',
159
+ '982$a' => 'Collection (982): Pacifica Radio Archives',
160
+ '998' => 'Tracks (998): PRA_NHPRC1_AZ1084_00_000_00.mp3 00:54:03'
161
+ }.each_with_object({}) do |(k, v), x|
162
+ field = fields[k]
163
+ x[field] = v
164
+ end
165
+
166
+ actual = Fields.default_values_from(marc_record)
167
+ expect(actual.keys).to eq(expected.keys)
168
+
169
+ aggregate_failures do
170
+ expected.each do |f, xv|
171
+ actual_value = actual[f].to_s
172
+ expect(actual_value).to eq(xv), "Wrong value for field #{f.inspect}: expected #{xv.inspect}, got #{actual_value.inspect}"
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,274 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module AV
5
+ describe Metadata do
6
+
7
+ before do
8
+ Config.avplayer_base_uri = 'https://avplayer.lib.berkeley.edu'
9
+ Config.tind_base_uri = 'https://digicoll.lib.berkeley.edu'
10
+ Config.alma_sru_host = 'berkeley.alma.exlibrisgroup.com'
11
+ Config.alma_institution_code = '01UCS_BER'
12
+ Config.alma_primo_host = 'search.library.berkeley.edu'
13
+ Config.alma_permalink_key = 'iqob43'
14
+ end
15
+
16
+ after do
17
+ Config.send(:clear!)
18
+ end
19
+
20
+ describe :title do
21
+ it 'finds the title' do
22
+ stub_sru_request('b22139658')
23
+ metadata = Metadata.for_record(record_id: 'b22139658')
24
+ expect(metadata.title).to eq('Communists on campus')
25
+ end
26
+
27
+ it 'returns UNKNOWN_TITLE if the title cannot be found' do
28
+ marc_record = alma_marc_record_for('b22139658')
29
+ marc_record.fields.delete_if { |f| f.tag == AV::Constants::TAG_TITLE_FIELD }
30
+ metadata = Metadata.new(record_id: 'b22139658', source: AV::Metadata::Source::ALMA, marc_record:)
31
+ expect(metadata.title).to eq(Metadata::UNKNOWN_TITLE)
32
+ end
33
+
34
+ it 'collapses spaces after hyphens' do
35
+ bib_number = 'b22139647'
36
+ stub_sru_request(bib_number)
37
+ metadata = Metadata.for_record(record_id: bib_number)
38
+ expect(metadata.title).to eq('Europe and the nuclear arms race, with David Owen and co-host Prof. Thomas Barnes')
39
+ end
40
+ end
41
+
42
+ describe :calnet_or_ip? do
43
+ it 'detects restricted audio' do
44
+ bib_number = 'b18538031'
45
+ stub_sru_request(bib_number)
46
+ metadata = Metadata.for_record(record_id: bib_number)
47
+ expect(metadata.calnet_or_ip?).to eq(true)
48
+ end
49
+
50
+ it 'detects restricted video' do
51
+ bib_number = 'b25207857'
52
+ stub_sru_request(bib_number)
53
+ metadata = Metadata.for_record(record_id: bib_number)
54
+ expect(metadata.calnet_or_ip?).to eq(true)
55
+ end
56
+
57
+ it 'detects CalNet restrictions' do
58
+ bib_number = 'b24659129'
59
+ stub_sru_request(bib_number)
60
+ metadata = Metadata.for_record(record_id: bib_number)
61
+ expect(metadata.calnet_or_ip?).to eq(true)
62
+ end
63
+
64
+ it 'detects unrestricted audio' do
65
+ bib_number = 'b23161018'
66
+ stub_sru_request(bib_number)
67
+ metadata = Metadata.for_record(record_id: bib_number)
68
+ expect(metadata.calnet_or_ip?).to eq(false)
69
+ end
70
+ end
71
+
72
+ # TODO: do we need to check the 799s?
73
+ context 'restrictions' do
74
+ it 'returns "UCB access"' do
75
+ bib_number = 'b18538031'
76
+ stub_sru_request(bib_number)
77
+ metadata = Metadata.for_record(record_id: bib_number)
78
+ expect(metadata.calnet_or_ip?).to eq(true)
79
+ end
80
+
81
+ it 'finds "UCB Access" (capitalized)' do
82
+ bib_number = 'b25716973'
83
+ stub_sru_request(bib_number)
84
+ metadata = Metadata.for_record(record_id: bib_number)
85
+ expect(metadata.calnet_or_ip?).to eq(true)
86
+ expect(metadata.calnet_only?).to eq(false)
87
+ end
88
+
89
+ it 'returns "Requires CalNet"' do
90
+ bib_number = 'b24659129'
91
+ stub_sru_request(bib_number)
92
+ metadata = Metadata.for_record(record_id: bib_number)
93
+ expect(metadata.calnet_or_ip?).to eq(true)
94
+ expect(metadata.calnet_only?).to eq(true)
95
+ end
96
+
97
+ it 'returns "Freely available" for unrestricted audio' do
98
+ bib_number = 'b23161018'
99
+ stub_sru_request(bib_number)
100
+ metadata = Metadata.for_record(record_id: bib_number)
101
+ expect(metadata.calnet_or_ip?).to eq(false)
102
+ expect(metadata.calnet_only?).to eq(false)
103
+ end
104
+
105
+ it 'extracts UCB restrictions from a TIND 856' do
106
+ marc_record = MARC::XMLReader.new('spec/data/record-(cityarts)00002.xml').first
107
+ metadata = Metadata.new(record_id: 'record-(cityarts)00002', source: Metadata::Source::TIND, marc_record:)
108
+ expect(metadata.calnet_or_ip?).to eq(true)
109
+ expect(metadata.calnet_only?).to eq(false)
110
+ end
111
+
112
+ it 'extracts UCB restrictions from an Alma 956' do
113
+ marc_record = MARC::XMLReader.new('spec/data/alma/991054360089706532-sru.xml').first
114
+ metadata = Metadata.new(record_id: '991047179369706532', source: Metadata::Source::ALMA, marc_record:)
115
+ expect(metadata.calnet_or_ip?).to eq(true)
116
+ expect(metadata.calnet_only?).to eq(false)
117
+ end
118
+
119
+ it 'extracts CalNet restrictions from an Alma 956' do
120
+ marc_record = MARC::XMLReader.new('spec/data/alma/991047179369706532-sru.xml').first
121
+ metadata = Metadata.new(record_id: '991054360089706532', source: Metadata::Source::ALMA, marc_record:)
122
+ expect(metadata.calnet_or_ip?).to eq(true)
123
+ expect(metadata.calnet_only?).to eq(true)
124
+ end
125
+
126
+ it 'extracts restrictions from a 998$r' do
127
+ marc_record = MARC::XMLReader.new('spec/data/alma/991005939359706532-sru.xml').first
128
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
129
+ expect(metadata.calnet_or_ip?).to eq(false) # just to be sure
130
+ expect(metadata.calnet_only?).to eq(false) # just to be sure
131
+
132
+ marc_record['998'].append(MARC::Subfield.new('r', 'UCB access. Requires CalNet.'))
133
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
134
+ expect(metadata.calnet_or_ip?).to eq(true)
135
+ expect(metadata.calnet_only?).to eq(true)
136
+ end
137
+
138
+ it 'extracts restrictions from multiple subfields 998$r' do
139
+ marc_record = MARC::XMLReader.new('spec/data/alma/991005939359706532-sru.xml').first
140
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
141
+ expect(metadata.calnet_or_ip?).to eq(false) # just to be sure
142
+ expect(metadata.calnet_only?).to eq(false) # just to be sure
143
+
144
+ marc_record['998'].append(MARC::Subfield.new('r', 'UCB access.'))
145
+ marc_record['998'].append(MARC::Subfield.new('r', 'Requires CalNet.'))
146
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
147
+ expect(metadata.calnet_or_ip?).to eq(true)
148
+ expect(metadata.calnet_only?).to eq(true)
149
+ end
150
+
151
+ it 'accepts "CalNet" anywhere in the 998$r' do
152
+ marc_record = MARC::XMLReader.new('spec/data/alma/991005939359706532-sru.xml').first
153
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
154
+ expect(metadata.calnet_or_ip?).to eq(false) # just to be sure
155
+ expect(metadata.calnet_only?).to eq(false) # just to be sure
156
+
157
+ marc_record['998'].append(MARC::Subfield.new('r', 'some string with CalNet in it somewhere'))
158
+ metadata = Metadata.new(record_id: '991005939359706532', source: Metadata::Source::ALMA, marc_record:)
159
+ expect(metadata.calnet_only?).to eq(true)
160
+ expect(metadata.calnet_or_ip?).to eq(false) # just to be sure
161
+ end
162
+ end
163
+
164
+ describe :values do
165
+
166
+ describe 'catalog link injection' do
167
+
168
+ it 'injects the catalog URL if not present' do
169
+ bib_number = 'b22139658'
170
+ stub_sru_request(bib_number)
171
+ metadata = Metadata.for_record(record_id: bib_number)
172
+
173
+ catalog_value = metadata.values_by_field[Metadata::Fields::CATALOG_LINK]
174
+ expected_links = [
175
+ Metadata::Link.new(
176
+ url: 'https://search.library.berkeley.edu/permalink/01UCS_BER/iqob43/alma991010948099706532',
177
+ body: AV::Metadata::Source::ALMA.catalog_link_text
178
+ )
179
+ ]
180
+ expect(catalog_value.entries).to contain_exactly(*expected_links)
181
+ end
182
+
183
+ it 'injects a TIND URL if not present (1/2)' do
184
+ tind_035 = '(miscmat)00615'
185
+ marc_xml = File.read("spec/data/record-#{tind_035}.xml")
186
+ search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
187
+ stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
188
+ metadata = Metadata.for_record(record_id: tind_035)
189
+
190
+ catalog_value = metadata.values_by_field[Metadata::Fields::CATALOG_LINK]
191
+ expected_links = [
192
+ Metadata::Link.new(
193
+ url: 'https://digicoll.lib.berkeley.edu/record/22513',
194
+ body: Metadata::Source::TIND.catalog_link_text
195
+ )
196
+ ]
197
+ expect(catalog_value.entries).to contain_exactly(*expected_links)
198
+ end
199
+
200
+ it 'injects a TIND URL if not present (2/2)' do
201
+ tind_035 = 'physcolloquia-bk00169017b'
202
+ marc_xml = File.read("spec/data/record-#{tind_035}.xml")
203
+ search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
204
+ stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
205
+ metadata = Metadata.for_record(record_id: tind_035)
206
+
207
+ catalog_value = metadata.values_by_field[Metadata::Fields::CATALOG_LINK]
208
+ expected_links = [
209
+ Metadata::Link.new(
210
+ url: 'https://digicoll.lib.berkeley.edu/record/21937',
211
+ body: Metadata::Source::TIND.catalog_link_text
212
+ )
213
+ ]
214
+ expect(catalog_value.entries).to contain_exactly(*expected_links)
215
+ end
216
+
217
+ # TODO: suppress these?
218
+ it 'works for TIND records with OskiCat URLs' do
219
+ tind_035 = '(pacradio)00107'
220
+ marc_xml = File.read("spec/data/record-#{tind_035}.xml")
221
+ search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
222
+ stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
223
+ metadata = Metadata.for_record(record_id: tind_035)
224
+
225
+ catalog_value = metadata.values_by_field[Metadata::Fields::CATALOG_LINK]
226
+ expected_links = [
227
+ Metadata::Link.new(
228
+ url: 'http://oskicat.berkeley.edu/record=b23305516',
229
+ body: 'View library catalog record.'
230
+ ),
231
+ Metadata::Link.new(
232
+ url: 'https://digicoll.lib.berkeley.edu/record/19816',
233
+ body: Metadata::Source::TIND.catalog_link_text
234
+ )
235
+ ]
236
+ expect(catalog_value.entries).to contain_exactly(*expected_links)
237
+ end
238
+
239
+ it 'works for TIND-only records' do
240
+ tind_035 = 'physcolloquia-bk00169017b'
241
+ marc_xml = File.read("spec/data/record-#{tind_035}.xml")
242
+ search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
243
+ stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
244
+ metadata = Metadata.for_record(record_id: tind_035)
245
+
246
+ catalog_value = metadata.values_by_field[Metadata::Fields::CATALOG_LINK]
247
+ expected_links = [
248
+ Metadata::Link.new(
249
+ body: Metadata::Source::TIND.catalog_link_text,
250
+ url: 'https://digicoll.lib.berkeley.edu/record/21937'
251
+ )
252
+ ]
253
+ expect(catalog_value.entries).to contain_exactly(*expected_links)
254
+ end
255
+
256
+ end
257
+
258
+ describe :each_value do
259
+ it 'returns the values' do
260
+ tind_035 = 'physcolloquia-bk00169017b'
261
+ marc_xml = File.read("spec/data/record-#{tind_035}.xml")
262
+ search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
263
+ stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
264
+ metadata = Metadata.for_record(record_id: tind_035)
265
+
266
+ expected_values = metadata.values_by_field.values
267
+ actual_values = metadata.each_value.to_a
268
+ expect(actual_values).to eq(expected_values)
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end