cocina-models 0.118.1 → 0.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -15
  3. data/.rubocop_todo.yml +33 -35
  4. data/Gemfile.lock +6 -6
  5. data/lib/cocina/models/builders/title_builder.rb +0 -4
  6. data/lib/cocina/models/california_historical_society_barcode.rb +1 -1
  7. data/lib/cocina/models/mapping/from_mods/form.rb +4 -2
  8. data/lib/cocina/models/mapping/from_mods/name_builder.rb +4 -2
  9. data/lib/cocina/models/mapping/from_mods/note.rb +12 -5
  10. data/lib/cocina/models/mapping/from_mods/related_resource.rb +37 -4
  11. data/lib/cocina/models/mapping/from_mods/subject.rb +0 -4
  12. data/lib/cocina/models/validators/catalog_links_validator.rb +3 -1
  13. data/lib/cocina/models/validators/description_values_validator.rb +15 -4
  14. data/lib/cocina/models/validators/json_schema_validator.rb +6 -1
  15. data/lib/cocina/models/validators/language_tag_validator.rb +3 -1
  16. data/lib/cocina/models/version.rb +1 -1
  17. data/lib/cocina/rspec/factories.rb +6 -2
  18. data/schema.json +55 -1
  19. metadata +2 -29
  20. data/lib/cocina/models/mapping/escape_html.rb +0 -23
  21. data/lib/cocina/models/mapping/normalizers/base.rb +0 -16
  22. data/lib/cocina/models/mapping/normalizers/mods/geo_extension_normalizer.rb +0 -69
  23. data/lib/cocina/models/mapping/normalizers/mods/name_normalizer.rb +0 -216
  24. data/lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb +0 -158
  25. data/lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb +0 -292
  26. data/lib/cocina/models/mapping/normalizers/mods/title_normalizer.rb +0 -91
  27. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +0 -410
  28. data/lib/cocina/models/mapping/to_mods/access.rb +0 -155
  29. data/lib/cocina/models/mapping/to_mods/admin_metadata.rb +0 -129
  30. data/lib/cocina/models/mapping/to_mods/contributor.rb +0 -49
  31. data/lib/cocina/models/mapping/to_mods/description.rb +0 -65
  32. data/lib/cocina/models/mapping/to_mods/event.rb +0 -206
  33. data/lib/cocina/models/mapping/to_mods/form.rb +0 -296
  34. data/lib/cocina/models/mapping/to_mods/geographic.rb +0 -149
  35. data/lib/cocina/models/mapping/to_mods/id_generator.rb +0 -25
  36. data/lib/cocina/models/mapping/to_mods/identifier.rb +0 -57
  37. data/lib/cocina/models/mapping/to_mods/language.rb +0 -82
  38. data/lib/cocina/models/mapping/to_mods/mods_writer.rb +0 -40
  39. data/lib/cocina/models/mapping/to_mods/name_title_group.rb +0 -29
  40. data/lib/cocina/models/mapping/to_mods/name_writer.rb +0 -299
  41. data/lib/cocina/models/mapping/to_mods/note.rb +0 -102
  42. data/lib/cocina/models/mapping/to_mods/part_writer.rb +0 -115
  43. data/lib/cocina/models/mapping/to_mods/related_resource.rb +0 -123
  44. data/lib/cocina/models/mapping/to_mods/role_writer.rb +0 -50
  45. data/lib/cocina/models/mapping/to_mods/subject.rb +0 -496
  46. data/lib/cocina/models/mapping/to_mods/title.rb +0 -274
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 980d1887539c11b65c897fc0f48a6d5529b8bb9e23821f9f87ac677623c7a05a
4
- data.tar.gz: 58b30197236ad99946ec8598fd84b03e8e8ea804a9625483ef4d678d93972dd9
3
+ metadata.gz: 95fdb985d82245efee3898558df726439ee7d27e7fa45bd47815b44d52f58679
4
+ data.tar.gz: 0a7644f423957828280316d0c5709847f260919e1ceb384c130e8196f4d5eb6a
5
5
  SHA512:
6
- metadata.gz: 8e599c4ce9337e1ef65ece3c33522f3efa88ee986b048d628889e329aaee752616208eb4e048193f2a5173fa506b9c8170b9032129418d9434f32e60f7c625d4
7
- data.tar.gz: 07ab88971c0c7a3d2810d9db68c3423755c421d96d7d778339350a64348a2d39a7c021719639fad4a05fdb14b08e4a5313953c3b62865521b7249b2b0a63059b
6
+ metadata.gz: ce4a6079617e05fd8d5b1547d16e983e06f0f53914339f9f19dcb4a870d52c1c565844bb39b0ed5decffe2c68f2a4fc4f2b385b9d8dd4796700f2c1f9aed5c7b
7
+ data.tar.gz: eb72b867dcab3ad0ee2e63d3b68276c17fb831365f4c6a785a95fa8250998b663c6bcca2d50d4ffc6786044a17df7321847c069595587a9ae3ac96120f093020
data/.rubocop.yml CHANGED
@@ -14,11 +14,12 @@ Layout/BeginEndAlignment: # (new in 0.91)
14
14
  Enabled: true
15
15
  Layout/EmptyLinesAroundAttributeAccessor:
16
16
  Enabled: true
17
+ Layout/SpaceAroundMethodCallOperator:
18
+ Enabled: true
17
19
  Layout/LineLength:
18
20
  Exclude:
19
21
  - lib/cocina/models/*
20
- Layout/SpaceAroundMethodCallOperator:
21
- Enabled: true
22
+ - spec/**/*
22
23
 
23
24
  # This cop throws an error in 1.37.1
24
25
  Layout/SpaceInsideHashLiteralBraces:
@@ -80,35 +81,35 @@ Metrics/BlockLength:
80
81
  - cocina-models.gemspec
81
82
  - spec/cocina/**/*
82
83
  - lib/cocina/rspec/matchers.rb
83
- - 'spec/support/mods_mapping_spec_helper.rb'
84
+ - "spec/support/mods_mapping_spec_helper.rb"
84
85
 
85
86
  # Offense count: 16
86
87
  # Configuration parameters: CountComments, CountAsOne.
87
88
  Metrics/ClassLength:
88
89
  Max: 100
89
90
  Exclude:
90
- - 'lib/cocina/rspec/factories.rb'
91
+ - "lib/cocina/rspec/factories.rb"
91
92
 
92
93
  Metrics/MethodLength:
93
94
  Max: 14
94
95
  Exclude:
95
- - 'spec/cocina/models/file_access_spec.rb'
96
- - 'spec/cocina/models/dro_access_spec.rb'
97
- - 'lib/cocina/rspec/factories.rb'
98
- - 'lib/cocina/models/mapping/to_mods/*'
99
- - 'lib/cocina/models/mapping/from_mods/*'
100
- - 'lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb'
101
- - 'lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb'
102
- - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
96
+ - "spec/cocina/models/file_access_spec.rb"
97
+ - "spec/cocina/models/dro_access_spec.rb"
98
+ - "lib/cocina/rspec/factories.rb"
99
+ - "lib/cocina/models/mapping/to_mods/*"
100
+ - "lib/cocina/models/mapping/from_mods/*"
101
+ - "lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb"
102
+ - "lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb"
103
+ - "lib/cocina/models/mapping/normalizers/mods_normalizer.rb"
103
104
 
104
105
  # Offense count: 37
105
106
  # Configuration parameters: IgnoredMethods.
106
107
  Metrics/PerceivedComplexity:
107
108
  # Max: 20
108
109
  Exclude:
109
- - 'lib/cocina/models/mapping/from_mods/*'
110
- - 'lib/cocina/models/mapping/to_mods/*'
111
- - 'lib/cocina/models/mapping/normalizers/**/*'
110
+ - "lib/cocina/models/mapping/from_mods/*"
111
+ - "lib/cocina/models/mapping/to_mods/*"
112
+ - "lib/cocina/models/mapping/normalizers/**/*"
112
113
 
113
114
  Naming/PredicatePrefix:
114
115
  ForbiddenPrefixes:
data/.rubocop_todo.yml CHANGED
@@ -1,27 +1,29 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude`
3
- # on 2023-11-01 19:51:40 UTC using RuboCop version 1.57.2.
3
+ # on 2026-06-02 13:55:43 UTC using RuboCop version 1.87.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 8
10
- # Configuration parameters: EnforcedStyle, AllowedGems, Include.
9
+ # Offense count: 7
10
+ # Configuration parameters: EnforcedStyle, AllowedGems.
11
11
  # SupportedStyles: Gemfile, gems.rb, gemspec
12
- # Include: **/*.gemspec, **/Gemfile, **/gems.rb
13
12
  Gemspec/DevelopmentDependencies:
14
13
  Exclude:
15
14
  - 'cocina-models.gemspec'
16
15
 
17
- # Offense count: 1
18
- Lint/NoReturnInBeginEndBlocks:
19
- Exclude:
20
- - 'lib/cocina/models/mapping/to_mods/description.rb'
16
+ # Offense count: 55
17
+ # This cop supports safe autocorrection (--autocorrect).
18
+ # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
19
+ # URISchemes: http, https
20
+ Layout/LineLength:
21
+ Max: 159
21
22
 
22
- # Offense count: 13
23
+ # Offense count: 12
23
24
  # This cop supports safe autocorrection (--autocorrect).
24
- # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
25
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
26
+ # NotImplementedExceptions: NotImplementedError
25
27
  Lint/UnusedMethodArgument:
26
28
  Exclude:
27
29
  - 'lib/cocina/models/mapping/from_mods/admin_metadata.rb'
@@ -34,17 +36,27 @@ Lint/UnusedMethodArgument:
34
36
  - 'lib/cocina/models/mapping/from_mods/language.rb'
35
37
  - 'lib/cocina/models/mapping/from_mods/note.rb'
36
38
  - 'lib/cocina/models/mapping/from_mods/subject.rb'
37
- - 'lib/cocina/models/mapping/to_mods/event.rb'
38
39
 
39
- # Offense count: 98
40
+ # Offense count: 62
40
41
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
41
42
  Metrics/AbcSize:
42
- Max: 40
43
+ Max: 48
43
44
 
44
- # Offense count: 43
45
- # Configuration parameters: AllowedMethods, AllowedPatterns.
45
+ # Offense count: 27
46
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
46
47
  Metrics/CyclomaticComplexity:
47
- Max: 12
48
+ Exclude:
49
+ - 'lib/cocina/generator/generator.rb'
50
+ - 'lib/cocina/models/builders/title_builder.rb'
51
+ - 'lib/cocina/models/mapping/from_mods/event.rb'
52
+ - 'lib/cocina/models/mapping/from_mods/form.rb'
53
+ - 'lib/cocina/models/mapping/from_mods/identifier_type.rb'
54
+ - 'lib/cocina/models/mapping/from_mods/language_term.rb'
55
+ - 'lib/cocina/models/mapping/from_mods/name_builder.rb'
56
+ - 'lib/cocina/models/mapping/from_mods/subject.rb'
57
+ - 'lib/cocina/models/mapping/from_mods/title.rb'
58
+ - 'lib/cocina/models/mapping/from_mods/title_builder.rb'
59
+ - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
48
60
 
49
61
  # Offense count: 1
50
62
  # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
@@ -52,12 +64,12 @@ Metrics/ParameterLists:
52
64
  Exclude:
53
65
  - 'lib/cocina/generator/schema_base.rb'
54
66
 
55
- # Offense count: 41
67
+ # Offense count: 32
56
68
  # Configuration parameters: IgnoredMetadata.
57
69
  RSpec/DescribeClass:
58
70
  Enabled: false
59
71
 
60
- # Offense count: 224
72
+ # Offense count: 95
61
73
  # Configuration parameters: CountAsOne.
62
74
  RSpec/ExampleLength:
63
75
  Max: 103
@@ -78,23 +90,9 @@ RSpec/PendingWithoutReason:
78
90
  - 'spec/cocina/models/mapping/descriptive/mods/title_info_spec.rb'
79
91
  - 'spec/cocina/models/mapping/descriptive/mods/type_of_resource_spec.rb'
80
92
 
81
- # Offense count: 1
93
+ # Offense count: 3
82
94
  # This cop supports safe autocorrection (--autocorrect).
83
95
  Style/IfUnlessModifier:
84
96
  Exclude:
85
- - 'lib/cocina/models/validators/open_api_validator.rb'
86
-
87
- # Offense count: 9
88
- Style/MultilineBlockChain:
89
- Exclude:
90
- - 'lib/cocina/models/mapping/to_mods/access.rb'
91
- - 'lib/cocina/models/mapping/to_mods/contributor.rb'
92
- - 'lib/cocina/models/mapping/to_mods/form.rb'
93
- - 'lib/cocina/models/mapping/to_mods/subject.rb'
94
-
95
- # Offense count: 249
96
- # This cop supports safe autocorrection (--autocorrect).
97
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
98
- # URISchemes: http, https
99
- Layout/LineLength:
100
- Max: 267
97
+ - 'lib/cocina/models/mapping/from_mods/name_builder.rb'
98
+ - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.118.1)
4
+ cocina-models (0.119.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -84,7 +84,7 @@ GEM
84
84
  prism (>= 1.3.0)
85
85
  rdoc (>= 4.0.0)
86
86
  reline (>= 0.4.2)
87
- json (2.19.5)
87
+ json (2.19.7)
88
88
  json_schemer (2.5.0)
89
89
  bigdecimal
90
90
  hana (~> 1.3)
@@ -142,7 +142,7 @@ GEM
142
142
  rspec-support (3.13.7)
143
143
  rspec_junit_formatter (0.6.0)
144
144
  rspec-core (>= 2, < 4, != 2.12.0)
145
- rubocop (1.86.2)
145
+ rubocop (1.87.0)
146
146
  json (~> 2.3)
147
147
  language_server-protocol (~> 3.17.0.2)
148
148
  lint_roller (~> 1.1.0)
@@ -210,7 +210,7 @@ CHECKSUMS
210
210
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
211
211
  bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
212
212
  bundler (4.0.12) sha256=7f8b757d28dfb636e7b24fba2344ac6dd13b5b24f4b46d62573d483f211825ac
213
- cocina-models (0.118.1)
213
+ cocina-models (0.119.0)
214
214
  concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
215
215
  connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
216
216
  date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
@@ -232,7 +232,7 @@ CHECKSUMS
232
232
  ice_nine (0.11.2) sha256=5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db
233
233
  io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
234
234
  irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
235
- json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59
235
+ json (2.19.7) sha256=fe432c8639f6efff69f9d73b518a3705d9581ab93156f981ea72806e1e5bcc3e
236
236
  json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
237
237
  jsonpath (1.1.5) sha256=29f70467193a2dc93ab864ec3d3326d54267961acc623f487340eb9c34931dbe
238
238
  language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
@@ -262,7 +262,7 @@ CHECKSUMS
262
262
  rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
263
263
  rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
264
264
  rspec_junit_formatter (0.6.0) sha256=40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15
265
- rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d
265
+ rubocop (1.87.0) sha256=b9d9ddf55116a513f8ef2c7ae660662d8b49301f118d3f0df61865b33a5c188d
266
266
  rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
267
267
  rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
268
268
  rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
@@ -227,8 +227,6 @@ module Cocina
227
227
  #
228
228
  # for punctuaion funky town, thank MARC and catalog cards
229
229
  #
230
- # rubocop:disable Metrics/AbcSize
231
- # rubocop:disable Metrics/CyclomaticComplexity
232
230
  # rubocop:disable Metrics/MethodLength
233
231
  # rubocop:disable Metrics/PerceivedComplexity
234
232
  def rebuild_structured_value(cocina_title)
@@ -283,8 +281,6 @@ module Cocina
283
281
 
284
282
  result
285
283
  end
286
- # rubocop:enable Metrics/AbcSize
287
- # rubocop:enable Metrics/CyclomaticComplexity
288
284
  # rubocop:enable Metrics/MethodLength
289
285
  # rubocop:enable Metrics/PerceivedComplexity
290
286
 
@@ -4,6 +4,6 @@ module Cocina
4
4
  module Models
5
5
  # The barcode associated with a CHS DRO, prefixed with 405
6
6
  # example: 405000111956
7
- CaliforniaHistoricalSocietyBarcode = Types::String.constrained(format: /^405[0-9]+$/)
7
+ CaliforniaHistoricalSocietyBarcode = Types::String.constrained(format: /^405[0-9]{9}$/)
8
8
  end
9
9
  end
@@ -9,6 +9,7 @@ module Cocina
9
9
  class Form
10
10
  # NOTE: H2 is the first case of structured form (genre/typeOfResource) values we're implementing
11
11
  H2_GENRE_TYPE_PREFIX = 'H2 '
12
+ H2_SOURCE_LABEL = 'Stanford self-deposit resource types'
12
13
 
13
14
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
14
15
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
@@ -58,7 +59,8 @@ module Cocina
58
59
 
59
60
  def build_cartographics(subject_node)
60
61
  carto_forms = []
61
- subject_node.xpath('mods:cartographics[mods:scale]', mods: Description::DESC_METADATA_NS).each do |carto_node|
62
+ subject_node.xpath('mods:cartographics[mods:scale]',
63
+ mods: Description::DESC_METADATA_NS).each do |carto_node|
62
64
  scale_nodes = carto_node.xpath('mods:scale', mods: Description::DESC_METADATA_NS).reject do |scale_node|
63
65
  scale_node.text.blank?
64
66
  end
@@ -142,7 +144,7 @@ module Cocina
142
144
  forms << {
143
145
  type: 'resource type',
144
146
  source: {
145
- value: Cocina::Models::Mapping::ToMods::Form::H2_SOURCE_LABEL
147
+ value: H2_SOURCE_LABEL
146
148
  },
147
149
  structuredValue: structured_genre.map do |genre|
148
150
  {
@@ -7,7 +7,7 @@ module Cocina
7
7
  module FromMods
8
8
  # Maps a name
9
9
  class NameBuilder
10
- UNCITED_DESCRIPTION = Cocina::Models::Mapping::ToMods::NameWriter::UNCITED_DESCRIPTION
10
+ UNCITED_DESCRIPTION = 'not included in citation'
11
11
  TYPE_FOR_ROLES = Cocina::Models::Mapping::FromMods::Contributor::ROLES.merge('event' => 'event').freeze
12
12
 
13
13
  # @param [Array<Nokogiri::XML::Element>] name_elements (multiple if parallel)
@@ -154,7 +154,9 @@ module Cocina
154
154
  end
155
155
 
156
156
  def build_structured_value_name(name_node, name_part_nodes)
157
- vals = name_part_nodes.filter_map { |name_part_node| build_name_part(name_node, name_part_node, default_type: name_node['type'] != 'corporate').presence }
157
+ vals = name_part_nodes.filter_map do |name_part_node|
158
+ build_name_part(name_node, name_part_node, default_type: name_node['type'] != 'corporate').presence
159
+ end
158
160
  display_form_node = name_node.xpath('mods:displayForm', mods: Description::DESC_METADATA_NS).first
159
161
  if display_form_node.present?
160
162
  cocina_contrib_name =
@@ -6,6 +6,11 @@ module Cocina
6
6
  module FromMods
7
7
  # Maps notes
8
8
  class Note # rubocop:disable Metrics/ClassLength
9
+ # notes with these types will produce an `abstract` XML node
10
+ NOTE_TYPE_TO_ABSTRACT_TYPE = ['summary', 'abstract', 'scope and content'].freeze
11
+ DISPLAY_LABEL_TO_ABSTRACT_TYPE = ['Content advice', 'Subject', 'Abstract', 'Review', 'Summary', 'Scope and content',
12
+ 'Scope and Content', 'Content Advice'].freeze
13
+
9
14
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
10
15
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder (not used, but passed in by DescriptionBuilder)
11
16
  # @param [String] purl (not used, but passed in by DescriptionBuilder)
@@ -28,7 +33,8 @@ module Cocina
28
33
  attr_reader :resource_element
29
34
 
30
35
  def abstracts
31
- all_abstract_nodes = resource_element.xpath('mods:abstract', mods: Description::DESC_METADATA_NS).select do |node|
36
+ all_abstract_nodes = resource_element.xpath('mods:abstract',
37
+ mods: Description::DESC_METADATA_NS).select do |node|
32
38
  note_present?(node)
33
39
  end
34
40
  altrepgroup_abstract_nodes, other_abstract_nodes = AltRepGroup.split(nodes: all_abstract_nodes)
@@ -58,13 +64,13 @@ module Cocina
58
64
  end
59
65
 
60
66
  def note_type(node)
61
- return node['type'].downcase if Cocina::Models::Mapping::ToMods::Note.note_type_to_abstract_type.include?(node['type']&.downcase)
67
+ return node['type'].downcase if NOTE_TYPE_TO_ABSTRACT_TYPE.include?(node['type']&.downcase)
62
68
 
63
69
  node['type']
64
70
  end
65
71
 
66
72
  def display_label(node)
67
- return node[:displayLabel].capitalize if Cocina::Models::Mapping::ToMods::Note.display_label_to_abstract_type.include? node[:displayLabel]
73
+ return node[:displayLabel].capitalize if DISPLAY_LABEL_TO_ABSTRACT_TYPE.include? node[:displayLabel]
68
74
 
69
75
  node[:displayLabel].presence
70
76
  end
@@ -72,7 +78,7 @@ module Cocina
72
78
  def abstract_type(node, parallel: false)
73
79
  if node['type'].present?
74
80
  { type: node['type'].downcase }
75
- elsif Cocina::Models::Mapping::ToMods::Note.display_label_to_abstract_type.exclude?(node['displayLabel']) && !parallel
81
+ elsif DISPLAY_LABEL_TO_ABSTRACT_TYPE.exclude?(node['displayLabel']) && !parallel
76
82
  { type: 'abstract' }
77
83
  else
78
84
  {}
@@ -111,7 +117,8 @@ module Cocina
111
117
  end
112
118
 
113
119
  def table_of_contents
114
- all_toc_nodes = resource_element.xpath('mods:tableOfContents', mods: Description::DESC_METADATA_NS).select do |node|
120
+ all_toc_nodes = resource_element.xpath('mods:tableOfContents',
121
+ mods: Description::DESC_METADATA_NS).select do |node|
115
122
  note_present?(node)
116
123
  end
117
124
  altrepgroup_toc_nodes, other_toc_nodes = AltRepGroup.split(nodes: all_toc_nodes)
@@ -5,9 +5,42 @@ module Cocina
5
5
  module Mapping
6
6
  module FromMods
7
7
  # Maps MODS relatedItem to cocina relatedResource
8
- class RelatedResource
9
- TYPES = Cocina::Models::Mapping::ToMods::RelatedResource::TYPES.invert.freeze
10
- DETAIL_TYPES = Cocina::Models::Mapping::ToMods::RelatedResource::DETAIL_TYPES.invert.freeze
8
+ class RelatedResource # rubocop:disable Metrics/ClassLength
9
+ # see https://docs.google.com/spreadsheets/d/1d5PokzgXqNykvQeckG2ND43B6i9_CsjfIVwS_IsphS8/edit#gid=0
10
+ TYPES = {
11
+ 'has original version' => 'original',
12
+ 'has other format' => 'otherFormat',
13
+ 'has part' => 'constituent',
14
+ 'has version' => 'otherVersion',
15
+ 'in series' => 'series',
16
+ 'part of' => 'host',
17
+ 'preceded by' => 'preceding',
18
+ 'related to' => nil, # 'related to' is a null type by design
19
+ 'reviewed by' => 'reviewOf',
20
+ 'referenced by' => 'isReferencedBy',
21
+ 'references' => 'references',
22
+ 'succeeded by' => 'succeeding'
23
+ }.invert.freeze
24
+
25
+ DETAIL_TYPES = {
26
+ 'location within source' => 'part',
27
+ 'volume' => 'volume',
28
+ 'issue' => 'issue',
29
+ 'chapter' => 'chapter',
30
+ 'section' => 'section',
31
+ 'paragraph' => 'paragraph',
32
+ 'track' => 'track',
33
+ 'marker' => 'marker'
34
+ }.invert.freeze
35
+
36
+ OTHER_TYPES = [
37
+ 'supplement to',
38
+ 'supplemented by',
39
+ 'derived from',
40
+ 'source of',
41
+ 'version of record',
42
+ 'identical to'
43
+ ].freeze
11
44
 
12
45
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
13
46
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
@@ -52,7 +85,7 @@ module Cocina
52
85
  if related_item['type']
53
86
  item[:type] = normalized_type_for(related_item['type'])
54
87
  elsif (other_type = related_item['otherType'])
55
- if Cocina::Models::Mapping::ToMods::RelatedResource::OTHER_TYPES.include?(other_type)
88
+ if OTHER_TYPES.include?(other_type)
56
89
  item[:type] = other_type
57
90
  else
58
91
  item[:type] = 'related to'
@@ -55,8 +55,6 @@ module Cocina
55
55
  }.compact.presence
56
56
  end
57
57
 
58
- # rubocop:disable Metrics/CyclomaticComplexity
59
- # rubocop:disable Metrics/AbcSize
60
58
  def build_subject(subject_node)
61
59
  if subject_node['xlink:href']
62
60
  return { valueAt: subject_node['xlink:href'] } if subject_node.elements.empty?
@@ -96,8 +94,6 @@ module Cocina
96
94
  simple_item(first_child_node, attrs)
97
95
  end
98
96
  end
99
- # rubocop:enable Metrics/CyclomaticComplexity
100
- # rubocop:enable Metrics/AbcSize
101
97
 
102
98
  def temporal_range?(children_nodes)
103
99
  children_nodes.all? { |node| node.name == 'temporal' && node['point'] }
@@ -39,7 +39,9 @@ module Cocina
39
39
 
40
40
  def validate_sort_key
41
41
  # TODO: remove this validation by switching to dependentRequired in schema.json
42
- serials_links = catalog_links.select { |catalog_link| catalog_link[:catalog] == 'folio' && catalog_link[:sortKey].present? }
42
+ serials_links = catalog_links.select do |catalog_link|
43
+ catalog_link[:catalog] == 'folio' && catalog_link[:sortKey].present?
44
+ end
43
45
  serials_links.each do |catalog_link|
44
46
  # If partLabel is present, catalog_link is valid
45
47
  next if catalog_link[:partLabel].present?
@@ -22,9 +22,18 @@ module Cocina
22
22
 
23
23
  validate_obj(attributes, [])
24
24
 
25
- raise ValidationError, "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths_multiple.join(', ')}" unless error_paths_multiple.empty?
26
- raise ValidationError, "Blank value in description: #{error_paths_blank.join(', ')}" unless error_paths_blank.empty?
27
- raise ValidationError, "Missing type for value in description: #{error_paths_missing_title_type.join(', ')}" unless error_paths_missing_title_type.empty?
25
+ unless error_paths_multiple.empty?
26
+ raise ValidationError,
27
+ "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths_multiple.join(', ')}"
28
+ end
29
+ unless error_paths_blank.empty?
30
+ raise ValidationError,
31
+ "Blank value in description: #{error_paths_blank.join(', ')}"
32
+ end
33
+ return if error_paths_missing_title_type.empty?
34
+
35
+ raise ValidationError,
36
+ "Missing type for value in description: #{error_paths_missing_title_type.join(', ')}"
28
37
  end
29
38
 
30
39
  private
@@ -62,7 +71,9 @@ module Cocina
62
71
  end
63
72
 
64
73
  def validate_values_for_multiples(hash, path)
65
- return unless hash.count { |key, value| %w[value groupedValue structuredValue parallelValue].include?(key) && value.present? } > 1
74
+ return unless hash.count do |key, value|
75
+ %w[value groupedValue structuredValue parallelValue].include?(key) && value.present?
76
+ end > 1
66
77
 
67
78
  error_paths_multiple << path_to_s(path)
68
79
  end
@@ -39,6 +39,11 @@ module Cocina
39
39
  new(...).validate
40
40
  end
41
41
 
42
+ # @return [JSONSchemer::Schema]
43
+ def self.schema
44
+ @schema ||= JSONSchemer.schema(document)
45
+ end
46
+
42
47
  # @return [Hash] a hash representation of the schema.json document
43
48
  def self.document
44
49
  @document ||= begin
@@ -77,7 +82,7 @@ module Cocina
77
82
 
78
83
  # @return [JSONSchemer::Schema]
79
84
  def schema
80
- @schema ||= JSONSchemer.schema(self.class.document)
85
+ self.class.schema
81
86
  end
82
87
 
83
88
  # @return [String] the method name derived from the class name
@@ -48,7 +48,9 @@ module Cocina
48
48
  end
49
49
 
50
50
  def invalid_filenames_with_language_tags
51
- invalid_files.map { |invalid_file| "#{invalid_file[:filename] || invalid_file[:label]} (#{invalid_file[:languageTag]})" }
51
+ invalid_files.map do |invalid_file|
52
+ "#{invalid_file[:filename] || invalid_file[:label]} (#{invalid_file[:languageTag]})"
53
+ end
52
54
  end
53
55
 
54
56
  def language_tag_files
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.118.1'
5
+ VERSION = '0.119.0'
6
6
  end
7
7
  end
@@ -143,7 +143,8 @@ module Cocina
143
143
  end
144
144
 
145
145
  # rubocop:disable Metrics/ParameterLists
146
- def self.build_request_collection_properties(type:, version:, label:, title:, admin_policy_id:, source_id: nil, catkeys: [], folio_instance_hrids: [])
146
+ def self.build_request_collection_properties(type:, version:, label:, title:, admin_policy_id:, source_id: nil,
147
+ catkeys: [], folio_instance_hrids: [])
147
148
  {
148
149
  type: type,
149
150
  version: version,
@@ -228,7 +229,10 @@ module Cocina
228
229
  props[:administrative][:accessTemplate][:copyright] = copyright if copyright
229
230
  props[:administrative][:accessTemplate][:license] = license if license
230
231
  props[:administrative][:registrationWorkflow] = registration_workflow if registration_workflow
231
- props[:administrative][:collectionsForRegistration] = collections_for_registration if collections_for_registration
232
+ if collections_for_registration
233
+ props[:administrative][:collectionsForRegistration] =
234
+ collections_for_registration
235
+ end
232
236
  props.delete(:description) if without_description
233
237
  end
234
238
  end
data/schema.json CHANGED
@@ -1039,7 +1039,61 @@
1039
1039
  "description": "URL or other pointer to the location of the value of the descriptive element.",
1040
1040
  "type": "string"
1041
1041
  }
1042
- }
1042
+ },
1043
+ "anyOf": [
1044
+ {
1045
+ "required": ["value"]
1046
+ },
1047
+ {
1048
+ "required": ["code"]
1049
+ },
1050
+ {
1051
+ "required": ["uri"]
1052
+ },
1053
+ {
1054
+ "required": ["identifier"],
1055
+ "properties": {
1056
+ "identifier": {
1057
+ "minItems": 1
1058
+ }
1059
+ }
1060
+ },
1061
+ {
1062
+ "required": ["note"],
1063
+ "properties": {
1064
+ "note": {
1065
+ "minItems": 1
1066
+ }
1067
+ }
1068
+ },
1069
+ {
1070
+ "required": ["valueAt"]
1071
+ },
1072
+ {
1073
+ "required": ["structuredValue"],
1074
+ "properties": {
1075
+ "structuredValue": {
1076
+ "minItems": 1
1077
+ }
1078
+ }
1079
+ },
1080
+ {
1081
+ "required": ["parallelValue"],
1082
+ "properties": {
1083
+ "parallelValue": {
1084
+ "minItems": 1
1085
+ }
1086
+ }
1087
+ },
1088
+ {
1089
+ "required": ["groupedValue"],
1090
+ "properties": {
1091
+ "groupedValue": {
1092
+ "minItems": 1
1093
+ }
1094
+ }
1095
+ }
1096
+ ]
1043
1097
  }
1044
1098
  ]
1045
1099
  },