metadata_presenter 3.3.2 → 3.3.4

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: 6b4dbad514bcffef84647d078cffbf0780d9913b2432f2ae2f9b266105017766
4
- data.tar.gz: a4e7481c08379633df45023fe4f3bce5296086a8328b3d3306afc3f11a36ad20
3
+ metadata.gz: b1383e7705f46897aab384b9e5e5f8af3fa252a68292c71e7ab4fb9ba810f003
4
+ data.tar.gz: '08a34570f899f09c6e6390ab54730febc3c19215ce7ff685005ae6fa90028671'
5
5
  SHA512:
6
- metadata.gz: a4caff0ac656b1356984b11588c402ead85557c3a3eff89219e6bf41ebc69fde21c61373827f28d90670a795bd61295f2d33d65cac919afaf27de92cfef17331
7
- data.tar.gz: 2aa8c5a38417c2a2e0d65a7892bc9413526539364e080e002b16a2df88a33384127a74f46f6c6fe8ad507ec5777c861688ebcc9bbc5f0fe787627a85e93d31d8
6
+ metadata.gz: 6a9461584ecb5471ef3f4e2dab87f24f10f22b317b0fcdd1f0b4b0126d2b84062f68159df671df6a6a358f99977b3dfd6fa48e1c5b0082028ad5c7834eabfc51
7
+ data.tar.gz: fadb737aaf8eb0a899bb0936268b3bea4187f318160ac99f396b9ce2904ae6b7f127f11e3ca3ffc4af91666db7d914c259497a55d3a2dff3f6eee026cbdff2f9
@@ -133,7 +133,6 @@ module MetadataPresenter
133
133
  end
134
134
 
135
135
  def answers_params
136
- params.permit(:page_slug, :save_for_later)
137
136
  params[:answers] ? params[:answers].permit! : {}
138
137
  end
139
138
 
@@ -44,11 +44,22 @@ module MetadataPresenter
44
44
 
45
45
  return {} unless file_details
46
46
 
47
- if file_details.is_a?(Hash) || file_details.is_a?(ActionController::Parameters)
48
- file_details.merge('original_filename' => sanitize(filename(update_filename(file_details['original_filename']))))
47
+ if file_details.is_a?(ActionController::Parameters)
48
+ unless file_details.permitted?
49
+ Rails.logger.warn("[PageAnswers#upload_answer] Permitting unfiltered params in component `#{component_id}`")
50
+ file_details.permit!
51
+ end
52
+
53
+ file_details.merge(
54
+ 'original_filename' => sanitize_filename(file_details['original_filename'])
55
+ )
56
+ elsif file_details.is_a?(Hash)
57
+ file_details.merge(
58
+ 'original_filename' => sanitize_filename(file_details['original_filename'])
59
+ )
49
60
  else
50
61
  {
51
- 'original_filename' => sanitize(filename(update_filename(file_details.original_filename))),
62
+ 'original_filename' => sanitize_filename(file_details.original_filename),
52
63
  'content_type' => file_details.content_type,
53
64
  'tempfile' => file_details.tempfile.path.to_s
54
65
  }
@@ -83,25 +94,27 @@ module MetadataPresenter
83
94
  return if answers[component_id].blank?
84
95
 
85
96
  if answers[component_id].is_a?(Array)
86
- answers[component_id].each { |answer| answer['original_filename'] = sanitize(filename(update_filename(answer['original_filename']))) }
97
+ answers[component_id].each { |answer| answer['original_filename'] = sanitize_filename(answer['original_filename']) }
87
98
  end
88
99
 
89
100
  answers[component_id] = answers[component_id].reject { |a| a['original_filename'].blank? }
90
101
  return answers
91
102
  end
92
103
 
104
+ return answers if answers.incoming_answer.blank?
105
+
93
106
  # uploading a new answer, this method will be called during multiple render operations
94
- if answers.incoming_answer.present? && answers.incoming_answer.is_a?(ActionController::Parameters)
95
- answers.incoming_answer[component_id].original_filename = sanitize(filename(update_filename(answers.incoming_answer[component_id].original_filename)))
107
+ if answers.incoming_answer.is_a?(ActionController::Parameters)
108
+ answers.incoming_answer[component_id].original_filename = sanitize_filename(answers.incoming_answer[component_id].original_filename)
96
109
  end
97
110
 
98
- if answers.incoming_answer.present? && answers.incoming_answer.is_a?(Hash)
99
- answers.incoming_answer['original_filename'] = sanitize(filename(update_filename(answers.incoming_answer['original_filename'])))
111
+ if answers.incoming_answer.is_a?(Hash)
112
+ answers.incoming_answer['original_filename'] = sanitize_filename(answers.incoming_answer['original_filename'])
100
113
  end
101
114
 
102
- if answers.incoming_answer.present? && answers.incoming_answer[component_id].is_a?(ActionDispatch::Http::UploadedFile)
115
+ if answers.incoming_answer[component_id].is_a?(ActionDispatch::Http::UploadedFile)
103
116
  answers.incoming_answer = {
104
- 'original_filename' => sanitize(filename(update_filename(answers.incoming_answer[component_id].original_filename))),
117
+ 'original_filename' => sanitize_filename(answers.incoming_answer[component_id].original_filename),
105
118
  'content_type' => answers.incoming_answer[component_id].content_type,
106
119
  'tempfile' => answers.incoming_answer[component_id].tempfile.path.to_s,
107
120
  'uuid' => SecureRandom.uuid
@@ -129,6 +142,10 @@ module MetadataPresenter
129
142
 
130
143
  private
131
144
 
145
+ def sanitize_filename(answer)
146
+ sanitize(filename(update_filename(answer)))
147
+ end
148
+
132
149
  def filename(path)
133
150
  return sanitize(path) if path.nil?
134
151
 
@@ -1,18 +1,7 @@
1
1
  module MetadataPresenter
2
- class AcceptValidator < UploadValidator
2
+ class AcceptValidator < BaseUploadValidator
3
3
  def error_name
4
4
  'accept'
5
5
  end
6
-
7
- def error_message_hash
8
- if component.type == 'multiupload'
9
- {
10
- control: page_answers.send(component.id)[component.id].last['original_filename'],
11
- schema_key.to_sym => component.validation[schema_key]
12
- }
13
- else
14
- super
15
- end
16
- end
17
6
  end
18
7
  end
@@ -0,0 +1,27 @@
1
+ module MetadataPresenter
2
+ class BaseUploadValidator < BaseValidator
3
+ def invalid_answer?
4
+ user_answer.error_name == error_name
5
+ end
6
+
7
+ def user_answer
8
+ page_answers.uploaded_files.find do |uploaded_file|
9
+ component.id == uploaded_file.component.id
10
+ end
11
+ end
12
+
13
+ def error_message_hash
14
+ super.merge(control:)
15
+ end
16
+
17
+ private
18
+
19
+ def control
20
+ if component.type == 'multiupload'
21
+ page_answers.send(component.id)[component.id].last['original_filename']
22
+ else
23
+ page_answers.send(component.id)['original_filename']
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ module MetadataPresenter
2
+ class CatchAllValidator < BaseValidator
3
+ ERROR_NAME_PREFIX = 'error.'.freeze
4
+
5
+ # NOTE: generic errors in other components can be implemented
6
+ # by introducing new case branching if neccessary.
7
+ def invalid_answer?
8
+ case component.type
9
+ when 'upload', 'multiupload'
10
+ upload_user_answer&.error_name.to_s.start_with?(ERROR_NAME_PREFIX)
11
+ else
12
+ false
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def upload_user_answer
19
+ page_answers.uploaded_files.find do |uploaded_file|
20
+ component.id == uploaded_file.component.id
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,13 +1,18 @@
1
1
  module MetadataPresenter
2
2
  class DateValidator < BaseValidator
3
3
  DATE_STRING_VALIDATIONS = %w[date_after date_before].freeze
4
+ YEAR_LOWER_BOUND = 1000
5
+ YEAR_UPPER_BOUND = 3000
4
6
 
5
7
  def invalid_answer?
6
- Date.strptime(
7
- "#{user_answer.year}-#{user_answer.month}-#{user_answer.day}",
8
- '%Y-%m-%d'
8
+ date = Date.civil(
9
+ user_answer.year.to_i, user_answer.month.to_i, user_answer.day.to_i
9
10
  )
10
11
 
12
+ # additional validations that `#civil` will not raise as errors
13
+ return true if date.year < YEAR_LOWER_BOUND
14
+ return true if date.year > YEAR_UPPER_BOUND
15
+
11
16
  false
12
17
  rescue Date::Error
13
18
  true
@@ -1,5 +1,5 @@
1
1
  module MetadataPresenter
2
- class MaxSizeValidator < UploadValidator
2
+ class MaxSizeValidator < BaseUploadValidator
3
3
  def error_name
4
4
  'invalid.too-large'
5
5
  end
@@ -1,22 +1,9 @@
1
1
  module MetadataPresenter
2
- class MultiuploadValidator < BaseValidator
2
+ class MultiuploadValidator < BaseUploadValidator
3
3
  def invalid_answer?
4
4
  user_answer.errors.any? { |error| error.attribute.to_s == error_name }
5
5
  end
6
6
 
7
- def user_answer
8
- page_answers.uploaded_files.find do |uploaded_file|
9
- component.id == uploaded_file.component.id
10
- end
11
- end
12
-
13
- def error_message_hash
14
- {
15
- control: page_answers.send(component.id)[component.id].last['original_filename'],
16
- schema_key.to_sym => component.validation[schema_key]
17
- }
18
- end
19
-
20
7
  def error_name
21
8
  'invalid.multiupload'
22
9
  end
@@ -21,29 +21,24 @@ module MetadataPresenter
21
21
  def validators
22
22
  components.map { |component|
23
23
  component_validations(component).map do |key|
24
- if key == 'max_files'
25
- 'MetadataPresenter::MaxFilesValidator'.constantize.new(
26
- **{
27
- page_answers:,
28
- component:
29
- }.merge(autocomplete_param(key))
30
- )
31
- else
32
- "MetadataPresenter::#{key.classify}Validator".constantize.new(
33
- **{
34
- page_answers:,
35
- component:
36
- }.merge(autocomplete_param(key))
37
- )
38
- end
24
+ "MetadataPresenter::#{key.camelize}Validator".constantize.new(
25
+ **{
26
+ page_answers:,
27
+ component:
28
+ }.merge(autocomplete_param(key))
29
+ )
39
30
  end
40
- }.compact.flatten
31
+ }.flatten.compact
41
32
  end
42
33
 
43
34
  def component_validations(component)
44
35
  return [] if component.validation.blank?
45
36
 
46
- component.validation.select { |_, value| value.present? }.keys
37
+ component.validation.compact_blank.keys + additional_validators
38
+ end
39
+
40
+ def additional_validators
41
+ %w[catch_all].freeze
47
42
  end
48
43
 
49
44
  def autocomplete_param(key)
@@ -1,5 +1,5 @@
1
1
  module MetadataPresenter
2
- class VirusScanValidator < UploadValidator
2
+ class VirusScanValidator < BaseUploadValidator
3
3
  def error_name
4
4
  'invalid.virus'
5
5
  end
@@ -115,7 +115,7 @@ en:
115
115
  continue: 'Continue'
116
116
  progress:
117
117
  heading: '%{service_name}'
118
- content_1: 'You have sucessfuly retrieved your saved information.'
118
+ content_1: 'You have successfully retrieved your saved information.'
119
119
  content_2: 'Here are the answers you have provided so far.'
120
120
  continue: 'Continue'
121
121
  footer:
@@ -0,0 +1,6 @@
1
+ {
2
+ "_id": "error.catch_all",
3
+ "_type": "string.error",
4
+ "description": "A generic validation error not handled by a more concrete validator",
5
+ "value": "We could not save your answer, please try again"
6
+ }
@@ -1,3 +1,3 @@
1
1
  module MetadataPresenter
2
- VERSION = '3.3.2'.freeze
2
+ VERSION = '3.3.4'.freeze
3
3
  end
@@ -120,7 +120,7 @@
120
120
  },
121
121
  "max_files": {
122
122
  "title": "Maximum files",
123
- "description": "The maximum number of fiels a user can upload",
123
+ "description": "The maximum number of files a user can upload",
124
124
  "type": "number",
125
125
  "minimum": 0
126
126
  },
@@ -464,9 +464,6 @@
464
464
  },
465
465
  "exclusive_minimum": {
466
466
  "$ref": "#/definitions/exclusive_minimum"
467
- },
468
- "max_files": {
469
- "$ref": "#/definitions/max_files"
470
467
  }
471
468
  }
472
469
  },
@@ -486,9 +483,6 @@
486
483
  },
487
484
  "exclusive_minimum": {
488
485
  "$ref": "#/definitions/errors_exclusive_minimum"
489
- },
490
- "max_files": {
491
- "$ref": "#/definitions/max_files"
492
486
  }
493
487
  }
494
488
  }
@@ -542,7 +536,7 @@
542
536
  "errors": {
543
537
  "properties": {
544
538
  "max_files": {
545
- "$ref": "#/definitions/max_files"
539
+ "$ref": "#/definitions/errors_max_files"
546
540
  }
547
541
  }
548
542
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metadata_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.2
4
+ version: 3.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - MoJ Forms
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-16 00:00:00.000000000 Z
11
+ date: 2023-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: govuk_design_system_formbuilder
@@ -266,16 +266,16 @@ dependencies:
266
266
  name: site_prism
267
267
  requirement: !ruby/object:Gem::Requirement
268
268
  requirements:
269
- - - '='
269
+ - - "<"
270
270
  - !ruby/object:Gem::Version
271
- version: '4.0'
271
+ version: '5.0'
272
272
  type: :development
273
273
  prerelease: false
274
274
  version_requirements: !ruby/object:Gem::Requirement
275
275
  requirements:
276
- - - '='
276
+ - - "<"
277
277
  - !ruby/object:Gem::Version
278
- version: '4.0'
278
+ version: '5.0'
279
279
  - !ruby/object:Gem::Dependency
280
280
  name: sqlite3
281
281
  requirement: !ruby/object:Gem::Requirement
@@ -373,7 +373,9 @@ files:
373
373
  - app/validators/email_confirmation_validator.rb
374
374
  - app/validators/metadata_presenter/accept_validator.rb
375
375
  - app/validators/metadata_presenter/autocomplete_validator.rb
376
+ - app/validators/metadata_presenter/base_upload_validator.rb
376
377
  - app/validators/metadata_presenter/base_validator.rb
378
+ - app/validators/metadata_presenter/catch_all_validator.rb
377
379
  - app/validators/metadata_presenter/date_after_validator.rb
378
380
  - app/validators/metadata_presenter/date_before_validator.rb
379
381
  - app/validators/metadata_presenter/date_validator.rb
@@ -389,7 +391,6 @@ files:
389
391
  - app/validators/metadata_presenter/multiupload_validator.rb
390
392
  - app/validators/metadata_presenter/number_validator.rb
391
393
  - app/validators/metadata_presenter/required_validator.rb
392
- - app/validators/metadata_presenter/upload_validator.rb
393
394
  - app/validators/metadata_presenter/validate_answers.rb
394
395
  - app/validators/metadata_presenter/validate_schema.rb
395
396
  - app/validators/metadata_presenter/virus_scan_validator.rb
@@ -490,6 +491,7 @@ files:
490
491
  - default_metadata/service/base.json
491
492
  - default_metadata/string/error.accept.json
492
493
  - default_metadata/string/error.autocomplete.json
494
+ - default_metadata/string/error.catch_all.json
493
495
  - default_metadata/string/error.date.json
494
496
  - default_metadata/string/error.date_after.json
495
497
  - default_metadata/string/error.date_before.json
@@ -1,20 +0,0 @@
1
- module MetadataPresenter
2
- class UploadValidator < BaseValidator
3
- def invalid_answer?
4
- user_answer.error_name == error_name
5
- end
6
-
7
- def user_answer
8
- page_answers.uploaded_files.find do |uploaded_file|
9
- component.id == uploaded_file.component.id
10
- end
11
- end
12
-
13
- def error_message_hash
14
- {
15
- control: page_answers.send(component.id)['original_filename'],
16
- schema_key.to_sym => component.validation[schema_key]
17
- }
18
- end
19
- end
20
- end