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.
- checksums.yaml +4 -4
- data/README.md +88 -1
- data/config/locales/defra_ruby/validators/business_type_validator/en.yml +6 -0
- data/config/locales/defra_ruby/validators/email_validator/en.yml +7 -0
- data/config/locales/defra_ruby/validators/grid_reference_validator/en.yml +8 -0
- data/config/locales/defra_ruby/validators/location_validator/en.yml +6 -0
- data/config/locales/defra_ruby/validators/phone_number_validator/en.yml +8 -0
- data/config/locales/defra_ruby/validators/position_validator/en.yml +7 -0
- data/config/locales/defra_ruby/validators/token_validator/en.yml +7 -0
- data/config/locales/defra_ruby/validators/true_false_validator/en.yml +2 -1
- data/lib/defra_ruby/validators.rb +10 -0
- data/lib/defra_ruby/validators/base_validator.rb +2 -4
- data/lib/defra_ruby/validators/business_type_validator.rb +15 -0
- data/lib/defra_ruby/validators/companies_house_number_validator.rb +5 -5
- data/lib/defra_ruby/validators/concerns/can_validate_characters.rb +19 -0
- data/lib/defra_ruby/validators/concerns/can_validate_length.rb +18 -0
- data/lib/defra_ruby/validators/concerns/can_validate_presence.rb +18 -0
- data/lib/defra_ruby/validators/concerns/can_validate_selection.rb +6 -8
- data/lib/defra_ruby/validators/email_validator.rb +28 -0
- data/lib/defra_ruby/validators/grid_reference_validator.rb +55 -0
- data/lib/defra_ruby/validators/location_validator.rb +15 -0
- data/lib/defra_ruby/validators/phone_number_validator.rb +32 -0
- data/lib/defra_ruby/validators/position_validator.rb +22 -0
- data/lib/defra_ruby/validators/token_validator.rb +27 -0
- data/lib/defra_ruby/validators/true_false_validator.rb +2 -2
- data/lib/defra_ruby/validators/version.rb +1 -1
- data/spec/cassettes/company_no_inactive.yml +14 -14
- data/spec/cassettes/company_no_not_found.yml +15 -15
- data/spec/cassettes/company_no_valid.yml +14 -14
- data/spec/defra_ruby/validators/business_type_validator_spec.rb +30 -0
- data/spec/defra_ruby/validators/companies_house_number_validator_spec.rb +15 -15
- data/spec/defra_ruby/validators/email_validator_spec.rb +42 -0
- data/spec/defra_ruby/validators/grid_reference_validator_spec.rb +49 -0
- data/spec/defra_ruby/validators/location_validator_spec.rb +30 -0
- data/spec/defra_ruby/validators/phone_number_validator_spec.rb +55 -0
- data/spec/defra_ruby/validators/position_validator_spec.rb +47 -0
- data/spec/defra_ruby/validators/token_validator_spec.rb +41 -0
- data/spec/defra_ruby/validators/true_false_validator_spec.rb +11 -4
- data/spec/examples.txt +79 -44
- data/spec/spec_helper.rb +4 -0
- data/spec/support/helpers/text_generator.rb +17 -0
- data/spec/support/helpers/translator.rb +2 -3
- data/spec/support/shared_examples/validators/characters_validator.rb +25 -0
- data/spec/support/shared_examples/validators/invalid_record.rb +13 -3
- data/spec/support/shared_examples/validators/length_validator.rb +25 -0
- data/spec/support/shared_examples/validators/presence_validator.rb +25 -0
- data/spec/support/shared_examples/validators/selection_validator.rb +11 -11
- metadata +70 -19
- data/spec/support/dotenv.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6eb5f30b11f406a2a5c91d2d2eabb709b6e662cc
|
4
|
+
data.tar.gz: '049bb686fcc859df2894534e21741d585e0ede29'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5aff6f7c03a848a1f03fff4be8d357d2ca3f8b37ad7d3489f3b76773f20122b8014c596369b27467349b90d331c90c695a8d6a935a7f4794afbedfeb6343fb9c
|
7
|
+
data.tar.gz: 05ccedb6de84b3ed7c55303f30e8e9357abebbbf71c1233d1a45df5de7e056d6993c3ca95396cb3e5d438562de9ef8046b71a1c87fa2b1b1934bf1f33895ae56
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[![Build Status](https://travis-ci.com/DEFRA/defra-ruby-validators.svg?branch=master)](https://travis-ci.com/DEFRA/defra-ruby-validators)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/a0f8611f1a879786f642/maintainability)](https://codeclimate.com/github/DEFRA/defra-ruby-validators/maintainability)
|
5
5
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/a0f8611f1a879786f642/test_coverage)](https://codeclimate.com/github/DEFRA/defra-ruby-validators/test_coverage)
|
6
|
+
[![security](https://hakiri.io/github/DEFRA/defra-ruby-validators/master.svg)](https://hakiri.io/github/DEFRA/defra-ruby-validators/master)
|
6
7
|
[![Gem Version](https://badge.fury.io/rb/defra_ruby_validators.svg)](https://badge.fury.io/rb/defra_ruby_validators)
|
7
8
|
[![Licence](https://img.shields.io/badge/Licence-OGLv3-blue.svg)](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3)
|
8
9
|
|
@@ -26,6 +27,25 @@ bundle install
|
|
26
27
|
|
27
28
|
With this gem installed, a number of active model based validators become available.
|
28
29
|
|
30
|
+
### Business type
|
31
|
+
|
32
|
+
This validator checks the value provided is one of our known business types
|
33
|
+
|
34
|
+
- `soleTrader`
|
35
|
+
- `limitedCompany`
|
36
|
+
- `partnership`
|
37
|
+
- `limitedLiabilityPartnership`
|
38
|
+
- `localAuthority`
|
39
|
+
- `charity`
|
40
|
+
|
41
|
+
If blank or not one of these it will return an error.
|
42
|
+
|
43
|
+
Add it to your model or form object using
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
validates :business_type, "defra_ruby/validators/business_type": true
|
47
|
+
```
|
48
|
+
|
29
49
|
### Companies House number
|
30
50
|
|
31
51
|
This validator checks the company registration number provided. Specifically it first checks that it matches a known format. All registration numbers are 8 characters long but can be formatted in the following ways.
|
@@ -48,6 +68,73 @@ Add it to your model or form object using
|
|
48
68
|
validates :company_no, "defra_ruby/validators/companies_house_number": true
|
49
69
|
```
|
50
70
|
|
71
|
+
### Email
|
72
|
+
|
73
|
+
This validator checks the value is present and in a format that meets [RFC 2822](https://tools.ietf.org/html/rfc2822) and [RFC 3696](https://tools.ietf.org/html/rfc3696) (we use [validates_email_format_of](https://github.com/validates-email-format-of/validates_email_format_of) to check the format).
|
74
|
+
|
75
|
+
Add it to your model or form object using
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
validates :email, "defra_ruby/validators/email": true
|
79
|
+
```
|
80
|
+
|
81
|
+
### Grid reference
|
82
|
+
|
83
|
+
This validator checks the value is present, is in the correct format for an [Ordnance Survey National Grid Reference](https://en.wikipedia.org/wiki/Ordnance_Survey_National_Grid), and that its valid (we use [os_map_ref](https://github.com/DEFRA/os-map-ref) to check the coordinate is valid).
|
84
|
+
|
85
|
+
Add it to your model or form object using
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
validates :grid_reference, "defra_ruby/validators/grid_reference": true
|
89
|
+
```
|
90
|
+
|
91
|
+
### Location
|
92
|
+
|
93
|
+
This validator checks the value provided is one of our accepted locations
|
94
|
+
|
95
|
+
- `england`
|
96
|
+
- `northern_ireland`
|
97
|
+
- `scotland`
|
98
|
+
- `wales`
|
99
|
+
|
100
|
+
If blank or not one of these it will return an error.
|
101
|
+
|
102
|
+
Add it to your model or form object using
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
validates :location, "defra_ruby/validators/location": true
|
106
|
+
```
|
107
|
+
|
108
|
+
### Phone number
|
109
|
+
|
110
|
+
This validator checks the value is present, is not too long (15 is th maximum length for any phone number), and is in the correct format as per [E.164](https://en.wikipedia.org/wiki/E.164) (we use [phonelib](https://github.com/daddyz/phonelib) to check the format).
|
111
|
+
|
112
|
+
Add it to your model or form object using
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
validates :phone_number, "defra_ruby/validators/phone_number": true
|
116
|
+
```
|
117
|
+
|
118
|
+
### Position
|
119
|
+
|
120
|
+
This validator checks the value provided for 'position' i.e. someones role or title within an organisation. This is an optional field so the validator has to handle the value being blank. If it's not then it can be no longer than 70 characters and only include letters, spaces, commas, full stops, hyphens and apostrophes else it will return an error.
|
121
|
+
|
122
|
+
Add it to your model or form object using
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
validates :position, "defra_ruby/validators/position": true
|
126
|
+
```
|
127
|
+
|
128
|
+
### Token
|
129
|
+
|
130
|
+
This validator checks the value is present and in the correct format, which in this case is that the value has a length of 24. If blank or not in a valid format it will return an error.
|
131
|
+
|
132
|
+
Add it to your model or form object using
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
validates :token, "defra_ruby/validators/token": true
|
136
|
+
```
|
137
|
+
|
51
138
|
### True or false
|
52
139
|
|
53
140
|
This validator checks the value provided is either `"true"` or `"false"`. If blank or not one of these it will return an error.
|
@@ -55,7 +142,7 @@ This validator checks the value provided is either `"true"` or `"false"`. If bla
|
|
55
142
|
Add it to your model or form object using
|
56
143
|
|
57
144
|
```ruby
|
58
|
-
validates :
|
145
|
+
validates :is_a_farmer, "defra_ruby/validators/true_false": true
|
59
146
|
```
|
60
147
|
|
61
148
|
## Contributing to this project
|
@@ -6,10 +6,20 @@ require_relative "validators/version"
|
|
6
6
|
require_relative "validators/configuration"
|
7
7
|
require_relative "validators/companies_house_service"
|
8
8
|
|
9
|
+
require_relative "validators/concerns/can_validate_characters"
|
10
|
+
require_relative "validators/concerns/can_validate_length"
|
11
|
+
require_relative "validators/concerns/can_validate_presence"
|
9
12
|
require_relative "validators/concerns/can_validate_selection"
|
10
13
|
|
11
14
|
require_relative "validators/base_validator"
|
15
|
+
require_relative "validators/business_type_validator"
|
12
16
|
require_relative "validators/companies_house_number_validator"
|
17
|
+
require_relative "validators/email_validator"
|
18
|
+
require_relative "validators/grid_reference_validator"
|
19
|
+
require_relative "validators/location_validator"
|
20
|
+
require_relative "validators/phone_number_validator"
|
21
|
+
require_relative "validators/position_validator"
|
22
|
+
require_relative "validators/token_validator"
|
13
23
|
require_relative "validators/true_false_validator"
|
14
24
|
|
15
25
|
module DefraRuby
|
@@ -6,10 +6,8 @@ module DefraRuby
|
|
6
6
|
|
7
7
|
protected
|
8
8
|
|
9
|
-
def error_message(attribute
|
10
|
-
|
11
|
-
|
12
|
-
I18n.t("defra_ruby.validators.#{class_name}.#{error}")
|
9
|
+
def error_message(attribute, error)
|
10
|
+
options[:message] || I18n.t("defra_ruby.validators.#{class_name}.#{attribute}.#{error}")
|
13
11
|
end
|
14
12
|
|
15
13
|
private
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DefraRuby
|
4
|
+
module Validators
|
5
|
+
class BusinessTypeValidator < BaseValidator
|
6
|
+
include CanValidateSelection
|
7
|
+
|
8
|
+
def validate_each(record, _attribute, value)
|
9
|
+
valid_options = %w[soleTrader limitedCompany partnership limitedLiabilityPartnership localAuthority charity]
|
10
|
+
|
11
|
+
value_is_included?(record, :business_type, value, valid_options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -25,14 +25,14 @@ module DefraRuby
|
|
25
25
|
def value_is_present?(record, attribute, value)
|
26
26
|
return true if value.present?
|
27
27
|
|
28
|
-
record.errors[attribute] << error_message(
|
28
|
+
record.errors[attribute] << error_message(:company_no, :blank)
|
29
29
|
false
|
30
30
|
end
|
31
31
|
|
32
32
|
def format_is_valid?(record, attribute, value)
|
33
33
|
return true if value.match?(VALID_COMPANIES_HOUSE_REGISTRATION_NUMBER_REGEX)
|
34
34
|
|
35
|
-
record.errors[attribute] << error_message(
|
35
|
+
record.errors[attribute] << error_message(:company_no, :invalid)
|
36
36
|
false
|
37
37
|
end
|
38
38
|
|
@@ -41,12 +41,12 @@ module DefraRuby
|
|
41
41
|
when :active
|
42
42
|
true
|
43
43
|
when :inactive
|
44
|
-
record.errors[attribute] << error_message(
|
44
|
+
record.errors[attribute] << error_message(:company_no, :inactive)
|
45
45
|
when :not_found
|
46
|
-
record.errors[attribute] << error_message(
|
46
|
+
record.errors[attribute] << error_message(:company_no, :not_found)
|
47
47
|
end
|
48
48
|
rescue StandardError
|
49
|
-
record.errors[attribute] << error_message(
|
49
|
+
record.errors[attribute] << error_message(:company_no, :error)
|
50
50
|
end
|
51
51
|
|
52
52
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DefraRuby
|
4
|
+
module Validators
|
5
|
+
module CanValidateCharacters
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def value_has_no_invalid_characters?(record, attribute, value)
|
10
|
+
# Name fields must contain only letters, spaces, commas, full stops, hyphens and apostrophes
|
11
|
+
return true if value.match?(/\A[-a-z\s,.']+\z/i)
|
12
|
+
|
13
|
+
record.errors[attribute] << error_message(attribute, :invalid)
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DefraRuby
|
4
|
+
module Validators
|
5
|
+
module CanValidateLength
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def value_is_not_too_long?(record, attribute, value, max_length)
|
10
|
+
return true if value.length <= max_length
|
11
|
+
|
12
|
+
record.errors[attribute] << error_message(attribute, :too_long)
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DefraRuby
|
4
|
+
module Validators
|
5
|
+
module CanValidatePresence
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def value_is_present?(record, attribute, value)
|
10
|
+
return true if value.present?
|
11
|
+
|
12
|
+
record.errors[attribute] << error_message(attribute, :blank)
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,18 +3,16 @@
|
|
3
3
|
module DefraRuby
|
4
4
|
module Validators
|
5
5
|
module CanValidateSelection
|
6
|
-
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
9
|
-
private
|
7
|
+
private
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
def value_is_included?(record, attribute, value, valid_options)
|
10
|
+
return true if value.present? && valid_options.include?(value)
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
record.errors[attribute] << error_message(attribute, :inclusion)
|
13
|
+
false
|
17
14
|
end
|
15
|
+
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "validates_email_format_of"
|
4
|
+
|
5
|
+
module DefraRuby
|
6
|
+
module Validators
|
7
|
+
class EmailValidator < BaseValidator
|
8
|
+
include CanValidatePresence
|
9
|
+
|
10
|
+
def validate_each(record, attribute, value)
|
11
|
+
return false unless value_is_present?(record, :email, value)
|
12
|
+
|
13
|
+
valid_format?(record, attribute, value)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_format?(record, attribute, value)
|
19
|
+
# validate_email_format returns nil if the validation passes
|
20
|
+
return true unless ValidatesEmailFormatOf.validate_email_format(value)
|
21
|
+
|
22
|
+
record.errors[attribute] << error_message(:email, :invalid_format)
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "os_map_ref"
|
4
|
+
|
5
|
+
module DefraRuby
|
6
|
+
module Validators
|
7
|
+
class GridReferenceValidator < BaseValidator
|
8
|
+
include CanValidatePresence
|
9
|
+
|
10
|
+
def validate_each(record, attribute, value)
|
11
|
+
return false unless value_is_present?(record, :grid_reference, value)
|
12
|
+
return false unless valid_format?(record, attribute, value)
|
13
|
+
|
14
|
+
valid_coordinate?(record, attribute, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# Note that OsMapRef will work with less specific coordinates than are
|
20
|
+
# required for this service (100m) - so we need to add an additional check
|
21
|
+
# rather than just jump straight to confirming if it's a valid coordinate
|
22
|
+
def valid_format?(record, attribute, value)
|
23
|
+
return true if value.match?(/\A#{grid_reference_pattern}\z/)
|
24
|
+
|
25
|
+
record.errors[attribute] << error_message(:grid_reference, :wrong_format)
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_coordinate?(record, attribute, value)
|
30
|
+
OsMapRef::Location.for(value).easting
|
31
|
+
true
|
32
|
+
rescue OsMapRef::Error
|
33
|
+
record.errors[attribute] << error_message(:grid_reference, :invalid)
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def grid_reference_pattern
|
38
|
+
[two_letters, optional_space, five_digits, optional_space, five_digits].join
|
39
|
+
end
|
40
|
+
|
41
|
+
def two_letters
|
42
|
+
"[A-Za-z]{2}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def five_digits
|
46
|
+
'\d{5}'
|
47
|
+
end
|
48
|
+
|
49
|
+
def optional_space
|
50
|
+
'\s*'
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|