activerecord_json_validator 2.1.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 851b94edf54cbfdcd0a66a80dab95bcdeeea0e1c4a8831f634bc55aad5cba226
4
- data.tar.gz: bf3a8280ffa8300469e793422adc68e83ab444047db67d9e6cbafec528f69803
3
+ metadata.gz: 669da2ce3ee468c5d588289edf6842fbec2e90a04058b110db4fc81fe10cb0e7
4
+ data.tar.gz: 76b04ff20e88c285ffd5711dc1ce6bee16c7e9bdf519a3ef95dac637d7a4b147
5
5
  SHA512:
6
- metadata.gz: 33766dfbea4cf464c499709f76b742f3bfe9b37dcc656206a15794f93733ec6711f127057ff2efb67bb75b6e439e64e75ada856d62fcdb2fece42e4ddd81b6ff
7
- data.tar.gz: 7192194e8663dfbd9d343b66866ebab63d843200581bbe59be2c3f3bd485819fb13bba58bfb29241afa661c180399acce0d6fa3cf24a9d6fd5852b1d300a1be8
6
+ metadata.gz: 40ccc0aa96e3601e49a6cb38fa35b83158f5b9a4597916577416b316f144534d271c56b17b42b5fe7071cdffd8f87c2b1ac3d84bfaa0da5794372eff6c5b9d89
7
+ data.tar.gz: 8a79553fc7bb7ab146ab77ed0ac57e186b7f9fd0f6cb6f47dd5e7bd94b920796abafd8d3d09e99a3954cf520f4aab6bb208341cd06aa29bb68ba0175763e949d
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2022, Mirego
1
+ Copyright (c) 2013-2024, Mirego
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
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.1.0'
19
+ gem 'activerecord_json_validator', '~> 3.0.0'
20
20
  ```
21
21
 
22
22
  ## Usage
@@ -164,9 +164,18 @@ 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
- `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.
178
+ `ActiveRecord::JSONValidator` is © 2013-2024 [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.
170
179
 
171
180
  The tree logo is based on [this lovely icon](https://thenounproject.com/term/tree/51004/) by [Sara Quintana](https://thenounproject.com/sara.quintana.75), from The Noun Project. Used under a [Creative Commons BY 3.0](https://creativecommons.org/licenses/by/3.0/) license.
172
181
 
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'rubocop-rspec', '~> 1.44'
28
28
  spec.add_development_dependency 'rubocop-standard', '~> 6.0'
29
29
 
30
- spec.add_dependency 'json_schemer', '~> 0.2.18'
30
+ spec.add_dependency 'json_schemer', '~> 2.2'
31
31
  spec.add_dependency 'activerecord', '>= 4.2.0', '< 8'
32
32
  end
@@ -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,9 @@ 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
+ details = errors.map { |e| e.fetch('error') }
29
29
  message(errors).each do |error|
30
- error = JSONSchemer::Errors.pretty(error) if error.is_a?(Hash)
30
+ error = error.fetch('error') if error.is_a?(Hash)
31
31
  record.errors.add(attribute, error, errors: details, value: value)
32
32
  end
33
33
  end
@@ -37,21 +37,23 @@ protected
37
37
  # Redefine the setter method for the attributes, since we want to
38
38
  # catch JSON parsing errors.
39
39
  def inject_setter_method(klass, attributes)
40
+ return if klass.nil?
41
+
40
42
  attributes.each do |attribute|
41
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
43
+ klass.prepend(Module.new do
42
44
  attr_reader :"#{attribute}_invalid_json"
43
45
 
44
46
  define_method "#{attribute}=" do |args|
45
47
  begin
46
- @#{attribute}_invalid_json = nil
48
+ instance_variable_set("@#{attribute}_invalid_json", nil)
47
49
  args = ::ActiveSupport::JSON.decode(args) if args.is_a?(::String)
48
50
  super(args)
49
51
  rescue ActiveSupport::JSON.parse_error
50
- @#{attribute}_invalid_json = args
52
+ instance_variable_set("@#{attribute}_invalid_json", args)
51
53
  super({})
52
54
  end
53
55
  end
54
- RUBY
56
+ end)
55
57
  end
56
58
  end
57
59
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module JSONValidator
5
- VERSION = '2.1.4'
5
+ VERSION = '3.0.0'
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,8 +38,11 @@ describe JsonValidator do
24
38
  "required": ["country"]
25
39
  }
26
40
  '
27
- serialize :data, JSON
28
- serialize :other_data, JSON
41
+
42
+ default_country_attribute :smart_data, country: 'Canada'
43
+
44
+ serialize :data, coder: JSON
45
+ serialize :other_data, coder: JSON
29
46
  validates :data, json: { schema: schema, message: ->(errors) { errors } }
30
47
  validates :other_data, json: { schema: schema, message: ->(errors) { errors.map { |error| error['details'].to_a.flatten.join(' ') } } }
31
48
  validates :smart_data, json: { value: ->(record, _, _) { record[:smart_data] }, schema: schema, message: ->(errors) { errors } }
@@ -41,31 +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
- expect(user.errors.full_messages).to eql(['Data root is missing required keys: country', 'Other data missing_keys country'])
67
+ expect(user.errors.full_messages).to eql(['Data object at root is missing required properties: country', 'Other data missing_keys country'])
51
68
  expect(user.errors.group_by_attribute[:data].first).to have_attributes(
52
- options: include(errors: ['root is missing required keys: country'])
69
+ options: include(errors: ['object at root is missing required properties: country'])
53
70
  )
54
71
  expect(user.errors.group_by_attribute[:other_data].first).to have_attributes(
55
- options: include(errors: ['root is missing required keys: country'])
72
+ options: include(errors: ['object at root is missing required properties: country'])
56
73
  )
57
74
  expect(user.data).to eql({ 'city' => 'Quebec City' })
58
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')
59
78
  end
60
79
  end
61
80
 
62
81
  context 'with invalid JSON data' do
63
82
  let(:data) { 'What? This is not JSON at all.' }
64
- let(:user) { User.new(data: data) }
83
+ let(:user) { User.new(data: data, smart_data: data) }
65
84
 
66
85
  specify do
67
86
  expect(user.data_invalid_json).to eql(data)
68
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
69
108
  end
70
109
  end
71
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
@@ -25,6 +25,6 @@ module DatabaseMacros
25
25
  adapter.reset_database!
26
26
 
27
27
  # Silence everything
28
- ActiveRecord::Base.logger = ActiveRecord::Migration.verbose = false
28
+ ActiveRecord::Base.logger = ActiveRecord::Migration.verbose = nil
29
29
  end
30
30
  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.4
4
+ version: 3.0.0
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: 2023-05-01 00:00:00.000000000 Z
11
+ date: 2024-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -134,14 +134,14 @@ dependencies:
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: 0.2.18
137
+ version: '2.2'
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: 0.2.18
144
+ version: '2.2'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: activerecord
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -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