33# rubocop:disable Metrics/BlockLength
44require 'spec_helper'
55
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+
618describe JsonValidator do
719 describe :validate_each do
820 before do
1426 end
1527
1628 spawn_model 'User' do
29+ include CountryDefaulter
30+
1731 schema = '
1832 {
1933 "type": "object",
2438 "required": ["country"]
2539 }
2640 '
41+
42+ default_country_attribute :smart_data , country : 'Canada'
43+
2744 serialize :data , JSON
2845 serialize :other_data , JSON
2946 validates :data , json : { schema : schema , message : -> ( errors ) { errors } }
@@ -41,7 +58,7 @@ def smart_data
4158 User . new (
4259 data : '{"city":"Quebec City"}' ,
4360 other_data : '{"city":"Quebec City"}' ,
44- smart_data : { country : 'Canada ' , city : 'Quebec City ' }
61+ smart_data : { country : 'Ireland ' , city : 'Dublin ' }
4562 )
4663 end
4764
@@ -56,16 +73,38 @@ def smart_data
5673 )
5774 expect ( user . data ) . to eql ( { 'city' => 'Quebec City' } )
5875 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' )
5978 end
6079 end
6180
6281 context 'with invalid JSON data' do
6382 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 ) }
6584
6685 specify do
6786 expect ( user . data_invalid_json ) . to eql ( data )
6887 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
69108 end
70109 end
71110 end
0 commit comments