activerecord_json_validator 2.1.3 → 2.1.5

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: f6f85c2656b56c867aa06f583528e3d315026c0537369311d6302adaeda42ad6
4
- data.tar.gz: 34894b9ed770db328de8011be097b72f59bb08431b45ddeb3024af01d1cf29b3
3
+ metadata.gz: 46e15a1f3a280bc1f2a5d197d0631a6b0e09a4beed596e971d66e1102e3a9c65
4
+ data.tar.gz: dfc7b7fd68462c50be8fb565d20d965fad13a29d487013df54d5cfab708b431d
5
5
  SHA512:
6
- metadata.gz: db0d5e91cbbefb083b7c55d2633ef82e87868943a54dd09254f27b4ab85a5d6474eaa277ab0e23ad988a6b7f6bfc35ca870a0b735d9007b32ef5ce638fe9e198
7
- data.tar.gz: a5cc28a84fd2037ec6623fce0cbbb665723a8481b89afb07139c46e6c7a8a047c885dfb1848aca667542196cd0e6c29fabf81081ad7b98c633644dbe4af4de7b
6
+ metadata.gz: a6b1c7770312b89c64889d8a1abeb6b59603b1be24a431e1a68cb9800268fbe36e617a1812d85c3f508ff603ffb1672c8c13a7c136847dd5b18959d815ef3304
7
+ data.tar.gz: 7aaf73c426c7918abb1323cc5812c04d5d8a3700192d7a0222dee9c23f2faa638692764926d34947a752ac6cb8cb14223c414f34a2595a101839ccbb11bb2552
data/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  Add this line to your application's Gemfile:
17
17
 
18
18
  ```ruby
19
- gem 'activerecord_json_validator', '~> 2.0.0'
19
+ gem 'activerecord_json_validator', '~> 2.1.0'
20
20
  ```
21
21
 
22
22
  ## Usage
@@ -164,6 +164,15 @@ user.errors.full_messages
164
164
  # ]
165
165
  ```
166
166
 
167
+ ## Development
168
+
169
+ The tests require a database. We've provided a simple `docker-compose.yml` that will make
170
+ it trivial to run the tests against PostgreSQL. Simply run `docker compose up -d`
171
+ followed by `rake spec`. When you're done, run `docker compose down` to stop the database.
172
+
173
+ In order to use another database, simply define the `DATABASE_URL` environment variable
174
+ appropriately.
175
+
167
176
  ## License
168
177
 
169
178
  `ActiveRecord::JSONValidator` is © 2013-2022 [Mirego](https://www.mirego.com) and may be freely distributed under the [New BSD license](https://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/activerecord_json_validator/blob/master/LICENSE.md) file.
@@ -0,0 +1,11 @@
1
+ version: '3.2'
2
+
3
+ services:
4
+ postgres:
5
+ image: postgres:10
6
+ ports:
7
+ - 5432:5432
8
+ restart: on-failure
9
+ environment:
10
+ POSTGRES_DB: activerecord_json_validator_test
11
+ POSTGRES_HOST_AUTH_METHOD: trust # don't require password
@@ -25,9 +25,10 @@ class JsonValidator < ActiveModel::EachValidator
25
25
  return if errors.empty? && record.send(:"#{attribute}_invalid_json").blank?
26
26
 
27
27
  # Add error message to the attribute
28
+ details = errors.map { |e| JSONSchemer::Errors.pretty(e) }
28
29
  message(errors).each do |error|
29
- error = error.is_a?(Hash) ? JSONSchemer::Errors.pretty(error) : error
30
- record.errors.add(attribute, error, value: value)
30
+ error = JSONSchemer::Errors.pretty(error) if error.is_a?(Hash)
31
+ record.errors.add(attribute, error, errors: details, value: value)
31
32
  end
32
33
  end
33
34
 
@@ -36,21 +37,23 @@ protected
36
37
  # Redefine the setter method for the attributes, since we want to
37
38
  # catch JSON parsing errors.
38
39
  def inject_setter_method(klass, attributes)
40
+ return if klass.nil?
41
+
39
42
  attributes.each do |attribute|
40
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
43
+ klass.prepend(Module.new do
41
44
  attr_reader :"#{attribute}_invalid_json"
42
45
 
43
46
  define_method "#{attribute}=" do |args|
44
47
  begin
45
- @#{attribute}_invalid_json = nil
48
+ instance_variable_set("@#{attribute}_invalid_json", nil)
46
49
  args = ::ActiveSupport::JSON.decode(args) if args.is_a?(::String)
47
50
  super(args)
48
51
  rescue ActiveSupport::JSON.parse_error
49
- @#{attribute}_invalid_json = args
52
+ instance_variable_set("@#{attribute}_invalid_json", args)
50
53
  super({})
51
54
  end
52
55
  end
53
- RUBY
56
+ end)
54
57
  end
55
58
  end
56
59
 
@@ -68,10 +71,7 @@ protected
68
71
 
69
72
  def message(errors)
70
73
  message = options.fetch(:message)
71
-
72
- case message
73
- when Proc then [message.call(errors)].flatten if message.is_a?(Proc)
74
- else [message]
75
- end
74
+ message = message.call(errors) if message.is_a?(Proc)
75
+ [message].flatten
76
76
  end
77
77
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module JSONValidator
5
- VERSION = '2.1.3'
5
+ VERSION = '2.1.5'
6
6
  end
7
7
  end
@@ -3,6 +3,18 @@
3
3
  # rubocop:disable Metrics/BlockLength
4
4
  require 'spec_helper'
5
5
 
6
+ module CountryDefaulter
7
+ extend ActiveSupport::Concern
8
+
9
+ class_methods do
10
+ def default_country_attribute(name, country:)
11
+ define_method("#{name}=") do |value|
12
+ self[name] = { country: country }.merge(value)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
6
18
  describe JsonValidator do
7
19
  describe :validate_each do
8
20
  before do
@@ -14,6 +26,8 @@ describe JsonValidator do
14
26
  end
15
27
 
16
28
  spawn_model 'User' do
29
+ include CountryDefaulter
30
+
17
31
  schema = '
18
32
  {
19
33
  "type": "object",
@@ -24,6 +38,9 @@ describe JsonValidator do
24
38
  "required": ["country"]
25
39
  }
26
40
  '
41
+
42
+ default_country_attribute :smart_data, country: 'Canada'
43
+
27
44
  serialize :data, JSON
28
45
  serialize :other_data, JSON
29
46
  validates :data, json: { schema: schema, message: ->(errors) { errors } }
@@ -41,25 +58,53 @@ describe JsonValidator do
41
58
  User.new(
42
59
  data: '{"city":"Quebec City"}',
43
60
  other_data: '{"city":"Quebec City"}',
44
- smart_data: { country: 'Canada', city: 'Quebec City' }
61
+ smart_data: { country: 'Ireland', city: 'Dublin' }
45
62
  )
46
63
  end
47
64
 
48
65
  specify do
49
66
  expect(user).not_to be_valid
50
67
  expect(user.errors.full_messages).to eql(['Data root is missing required keys: country', 'Other data missing_keys country'])
68
+ expect(user.errors.group_by_attribute[:data].first).to have_attributes(
69
+ options: include(errors: ['root is missing required keys: country'])
70
+ )
71
+ expect(user.errors.group_by_attribute[:other_data].first).to have_attributes(
72
+ options: include(errors: ['root is missing required keys: country'])
73
+ )
51
74
  expect(user.data).to eql({ 'city' => 'Quebec City' })
52
75
  expect(user.data_invalid_json).to be_nil
76
+ expect(user.smart_data.city).to eql('Dublin')
77
+ expect(user.smart_data.country).to eql('Ireland')
53
78
  end
54
79
  end
55
80
 
56
81
  context 'with invalid JSON data' do
57
82
  let(:data) { 'What? This is not JSON at all.' }
58
- let(:user) { User.new(data: data) }
83
+ let(:user) { User.new(data: data, smart_data: data) }
59
84
 
60
85
  specify do
61
86
  expect(user.data_invalid_json).to eql(data)
62
87
  expect(user.data).to eql({})
88
+
89
+ # Ensure that both setters ran
90
+ expect(user.smart_data_invalid_json).to eql(data)
91
+ expect(user.smart_data).to eql(OpenStruct.new({ country: 'Canada' }))
92
+ end
93
+ end
94
+
95
+ context 'with missing country in smart data' do
96
+ let(:user) do
97
+ User.new(
98
+ data: '{"city":"Quebec City","country":"Canada"}',
99
+ other_data: '{"city":"Quebec City","country":"Canada"}',
100
+ smart_data: { city: 'Quebec City' }
101
+ )
102
+ end
103
+
104
+ specify do
105
+ expect(user).to be_valid
106
+ expect(user.smart_data.city).to eql('Quebec City')
107
+ expect(user.smart_data.country).to eql('Canada') # Due to CountryDefaulter
63
108
  end
64
109
  end
65
110
  end
@@ -6,6 +6,6 @@ class DatabaseAdapter
6
6
  end
7
7
 
8
8
  def establish_connection!
9
- ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
9
+ ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL', 'postgres://postgres@localhost/activerecord_json_validator_test'))
10
10
  end
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord_json_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 2.1.5
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: 2022-11-24 00:00:00.000000000 Z
11
+ date: 2023-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -179,6 +179,7 @@ files:
179
179
  - README.md
180
180
  - Rakefile
181
181
  - activerecord_json_validator.gemspec
182
+ - docker-compose.yml
182
183
  - lib/active_record/json_validator/validator.rb
183
184
  - lib/active_record/json_validator/version.rb
184
185
  - lib/activerecord_json_validator.rb