cocina-models 0.100.0 → 0.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf0adcf9839eca5b38d5ea38c28b9ee8d853e0f5cdec7b35a2c8fee57e3081fd
4
- data.tar.gz: 8824e1540a5d8eb2fca36f8afbeeb340f4b134385075af10dac74408c7e35598
3
+ metadata.gz: 020bb1af47ff01f6e95a8d126cabaae16a19a1cd92ae8bdade1e18f97f519af6
4
+ data.tar.gz: e05e3b0a0a6122a1297fe3d12e3b9737b618ed03ae246d8b4b24e0740254ad9a
5
5
  SHA512:
6
- metadata.gz: 96f4f445895f8be40633be3caf07455fc72ac83fdf592996c38510faef3367c3c32b529f0a3c865385522833802e5e02a608b6918ec2a05905911d436f6a0d4b
7
- data.tar.gz: ef3acb51f35dea27da4f6378d625a4872a07652bb4cd1a2f4d40162adc1b6d8682d86bc4253639dff56ef66abbd4513ea6ba810fbc34b49e6a8008280c399bfc
6
+ metadata.gz: fd8a640dfe907eaebfc3f0b6b72f044b8b149718601d8845b315d529f861634fc0ce194f684236802e2799378a5a01920d8facf7f3669a95ac9e6d1ede066ce5
7
+ data.tar.gz: eb7d1fc6c14ebadb308e7c7b53f00640d20de07ca337523e33cc77e7b039b00d737fa94079282e29254c8f46b6dffb654ae5c3c5dbfb7fe5cc7cabc592e1fa93
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@4.5.0
3
+ ruby-rails: sul-dlss/ruby-rails@4.6.0
4
4
  workflows:
5
5
  build:
6
6
  jobs:
@@ -11,4 +11,3 @@ workflows:
11
11
  - ruby-rails/test-gem:
12
12
  name: test
13
13
  context: dlss
14
- use-codecov: true
data/.rubocop.yml CHANGED
@@ -1,9 +1,9 @@
1
1
  # This is the configuration used to check the rubocop source code.
2
2
 
3
3
  inherit_from: .rubocop_todo.yml
4
- require:
5
- - rubocop-rspec
4
+ plugins:
6
5
  - rubocop-rake
6
+ - rubocop-rspec
7
7
 
8
8
  AllCops:
9
9
  TargetRubyVersion: 3.0
@@ -301,10 +301,6 @@ RSpec/IdenticalEqualityAssertion: # new in 2.4
301
301
  Enabled: true
302
302
  RSpec/SubjectDeclaration: # new in 2.5
303
303
  Enabled: true
304
- FactoryBot/SyntaxMethods: # new in 2.7
305
- Enabled: true
306
- RSpecRails/AvoidSetupHook: # new in 2.4
307
- Enabled: true
308
304
  Style/NestedFileDirname: # new in 1.26
309
305
  Enabled: true
310
306
 
@@ -341,17 +337,10 @@ Style/MapCompactWithConditionalBlock: # new in 1.30
341
337
  Enabled: true
342
338
  RSpec/ChangeByZero: # new in 2.11.0
343
339
  Enabled: true
344
- Capybara/SpecificMatcher: # new in 2.12
345
- Enabled: false
346
- RSpecRails/HaveHttpStatus: # new in 2.12
347
- Enabled: false
348
-
349
340
  RSpec/ClassCheck: # new in 2.13
350
341
  Enabled: true
351
342
  RSpec/NoExpectationExample: # new in 2.13
352
343
  Enabled: true
353
- Capybara/SpecificFinders: # new in 2.13
354
- Enabled: true
355
344
  Gemspec/DevelopmentDependencies: # new in 1.44
356
345
  Enabled: true
357
346
  Lint/DuplicateMagicComment: # new in 1.37
@@ -378,29 +367,14 @@ Style/RedundantEach: # new in 1.38
378
367
  Enabled: true
379
368
  Style/RedundantStringEscape: # new in 1.37
380
369
  Enabled: true
381
- Capybara/MatchStyle: # new in <<next>>
382
- Enabled: true
383
- Capybara/NegationMatcher: # new in 2.14
384
- Enabled: true
385
- Capybara/SpecificActions: # new in 2.14
386
- Enabled: true
387
370
  RSpec/DuplicatedMetadata: # new in 2.16
388
371
  Enabled: true
389
372
  RSpec/PendingWithoutReason: # new in 2.16
390
373
  Enabled: true
391
374
  RSpec/SortMetadata: # new in 2.14
392
375
  Enabled: true
393
- FactoryBot/ConsistentParenthesesStyle: # new in 2.14
394
- Enabled: true
395
- FactoryBot/FactoryNameStyle: # new in 2.16
396
- Enabled: true
397
- RSpecRails/InferredSpecType: # new in 2.14
398
- Enabled: true
399
- RSpecRails/MinitestAssertions: # new in 2.17
400
- Enabled: true
401
376
  Style/RedundantHeredocDelimiterQuotes: # new in 1.45
402
377
  Enabled: true
403
-
404
378
  Metrics/CollectionLiteralLength: # new in 1.47
405
379
  Enabled: true
406
380
  Style/DirEmpty: # new in 1.48
@@ -411,9 +385,6 @@ RSpec/RedundantAround: # new in 2.19
411
385
  Enabled: true
412
386
  RSpec/SkipBlockInsideExample: # new in 2.19
413
387
  Enabled: true
414
- RSpecRails/TravelAround: # new in 2.19
415
- Enabled: true
416
-
417
388
  Lint/DuplicateMatchPattern: # new in 1.50
418
389
  Enabled: true
419
390
  Style/DataInheritance: # new in 1.49
@@ -428,12 +399,6 @@ Style/RedundantLineContinuation: # new in 1.49
428
399
  Enabled: true
429
400
  Style/RedundantRegexpConstructor: # new in 1.52
430
401
  Enabled: true
431
- FactoryBot/AssociationStyle: # new in 2.23
432
- Enabled: true
433
- FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
434
- Enabled: true
435
- FactoryBot/RedundantFactoryOption: # new in 2.23
436
- Enabled: true
437
402
  RSpec/BeEmpty: # new in 2.20
438
403
  Enabled: true
439
404
  RSpec/ContainExactly: # new in 2.19
@@ -457,9 +422,6 @@ Style/YAMLFileRead: # new in 1.53
457
422
  Enabled: true
458
423
  RSpec/ReceiveMessages: # new in 2.23
459
424
  Enabled: true
460
- RSpecRails/NegationBeValid: # new in 2.23
461
- Enabled: true
462
-
463
425
  Lint/ItWithoutArgumentsInBlock: # new in 1.59
464
426
  Enabled: true
465
427
  Lint/LiteralAssignmentInCondition: # new in 1.58
@@ -468,18 +430,6 @@ Style/SingleLineDoEndBlock: # new in 1.57
468
430
  Enabled: true
469
431
  Style/SuperWithArgsParentheses: # new in 1.58
470
432
  Enabled: true
471
- Capybara/ClickLinkOrButtonStyle: # new in 2.19
472
- Enabled: true
473
- Capybara/RedundantWithinFind: # new in 2.20
474
- Enabled: true
475
- Capybara/RSpec/HaveSelector: # new in 2.19
476
- Enabled: true
477
- Capybara/RSpec/PredicateMatcher: # new in 2.19
478
- Enabled: true
479
- FactoryBot/ExcessiveCreateList: # new in 2.25
480
- Enabled: true
481
- FactoryBot/IdSequence: # new in 2.24
482
- Enabled: true
483
433
  RSpec/EmptyMetadata: # new in 2.24
484
434
  Enabled: true
485
435
  RSpec/Eq: # new in 2.24
@@ -498,7 +448,6 @@ RSpec/IsExpectedSpecify: # new in 2.27
498
448
  Enabled: true
499
449
  RSpec/RepeatedSubjectCall: # new in 2.27
500
450
  Enabled: true
501
-
502
451
  Style/MapIntoArray: # new in 1.63
503
452
  Enabled: true
504
453
  Style/SendWithLiteralMethodName: # new in 1.64
@@ -511,7 +460,6 @@ RSpec/ExpectInLet: # new in 2.30
511
460
  Enabled: true
512
461
  RSpec/UndescriptiveLiteralsDescription: # new in 2.29
513
462
  Enabled: true
514
-
515
463
  Gemspec/AddRuntimeDependency: # new in 1.65
516
464
  Enabled: true
517
465
  Lint/DuplicateSetElement: # new in 1.67
@@ -532,3 +480,35 @@ Style/RedundantInterpolationUnfreeze: # new in 1.66
532
480
  Enabled: true
533
481
  Style/SafeNavigationChainLength: # new in 1.68
534
482
  Enabled: false
483
+ Lint/ArrayLiteralInRegexp: # new in 1.71
484
+ Enabled: true
485
+ Lint/ConstantReassignment: # new in 1.70
486
+ Enabled: true
487
+ Lint/CopDirectiveSyntax: # new in 1.72
488
+ Enabled: true
489
+ Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
490
+ Enabled: true
491
+ Lint/NumericOperationWithConstantResult: # new in 1.69
492
+ Enabled: true
493
+ Lint/RedundantTypeConversion: # new in 1.72
494
+ Enabled: true
495
+ Lint/SharedMutableDefault: # new in 1.70
496
+ Enabled: true
497
+ Lint/SuppressedExceptionInNumberConversion: # new in 1.72
498
+ Enabled: true
499
+ Lint/UselessConstantScoping: # new in 1.72
500
+ Enabled: true
501
+ Lint/UselessDefined: # new in 1.69
502
+ Enabled: true
503
+ Style/DigChain: # new in 1.69
504
+ Enabled: true
505
+ Style/FileNull: # new in 1.69
506
+ Enabled: true
507
+ Style/FileTouch: # new in 1.69
508
+ Enabled: true
509
+ Style/HashSlice: # new in 1.71
510
+ Enabled: true
511
+ Style/ItAssignment: # new in 1.70
512
+ Enabled: true
513
+ Style/RedundantFormat: # new in 1.72
514
+ Enabled: true
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.100.0)
4
+ cocina-models (0.101.1)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -19,7 +19,7 @@ PATH
19
19
  GEM
20
20
  remote: https://rubygems.org/
21
21
  specs:
22
- activesupport (8.0.1)
22
+ activesupport (8.0.2)
23
23
  base64
24
24
  benchmark (>= 0.3)
25
25
  bigdecimal
@@ -32,12 +32,12 @@ GEM
32
32
  securerandom (>= 0.3)
33
33
  tzinfo (~> 2.0, >= 2.0.5)
34
34
  uri (>= 0.13.1)
35
- ast (2.4.2)
35
+ ast (2.4.3)
36
36
  attr_extras (7.1.0)
37
37
  base64 (0.2.0)
38
38
  benchmark (0.4.0)
39
39
  bigdecimal (3.1.9)
40
- byebug (11.1.3)
40
+ byebug (12.0.0)
41
41
  committee (5.0.0)
42
42
  json_schema (~> 0.14, >= 0.14.3)
43
43
  openapi_parser (~> 1.0)
@@ -46,7 +46,7 @@ GEM
46
46
  connection_pool (2.5.0)
47
47
  deprecation (1.1.0)
48
48
  activesupport
49
- diff-lcs (1.5.1)
49
+ diff-lcs (1.6.1)
50
50
  docile (1.4.1)
51
51
  drb (2.2.1)
52
52
  dry-core (1.1.0)
@@ -59,7 +59,7 @@ GEM
59
59
  concurrent-ruby (~> 1.0)
60
60
  dry-core (~> 1.1)
61
61
  zeitwerk (~> 2.6)
62
- dry-struct (1.7.1)
62
+ dry-struct (1.8.0)
63
63
  dry-core (~> 1.1)
64
64
  dry-types (~> 1.8, >= 1.8.2)
65
65
  ice_nine (~> 0.11)
@@ -78,28 +78,30 @@ GEM
78
78
  i18n (1.14.7)
79
79
  concurrent-ruby (~> 1.0)
80
80
  ice_nine (0.11.2)
81
- json (2.9.1)
81
+ json (2.10.2)
82
82
  json_schema (0.21.0)
83
83
  jsonpath (1.1.5)
84
84
  multi_json
85
85
  language_server-protocol (3.17.0.4)
86
- logger (1.6.5)
86
+ lint_roller (1.1.0)
87
+ logger (1.7.0)
87
88
  mini_portile2 (2.8.8)
88
- minitest (5.25.4)
89
+ minitest (5.25.5)
89
90
  multi_json (1.15.0)
90
- nokogiri (1.18.2)
91
+ nokogiri (1.18.7)
91
92
  mini_portile2 (~> 2.8.2)
92
93
  racc (~> 1.4)
93
94
  openapi_parser (1.0.0)
94
- optimist (3.2.0)
95
+ optimist (3.2.1)
95
96
  parallel (1.26.3)
96
- parser (3.3.7.1)
97
+ parser (3.3.8.0)
97
98
  ast (~> 2.4.1)
98
99
  racc
99
100
  patience_diff (1.2.0)
100
101
  optimist (~> 3.0)
102
+ prism (1.4.0)
101
103
  racc (1.8.1)
102
- rack (3.1.9)
104
+ rack (3.1.13)
103
105
  rainbow (3.1.1)
104
106
  rake (13.2.1)
105
107
  regexp_parser (2.10.0)
@@ -118,31 +120,26 @@ GEM
118
120
  rspec-support (3.13.2)
119
121
  rspec_junit_formatter (0.6.0)
120
122
  rspec-core (>= 2, < 4, != 2.12.0)
121
- rubocop (1.71.2)
123
+ rubocop (1.75.2)
122
124
  json (~> 2.3)
123
- language_server-protocol (>= 3.17.0)
125
+ language_server-protocol (~> 3.17.0.2)
126
+ lint_roller (~> 1.1.0)
124
127
  parallel (~> 1.10)
125
128
  parser (>= 3.3.0.2)
126
129
  rainbow (>= 2.2.2, < 4.0)
127
130
  regexp_parser (>= 2.9.3, < 3.0)
128
- rubocop-ast (>= 1.38.0, < 2.0)
131
+ rubocop-ast (>= 1.44.0, < 2.0)
129
132
  ruby-progressbar (~> 1.7)
130
133
  unicode-display_width (>= 2.4.0, < 4.0)
131
- rubocop-ast (1.38.0)
132
- parser (>= 3.3.1.0)
133
- rubocop-capybara (2.21.0)
134
- rubocop (~> 1.41)
135
- rubocop-factory_bot (2.26.1)
136
- rubocop (~> 1.61)
137
- rubocop-rake (0.6.0)
138
- rubocop (~> 1.0)
139
- rubocop-rspec (2.31.0)
140
- rubocop (~> 1.40)
141
- rubocop-capybara (~> 2.17)
142
- rubocop-factory_bot (~> 2.22)
143
- rubocop-rspec_rails (~> 2.28)
144
- rubocop-rspec_rails (2.29.1)
145
- rubocop (~> 1.61)
134
+ rubocop-ast (1.44.1)
135
+ parser (>= 3.3.7.2)
136
+ prism (~> 1.4)
137
+ rubocop-rake (0.7.1)
138
+ lint_roller (~> 1.1)
139
+ rubocop (>= 1.72.1)
140
+ rubocop-rspec (3.5.0)
141
+ lint_roller (~> 1.1)
142
+ rubocop (~> 1.72, >= 1.72.1)
146
143
  ruby-progressbar (1.13.0)
147
144
  securerandom (0.4.1)
148
145
  simplecov (0.22.0)
@@ -161,8 +158,8 @@ GEM
161
158
  unicode-display_width (3.1.4)
162
159
  unicode-emoji (~> 4.0, >= 4.0.4)
163
160
  unicode-emoji (4.0.4)
164
- uri (1.0.2)
165
- zeitwerk (2.7.1)
161
+ uri (1.0.3)
162
+ zeitwerk (2.7.2)
166
163
 
167
164
  PLATFORMS
168
165
  ruby
@@ -177,8 +174,8 @@ DEPENDENCIES
177
174
  rspec_junit_formatter
178
175
  rubocop (~> 1.24)
179
176
  rubocop-rake
180
- rubocop-rspec (~> 2.1)
177
+ rubocop-rspec
181
178
  simplecov
182
179
 
183
180
  BUNDLED WITH
184
- 2.4.13
181
+ 2.6.8
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'rspec', '~> 3.0'
47
47
  spec.add_development_dependency 'rubocop', '~> 1.24'
48
48
  spec.add_development_dependency 'rubocop-rake'
49
- spec.add_development_dependency 'rubocop-rspec', '~> 2.1'
49
+ spec.add_development_dependency 'rubocop-rspec'
50
50
  spec.add_development_dependency 'simplecov'
51
51
  spec.metadata['rubygems_mfa_required'] = 'true'
52
52
  end
@@ -136,6 +136,7 @@ module Cocina
136
136
  version.rb
137
137
  vocabulary.rb
138
138
  ].freeze
139
+ private_constant :NO_CLEAN
139
140
 
140
141
  def clean_output
141
142
  FileUtils.mkdir_p(options[:output])
@@ -49,6 +49,7 @@ module Cocina
49
49
  'ObjectType' => BASE,
50
50
  'FileSetType' => "#{BASE}resources/"
51
51
  }.freeze
52
+ private_constant :BASE, :URIS
52
53
 
53
54
  def vocabs
54
55
  type_properties = schemas.values.map { |schema| schema.properties&.[]('type') }.compact
@@ -8,26 +8,28 @@ module Cocina
8
8
  # TitleBuilder selects the prefered title from the cocina object for solr indexing
9
9
  class TitleBuilder # rubocop:disable Metrics/ClassLength
10
10
  extend Deprecation
11
- # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
11
+ # @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
12
+ # @param [Array<Cocina::Models::FolioCatalogLink>] catalog_links the folio catalog links to check for digital serials part labels
12
13
  # @param [Symbol] strategy ":first" is the strategy for selection when primary or display
13
14
  # title are missing
14
15
  # @param [Boolean] add_punctuation determines if the title should be formmated with punctuation
15
16
  # @return [String, Array] the title value for Solr - for :first strategy, a string; for :all strategy, an array
16
17
  # (e.g. title displayed in blacklight search results vs boosting values for search result rankings)
17
- def self.build(titles, strategy: :first, add_punctuation: true)
18
+ def self.build(titles, catalog_links: [], strategy: :first, add_punctuation: true)
19
+ part_label = catalog_links.find { |link| link.catalog == 'folio' }&.partLabel
18
20
  if titles.respond_to?(:description)
19
21
  Deprecation.warn(self,
20
22
  "Calling TitleBuilder.build with a #{titles.class} is deprecated. " \
21
23
  'It must be called with an array of titles')
22
24
  titles = titles.description.title
23
25
  end
24
- new(strategy: strategy, add_punctuation: add_punctuation).build(titles)
26
+ new(strategy: strategy, add_punctuation: add_punctuation, part_label: part_label).build(titles)
25
27
  end
26
28
 
27
29
  # the "main title" is the title withOUT subtitle, part name, etc. We want to index it separately so
28
30
  # we can boost matches on it in search results (boost matching this string higher than matching full title string)
29
31
  # e.g. "The Hobbit" (main_title) vs "The Hobbit, or, There and Back Again (full_title)
30
- # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
32
+ # @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
31
33
  # @return [Array<String>] the main title value(s) for Solr - array due to possible parallelValue
32
34
  def self.main_title(titles)
33
35
  new(strategy: :first, add_punctuation: false).main_title(titles)
@@ -35,7 +37,7 @@ module Cocina
35
37
 
36
38
  # the "full title" is the title WITH subtitle, part name, etc. We want to able able to index it separately so
37
39
  # we can boost matches on it in search results (boost matching this string higher than other titles present)
38
- # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
40
+ # @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
39
41
  # @return [Array<String>] the full title value(s) for Solr - array due to possible parallelValue
40
42
  def self.full_title(titles)
41
43
  [new(strategy: :first, add_punctuation: false, only_one_parallel_value: false).build(titles)].flatten.compact
@@ -43,7 +45,7 @@ module Cocina
43
45
 
44
46
  # "additional titles" are all title data except for full_title. We want to able able to index it separately so
45
47
  # we can boost matches on it in search results (boost matching these strings lower than other titles present)
46
- # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
48
+ # @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
47
49
  # @return [Array<String>] the values for Solr
48
50
  def self.additional_titles(titles)
49
51
  [new(strategy: :all, add_punctuation: false).build(titles)].flatten - full_title(titles)
@@ -57,13 +59,16 @@ module Cocina
57
59
  # of primary, untyped, first occurrence. When false, return an array containing all the parallel values.
58
60
  # Why? Think of e.g. title displayed in blacklight search results vs boosting values for ranking of search
59
61
  # results
60
- def initialize(strategy:, add_punctuation:, only_one_parallel_value: true)
62
+ # @param part_label [String] the partLabel to add for digital serials display
63
+ def initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil)
61
64
  @strategy = strategy
62
65
  @add_punctuation = add_punctuation
63
66
  @only_one_parallel_value = only_one_parallel_value
67
+ @part_label = part_label
64
68
  end
65
69
 
66
- # @param [[Array<Cocina::Models::Title>] cocina_titles the titles to consider
70
+ # @param [Array<Cocina::Models::Title>] cocina_titles the titles to consider
71
+ # @param [String, nil] part_label the partLabel to add to the title for digital serials
67
72
  # @return [String, Array] the title value for Solr - for :first strategy, a string; for :all strategy, an array
68
73
  # (e.g. title displayed in blacklight search results vs boosting values for search result rankings)
69
74
  #
@@ -71,9 +76,9 @@ module Cocina
71
76
  def build(cocina_titles)
72
77
  cocina_title = primary_title(cocina_titles) || untyped_title(cocina_titles)
73
78
  cocina_title = other_title(cocina_titles) if cocina_title.blank?
74
-
75
79
  if strategy == :first
76
- extract_title(cocina_title)
80
+ result = extract_title(cocina_title)
81
+ add_part_label(result)
77
82
  else
78
83
  result = cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
79
84
  if only_one_parallel_value? && result.length == 1
@@ -97,7 +102,13 @@ module Cocina
97
102
 
98
103
  private
99
104
 
100
- attr_reader :strategy
105
+ attr_reader :strategy, :part_label
106
+
107
+ def add_part_label(title)
108
+ # when a digital serial
109
+ title = "#{title.sub(/[ .,]*$/, '')}, #{part_label}" if part_label.present?
110
+ title
111
+ end
101
112
 
102
113
  def extract_title(cocina_title)
103
114
  title_values = if cocina_title.value
@@ -11,6 +11,10 @@ module Cocina
11
11
  attribute :refresh, Types::Strict::Bool.default(false)
12
12
  # Record identifier that is unique within the context of the linked record's catalog.
13
13
  attribute :catalogRecordId, MigratedFromSymphonyIdentifier | MigratedFromVoyagerIdentifier | CreatedInFolioIdentifier
14
+ # Label for use in display of serials via Folio record
15
+ attribute? :partLabel, Types::Strict::String
16
+ # Sorting information for use in display of serials via Folio record
17
+ attribute? :sortKey, Types::Strict::String
14
18
  end
15
19
  end
16
20
  end
@@ -178,6 +178,7 @@ module Cocina
178
178
  end
179
179
 
180
180
  XPATH_HAS_CONTENT_PREDICATE = '[string-length(normalize-space()) > 0]'
181
+ private_constant :XPATH_HAS_CONTENT_PREDICATE
181
182
 
182
183
  def build_copyright_notice_event(origin_info_node)
183
184
  date_nodes = origin_info_node.xpath("mods:copyrightDate#{XPATH_HAS_CONTENT_PREDICATE}",
@@ -56,6 +56,7 @@ module Cocina
56
56
  end
57
57
 
58
58
  LEGACY_EVENT_TYPES_2_TYPE = Cocina::Models::Mapping::FromMods::Event::LEGACY_EVENT_TYPES_2_TYPE
59
+ private_constant :LEGACY_EVENT_TYPES_2_TYPE
59
60
 
60
61
  # because eventType is a relatively new addition to the MODS schema, records converted from MARC to MODS prior
61
62
  # to its introduction used displayLabel as a stopgap measure, with certain values
@@ -21,6 +21,7 @@ module Cocina
21
21
 
22
22
  validate_catalog('symphony')
23
23
  validate_catalog('folio')
24
+ validate_sort_key
24
25
  end
25
26
 
26
27
  private
@@ -36,6 +37,17 @@ module Cocina
36
37
  "(only one allowed) #{refresh_catalog_links}"
37
38
  end
38
39
 
40
+ def validate_sort_key
41
+ # TODO: remove this validation once we upgrade to OpenAPI 3.1 and can use dependentRequired in openapi.yml
42
+ serials_links = catalog_links.select { |catalog_link| catalog_link[:catalog] == 'folio' && catalog_link[:sortKey].present? }
43
+ serials_links.each do |catalog_link|
44
+ # If partLabel is present, catalog_link is valid
45
+ next if catalog_link[:partLabel].present?
46
+
47
+ raise ValidationError, "partLabel must also be present if a sortKey is used in catalog link #{catalog_link}"
48
+ end
49
+ end
50
+
39
51
  def catalog_links
40
52
  @catalog_links ||= Array(attributes.dig(:identification, :catalogLinks))
41
53
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.100.0'
5
+ VERSION = '0.101.1'
6
6
  end
7
7
  end
data/openapi.yml CHANGED
@@ -1174,6 +1174,12 @@ components:
1174
1174
  - $ref: '#/components/schemas/MigratedFromSymphonyIdentifier'
1175
1175
  - $ref: '#/components/schemas/MigratedFromVoyagerIdentifier'
1176
1176
  - $ref: '#/components/schemas/CreatedInFolioIdentifier'
1177
+ partLabel:
1178
+ description: Label for use in display of serials via Folio record
1179
+ type: string
1180
+ sortKey:
1181
+ description: Sorting information for use in display of serials via Folio record
1182
+ type: string
1177
1183
  required:
1178
1184
  - catalog
1179
1185
  - catalogRecordId
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.100.0
4
+ version: 0.101.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-02-19 00:00:00.000000000 Z
10
+ date: 2025-04-18 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -280,16 +279,16 @@ dependencies:
280
279
  name: rubocop-rspec
281
280
  requirement: !ruby/object:Gem::Requirement
282
281
  requirements:
283
- - - "~>"
282
+ - - ">="
284
283
  - !ruby/object:Gem::Version
285
- version: '2.1'
284
+ version: '0'
286
285
  type: :development
287
286
  prerelease: false
288
287
  version_requirements: !ruby/object:Gem::Requirement
289
288
  requirements:
290
- - - "~>"
289
+ - - ">="
291
290
  - !ruby/object:Gem::Version
292
- version: '2.1'
291
+ version: '0'
293
292
  - !ruby/object:Gem::Dependency
294
293
  name: simplecov
295
294
  requirement: !ruby/object:Gem::Requirement
@@ -521,7 +520,6 @@ homepage: https://github.com/sul-dlss/cocina-models
521
520
  licenses: []
522
521
  metadata:
523
522
  rubygems_mfa_required: 'true'
524
- post_install_message:
525
523
  rdoc_options: []
526
524
  require_paths:
527
525
  - lib
@@ -536,8 +534,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
536
534
  - !ruby/object:Gem::Version
537
535
  version: '0'
538
536
  requirements: []
539
- rubygems_version: 3.5.11
540
- signing_key:
537
+ rubygems_version: 3.6.2
541
538
  specification_version: 4
542
539
  summary: Data models for the SDR
543
540
  test_files: []