defra_ruby_validators 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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