cocina-models 0.92.0 → 0.93.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fb90197036280ad978dc4e59b548fcb954d7b602799294cfdde8bd3ef2a1568
4
- data.tar.gz: fd7c2c49522772f866dc04d629296c537f88d88dd8943ce4b74bb77460be31d9
3
+ metadata.gz: 9cf74f9126fce8106b3bfd5964c11731c460546a4f457da9ba7f35f895243c7a
4
+ data.tar.gz: 58467364ec8a96eac4f6d335dce400c0086833830f5704e263bae7365741d473
5
5
  SHA512:
6
- metadata.gz: 84a09b86f9f922ba9b8c433760fe3613035d72cba102f5a93dc9e7ec07a4d7bfdef5f449375fa4792eb0b8045f3324f23360183b0f9b5aa8ea21082336681b22
7
- data.tar.gz: 93b59a61650aae4c19cab66d84a216f66f65a289444e58fc48fdbd9088d33dd083fe9c57f57971574dae13a0b21ab4453ee48f8bad14f408ee3149534eb2aa99
6
+ metadata.gz: e2106344f663362d1609f5e40daf001c43f976abbbe7ae8a43c52295b2a2e280952c7d6d01b6f6b4cbdf124a07c26372bdfc17f9a903cce666edc39ba3b3db35
7
+ data.tar.gz: 5675d10901a099d8869baed51c4bdb82608305053d0e830130c28577644daddf73a650410cb20425e4e27ff4dfc60188f0e2cb0b77954c49bd3f00980ee56cf1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.92.0)
4
+ cocina-models (0.93.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -97,7 +97,7 @@ GEM
97
97
  racc
98
98
  patience_diff (1.2.0)
99
99
  optimist (~> 3.0)
100
- racc (1.7.1)
100
+ racc (1.7.3)
101
101
  rack (3.0.8)
102
102
  rainbow (3.1.1)
103
103
  rake (13.1.0)
@@ -23,9 +23,9 @@ module Cocina
23
23
  # MIME Type of the File.
24
24
  attribute? :hasMimeType, Types::Strict::String
25
25
  # BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
26
- attribute? :languageTag, Types::Strict::String
26
+ attribute? :languageTag, LanguageTag.optional
27
27
  # Use for the File.
28
- attribute? :use, Types::Strict::String
28
+ attribute? :use, FileUse.optional
29
29
  attribute :hasMessageDigests, Types::Strict::Array.of(MessageDigest).default([].freeze)
30
30
  attribute(:access, FileAccess.default { FileAccess.new })
31
31
  attribute(:administrative, FileAdministrative.default { FileAdministrative.new })
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ FileUse = Types::String
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ LanguageTag = Types::String
6
+ end
7
+ end
@@ -13,9 +13,11 @@ module Cocina
13
13
  attribute? :size, Types::Strict::Integer
14
14
  attribute :version, Types::Strict::Integer
15
15
  attribute? :hasMimeType, Types::Strict::String
16
- attribute? :languageTag, Types::Strict::String
16
+ # BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
17
+ attribute? :languageTag, LanguageTag.optional
17
18
  attribute? :externalIdentifier, Types::Strict::String
18
- attribute? :use, Types::Strict::String
19
+ # Use for the File.
20
+ attribute? :use, FileUse.optional
19
21
  attribute :hasMessageDigests, Types::Strict::Array.of(MessageDigest).default([].freeze)
20
22
  attribute(:access, FileAccess.default { FileAccess.new })
21
23
  attribute(:administrative, FileAdministrative.default { FileAdministrative.new })
@@ -39,12 +39,7 @@ module Cocina
39
39
  end
40
40
 
41
41
  def invalid_files
42
- @invalid_files ||=
43
- [].tap do |invalid_files|
44
- files.each do |file|
45
- invalid_files << file if invalid?(file)
46
- end
47
- end
42
+ @invalid_files ||= files.select { |file| invalid?(file) }
48
43
  end
49
44
 
50
45
  def invalid_filenames
@@ -12,7 +12,8 @@ module Cocina
12
12
  def initialize(clazz, attributes)
13
13
  @clazz = clazz
14
14
  @attributes = attributes
15
- @error_paths = []
15
+ @error_paths_multiple = []
16
+ @error_paths_blank = []
16
17
  end
17
18
 
18
19
  def validate
@@ -20,21 +21,21 @@ module Cocina
20
21
 
21
22
  validate_obj(attributes, [])
22
23
 
23
- return if error_paths.empty?
24
-
25
- raise ValidationError, "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths.join(', ')}"
24
+ raise ValidationError, "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths_multiple.join(', ')}" unless error_paths_multiple.empty?
25
+ raise ValidationError, "Blank value in description: #{error_paths_blank.join(', ')}" unless error_paths_blank.empty?
26
26
  end
27
27
 
28
28
  private
29
29
 
30
- attr_reader :clazz, :attributes, :error_paths
30
+ attr_reader :clazz, :attributes, :error_paths_blank, :error_paths_multiple
31
31
 
32
32
  def meets_preconditions?
33
33
  [Cocina::Models::Description, Cocina::Models::RequestDescription].include?(clazz)
34
34
  end
35
35
 
36
36
  def validate_hash(hash, path)
37
- validate_values(hash, path)
37
+ validate_values_for_blanks(hash, path)
38
+ validate_values_for_multiples(hash, path)
38
39
  hash.each do |key, obj|
39
40
  validate_obj(obj, path + [key])
40
41
  end
@@ -51,10 +52,16 @@ module Cocina
51
52
  validate_array(obj, path) if obj.is_a?(Array)
52
53
  end
53
54
 
54
- def validate_values(hash, path)
55
+ def validate_values_for_blanks(hash, path)
56
+ return unless hash[:value] && hash[:value].is_a?(String) && /\A\s+\z/.match?(hash[:value]) # rubocop:disable Style/SafeNavigation
57
+
58
+ error_paths_blank << path_to_s(path)
59
+ end
60
+
61
+ def validate_values_for_multiples(hash, path)
55
62
  return unless hash.count { |key, value| %i[value groupedValue structuredValue parallelValue].include?(key) && value.present? } > 1
56
63
 
57
- error_paths << path_to_s(path)
64
+ error_paths_multiple << path_to_s(path)
58
65
  end
59
66
 
60
67
  def path_to_s(path)
@@ -17,10 +17,10 @@ module Cocina
17
17
  def validate
18
18
  return unless meets_preconditions?
19
19
 
20
- return if valid_language_tag?
20
+ return if invalid_files.empty?
21
21
 
22
- raise ValidationError, 'The provided language tag is not valid according to RFC 4646: ' \
23
- "#{attributes[:languageTag]}"
22
+ raise ValidationError, 'Some files have invalid language tags according to RFC 4646: ' \
23
+ "#{invalid_filenames_with_language_tags.join(', ')}"
24
24
  end
25
25
 
26
26
  private
@@ -28,19 +28,45 @@ module Cocina
28
28
  attr_reader :clazz, :attributes
29
29
 
30
30
  def meets_preconditions?
31
- file? && attributes[:languageTag].present?
31
+ dro?
32
32
  end
33
33
 
34
- def file?
35
- (clazz::TYPES & File::TYPES).any?
34
+ def dro?
35
+ (clazz::TYPES & DRO::TYPES).any?
36
36
  rescue NameError
37
37
  false
38
38
  end
39
39
 
40
- def valid_language_tag?
41
- parsed_tag = I18n::Locale::Tag::Rfc4646.tag(attributes[:languageTag])
40
+ def valid_language_tag?(file)
41
+ # I18n::Locale::Tag::Rfc4646.tag will return an instance of I18n::Locale::Tag::Rfc4646 (with fields like language, script,
42
+ # region) for strings that can be parsed according to RFC 4646, and nil for strings that do not conform to the spec.
43
+ I18n::Locale::Tag::Rfc4646.tag(file[:languageTag]).present?
44
+ end
45
+
46
+ def invalid_files
47
+ @invalid_files ||= language_tag_files.reject { |file| valid_language_tag?(file) }
48
+ end
49
+
50
+ def invalid_filenames_with_language_tags
51
+ invalid_files.map { |invalid_file| "#{invalid_file[:filename] || invalid_file[:label]} (#{invalid_file[:languageTag]})" }
52
+ end
53
+
54
+ def language_tag_files
55
+ files.select { |file| file[:languageTag].present? }
56
+ end
57
+
58
+ def files
59
+ [].tap do |files|
60
+ next if attributes.dig(:structural, :contains).nil?
61
+
62
+ attributes[:structural][:contains].each do |fileset|
63
+ next if fileset.dig(:structural, :contains).nil?
42
64
 
43
- parsed_tag.present? && parsed_tag.is_a?(I18n::Locale::Tag::Rfc4646)
65
+ fileset[:structural][:contains].each do |file|
66
+ files << file
67
+ end
68
+ end
69
+ end
44
70
  end
45
71
  end
46
72
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.92.0'
5
+ VERSION = '0.93.0'
6
6
  end
7
7
  end
data/openapi.yml CHANGED
@@ -1045,11 +1045,9 @@ components:
1045
1045
  description: MIME Type of the File.
1046
1046
  type: string
1047
1047
  languageTag:
1048
- description: "BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang"
1049
- type: string
1048
+ $ref: '#/components/schemas/LanguageTag'
1050
1049
  use:
1051
- description: Use for the File.
1052
- type: string
1050
+ $ref: '#/components/schemas/FileUse'
1053
1051
  hasMessageDigests:
1054
1052
  type: array
1055
1053
  items:
@@ -1144,6 +1142,10 @@ components:
1144
1142
  type: array
1145
1143
  items:
1146
1144
  $ref: '#/components/schemas/File'
1145
+ FileUse:
1146
+ description: Use for the File.
1147
+ type: string
1148
+ nullable: true
1147
1149
  FolioCatalogLink:
1148
1150
  description: A linkage between an object and a Folio catalog record
1149
1151
  type: object
@@ -1272,6 +1274,10 @@ components:
1272
1274
  valueLanguage:
1273
1275
  # description: present for mapping to additional schemas in the future and for consistency but not otherwise used
1274
1276
  $ref: "#/components/schemas/DescriptiveValueLanguage"
1277
+ LanguageTag:
1278
+ description: "BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang"
1279
+ type: string
1280
+ nullable: true
1275
1281
  License:
1276
1282
  description: The license governing reuse of the DRO. Should be an IRI for known licenses (i.e. CC, RightsStatement.org URI, etc.).
1277
1283
  type: string
@@ -1779,11 +1785,11 @@ components:
1779
1785
  hasMimeType:
1780
1786
  type: string
1781
1787
  languageTag:
1782
- type: string
1788
+ $ref: '#/components/schemas/LanguageTag'
1783
1789
  externalIdentifier:
1784
1790
  type: string
1785
1791
  use:
1786
- type: string
1792
+ $ref: '#/components/schemas/FileUse'
1787
1793
  hasMessageDigests:
1788
1794
  type: array
1789
1795
  items:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.92.0
4
+ version: 0.93.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-02 00:00:00.000000000 Z
11
+ date: 2023-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -429,11 +429,13 @@ files:
429
429
  - lib/cocina/models/file_set.rb
430
430
  - lib/cocina/models/file_set_structural.rb
431
431
  - lib/cocina/models/file_set_type.rb
432
+ - lib/cocina/models/file_use.rb
432
433
  - lib/cocina/models/folio_catalog_link.rb
433
434
  - lib/cocina/models/geographic.rb
434
435
  - lib/cocina/models/identification.rb
435
436
  - lib/cocina/models/lane_medical_barcode.rb
436
437
  - lib/cocina/models/language.rb
438
+ - lib/cocina/models/language_tag.rb
437
439
  - lib/cocina/models/license.rb
438
440
  - lib/cocina/models/location_based_access.rb
439
441
  - lib/cocina/models/location_based_download_access.rb