activerecord_json_validator 1.3.0 → 2.1.1

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: d9dce365377ebd51d3f5b8156e3cf928507014ed1278c0ca794675b4fecd3d2c
4
- data.tar.gz: b1f58a7b215df70ff616dd80ee31dd24dd8fa0b0020189ee99318fb577a38621
3
+ metadata.gz: 1ebef8de77a6adb6c1ea4ff00c49c9e91b843952c4d226f4b149c04df9d585a6
4
+ data.tar.gz: 7efc4fa80a8dc82343bf1c7148e20f06df2acf127cbdbf9bc98e591e706940db
5
5
  SHA512:
6
- metadata.gz: 3b0f0f8e654453f06fd16d31324b8d3cfa069411e206cbc3b58575987984bda9ece9156411121d5202c701fd4dcece6ed5ab7b40eac5d5116a02f3347f2e0a4c
7
- data.tar.gz: 355f0fec168526d3e881efb0b9ef5434089d2bc531adeb6f6dc9af61ea96dbb4a30600d744babd82dd57df2b6157d36a1d4e9ed837af902295d8419b7e5bfe91
6
+ metadata.gz: 1f096c0becc38bcdfb81cf70f59174509ea463f088ae02e514c612b397200aaef4dc76e7fd5cfe44ff0bf7c17fe2715a77d41d02101bac55afad19bbb076497a
7
+ data.tar.gz: e94f0da67f515a20eeb5699be8823c267144eeb36d09c6a1a892d24faab9bc65ca8d2d70edbe4388f088505d75875ede5cd91366393f2b71d42675713f8423ed
data/.travis.yml CHANGED
@@ -3,16 +3,24 @@ language: ruby
3
3
  rvm:
4
4
  - 2.4.6
5
5
  - 2.6.3
6
+ - 2.7.5
6
7
 
7
8
  gemfile:
8
9
  - gemfiles/Gemfile.activerecord-4.2.x
9
10
  - gemfiles/Gemfile.activerecord-5.0.x
10
11
  - gemfiles/Gemfile.activerecord-6.0.x
12
+ - gemfiles/Gemfile.activerecord-7.0.x
11
13
 
12
14
  matrix:
13
15
  exclude:
14
16
  - gemfile: gemfiles/Gemfile.activerecord-6.0.x
15
17
  rvm: 2.4.6
18
+ - gemfile: gemfiles/Gemfile.activerecord-7.0.x
19
+ rvm: 2.4.6
20
+ - gemfile: gemfiles/Gemfile.activerecord-7.0.x
21
+ rvm: 2.6.3
22
+ - gemfile: gemfiles/Gemfile.activerecord-4.2.x
23
+ rvm: 2.7.5
16
24
 
17
25
  sudo: false
18
26
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <a href="https://github.com/mirego/activerecord_json_validator">
3
- <img src="https://cloud.githubusercontent.com/assets/11348/6099354/cffcf35e-afc3-11e4-9a4d-d872941bbcf6.png" alt="" />
3
+ <img src="https://user-images.githubusercontent.com/11348/126779905-3468eb15-d554-46d5-925b-235f68169d86.png" alt="" />
4
4
  </a>
5
5
  <br />
6
6
  <code>ActiveRecord::JSONValidator</code> makes it easy to validate<br /> JSON attributes against a <a href="http://json-schema.org/">JSON schema</a>.
@@ -16,17 +16,19 @@
16
16
  Add this line to your application's Gemfile:
17
17
 
18
18
  ```ruby
19
- gem 'activerecord_json_validator'
19
+ gem 'activerecord_json_validator', '~> 2.0.0'
20
20
  ```
21
21
 
22
22
  ## Usage
23
23
 
24
24
  ### JSON Schema
25
25
 
26
+ Schemas should be a JSON file
27
+
26
28
  ```json
27
29
  {
28
30
  "type": "object",
29
- "$schema": "http://json-schema.org/draft-04/schema",
31
+ "$schema": "http://json-schema.org/draft-04/schema#",
30
32
  "properties": {
31
33
  "city": { "type": "string" },
32
34
  "country": { "type": "string" }
@@ -45,7 +47,7 @@ end
45
47
 
46
48
  class User < ActiveRecord::Base
47
49
  # Constants
48
- PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
50
+ PROFILE_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json')
49
51
 
50
52
  # Validations
51
53
  validates :name, presence: true
@@ -65,17 +67,16 @@ user.profile_invalid_json # => '{invalid JSON":}'
65
67
 
66
68
  #### Options
67
69
 
68
- | Option | Description
69
- |------------|-----------------------------------------------------
70
- | `:schema` | The JSON schema to validate the data against (see **Schema** section)
71
- | `:message` | The ActiveRecord message added to the record errors (see **Message** section)
72
- | `:options` | A `Hash` of [`json-schema`](https://github.com/ruby-json-schema/json-schema)-supported options to pass to the validator
70
+ | Option | Description |
71
+ | ---------- | ------------------------------------------------------------------------------------------------------------------------------ |
72
+ | `:schema` | The JSON schema to validate the data against (see **Schema** section) |
73
+ | `:message` | The ActiveRecord message added to the record errors (see **Message** section) |
74
+ | `:options` | A `Hash` of [`json_schemer`](https://github.com/davishmcclurg/json_schemer#options)-supported options to pass to the validator |
73
75
 
74
76
  ##### Schema
75
77
 
76
- `ActiveRecord::JSONValidator` uses the `json-schema` gem to validate the JSON
77
- data against a JSON schema. You can use [any value](https://github.com/ruby-json-schema/json-schema/tree/master#usage) that
78
- `JSON::Validator.validate` would take as the `schema` argument.
78
+ `ActiveRecord::JSONValidator` uses the [json_schemer](https://github.com/davishmcclurg/json_schemer) gem to validate the JSON
79
+ data against a JSON schema.
79
80
 
80
81
  Additionally, you can use a `Symbol` or a `Proc`. Both will be executed in the
81
82
  context of the validated record (`Symbol` will be sent as a method and the
@@ -84,8 +85,8 @@ context of the validated record (`Symbol` will be sent as a method and the
84
85
  ```ruby
85
86
  class User < ActiveRecord::Base
86
87
  # Constants
87
- PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema').to_s
88
- PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema').to_s
88
+ PROFILE_REGULAR_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile.json_schema')
89
+ PROFILE_ADMIN_JSON_SCHEMA = Rails.root.join('config', 'schemas', 'profile_admin.json_schema')
89
90
 
90
91
  # Validations
91
92
  validates :profile, presence: true, json: { schema: lambda { dynamic_profile_schema } } # `schema: :dynamic_profile_schema` would also work
@@ -122,7 +123,7 @@ user.errors.full_messages
122
123
 
123
124
  ## License
124
125
 
125
- `ActiveRecord::JSONValidator` is © 2013-2016 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/activerecord_json_validator/blob/master/LICENSE.md) file.
126
+ `ActiveRecord::JSONValidator` is © 2013-2016 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/activerecord_json_validator/blob/master/LICENSE.md) file.
126
127
 
127
128
  The tree logo is based on [this lovely icon](http://thenounproject.com/term/tree/51004/) by [Sara Quintana](http://thenounproject.com/sara.quintana.75), from The Noun Project. Used under a [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/) license.
128
129
 
@@ -18,15 +18,15 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency 'bundler', '~> 1.12'
21
+ spec.add_development_dependency 'bundler', '>= 1.12'
22
22
  spec.add_development_dependency 'rake'
23
23
  spec.add_development_dependency 'rspec', '~> 3.5'
24
24
  spec.add_development_dependency 'pg'
25
25
  spec.add_development_dependency 'mysql2'
26
- spec.add_development_dependency 'activesupport', '>= 4.2.0', '< 7'
26
+ spec.add_development_dependency 'activesupport', '>= 4.2.0', '< 8'
27
27
  spec.add_development_dependency 'phare'
28
28
  spec.add_development_dependency 'rubocop', '~> 0.28'
29
29
 
30
- spec.add_dependency 'json-schema', '~> 2.8'
31
- spec.add_dependency 'activerecord', '>= 4.2.0', '< 7'
30
+ spec.add_dependency 'json_schemer', '~> 0.2.18'
31
+ spec.add_dependency 'activerecord', '>= 4.2.0', '< 8'
32
32
  end
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'activerecord', '~> 7.0.0.rc1'
@@ -14,14 +14,15 @@ class JsonValidator < ActiveModel::EachValidator
14
14
 
15
15
  # Validate the JSON value with a JSON schema path or String
16
16
  def validate_each(record, attribute, value)
17
- # Validate value with JSON::Validator
18
- errors = ::JSON::Validator.fully_validate(schema(record), validatable_value(value), options.fetch(:options))
17
+ # Validate value with JSON Schemer
18
+ errors = JSONSchemer.schema(schema(record), **options.fetch(:options)).validate(value).to_a
19
19
 
20
20
  # Everything is good if we don’t have any errors and we got valid JSON value
21
21
  return if errors.empty? && record.send(:"#{attribute}_invalid_json").blank?
22
22
 
23
23
  # Add error message to the attribute
24
24
  message(errors).each do |error|
25
+ error = error.is_a?(Hash) ? JSONSchemer::Errors.pretty(error) : error
25
26
  record.errors.add(attribute, error, value: value)
26
27
  end
27
28
  end
@@ -49,7 +50,7 @@ protected
49
50
  end
50
51
  end
51
52
 
52
- # Return a valid schema for JSON::Validator.fully_validate, recursively calling
53
+ # Return a valid schema, recursively calling
53
54
  # itself until it gets a non-Proc/non-Symbol value.
54
55
  def schema(record, schema = nil)
55
56
  schema ||= options.fetch(:schema)
@@ -61,12 +62,6 @@ protected
61
62
  end
62
63
  end
63
64
 
64
- def validatable_value(value)
65
- return value if value.is_a?(String)
66
-
67
- ::ActiveSupport::JSON.encode(value)
68
- end
69
-
70
65
  def message(errors)
71
66
  message = options.fetch(:message)
72
67
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module JSONValidator
5
- VERSION = '1.3.0'
5
+ VERSION = '2.1.1'
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_record'
4
- require 'json-schema'
4
+ require 'json_schemer'
5
5
 
6
6
  require 'active_record/json_validator/version'
7
7
  require 'active_record/json_validator/validator'
@@ -4,105 +4,51 @@
4
4
  require 'spec_helper'
5
5
 
6
6
  describe JsonValidator do
7
- describe :initialize do
8
- # NOTE: We do not explicitely call `JsonValidator.new` in the tests,
9
- # because we let Rails (ActiveModel::Validations) do that when we call
10
- # `validates … json: true` on the model.
11
- #
12
- # This allows us to test the constructor behavior when executed in
13
- # different Rails versions that do not pass the same arguments to it.
7
+ describe :validate_each do
14
8
  before do
15
9
  run_migration do
16
10
  create_table(:users, force: true) do |t|
17
- t.string :name
18
11
  t.text :data
19
12
  end
20
13
  end
21
14
 
22
15
  spawn_model 'User' do
16
+ schema = '
17
+ {
18
+ "type": "object",
19
+ "properties": {
20
+ "city": { "type": "string" },
21
+ "country": { "type": "string" }
22
+ },
23
+ "required": ["country"]
24
+ }
25
+ '
23
26
  serialize :data, JSON
24
- validates :data, json: true
27
+ serialize :other_data, JSON
28
+ validates :data, json: { schema: schema, message: ->(errors) { errors } }
29
+ validates :other_data, json: { schema: schema, message: ->(errors) { errors.map { |error| error['details'].to_a.flatten.join(' ') } } }
25
30
  end
26
-
27
- record.data = data
28
- end
29
-
30
- let(:record) { User.new }
31
-
32
- context 'with valid JSON data' do
33
- let(:data) { 'What? This is not JSON at all.' }
34
- it { expect(record.data_invalid_json).to eql(data) }
35
- end
36
-
37
- context 'with invalid JSON data' do
38
- let(:data) { { foo: 'bar' } }
39
- it { expect(record.data_invalid_json).to be_nil }
40
31
  end
41
- end
42
32
 
43
- describe :validate_each do
44
- let(:validator) { JsonValidator.new(options) }
45
- let(:options) { { attributes: [attribute], options: { strict: true } } }
46
- let(:validate_each!) { validator.validate_each(record, attribute, value) }
47
-
48
- # Doubles
49
- let(:attribute) { double(:attribute, to_s: 'attribute_name') }
50
- let(:record) { double(:record, errors: record_errors) }
51
- let(:record_errors) { double(:errors) }
52
- let(:value) { double(:value) }
53
- let(:schema) { double(:schema) }
54
- let(:validatable_value) { double(:validatable_value) }
55
- let(:validator_errors) { double(:validator_errors) }
33
+ context 'with valid JSON data but schema errors' do
34
+ let(:user) { User.new(data: '{"city":"Quebec City"}', other_data: '{"city":"Quebec City"}') }
56
35
 
57
- before do
58
- expect(validator).to receive(:schema).with(record).and_return(schema)
59
- expect(validator).to receive(:validatable_value).with(value).and_return(validatable_value)
60
- expect(::JSON::Validator).to receive(:fully_validate).with(schema, validatable_value, options[:options]).and_return(validator_errors)
61
- end
62
-
63
- context 'with JSON::Validator errors' do
64
- before do
65
- expect(validator_errors).to receive(:empty?).and_return(false)
66
- expect(record).not_to receive(:"#{attribute}_invalid_json")
67
- expect(record_errors).to receive(:add).with(attribute, options[:message], value: value)
36
+ specify do
37
+ expect(user).not_to be_valid
38
+ expect(user.errors.full_messages).to eql(['Data root is missing required keys: country', 'Other data missing_keys country'])
39
+ expect(user.data).to eql({ 'city' => 'Quebec City' })
40
+ expect(user.data_invalid_json).to be_nil
68
41
  end
69
-
70
- specify { validate_each! }
71
42
  end
72
43
 
73
- context 'without JSON::Validator errors but with invalid JSON data' do
74
- before do
75
- expect(validator_errors).to receive(:empty?).and_return(true)
76
- expect(record).to receive(:"#{attribute}_invalid_json").and_return('foo"{]')
77
- expect(record_errors).to receive(:add).with(attribute, options[:message], value: value)
78
- end
79
-
80
- specify { validate_each! }
81
- end
82
-
83
- context 'without JSON::Validator errors and valid JSON data' do
84
- before do
85
- expect(validator_errors).to receive(:empty?).and_return(true)
86
- expect(record).to receive(:"#{attribute}_invalid_json").and_return(nil)
87
- expect(record_errors).not_to receive(:add)
88
- end
89
-
90
- specify { validate_each! }
91
- end
92
-
93
- context 'with multiple error messages' do
94
- let(:options) { { attributes: [attribute], message: message, options: { strict: true } } }
95
- let(:message) { ->(errors) { errors.to_a } }
44
+ context 'with invalid JSON data' do
45
+ let(:data) { 'What? This is not JSON at all.' }
46
+ let(:user) { User.new(data: data) }
96
47
 
97
- before do
98
- expect(validator_errors).to receive(:empty?).and_return(false)
99
- expect(validator_errors).to receive(:to_a).and_return(%i[first_error second_error])
100
- expect(record).not_to receive(:"#{attribute}_invalid_json")
101
- expect(record_errors).to receive(:add).with(attribute, :first_error, value: value)
102
- expect(record_errors).to receive(:add).with(attribute, :second_error, value: value)
48
+ specify do
49
+ expect(user.data_invalid_json).to eql(data)
50
+ expect(user.data).to eql({})
103
51
  end
104
-
105
- specify { validate_each! }
106
52
  end
107
53
  end
108
54
 
@@ -155,22 +101,6 @@ describe JsonValidator do
155
101
  end
156
102
  end
157
103
 
158
- describe :validatable_value do
159
- let(:validator) { JsonValidator.new(options) }
160
- let(:options) { { attributes: [:foo] } }
161
- let(:validatable_value) { validator.send(:validatable_value, value) }
162
-
163
- context 'with non-String value' do
164
- let(:value) { { foo: 'bar' } }
165
- it { expect(validatable_value).to eql('{"foo":"bar"}') }
166
- end
167
-
168
- context 'with String value' do
169
- let(:value) { '{\"foo\":\"bar\"}' }
170
- it { expect(validatable_value).to eql(value) }
171
- end
172
- end
173
-
174
104
  describe :message do
175
105
  let(:validator) { JsonValidator.new(options) }
176
106
  let(:options) { { attributes: [:foo], message: message_option } }
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_json_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rémi Prévost
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-27 00:00:00.000000000 Z
11
+ date: 2022-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.12'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.12'
27
27
  - !ruby/object:Gem::Dependency
@@ -89,7 +89,7 @@ dependencies:
89
89
  version: 4.2.0
90
90
  - - "<"
91
91
  - !ruby/object:Gem::Version
92
- version: '7'
92
+ version: '8'
93
93
  type: :development
94
94
  prerelease: false
95
95
  version_requirements: !ruby/object:Gem::Requirement
@@ -99,7 +99,7 @@ dependencies:
99
99
  version: 4.2.0
100
100
  - - "<"
101
101
  - !ruby/object:Gem::Version
102
- version: '7'
102
+ version: '8'
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: phare
105
105
  requirement: !ruby/object:Gem::Requirement
@@ -129,19 +129,19 @@ dependencies:
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0.28'
131
131
  - !ruby/object:Gem::Dependency
132
- name: json-schema
132
+ name: json_schemer
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '2.8'
137
+ version: 0.2.18
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '2.8'
144
+ version: 0.2.18
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: activerecord
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +151,7 @@ dependencies:
151
151
  version: 4.2.0
152
152
  - - "<"
153
153
  - !ruby/object:Gem::Version
154
- version: '7'
154
+ version: '8'
155
155
  type: :runtime
156
156
  prerelease: false
157
157
  version_requirements: !ruby/object:Gem::Requirement
@@ -161,7 +161,7 @@ dependencies:
161
161
  version: 4.2.0
162
162
  - - "<"
163
163
  - !ruby/object:Gem::Version
164
- version: '7'
164
+ version: '8'
165
165
  description: ActiveRecord::JSONValidator makes it easy to validate JSON attributes
166
166
  with a JSON schema.
167
167
  email:
@@ -182,6 +182,7 @@ files:
182
182
  - gemfiles/Gemfile.activerecord-4.2.x
183
183
  - gemfiles/Gemfile.activerecord-5.0.x
184
184
  - gemfiles/Gemfile.activerecord-6.0.x
185
+ - gemfiles/Gemfile.activerecord-7.0.x
185
186
  - lib/active_record/json_validator/validator.rb
186
187
  - lib/active_record/json_validator/version.rb
187
188
  - lib/activerecord_json_validator.rb
@@ -211,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
212
  - !ruby/object:Gem::Version
212
213
  version: '0'
213
214
  requirements: []
214
- rubygems_version: 3.0.3
215
+ rubygems_version: 3.1.6
215
216
  signing_key:
216
217
  specification_version: 4
217
218
  summary: ActiveRecord::JSONValidator makes it easy to validate JSON attributes with