berkeley_library-av-core 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.dockerignore +391 -0
- data/.github/workflows/build.yml +30 -0
- data/.gitignore +388 -0
- data/.idea/av_core.iml +146 -0
- data/.idea/codeStyles/Project.xml +12 -0
- data/.idea/codeStyles/codeStyleConfig.xml +5 -0
- data/.idea/go.imports.xml +6 -0
- data/.idea/inspectionProfiles/Project_Default.xml +37 -0
- data/.idea/misc.xml +6 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.rubocop.yml +241 -0
- data/.ruby-version +1 -0
- data/.simplecov +8 -0
- data/CHANGES.md +38 -0
- data/Gemfile +3 -0
- data/Jenkinsfile +16 -0
- data/LICENSE.md +21 -0
- data/README.md +20 -0
- data/Rakefile +20 -0
- data/av_core.gemspec +49 -0
- data/lib/berkeley_library/av/config.rb +238 -0
- data/lib/berkeley_library/av/constants.rb +30 -0
- data/lib/berkeley_library/av/core/module_info.rb +18 -0
- data/lib/berkeley_library/av/core.rb +7 -0
- data/lib/berkeley_library/av/marc/util.rb +114 -0
- data/lib/berkeley_library/av/marc.rb +52 -0
- data/lib/berkeley_library/av/metadata/README.md +5 -0
- data/lib/berkeley_library/av/metadata/field.rb +110 -0
- data/lib/berkeley_library/av/metadata/fields.rb +130 -0
- data/lib/berkeley_library/av/metadata/link.rb +28 -0
- data/lib/berkeley_library/av/metadata/readers/alma.rb +54 -0
- data/lib/berkeley_library/av/metadata/readers/base.rb +53 -0
- data/lib/berkeley_library/av/metadata/readers/tind.rb +52 -0
- data/lib/berkeley_library/av/metadata/readers.rb +2 -0
- data/lib/berkeley_library/av/metadata/source.rb +93 -0
- data/lib/berkeley_library/av/metadata/tind_html_metadata_da.json +2076 -0
- data/lib/berkeley_library/av/metadata/value.rb +121 -0
- data/lib/berkeley_library/av/metadata.rb +103 -0
- data/lib/berkeley_library/av/record.rb +86 -0
- data/lib/berkeley_library/av/record_id.rb +121 -0
- data/lib/berkeley_library/av/record_not_found.rb +7 -0
- data/lib/berkeley_library/av/restrictions.rb +36 -0
- data/lib/berkeley_library/av/track.rb +132 -0
- data/lib/berkeley_library/av/types/duration.rb +67 -0
- data/lib/berkeley_library/av/types/file_type.rb +84 -0
- data/lib/berkeley_library/av/util.rb +65 -0
- data/rakelib/bundle.rake +8 -0
- data/rakelib/coverage.rake +11 -0
- data/rakelib/gem.rake +54 -0
- data/rakelib/rubocop.rake +18 -0
- data/rakelib/spec.rake +12 -0
- data/spec/.rubocop.yml +116 -0
- data/spec/data/10.23.19.JessieLaCavalier.02.mrc +3 -0
- data/spec/data/alma/991005939359706532-sru.xml +123 -0
- data/spec/data/alma/991034756419706532-sru.xml +162 -0
- data/spec/data/alma/991047179369706532-sru.xml +210 -0
- data/spec/data/alma/991054360089706532-sru.xml +186 -0
- data/spec/data/alma/b11082434-sru.xml +165 -0
- data/spec/data/alma/b18538031-sru.xml +123 -0
- data/spec/data/alma/b20786580-sru.xml +123 -0
- data/spec/data/alma/b22139647-sru.xml +171 -0
- data/spec/data/alma/b22139658-sru.xml +282 -0
- data/spec/data/alma/b23161018-sru.xml +182 -0
- data/spec/data/alma/b23305522-sru.xml +144 -0
- data/spec/data/alma/b24071548-sru.xml +136 -0
- data/spec/data/alma/b24659129-sru.xml +210 -0
- data/spec/data/alma/b25207857-sru.xml +217 -0
- data/spec/data/alma/b25716973-sru.xml +186 -0
- data/spec/data/alma/b25742488-sru.xml +246 -0
- data/spec/data/record-(cityarts)00002.xml +78 -0
- data/spec/data/record-(cityarts)00773.xml +94 -0
- data/spec/data/record-(clir)00020.xml +153 -0
- data/spec/data/record-(miscmat)00615.xml +45 -0
- data/spec/data/record-(pacradio)00107.xml +85 -0
- data/spec/data/record-(pacradio)01469.xml +82 -0
- data/spec/data/record-empty-result.xml +4 -0
- data/spec/data/record-multiple-998s-disordered.xml +178 -0
- data/spec/data/record-multiple-998s.xml +178 -0
- data/spec/data/record-physcolloquia-bk00169017b.xml +78 -0
- data/spec/data/record-ragged-998-subfields.xml +122 -0
- data/spec/data/record-ragged-998s-multiple-fields.xml +160 -0
- data/spec/data/record-redirect-to-login.html +288 -0
- data/spec/data/record_id/bibs_with_check_digits.txt +151 -0
- data/spec/data/search-1993.xml +158 -0
- data/spec/data/search-b23305516.xml +81 -0
- data/spec/lib/berkeley_library/av/av_spec.rb +12 -0
- data/spec/lib/berkeley_library/av/config_spec.rb +250 -0
- data/spec/lib/berkeley_library/av/marc/util_spec.rb +150 -0
- data/spec/lib/berkeley_library/av/marc_spec.rb +62 -0
- data/spec/lib/berkeley_library/av/metadata/field_spec.rb +81 -0
- data/spec/lib/berkeley_library/av/metadata/fields_spec.rb +180 -0
- data/spec/lib/berkeley_library/av/metadata/metadata_spec.rb +274 -0
- data/spec/lib/berkeley_library/av/metadata/source_spec.rb +261 -0
- data/spec/lib/berkeley_library/av/metadata/value_spec.rb +29 -0
- data/spec/lib/berkeley_library/av/record_id_spec.rb +72 -0
- data/spec/lib/berkeley_library/av/record_spec.rb +284 -0
- data/spec/lib/berkeley_library/av/track_spec.rb +335 -0
- data/spec/lib/berkeley_library/av/types/duration_spec.rb +91 -0
- data/spec/lib/berkeley_library/av/types/file_type_spec.rb +98 -0
- data/spec/lib/berkeley_library/av/util_spec.rb +30 -0
- data/spec/spec_helper.rb +63 -0
- metadata +499 -0
@@ -0,0 +1,335 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module AV
|
5
|
+
describe Track do
|
6
|
+
|
7
|
+
describe :file_type do
|
8
|
+
it 'extrapolates from path' do
|
9
|
+
track = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
10
|
+
expect(track.file_type).to eq(AV::Types::FileType::MP3)
|
11
|
+
|
12
|
+
track = Track.new(sort_order: 1, path: 'mrc/6927.mp4')
|
13
|
+
expect(track.file_type).to eq(AV::Types::FileType::MP4)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe :inspect do
|
18
|
+
it 'does something useful' do
|
19
|
+
track = Track.new(sort_order: 0, title: 'Part 1', path: 'MRCAudio/frost-read1.mp3', duration: AV::Types::Duration.from_string('01:02:29'))
|
20
|
+
result = track.inspect
|
21
|
+
expect(result).to include(Track.name)
|
22
|
+
expect(result).to include(track.to_s)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe :<=> do
|
27
|
+
it 'treats object as equal to itself' do
|
28
|
+
track = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
29
|
+
expect(track == track).to eq(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'treats object as equal to identical object' do
|
33
|
+
t1 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
34
|
+
t2 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
35
|
+
expect(t1 == t2).to eq(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'sorts by sort order' do
|
39
|
+
t1 = Track.new(sort_order: 3, title: 'Part 2', path: 'frost-read2.mp3')
|
40
|
+
t2 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
41
|
+
expect(t1 > t2).to eq(true)
|
42
|
+
expect(t2 < t1).to eq(true)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'sorts by title' do
|
46
|
+
t1 = Track.new(sort_order: 2, title: 'Part 3', path: 'frost-read2.mp3')
|
47
|
+
t2 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
48
|
+
expect(t1 > t2).to eq(true)
|
49
|
+
expect(t2 < t1).to eq(true)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'sorts by path' do
|
53
|
+
t1 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp4')
|
54
|
+
t2 = Track.new(sort_order: 2, title: 'Part 2', path: 'frost-read2.mp3')
|
55
|
+
expect(t1 > t2).to eq(true)
|
56
|
+
expect(t2 < t1).to eq(true)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns nil for nil' do
|
60
|
+
track = Track.new(sort_order: 1, path: 'mrc/6927.mp4')
|
61
|
+
expect(track <=> nil).to be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns nil for things that are not Tracks' do
|
65
|
+
track = Track.new(sort_order: 1, path: 'mrc/6927.mp4')
|
66
|
+
expect(track <=> track.to_s).to be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :to_s do
|
71
|
+
it 'includes all relevant info' do
|
72
|
+
track_params = {
|
73
|
+
sort_order: 19,
|
74
|
+
title: 'reel 20, part 1',
|
75
|
+
path: 'MRCAudio/C040791201_1.mp3',
|
76
|
+
duration: AV::Types::Duration.from_string('00:40:12')
|
77
|
+
}
|
78
|
+
track_str = Track.new(**track_params).to_s
|
79
|
+
track_params.each_value do |v|
|
80
|
+
expect(track_str).to include(v.to_s)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe :to_marc_subfields do
|
86
|
+
it 'returns the MARC subfields' do
|
87
|
+
track = Track.new(
|
88
|
+
sort_order: 0,
|
89
|
+
title: 'reel 1, part 1',
|
90
|
+
path: 'MRCAudio/C040790863_1.mp3',
|
91
|
+
duration: AV::Types::Duration.from_string('00:47:49')
|
92
|
+
)
|
93
|
+
marc_subfields = track.to_marc_subfields
|
94
|
+
expect(marc_subfields.size).to eq(3)
|
95
|
+
|
96
|
+
duration_subfield = marc_subfields[0]
|
97
|
+
expect(duration_subfield.code).to eq(AV::Constants::SUBFIELD_CODE_DURATION)
|
98
|
+
expect(duration_subfield.value).to eq(track.duration.to_s)
|
99
|
+
|
100
|
+
title_subfield = marc_subfields[1]
|
101
|
+
expect(title_subfield.code).to eq(AV::Constants::SUBFIELD_CODE_TITLE)
|
102
|
+
expect(title_subfield.value).to eq(track.title)
|
103
|
+
|
104
|
+
path_subfield = marc_subfields[2]
|
105
|
+
expect(path_subfield.code).to eq(AV::Constants::SUBFIELD_CODE_PATH)
|
106
|
+
expect(path_subfield.value).to eq(track.path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe :tracks_from do
|
111
|
+
it 'reads the tracks' do
|
112
|
+
expected_tracks = [
|
113
|
+
Track.new(sort_order: 0, title: 'reel 1, part 1', path: 'MRCAudio/C040790863_1.mp3', duration: AV::Types::Duration.from_string('00:47:49')),
|
114
|
+
Track.new(sort_order: 1, title: 'reel 2, part 1', path: 'MRCAudio/C040790960_1.mp3', duration: AV::Types::Duration.from_string('00:23:29')),
|
115
|
+
Track.new(sort_order: 2, title: 'reel 3, part 1', path: 'MRCAudio/C040791061_1.mp3', duration: AV::Types::Duration.from_string('00:22:56')),
|
116
|
+
Track.new(sort_order: 3, title: 'reel 4, part 1', path: 'MRCAudio/C040791168_1.mp3', duration: AV::Types::Duration.from_string('00:21:46')),
|
117
|
+
Track.new(sort_order: 4, title: 'reel 5, part 1', path: 'MRCAudio/C040790872_1.mp3', duration: AV::Types::Duration.from_string('00:24:19')),
|
118
|
+
Track.new(sort_order: 5, title: 'reel 6, part 1', path: 'MRCAudio/C040790979_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
119
|
+
Track.new(sort_order: 6, title: 'reel 7, part 1', path: 'MRCAudio/C040791070_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
120
|
+
Track.new(sort_order: 7, title: 'reel 8, part 1', path: 'MRCAudio/C040791177_1.mp3', duration: AV::Types::Duration.from_string('00:23:23')),
|
121
|
+
Track.new(sort_order: 8, title: 'reel 9, part 1', path: 'MRCAudio/C040790881_1.mp3', duration: AV::Types::Duration.from_string('00:20:01')),
|
122
|
+
Track.new(sort_order: 9, title: 'reel 10', path: 'MRCAudio/C040790988.mp3', duration: AV::Types::Duration.from_string('00:22:38')),
|
123
|
+
Track.new(sort_order: 10, title: 'reel 11', path: 'MRCAudio/C040791089.mp3', duration: AV::Types::Duration.from_string('00:23:44')),
|
124
|
+
Track.new(sort_order: 11, title: 'reel 12', path: 'MRCAudio/C040791186.mp3', duration: AV::Types::Duration.from_string('00:22:27')),
|
125
|
+
Track.new(sort_order: 12, title: 'reel 13, part 1', path: 'MRCAudio/C040790890_1.mp3',
|
126
|
+
duration: AV::Types::Duration.from_string('00:21:57')),
|
127
|
+
Track.new(sort_order: 13, title: 'reel 14, part 1', path: 'MRCAudio/C040790997_1.mp3',
|
128
|
+
duration: AV::Types::Duration.from_string('00:44:28')),
|
129
|
+
Track.new(sort_order: 14, title: 'reel 15, part 1', path: 'MRCAudio/C040791098_1.mp3',
|
130
|
+
duration: AV::Types::Duration.from_string('00:44:33')),
|
131
|
+
Track.new(sort_order: 15, title: 'reel 16, part 1', path: 'MRCAudio/C040790906_1.mp3',
|
132
|
+
duration: AV::Types::Duration.from_string('00:44:01')),
|
133
|
+
Track.new(sort_order: 16, title: 'reel 17, part 1', path: 'MRCAudio/C040791007_1.mp3',
|
134
|
+
duration: AV::Types::Duration.from_string('00:46:58')),
|
135
|
+
Track.new(sort_order: 17, title: 'reel 18, part 1', path: 'MRCAudio/C040791104_1.mp3',
|
136
|
+
duration: AV::Types::Duration.from_string('00:42:49')),
|
137
|
+
Track.new(sort_order: 18, title: 'reel 19, part 1', path: 'MRCAudio/C040791195_1.mp3',
|
138
|
+
duration: AV::Types::Duration.from_string('00:44:35')),
|
139
|
+
Track.new(sort_order: 19, title: 'reel 20, part 1', path: 'MRCAudio/C040791201_1.mp3',
|
140
|
+
duration: AV::Types::Duration.from_string('00:40:12'))
|
141
|
+
]
|
142
|
+
|
143
|
+
bib_number = 'b23161018'
|
144
|
+
marc_record = alma_marc_record_for(bib_number)
|
145
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
146
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
147
|
+
aggregate_failures 'tracks' do
|
148
|
+
tracks.each_with_index do |track, i|
|
149
|
+
expect(track).to eq(expected_tracks[i])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'reads tracks from multiple 998s' do
|
155
|
+
expected_tracks = [
|
156
|
+
Track.new(sort_order: 0, title: 'reel 1, part 1', path: 'MRCAudio/C040790863_1.mp3', duration: AV::Types::Duration.from_string('00:47:49')),
|
157
|
+
Track.new(sort_order: 1, title: 'reel 2, part 1', path: 'MRCAudio/C040790960_1.mp3', duration: AV::Types::Duration.from_string('00:23:29')),
|
158
|
+
Track.new(sort_order: 2, title: 'reel 3, part 1', path: 'MRCAudio/C040791061_1.mp3', duration: AV::Types::Duration.from_string('00:22:56')),
|
159
|
+
Track.new(sort_order: 3, title: 'reel 4, part 1', path: 'MRCAudio/C040791168_1.mp3', duration: AV::Types::Duration.from_string('00:21:46')),
|
160
|
+
Track.new(sort_order: 4, title: 'reel 5, part 1', path: 'MRCAudio/C040790872_1.mp3', duration: AV::Types::Duration.from_string('00:24:19')),
|
161
|
+
Track.new(sort_order: 5, title: 'reel 6, part 1', path: 'MRCAudio/C040790979_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
162
|
+
Track.new(sort_order: 6, title: 'reel 7, part 1', path: 'MRCAudio/C040791070_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
163
|
+
Track.new(sort_order: 7, title: 'reel 8, part 1', path: 'MRCAudio/C040791177_1.mp3', duration: AV::Types::Duration.from_string('00:23:23')),
|
164
|
+
Track.new(sort_order: 8, title: 'reel 9, part 1', path: 'MRCAudio/C040790881_1.mp3', duration: AV::Types::Duration.from_string('00:20:01')),
|
165
|
+
Track.new(sort_order: 9, title: 'reel 10', path: 'MRCAudio/C040790988.mp3', duration: AV::Types::Duration.from_string('00:22:38')),
|
166
|
+
Track.new(sort_order: 10, title: 'reel 11', path: 'MRCAudio/C040791089.mp3', duration: AV::Types::Duration.from_string('00:23:44')),
|
167
|
+
Track.new(sort_order: 11, title: 'reel 12', path: 'MRCAudio/C040791186.mp3', duration: AV::Types::Duration.from_string('00:22:27')),
|
168
|
+
Track.new(sort_order: 12, title: 'reel 13, part 1', path: 'MRCAudio/C040790890_1.mp3',
|
169
|
+
duration: AV::Types::Duration.from_string('00:21:57')),
|
170
|
+
Track.new(sort_order: 13, title: 'reel 14, part 1', path: 'MRCAudio/C040790997_1.mp3',
|
171
|
+
duration: AV::Types::Duration.from_string('00:44:28')),
|
172
|
+
Track.new(sort_order: 14, title: 'reel 15, part 1', path: 'MRCAudio/C040791098_1.mp3',
|
173
|
+
duration: AV::Types::Duration.from_string('00:44:33')),
|
174
|
+
Track.new(sort_order: 15, title: 'reel 16, part 1', path: 'MRCAudio/C040790906_1.mp3',
|
175
|
+
duration: AV::Types::Duration.from_string('00:44:01')),
|
176
|
+
Track.new(sort_order: 16, title: 'reel 17, part 1', path: 'MRCAudio/C040791007_1.mp3',
|
177
|
+
duration: AV::Types::Duration.from_string('00:46:58')),
|
178
|
+
Track.new(sort_order: 17, title: 'reel 18, part 1', path: 'MRCAudio/C040791104_1.mp3',
|
179
|
+
duration: AV::Types::Duration.from_string('00:42:49')),
|
180
|
+
Track.new(sort_order: 18, title: 'reel 19, part 1', path: 'MRCAudio/C040791195_1.mp3',
|
181
|
+
duration: AV::Types::Duration.from_string('00:44:35')),
|
182
|
+
Track.new(sort_order: 19, title: 'reel 20, part 1', path: 'MRCAudio/C040791201_1.mp3',
|
183
|
+
duration: AV::Types::Duration.from_string('00:40:12'))
|
184
|
+
]
|
185
|
+
|
186
|
+
marc_record = AV::Marc.from_xml(File.read('spec/data/record-multiple-998s.xml'))
|
187
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
188
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
189
|
+
aggregate_failures 'tracks' do
|
190
|
+
tracks.each_with_index do |track, i|
|
191
|
+
expect(track).to eq(expected_tracks[i])
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'accepts disordered fields in multiple 998s' do
|
197
|
+
expected_tracks = [
|
198
|
+
Track.new(sort_order: 0, title: 'reel 1, part 1', path: 'MRCAudio/C040790863_1.mp3', duration: AV::Types::Duration.from_string('00:47:49')),
|
199
|
+
Track.new(sort_order: 1, title: 'reel 2, part 1', path: 'MRCAudio/C040790960_1.mp3', duration: AV::Types::Duration.from_string('00:23:29')),
|
200
|
+
Track.new(sort_order: 2, title: 'reel 3, part 1', path: 'MRCAudio/C040791061_1.mp3', duration: AV::Types::Duration.from_string('00:22:56')),
|
201
|
+
Track.new(sort_order: 3, title: 'reel 4, part 1', path: 'MRCAudio/C040791168_1.mp3', duration: AV::Types::Duration.from_string('00:21:46')),
|
202
|
+
Track.new(sort_order: 4, title: 'reel 5, part 1', path: 'MRCAudio/C040790872_1.mp3', duration: AV::Types::Duration.from_string('00:24:19')),
|
203
|
+
Track.new(sort_order: 5, title: 'reel 6, part 1', path: 'MRCAudio/C040790979_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
204
|
+
Track.new(sort_order: 6, title: 'reel 7, part 1', path: 'MRCAudio/C040791070_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
205
|
+
Track.new(sort_order: 7, title: 'reel 8, part 1', path: 'MRCAudio/C040791177_1.mp3', duration: AV::Types::Duration.from_string('00:23:23')),
|
206
|
+
Track.new(sort_order: 8, title: 'reel 9, part 1', path: 'MRCAudio/C040790881_1.mp3', duration: AV::Types::Duration.from_string('00:20:01')),
|
207
|
+
Track.new(sort_order: 9, title: 'reel 10', path: 'MRCAudio/C040790988.mp3', duration: AV::Types::Duration.from_string('00:22:38')),
|
208
|
+
Track.new(sort_order: 10, title: 'reel 11', path: 'MRCAudio/C040791089.mp3', duration: AV::Types::Duration.from_string('00:23:44')),
|
209
|
+
Track.new(sort_order: 11, title: 'reel 12', path: 'MRCAudio/C040791186.mp3', duration: AV::Types::Duration.from_string('00:22:27')),
|
210
|
+
Track.new(sort_order: 12, title: 'reel 13, part 1', path: 'MRCAudio/C040790890_1.mp3',
|
211
|
+
duration: AV::Types::Duration.from_string('00:21:57')),
|
212
|
+
Track.new(sort_order: 13, title: 'reel 14, part 1', path: 'MRCAudio/C040790997_1.mp3',
|
213
|
+
duration: AV::Types::Duration.from_string('00:44:28')),
|
214
|
+
Track.new(sort_order: 14, title: 'reel 15, part 1', path: 'MRCAudio/C040791098_1.mp3',
|
215
|
+
duration: AV::Types::Duration.from_string('00:44:33')),
|
216
|
+
Track.new(sort_order: 15, title: 'reel 16, part 1', path: 'MRCAudio/C040790906_1.mp3',
|
217
|
+
duration: AV::Types::Duration.from_string('00:44:01')),
|
218
|
+
Track.new(sort_order: 16, title: 'reel 17, part 1', path: 'MRCAudio/C040791007_1.mp3',
|
219
|
+
duration: AV::Types::Duration.from_string('00:46:58')),
|
220
|
+
Track.new(sort_order: 17, title: 'reel 18, part 1', path: 'MRCAudio/C040791104_1.mp3',
|
221
|
+
duration: AV::Types::Duration.from_string('00:42:49')),
|
222
|
+
Track.new(sort_order: 18, title: 'reel 19, part 1', path: 'MRCAudio/C040791195_1.mp3',
|
223
|
+
duration: AV::Types::Duration.from_string('00:44:35')),
|
224
|
+
Track.new(sort_order: 19, title: 'reel 20, part 1', path: 'MRCAudio/C040791201_1.mp3',
|
225
|
+
duration: AV::Types::Duration.from_string('00:40:12'))
|
226
|
+
]
|
227
|
+
|
228
|
+
marc_record = AV::Marc.from_xml(File.read('spec/data/record-multiple-998s-disordered.xml'))
|
229
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
230
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
231
|
+
aggregate_failures 'tracks' do
|
232
|
+
tracks.each_with_index do |track, i|
|
233
|
+
expect(track).to eq(expected_tracks[i])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'accepts ragged subfields in multiple 998s' do
|
239
|
+
expected_tracks = [
|
240
|
+
Track.new(sort_order: 0, path: 'MRCAudio/C040790863_1.mp3', duration: AV::Types::Duration.from_string('00:47:49')),
|
241
|
+
Track.new(sort_order: 1, path: 'MRCAudio/C040790960_1.mp3', duration: AV::Types::Duration.from_string('00:23:29')),
|
242
|
+
Track.new(sort_order: 2, path: 'MRCAudio/C040791061_1.mp3', duration: AV::Types::Duration.from_string('00:22:56')),
|
243
|
+
Track.new(sort_order: 3, path: 'MRCAudio/C040791168_1.mp3', duration: AV::Types::Duration.from_string('00:21:46')),
|
244
|
+
Track.new(sort_order: 4, path: 'MRCAudio/C040790872_1.mp3', duration: AV::Types::Duration.from_string('00:24:19')),
|
245
|
+
Track.new(sort_order: 5, path: 'MRCAudio/C040790979_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
246
|
+
Track.new(sort_order: 6, path: 'MRCAudio/C040791070_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
247
|
+
Track.new(sort_order: 7, path: 'MRCAudio/C040791177_1.mp3', duration: AV::Types::Duration.from_string('00:23:23')),
|
248
|
+
Track.new(sort_order: 8, path: 'MRCAudio/C040790881_1.mp3', duration: AV::Types::Duration.from_string('00:20:01')),
|
249
|
+
Track.new(sort_order: 9, path: 'MRCAudio/C040790988.mp3', duration: AV::Types::Duration.from_string('00:22:38')),
|
250
|
+
Track.new(sort_order: 10, title: 'reel 11', path: 'MRCAudio/C040791089.mp3'),
|
251
|
+
Track.new(sort_order: 11, title: 'reel 12', path: 'MRCAudio/C040791186.mp3'),
|
252
|
+
Track.new(sort_order: 12, title: 'reel 13, part 1', path: 'MRCAudio/C040790890_1.mp3'),
|
253
|
+
Track.new(sort_order: 13, title: 'reel 14, part 1', path: 'MRCAudio/C040790997_1.mp3'),
|
254
|
+
Track.new(sort_order: 14, title: 'reel 15, part 1', path: 'MRCAudio/C040791098_1.mp3'),
|
255
|
+
Track.new(sort_order: 15, title: 'reel 16, part 1', path: 'MRCAudio/C040790906_1.mp3'),
|
256
|
+
Track.new(sort_order: 16, title: 'reel 17, part 1', path: 'MRCAudio/C040791007_1.mp3'),
|
257
|
+
Track.new(sort_order: 17, title: 'reel 18, part 1', path: 'MRCAudio/C040791104_1.mp3'),
|
258
|
+
Track.new(sort_order: 18, title: 'reel 19, part 1', path: 'MRCAudio/C040791195_1.mp3'),
|
259
|
+
Track.new(sort_order: 19, title: 'reel 20, part 1', path: 'MRCAudio/C040791201_1.mp3')
|
260
|
+
]
|
261
|
+
|
262
|
+
marc_record = AV::Marc.from_xml(File.read('spec/data/record-ragged-998s-multiple-fields.xml'))
|
263
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
264
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
265
|
+
aggregate_failures 'tracks' do
|
266
|
+
tracks.each_with_index do |track, i|
|
267
|
+
expect(track).to eq(expected_tracks[i])
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'accepts ragged subfields in a single 998 if ordered correctly' do
|
273
|
+
expected_tracks = [
|
274
|
+
Track.new(sort_order: 0, path: 'MRCAudio/C040790863_1.mp3', duration: AV::Types::Duration.from_string('00:47:49')),
|
275
|
+
Track.new(sort_order: 1, path: 'MRCAudio/C040790960_1.mp3', duration: AV::Types::Duration.from_string('00:23:29')),
|
276
|
+
Track.new(sort_order: 2, path: 'MRCAudio/C040791061_1.mp3', duration: AV::Types::Duration.from_string('00:22:56')),
|
277
|
+
Track.new(sort_order: 3, path: 'MRCAudio/C040791168_1.mp3', duration: AV::Types::Duration.from_string('00:21:46')),
|
278
|
+
Track.new(sort_order: 4, path: 'MRCAudio/C040790872_1.mp3', duration: AV::Types::Duration.from_string('00:24:19')),
|
279
|
+
Track.new(sort_order: 5, path: 'MRCAudio/C040790979_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
280
|
+
Track.new(sort_order: 6, path: 'MRCAudio/C040791070_1.mp3', duration: AV::Types::Duration.from_string('00:24:18')),
|
281
|
+
Track.new(sort_order: 7, path: 'MRCAudio/C040791177_1.mp3', duration: AV::Types::Duration.from_string('00:23:23')),
|
282
|
+
Track.new(sort_order: 8, path: 'MRCAudio/C040790881_1.mp3', duration: AV::Types::Duration.from_string('00:20:01')),
|
283
|
+
Track.new(sort_order: 9, path: 'MRCAudio/C040790988.mp3', duration: AV::Types::Duration.from_string('00:22:38')),
|
284
|
+
Track.new(sort_order: 10, title: 'reel 11', path: 'MRCAudio/C040791089.mp3'),
|
285
|
+
Track.new(sort_order: 11, title: 'reel 12', path: 'MRCAudio/C040791186.mp3'),
|
286
|
+
Track.new(sort_order: 12, title: 'reel 13, part 1', path: 'MRCAudio/C040790890_1.mp3'),
|
287
|
+
Track.new(sort_order: 13, title: 'reel 14, part 1', path: 'MRCAudio/C040790997_1.mp3'),
|
288
|
+
Track.new(sort_order: 14, title: 'reel 15, part 1', path: 'MRCAudio/C040791098_1.mp3'),
|
289
|
+
Track.new(sort_order: 15, title: 'reel 16, part 1', path: 'MRCAudio/C040790906_1.mp3'),
|
290
|
+
Track.new(sort_order: 16, title: 'reel 17, part 1', path: 'MRCAudio/C040791007_1.mp3'),
|
291
|
+
Track.new(sort_order: 17, title: 'reel 18, part 1', path: 'MRCAudio/C040791104_1.mp3'),
|
292
|
+
Track.new(sort_order: 18, title: 'reel 19, part 1', path: 'MRCAudio/C040791195_1.mp3'),
|
293
|
+
Track.new(sort_order: 19, title: 'reel 20, part 1', path: 'MRCAudio/C040791201_1.mp3')
|
294
|
+
]
|
295
|
+
|
296
|
+
marc_record = AV::Marc.from_xml(File.read('spec/data/record-ragged-998-subfields.xml'))
|
297
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
298
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
299
|
+
aggregate_failures 'tracks' do
|
300
|
+
tracks.each_with_index do |track, i|
|
301
|
+
expect(track).to eq(expected_tracks[i])
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'handles records with no tracks' do
|
307
|
+
bib_number = 'b23161018'
|
308
|
+
marc_record = alma_marc_record_for(bib_number)
|
309
|
+
marc_record.fields.reject! { |df| df.tag == AV::Constants::TAG_TRACK_FIELD }
|
310
|
+
|
311
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
312
|
+
expect(tracks).to eq([])
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'handles tracks with spaces' do
|
316
|
+
expected_tracks = [
|
317
|
+
Track.new(sort_order: 0, title: 'Part 1', path: 'MRCAudio/frost-read1.mp3', duration: AV::Types::Duration.from_string('01:02:29')),
|
318
|
+
Track.new(sort_order: 1, title: 'Part 2', path: 'MRCAudio/frost-read2.mp3', duration: AV::Types::Duration.from_string('00:28:58'))
|
319
|
+
]
|
320
|
+
|
321
|
+
bib_number = 'b11082434'
|
322
|
+
marc_record = alma_marc_record_for(bib_number)
|
323
|
+
|
324
|
+
tracks = Track.tracks_from(marc_record, collection: 'MRCAudio')
|
325
|
+
expect(tracks.size).to eq(expected_tracks.size)
|
326
|
+
aggregate_failures 'tracks' do
|
327
|
+
tracks.each_with_index do |track, i|
|
328
|
+
expect(track).to eq(expected_tracks[i])
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module AV
|
5
|
+
module Types
|
6
|
+
describe Duration do
|
7
|
+
describe :from_string do
|
8
|
+
it 'parses HH:MM:SS' do
|
9
|
+
duration = Duration.from_string('12:34:56')
|
10
|
+
expect(duration).not_to be_nil
|
11
|
+
expect(duration.hours).to eq(12)
|
12
|
+
expect(duration.minutes).to eq(34)
|
13
|
+
expect(duration.seconds).to eq(56)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'parses HHMMSS' do
|
17
|
+
duration = Duration.from_string('123456')
|
18
|
+
expect(duration).not_to be_nil
|
19
|
+
expect(duration.hours).to eq(12)
|
20
|
+
expect(duration.minutes).to eq(34)
|
21
|
+
expect(duration.seconds).to eq(56)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'parses H:MM:SS' do
|
25
|
+
duration = Duration.from_string('2:34:56')
|
26
|
+
expect(duration).not_to be_nil
|
27
|
+
expect(duration.hours).to eq(2)
|
28
|
+
expect(duration.minutes).to eq(34)
|
29
|
+
expect(duration.seconds).to eq(56)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'parses HMMSS' do
|
33
|
+
duration = Duration.from_string('23456')
|
34
|
+
expect(duration).not_to be_nil
|
35
|
+
expect(duration.hours).to eq(2)
|
36
|
+
expect(duration.minutes).to eq(34)
|
37
|
+
expect(duration.seconds).to eq(56)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'parses MM:SS' do
|
41
|
+
duration = Duration.from_string('34:56')
|
42
|
+
expect(duration).not_to be_nil
|
43
|
+
expect(duration.hours).to eq(0)
|
44
|
+
expect(duration.minutes).to eq(34)
|
45
|
+
expect(duration.seconds).to eq(56)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'parses MMSS' do
|
49
|
+
duration = Duration.from_string('3456')
|
50
|
+
expect(duration).not_to be_nil
|
51
|
+
expect(duration.hours).to eq(0)
|
52
|
+
expect(duration.minutes).to eq(34)
|
53
|
+
expect(duration.seconds).to eq(56)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns nil for garbage' do
|
57
|
+
duration = Duration.from_string('Not a duration')
|
58
|
+
expect(duration).to be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'handles whitespace' do
|
62
|
+
duration = Duration.from_string('00: 23:44')
|
63
|
+
expect(duration).not_to be_nil
|
64
|
+
expect(duration.hours).to eq(0)
|
65
|
+
expect(duration.minutes).to eq(23)
|
66
|
+
expect(duration.seconds).to eq(44)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :<=> do
|
71
|
+
it 'returns 0 for equivalent durations' do
|
72
|
+
d1 = Duration.from_string('00:34:56')
|
73
|
+
d2 = Duration.new(hours: 0, minutes: 34, seconds: 56)
|
74
|
+
expect(d1 <=> d2).to eq(0)
|
75
|
+
expect(d2 <=> d1).to eq(0)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns nil for nil' do
|
79
|
+
d = Duration.from_string('00:34:56')
|
80
|
+
expect(d <=> nil).to be_nil
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returs nil for things that are not durations' do
|
84
|
+
d = Duration.from_string('00:34:56')
|
85
|
+
expect(d <=> d.to_s).to be_nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module AV
|
5
|
+
module Types
|
6
|
+
describe FileType do
|
7
|
+
describe :mime_type do
|
8
|
+
it 'is correct' do
|
9
|
+
expected = {
|
10
|
+
FileType::MP3 => 'application/x-mpegURL',
|
11
|
+
FileType::MP4 => 'video/mp4',
|
12
|
+
FileType::UNKNOWN => 'application/octet-stream'
|
13
|
+
}
|
14
|
+
expected.each do |t, mt_expected|
|
15
|
+
expect(t.mime_type).to eq(mt_expected)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe :player_tag do
|
21
|
+
it 'is correct' do
|
22
|
+
expected = {
|
23
|
+
FileType::MP3 => 'audio',
|
24
|
+
FileType::MP4 => 'video',
|
25
|
+
FileType::UNKNOWN => 'object'
|
26
|
+
}
|
27
|
+
expected.each do |t, pt_expected|
|
28
|
+
expect(t.player_tag).to eq(pt_expected)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe :prefix do
|
34
|
+
it 'is correct' do
|
35
|
+
expected = {
|
36
|
+
FileType::MP3 => 'mp3',
|
37
|
+
FileType::MP4 => 'mp4',
|
38
|
+
FileType::UNKNOWN => 'unknown'
|
39
|
+
}
|
40
|
+
expected.each do |t, prefix_expected|
|
41
|
+
expect(t.prefix).to eq(prefix_expected)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe :label do
|
47
|
+
it 'is correct' do
|
48
|
+
expected = {
|
49
|
+
FileType::MP3 => 'Audio',
|
50
|
+
FileType::MP4 => 'Video',
|
51
|
+
FileType::UNKNOWN => 'Unknown'
|
52
|
+
}
|
53
|
+
expected.each do |t, pt_expected|
|
54
|
+
expect(t.label).to eq(pt_expected)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe :to_s do
|
60
|
+
it 'returns the value' do
|
61
|
+
FileType.each do |t|
|
62
|
+
expect(t.to_s).to eq(t.value.to_s)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe :for_path do
|
68
|
+
it 'identifies an MP3' do
|
69
|
+
expect(FileType.for_path('foo.mp3')).to eq(AV::Types::FileType::MP3)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'identifies an MP4' do
|
73
|
+
%w[.mp4 .f4v .mov .m4a .m4v .mp4a .mp4v .3gp .3g2].each do |ext|
|
74
|
+
expect(FileType.for_path("foo#{ext}")).to eq(AV::Types::FileType::MP4)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'returns UNKNOWN for nil' do
|
79
|
+
# noinspection RubyYardParamTypeMatch
|
80
|
+
expect(FileType.for_path(nil)).to eq(AV::Types::FileType::UNKNOWN)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns UNKNOWN for unknown types' do
|
84
|
+
expect(FileType.for_path('foo.txt')).to eq(AV::Types::FileType::UNKNOWN)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe :new do
|
89
|
+
it "doesn't allow duplicate extensions" do
|
90
|
+
expect { FileType.send(:new, :QT, 'video', 'video/qt', extensions: ['.mov']) }
|
91
|
+
.to raise_error(ArgumentError, /.mov/)
|
92
|
+
expect(defined? FileType::QT).to be_nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module AV
|
5
|
+
describe Util do
|
6
|
+
describe :do_get do
|
7
|
+
|
8
|
+
it 'sends a custom user-agent header' do
|
9
|
+
expected_ua = Util::DEFAULT_USER_AGENT
|
10
|
+
|
11
|
+
bib_number = 'b11082434'
|
12
|
+
url = alma_sru_url_for(bib_number)
|
13
|
+
data_path = alma_sru_data_path_for(bib_number)
|
14
|
+
body = File.read(data_path)
|
15
|
+
stub_request(:get, url).with(headers: { 'User-Agent' => expected_ua }).to_return(status: 200, body:)
|
16
|
+
|
17
|
+
result = AV::Util.do_get(url)
|
18
|
+
expect(result).to eq(body.scrub)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'ignores errors if ignore_errors is set to true' do
|
22
|
+
url = alma_sru_url_for('b11082434')
|
23
|
+
stub_request(:get, url).to_return(status: 404)
|
24
|
+
result = AV::Util.do_get(url, ignore_errors: true)
|
25
|
+
expect(result).to be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# ------------------------------------------------------------
|
2
|
+
# Simplecov
|
3
|
+
|
4
|
+
if ENV['COVERAGE']
|
5
|
+
require 'colorize'
|
6
|
+
require 'simplecov'
|
7
|
+
end
|
8
|
+
|
9
|
+
# ------------------------------------------------------------
|
10
|
+
# RSpec
|
11
|
+
|
12
|
+
require 'webmock/rspec'
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.color = true
|
16
|
+
config.tty = true
|
17
|
+
config.formatter = :documentation
|
18
|
+
config.before { WebMock.disable_net_connect!(allow_localhost: true) }
|
19
|
+
config.after { WebMock.allow_net_connect! }
|
20
|
+
config.mock_with :rspec do |mocks|
|
21
|
+
mocks.verify_partial_doubles = true
|
22
|
+
end
|
23
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
24
|
+
end
|
25
|
+
|
26
|
+
# ------------------------------------------------------------
|
27
|
+
# Code under test
|
28
|
+
|
29
|
+
require 'berkeley_library/av/core'
|
30
|
+
|
31
|
+
# ------------------------------------------------------------
|
32
|
+
# Utility methods
|
33
|
+
|
34
|
+
def sru_url_base
|
35
|
+
'https://berkeley.alma.exlibrisgroup.com/view/sru/01UCS_BER?version=1.2&operation=searchRetrieve&query='
|
36
|
+
end
|
37
|
+
|
38
|
+
def permalink_base
|
39
|
+
'https://search.library.berkeley.edu/permalink/01UCS_BER/iqob43/alma'
|
40
|
+
end
|
41
|
+
|
42
|
+
def alma_sru_url_for(record_id)
|
43
|
+
return "#{sru_url_base}alma.mms_id%3D#{record_id}" unless BerkeleyLibrary::AV::RecordId::Type.for_id(record_id) == BerkeleyLibrary::AV::RecordId::Type::MILLENNIUM
|
44
|
+
|
45
|
+
full_bib = BerkeleyLibrary::AV::RecordId.ensure_check_digit(record_id)
|
46
|
+
"#{sru_url_base}alma.other_system_number%3DUCB-#{full_bib}-01ucs_ber"
|
47
|
+
end
|
48
|
+
|
49
|
+
def alma_sru_data_path_for(record_id)
|
50
|
+
"spec/data/alma/#{record_id}-sru.xml"
|
51
|
+
end
|
52
|
+
|
53
|
+
def stub_sru_request(record_id)
|
54
|
+
sru_url = alma_sru_url_for(record_id)
|
55
|
+
marc_xml_path = alma_sru_data_path_for(record_id)
|
56
|
+
|
57
|
+
stub_request(:get, sru_url).to_return(status: 200, body: File.read(marc_xml_path))
|
58
|
+
end
|
59
|
+
|
60
|
+
def alma_marc_record_for(record_id)
|
61
|
+
marc_xml_path = alma_sru_data_path_for(record_id)
|
62
|
+
MARC::XMLReader.new(marc_xml_path).first
|
63
|
+
end
|