defra_ruby_validators 1.1.0 → 1.2.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -1
  3. data/config/locales/defra_ruby/validators/business_type_validator/en.yml +6 -0
  4. data/config/locales/defra_ruby/validators/email_validator/en.yml +7 -0
  5. data/config/locales/defra_ruby/validators/grid_reference_validator/en.yml +8 -0
  6. data/config/locales/defra_ruby/validators/location_validator/en.yml +6 -0
  7. data/config/locales/defra_ruby/validators/phone_number_validator/en.yml +8 -0
  8. data/config/locales/defra_ruby/validators/position_validator/en.yml +7 -0
  9. data/config/locales/defra_ruby/validators/token_validator/en.yml +7 -0
  10. data/config/locales/defra_ruby/validators/true_false_validator/en.yml +2 -1
  11. data/lib/defra_ruby/validators.rb +10 -0
  12. data/lib/defra_ruby/validators/base_validator.rb +2 -4
  13. data/lib/defra_ruby/validators/business_type_validator.rb +15 -0
  14. data/lib/defra_ruby/validators/companies_house_number_validator.rb +5 -5
  15. data/lib/defra_ruby/validators/concerns/can_validate_characters.rb +19 -0
  16. data/lib/defra_ruby/validators/concerns/can_validate_length.rb +18 -0
  17. data/lib/defra_ruby/validators/concerns/can_validate_presence.rb +18 -0
  18. data/lib/defra_ruby/validators/concerns/can_validate_selection.rb +6 -8
  19. data/lib/defra_ruby/validators/email_validator.rb +28 -0
  20. data/lib/defra_ruby/validators/grid_reference_validator.rb +55 -0
  21. data/lib/defra_ruby/validators/location_validator.rb +15 -0
  22. data/lib/defra_ruby/validators/phone_number_validator.rb +32 -0
  23. data/lib/defra_ruby/validators/position_validator.rb +22 -0
  24. data/lib/defra_ruby/validators/token_validator.rb +27 -0
  25. data/lib/defra_ruby/validators/true_false_validator.rb +2 -2
  26. data/lib/defra_ruby/validators/version.rb +1 -1
  27. data/spec/cassettes/company_no_inactive.yml +14 -14
  28. data/spec/cassettes/company_no_not_found.yml +15 -15
  29. data/spec/cassettes/company_no_valid.yml +14 -14
  30. data/spec/defra_ruby/validators/business_type_validator_spec.rb +30 -0
  31. data/spec/defra_ruby/validators/companies_house_number_validator_spec.rb +15 -15
  32. data/spec/defra_ruby/validators/email_validator_spec.rb +42 -0
  33. data/spec/defra_ruby/validators/grid_reference_validator_spec.rb +49 -0
  34. data/spec/defra_ruby/validators/location_validator_spec.rb +30 -0
  35. data/spec/defra_ruby/validators/phone_number_validator_spec.rb +55 -0
  36. data/spec/defra_ruby/validators/position_validator_spec.rb +47 -0
  37. data/spec/defra_ruby/validators/token_validator_spec.rb +41 -0
  38. data/spec/defra_ruby/validators/true_false_validator_spec.rb +11 -4
  39. data/spec/examples.txt +79 -44
  40. data/spec/spec_helper.rb +4 -0
  41. data/spec/support/helpers/text_generator.rb +17 -0
  42. data/spec/support/helpers/translator.rb +2 -3
  43. data/spec/support/shared_examples/validators/characters_validator.rb +25 -0
  44. data/spec/support/shared_examples/validators/invalid_record.rb +13 -3
  45. data/spec/support/shared_examples/validators/length_validator.rb +25 -0
  46. data/spec/support/shared_examples/validators/presence_validator.rb +25 -0
  47. data/spec/support/shared_examples/validators/selection_validator.rb +11 -11
  48. metadata +70 -19
  49. data/spec/support/dotenv.rb +0 -4
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Validators
5
+ class LocationValidator < BaseValidator
6
+ include CanValidateSelection
7
+
8
+ def validate_each(record, _attribute, value)
9
+ valid_options = %w[england northern_ireland scotland wales]
10
+
11
+ value_is_included?(record, :location, value, valid_options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "phonelib"
4
+
5
+ module DefraRuby
6
+ module Validators
7
+ class PhoneNumberValidator < BaseValidator
8
+ include CanValidatePresence
9
+ include CanValidateLength
10
+
11
+ MAX_LENGTH = 15
12
+
13
+ def validate_each(record, attribute, value)
14
+ return false unless value_is_present?(record, :phone_number, value)
15
+ return false unless value_is_not_too_long?(record, :phone_number, value, MAX_LENGTH)
16
+
17
+ valid_format?(record, attribute, value)
18
+ end
19
+
20
+ private
21
+
22
+ def valid_format?(record, attribute, value)
23
+ Phonelib.default_country = "GB"
24
+ return true if Phonelib.valid?(value)
25
+
26
+ record.errors[attribute] << error_message(:phone_number, :invalid_format)
27
+ false
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Validators
5
+ class PositionValidator < BaseValidator
6
+ include CanValidateCharacters
7
+ include CanValidateLength
8
+
9
+ MAX_LENGTH = 70
10
+
11
+ def validate_each(record, _attribute, value)
12
+ # Position is an optional field so its immediately valid if it's blank
13
+ return true if value.blank?
14
+ return false unless value_has_no_invalid_characters?(record, :position, value)
15
+
16
+ value_is_not_too_long?(record, :position, value, MAX_LENGTH)
17
+ value_has_no_invalid_characters?(record, :position, value)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefraRuby
4
+ module Validators
5
+ class TokenValidator < BaseValidator
6
+ include CanValidatePresence
7
+
8
+ def validate_each(record, attribute, value)
9
+ return false unless value_is_present?(record, :token, value)
10
+
11
+ valid_format?(record, attribute, value)
12
+ end
13
+
14
+ private
15
+
16
+ def valid_format?(record, attribute, value)
17
+ # The token is assumed to have been generated using
18
+ # https://github.com/robertomiranda/has_secure_token which creates
19
+ # 24-character unique tokens
20
+ return true if value.length == 24
21
+
22
+ record.errors[attribute] << error_message(:token, :invalid_format)
23
+ false
24
+ end
25
+ end
26
+ end
27
+ end
@@ -5,10 +5,10 @@ module DefraRuby
5
5
  class TrueFalseValidator < BaseValidator
6
6
  include CanValidateSelection
7
7
 
8
- def validate_each(record, attribute, value)
8
+ def validate_each(record, _attribute, value)
9
9
  valid_options = %w[true false]
10
10
 
11
- value_is_included?(record, attribute, value, valid_options)
11
+ value_is_included?(record, :attribute, value, valid_options)
12
12
  end
13
13
  end
14
14
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module DefraRuby
4
4
  module Validators
5
- VERSION = "1.1.0"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  end
@@ -12,7 +12,7 @@ http_interactions:
12
12
  Accept-Encoding:
13
13
  - gzip, deflate
14
14
  User-Agent:
15
- - rest-client/2.0.2 (darwin18.2.0 x86_64) ruby/2.4.2p198
15
+ - rest-client/2.0.2 (darwin16.7.0 x86_64) ruby/2.4.2p198
16
16
  Host:
17
17
  - api.companieshouse.gov.uk
18
18
  Authorization:
@@ -22,6 +22,14 @@ http_interactions:
22
22
  code: 200
23
23
  message: OK
24
24
  headers:
25
+ Date:
26
+ - Tue, 06 Aug 2019 09:09:38 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Content-Length:
30
+ - '979'
31
+ Connection:
32
+ - keep-alive
25
33
  Access-Control-Allow-Credentials:
26
34
  - 'true'
27
35
  Access-Control-Allow-Headers:
@@ -36,26 +44,18 @@ http_interactions:
36
44
  - '3600'
37
45
  Cache-Control:
38
46
  - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
39
- Content-Type:
40
- - application/json
41
- Date:
42
- - Tue, 04 Jun 2019 22:42:41 GMT
43
47
  Pragma:
44
48
  - no-cache
45
- Server:
46
- - CompaniesHouse
47
49
  X-Ratelimit-Limit:
48
50
  - '600'
49
51
  X-Ratelimit-Remain:
50
- - '599'
52
+ - '595'
51
53
  X-Ratelimit-Reset:
52
- - '1559688461'
54
+ - '1565082737'
53
55
  X-Ratelimit-Window:
54
56
  - 5m
55
- Content-Length:
56
- - '979'
57
- Connection:
58
- - keep-alive
57
+ Server:
58
+ - CompaniesHouse
59
59
  body:
60
60
  encoding: UTF-8
61
61
  string: '{"sic_codes":["82990"],"company_number":"07281919","has_been_liquidated":false,"accounts":{"last_accounts":{"made_up_to":"2013-06-30","type":"total-exemption-small"},"accounting_reference_date":{"day":"30","month":"06"}},"last_full_members_list_date":"2014-06-11","status":"active","type":"ltd","date_of_creation":"2010-06-11","registered_office_address":{"postal_code":"HA8
@@ -63,5 +63,5 @@ http_interactions:
63
63
  Elizabeth House","address_line_2":"54-58 High Street"},"undeliverable_registered_office_address":false,"company_name":"DIRECT
64
64
  SKIPS UK LTD","annual_return":{"last_made_up_to":"2014-06-11"},"jurisdiction":"england-wales","etag":"1cdef5bc2a020b3e9003b086033b64b78bcb28f6","company_status":"dissolved","has_insolvency_history":false,"has_charges":false,"links":{"self":"/company/07281919","filing_history":"/company/07281919/filing-history","officers":"/company/07281919/officers"},"date_of_cessation":"2016-01-05","can_file":false}'
65
65
  http_version:
66
- recorded_at: Tue, 04 Jun 2019 22:42:41 GMT
66
+ recorded_at: Tue, 06 Aug 2019 09:09:36 GMT
67
67
  recorded_with: VCR 4.0.0
@@ -12,7 +12,7 @@ http_interactions:
12
12
  Accept-Encoding:
13
13
  - gzip, deflate
14
14
  User-Agent:
15
- - rest-client/2.0.2 (darwin18.2.0 x86_64) ruby/2.4.2p198
15
+ - rest-client/2.0.2 (darwin16.7.0 x86_64) ruby/2.4.2p198
16
16
  Host:
17
17
  - api.companieshouse.gov.uk
18
18
  Authorization:
@@ -22,6 +22,14 @@ http_interactions:
22
22
  code: 404
23
23
  message: Not Found
24
24
  headers:
25
+ Date:
26
+ - Tue, 06 Aug 2019 09:09:39 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Content-Length:
30
+ - '70'
31
+ Connection:
32
+ - keep-alive
25
33
  Access-Control-Allow-Credentials:
26
34
  - 'true'
27
35
  Access-Control-Allow-Headers:
@@ -36,29 +44,21 @@ http_interactions:
36
44
  - '3600'
37
45
  Cache-Control:
38
46
  - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
39
- Content-Type:
40
- - application/json
41
- Date:
42
- - Tue, 04 Jun 2019 22:42:41 GMT
43
47
  Pragma:
44
48
  - no-cache
45
- Server:
46
- - CompaniesHouse
47
49
  X-Ratelimit-Limit:
48
50
  - '600'
49
51
  X-Ratelimit-Remain:
50
- - '598'
52
+ - '593'
51
53
  X-Ratelimit-Reset:
52
- - '1559688461'
54
+ - '1565082737'
53
55
  X-Ratelimit-Window:
54
56
  - 5m
55
- Content-Length:
56
- - '70'
57
- Connection:
58
- - keep-alive
57
+ Server:
58
+ - CompaniesHouse
59
59
  body:
60
60
  encoding: UTF-8
61
- string: '{"errors":[{"type":"ch:service","error":"company-profile-not-found"}]}'
61
+ string: '{"errors":[{"error":"company-profile-not-found","type":"ch:service"}]}'
62
62
  http_version:
63
- recorded_at: Tue, 04 Jun 2019 22:42:41 GMT
63
+ recorded_at: Tue, 06 Aug 2019 09:09:36 GMT
64
64
  recorded_with: VCR 4.0.0
@@ -12,7 +12,7 @@ http_interactions:
12
12
  Accept-Encoding:
13
13
  - gzip, deflate
14
14
  User-Agent:
15
- - rest-client/2.0.2 (darwin18.2.0 x86_64) ruby/2.4.2p198
15
+ - rest-client/2.0.2 (darwin16.7.0 x86_64) ruby/2.4.2p198
16
16
  Host:
17
17
  - api.companieshouse.gov.uk
18
18
  Authorization:
@@ -22,6 +22,14 @@ http_interactions:
22
22
  code: 200
23
23
  message: OK
24
24
  headers:
25
+ Date:
26
+ - Tue, 06 Aug 2019 09:09:39 GMT
27
+ Content-Type:
28
+ - application/json
29
+ Content-Length:
30
+ - '1178'
31
+ Connection:
32
+ - keep-alive
25
33
  Access-Control-Allow-Credentials:
26
34
  - 'true'
27
35
  Access-Control-Allow-Headers:
@@ -36,30 +44,22 @@ http_interactions:
36
44
  - '3600'
37
45
  Cache-Control:
38
46
  - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
39
- Content-Type:
40
- - application/json
41
- Date:
42
- - Tue, 04 Jun 2019 22:42:41 GMT
43
47
  Pragma:
44
48
  - no-cache
45
- Server:
46
- - CompaniesHouse
47
49
  X-Ratelimit-Limit:
48
50
  - '600'
49
51
  X-Ratelimit-Remain:
50
- - '597'
52
+ - '594'
51
53
  X-Ratelimit-Reset:
52
- - '1559688461'
54
+ - '1565082737'
53
55
  X-Ratelimit-Window:
54
56
  - 5m
55
- Content-Length:
56
- - '1178'
57
- Connection:
58
- - keep-alive
57
+ Server:
58
+ - CompaniesHouse
59
59
  body:
60
60
  encoding: UTF-8
61
61
  string: '{"type":"ltd","company_name":"0800 WASTE LTD.","has_insolvency_history":false,"accounts":{"next_due":"2019-09-30","next_made_up_to":"2018-12-31","next_accounts":{"overdue":false,"period_start_on":"2018-01-01","due_on":"2019-09-30","period_end_on":"2018-12-31"},"accounting_reference_date":{"month":"12","day":"31"},"last_accounts":{"period_end_on":"2017-12-31","period_start_on":"2017-01-01","made_up_to":"2017-12-31"},"overdue":false},"undeliverable_registered_office_address":false,"etag":"0ec9d00cab0ffee2ef1f5d59f4f714fa5b1618f5","company_number":"09360070","registered_office_address":{"postal_code":"SM3
62
62
  9ND","locality":"Sutton","region":"Surrey","address_line_1":"21 Haslam Avenue"},"jurisdiction":"england-wales","date_of_creation":"2014-12-18","company_status":"active","has_charges":false,"sic_codes":["38110"],"last_full_members_list_date":"2015-12-18","confirmation_statement":{"overdue":false,"next_made_up_to":"2020-01-23","last_made_up_to":"2019-01-23","next_due":"2020-02-06"},"links":{"self":"/company/09360070","filing_history":"/company/09360070/filing-history","officers":"/company/09360070/officers"},"registered_office_is_in_dispute":false,"can_file":true}'
63
63
  http_version:
64
- recorded_at: Tue, 04 Jun 2019 22:42:41 GMT
64
+ recorded_at: Tue, 06 Aug 2019 09:09:36 GMT
65
65
  recorded_with: VCR 4.0.0
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Test
6
+ BusinessTypeValidatable = Struct.new(:business_type) do
7
+ include ActiveModel::Validations
8
+
9
+ validates :business_type, "defra_ruby/validators/business_type": true
10
+ end
11
+ end
12
+
13
+ module DefraRuby
14
+ module Validators
15
+ RSpec.describe BusinessTypeValidator do
16
+
17
+ valid_type = %w[soleTrader limitedCompany partnership limitedLiabilityPartnership localAuthority charity].sample
18
+ invalid_type = "coven"
19
+
20
+ it_behaves_like("a validator")
21
+ it_behaves_like(
22
+ "a selection validator",
23
+ BusinessTypeValidator,
24
+ Test::BusinessTypeValidatable,
25
+ :business_type,
26
+ valid: valid_type, invalid: invalid_type
27
+ )
28
+ end
29
+ end
30
+ end
@@ -38,9 +38,9 @@ module DefraRuby
38
38
  context "because it is blank" do
39
39
  validatable = Test::CompaniesHouseNumberValidatable.new
40
40
  error_message = Helpers::Translator.error_message(
41
- klass: CompaniesHouseNumberValidator,
42
- attribute: :company_no,
43
- error: :blank
41
+ CompaniesHouseNumberValidator,
42
+ :company_no,
43
+ :blank
44
44
  )
45
45
 
46
46
  it_behaves_like "an invalid record", validatable, :company_no, error_message
@@ -49,9 +49,9 @@ module DefraRuby
49
49
  context "because the format is wrong" do
50
50
  validatable = Test::CompaniesHouseNumberValidatable.new(invalid_format_number)
51
51
  error_message = Helpers::Translator.error_message(
52
- klass: CompaniesHouseNumberValidator,
53
- attribute: :company_no,
54
- error: :invalid
52
+ CompaniesHouseNumberValidator,
53
+ :company_no,
54
+ :invalid
55
55
  )
56
56
 
57
57
  it_behaves_like "an invalid record", validatable, :company_no, error_message
@@ -64,9 +64,9 @@ module DefraRuby
64
64
 
65
65
  validatable = Test::CompaniesHouseNumberValidatable.new(unknown_number)
66
66
  error_message = Helpers::Translator.error_message(
67
- klass: CompaniesHouseNumberValidator,
68
- attribute: :company_no,
69
- error: :not_found
67
+ CompaniesHouseNumberValidator,
68
+ :company_no,
69
+ :not_found
70
70
  )
71
71
 
72
72
  it_behaves_like "an invalid record", validatable, :company_no, error_message
@@ -79,9 +79,9 @@ module DefraRuby
79
79
 
80
80
  validatable = Test::CompaniesHouseNumberValidatable.new(inactive_number)
81
81
  error_message = Helpers::Translator.error_message(
82
- klass: CompaniesHouseNumberValidator,
83
- attribute: :company_no,
84
- error: :inactive
82
+ CompaniesHouseNumberValidator,
83
+ :company_no,
84
+ :inactive
85
85
  )
86
86
 
87
87
  it_behaves_like "an invalid record", validatable, :company_no, error_message
@@ -95,9 +95,9 @@ module DefraRuby
95
95
 
96
96
  validatable = Test::CompaniesHouseNumberValidatable.new(valid_numbers.sample)
97
97
  error_message = Helpers::Translator.error_message(
98
- klass: CompaniesHouseNumberValidator,
99
- attribute: :company_no,
100
- error: :error
98
+ CompaniesHouseNumberValidator,
99
+ :company_no,
100
+ :error
101
101
  )
102
102
 
103
103
  it_behaves_like "an invalid record", validatable, :company_no, error_message
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Test
6
+ EmailValidatable = Struct.new(:email) do
7
+ include ActiveModel::Validations
8
+
9
+ validates :email, "defra_ruby/validators/email": true
10
+ end
11
+ end
12
+
13
+ module DefraRuby
14
+ module Validators
15
+ RSpec.describe EmailValidator, type: :model do
16
+
17
+ valid_email = "test@example.com"
18
+ invalid_email = "foo@bar"
19
+
20
+ it_behaves_like("a validator")
21
+ it_behaves_like(
22
+ "a presence validator",
23
+ EmailValidator,
24
+ Test::EmailValidatable,
25
+ :email,
26
+ valid: valid_email
27
+ )
28
+
29
+ describe "#validate_each" do
30
+ context "when the email is not valid" do
31
+ context "because the email is not correctly formatted" do
32
+ validatable = Test::EmailValidatable.new(invalid_email)
33
+
34
+ error_message = Helpers::Translator.error_message(EmailValidator, :email, :invalid_format)
35
+
36
+ it_behaves_like "an invalid record", validatable, :email, error_message
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Test
6
+ GridReferenceValidatable = Struct.new(:grid_reference) do
7
+ include ActiveModel::Validations
8
+
9
+ validates :grid_reference, "defra_ruby/validators/grid_reference": true
10
+ end
11
+ end
12
+
13
+ module DefraRuby
14
+ module Validators
15
+ RSpec.describe GridReferenceValidator, type: :model do
16
+
17
+ valid_grid_reference = "ST 58337 72855" # Bristol, City of Bristol
18
+ invalid_grid_reference = "58337 72855"
19
+ non_coordinate_grid_reference = "AA 12345 67890"
20
+
21
+ it_behaves_like("a validator")
22
+ it_behaves_like(
23
+ "a presence validator",
24
+ GridReferenceValidator,
25
+ Test::GridReferenceValidatable,
26
+ :grid_reference,
27
+ valid: valid_grid_reference
28
+ )
29
+
30
+ describe "#validate_each" do
31
+ context "when the grid reference is not valid" do
32
+ context "because the grid reference is not correctly formatted" do
33
+ validatable = Test::GridReferenceValidatable.new(invalid_grid_reference)
34
+ error_message = Helpers::Translator.error_message(GridReferenceValidator, :grid_reference, :wrong_format)
35
+
36
+ it_behaves_like "an invalid record", validatable, :grid_reference, error_message
37
+ end
38
+
39
+ context "because the grid reference is not a coordinate" do
40
+ validatable = Test::GridReferenceValidatable.new(non_coordinate_grid_reference)
41
+ error_message = Helpers::Translator.error_message(GridReferenceValidator, :grid_reference, :invalid)
42
+
43
+ it_behaves_like "an invalid record", validatable, :grid_reference, error_message
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end