lhs 11.1.0 → 11.2.0

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
  SHA1:
3
- metadata.gz: abf5de2dde8813263d07b049e423c569bf0e187c
4
- data.tar.gz: 2bf40b2701cfa58783ce975c260da734a8952b1c
3
+ metadata.gz: ec9e7eae2816a09a270575802d332cf27a0a4ae5
4
+ data.tar.gz: fee348a432bdace92a25a94a48efc319d0ed848d
5
5
  SHA512:
6
- metadata.gz: e87e3813fd4afa5c1aa2a9053745e473936ce7262e3bcba83d75032a3261c9ecc045fa70d4a8350428a754baf1dcc3d5c0c5439ab1121ae37da30c447ead8cbd
7
- data.tar.gz: 78c83def6fbe617c6d1c5c7bcb91d8ebe3ca3fdd1b092eb8e51166b8fec51699cbbbe6ffdf3297cb7ff7c364fe11191d6e7a02a98ad05f56b6e7819daa7bb217
6
+ metadata.gz: e7e1fd9491380f0bf1cf439d4e895e515160922bcf10df80c92b542b50b0eed85e6d78a5f3a78459db26ab098a252aad52f7f8e3f7b1a4c6d78e6bb66c1ab982
7
+ data.tar.gz: 75201af82683c6d58d8f7270f8b309ada0a6d81ea4c37bd9ebaebd445614813dcf82e9cbfa8f279291aa1bc64ad7f90eca9f61506163b223a6ef545cd87b176e
data/README.md CHANGED
@@ -771,6 +771,19 @@ You can also access those nested errors like:
771
771
  @customer.address.street.errors
772
772
  ```
773
773
 
774
+ ### Translation of validation errors
775
+
776
+ Just like Activerecord, LHS tries to translate validation error messages.
777
+ If a translation exists for one of the following translation keys, LHS will take a translated error (also in the following order) rather than the plain error message/code:
778
+
779
+ ```ruby
780
+ lhs.errors.records.customer.attributes.name.unsupported_property_value
781
+ lhs.errors.records.customer.unsupported_property_value
782
+ lhs.errors.messages.unsupported_property_value
783
+ lhs.errors.attributes.name.unsupported_property_value
784
+ lhs.errors.fallback_message
785
+ ```
786
+
774
787
  ### Know issue with `ActiveModel::Validations`
775
788
  If you are using `ActiveModel::Validations` and add errors to the LHS::Record instance - as described above - then those errors will be overwritten by the errors from `ActiveModel::Validations` when using `save` or `valid?`. [Open issue](https://github.com/local-ch/lhs/issues/159)
776
789
 
@@ -20,7 +20,7 @@ class LHS::Item < LHS::Proxy
20
20
  apply_default_creation_options(options, url, data)
21
21
  )
22
22
  rescue LHC::Error => e
23
- self.errors = LHS::Errors::Base.new(e.response)
23
+ self.errors = LHS::Errors::Base.new(e.response, record)
24
24
  raise e
25
25
  end
26
26
 
@@ -34,19 +34,18 @@ class LHS::Item < LHS::Proxy
34
34
  end
35
35
 
36
36
  def create_and_merge_data!(options)
37
- direct_response_data = record_for_persistance.request(options)
37
+ direct_response_data = record.request(options)
38
38
  _data.merge_raw!(direct_response_data)
39
39
  response_headers = direct_response_data._request.response.headers
40
40
  if response_headers && response_headers['Location']
41
- location_data = record_for_persistance.request(options.merge(url: response_headers['Location'], method: :get, body: nil))
41
+ location_data = record.request(options.merge(url: response_headers['Location'], method: :get, body: nil))
42
42
  _data.merge_raw!(location_data)
43
43
  end
44
44
  true
45
45
  end
46
46
 
47
47
  def endpoint_for_persistance(data, options)
48
- record_for_persistance
49
- .find_endpoint(merge_data_with_options(data, options))
48
+ record.find_endpoint(merge_data_with_options(data, options))
50
49
  end
51
50
 
52
51
  def merge_data_with_options(data, options)
@@ -57,10 +56,6 @@ class LHS::Item < LHS::Proxy
57
56
  end
58
57
  end
59
58
 
60
- def record_for_persistance
61
- _data.class
62
- end
63
-
64
59
  def url_for_persistance!(options, data)
65
60
  return href if href.present?
66
61
  endpoint = endpoint_for_persistance(data, options)
@@ -9,14 +9,14 @@ class LHS::Item < LHS::Proxy
9
9
  def update(params, options = nil)
10
10
  update!(params, options)
11
11
  rescue LHC::Error => e
12
- self.errors = LHS::Errors::Base.new(e.response)
12
+ self.errors = LHS::Errors::Base.new(e.response, record)
13
13
  false
14
14
  end
15
15
 
16
16
  def update!(params, options = {})
17
17
  options ||= {}
18
- _data.merge_raw!(LHS::Data.new(params, _data.parent, _data.class))
19
- response_data = _data.class.request(
18
+ _data.merge_raw!(LHS::Data.new(params, _data.parent, record))
19
+ response_data = record.request(
20
20
  options.merge(
21
21
  method: :post,
22
22
  url: href,
@@ -16,7 +16,7 @@ class LHS::Item < LHS::Proxy
16
16
  run_validation!(record, options, url, params)
17
17
  true
18
18
  rescue LHC::Error => e
19
- self.errors = LHS::Errors::Base.new(e.response)
19
+ self.errors = LHS::Errors::Base.new(e.response, record)
20
20
  false
21
21
  end
22
22
  alias validate valid?
@@ -51,7 +51,7 @@ class LHS::Item < LHS::Proxy
51
51
 
52
52
  def validation_endpoint
53
53
  endpoint = endpoint_from_link if _data.href # take embeded first
54
- endpoint ||= _data._record.find_endpoint(_data._raw)
54
+ endpoint ||= record.find_endpoint(_data._raw)
55
55
  validates = endpoint.options && endpoint.options.fetch(:validates, false)
56
56
  raise 'Endpoint does not support validations!' unless validates
57
57
  endpoint
@@ -11,11 +11,11 @@ class LHS::Proxy
11
11
 
12
12
  def initialize(data)
13
13
  super(data)
14
- self.errors = LHS::Errors::Base.new
14
+ self.errors = LHS::Errors::Base.new(nil, record)
15
15
  end
16
16
 
17
17
  def errors
18
- @errors ||= LHS::Errors::Base.new
18
+ @errors ||= LHS::Errors::Base.new(nil, record)
19
19
  end
20
20
  end
21
21
  end
@@ -3,10 +3,11 @@ module LHS::Errors
3
3
  class Base
4
4
  include Enumerable
5
5
 
6
- attr_reader :messages, :message, :raw
6
+ attr_reader :messages, :message, :raw, :record
7
7
 
8
- def initialize(response = nil)
8
+ def initialize(response = nil, record = nil)
9
9
  @raw = response.body if response
10
+ @record = record
10
11
  @messages = messages_from_response(response)
11
12
  @message = message_from_response(response)
12
13
  rescue JSON::ParserError
@@ -21,9 +22,9 @@ module LHS::Errors
21
22
  alias has_key? include?
22
23
  alias key? include?
23
24
 
24
- def add(attribute, message = :invalid, _options = {})
25
+ def add(attribute, message = :invalid, options = {})
25
26
  self[attribute]
26
- messages[attribute] << message
27
+ messages[attribute] << generate_message(attribute, message, options)
27
28
  end
28
29
 
29
30
  def get(key)
@@ -31,7 +32,7 @@ module LHS::Errors
31
32
  end
32
33
 
33
34
  def set(key, value)
34
- messages[key] = value
35
+ messages[key] = generate_message(key, value)
35
36
  end
36
37
 
37
38
  delegate :delete, to: :messages
@@ -41,7 +42,7 @@ module LHS::Errors
41
42
  end
42
43
 
43
44
  def []=(attribute, error)
44
- self[attribute] << error
45
+ self[attribute] << generate_message(attribute, error)
45
46
  end
46
47
 
47
48
  def each
@@ -76,7 +77,27 @@ module LHS::Errors
76
77
  def add_error(messages, key, value)
77
78
  key = key.to_sym
78
79
  messages[key] ||= []
79
- messages[key].push(value)
80
+ messages[key].push(generate_message(key, value))
81
+ end
82
+
83
+ def generate_message(attribute, message, _options = {})
84
+ find_translated_error_message(attribute, message) || message
85
+ end
86
+
87
+ def find_translated_error_message(attribute, message)
88
+ record_name = record.model_name.name.underscore
89
+ normalized_attribute = attribute.to_s.underscore
90
+ normalized_message = message.to_s.underscore
91
+ [
92
+ ['lhs', 'errors', 'records', record_name, 'attributes', normalized_attribute, normalized_message],
93
+ ['lhs', 'errors', 'records', record_name, normalized_message],
94
+ ['lhs', 'errors', 'messages', normalized_message],
95
+ ['lhs', 'errors', 'attributes', normalized_attribute, normalized_message],
96
+ ['lhs', 'errors', 'fallback_message']
97
+ ].detect do |path|
98
+ key = path.join('.')
99
+ return I18n.translate(key) if I18n.exists?(key)
100
+ end
80
101
  end
81
102
 
82
103
  def parse_messages(json)
data/lib/lhs/proxy.rb CHANGED
@@ -16,6 +16,10 @@ class LHS::Proxy
16
16
  self._loaded = false
17
17
  end
18
18
 
19
+ def record
20
+ _data.class
21
+ end
22
+
19
23
  def load!(options = nil)
20
24
  return self if _loaded
21
25
  reload!(options)
data/lib/lhs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module LHS
2
- VERSION = "11.1.0"
2
+ VERSION = "11.2.0"
3
3
  end
@@ -0,0 +1,197 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHS::Item do
4
+ before(:each) do
5
+ class Record < LHS::Record
6
+ endpoint 'http://dataste/records'
7
+ end
8
+
9
+ stub_request(:post, "http://dataste/records")
10
+ .to_return(
11
+ status: 400,
12
+ body: {
13
+ field_errors: [{
14
+ "code" => "UNSUPPORTED_PROPERTY_VALUE",
15
+ "path" => ["name"]
16
+ }]
17
+ }.to_json
18
+ )
19
+
20
+ I18n.reload!
21
+ I18n.backend.store_translations(:en, YAML.safe_load(translation)) if translation.present?
22
+ end
23
+
24
+ let(:errors) { Record.create(name: 'Steve').errors }
25
+
26
+ context 'detailed error translation for record and attribute' do
27
+ let(:translation) do
28
+ %q{
29
+ lhs:
30
+ errors:
31
+ records:
32
+ record:
33
+ attributes:
34
+ name:
35
+ unsupported_property_value: 'This value is not supported'
36
+ }
37
+ end
38
+
39
+ it 'translates errors automatically when they are around' do
40
+ expect(errors[:name]).to eq ['This value is not supported']
41
+ end
42
+ end
43
+
44
+ context 'error translation for record' do
45
+ let(:translation) do
46
+ %q{
47
+ lhs:
48
+ errors:
49
+ records:
50
+ record:
51
+ unsupported_property_value: 'This value is unfortunately not supported'
52
+ }
53
+ end
54
+
55
+ it 'translates errors automatically when they are around' do
56
+ expect(errors[:name]).to eq ['This value is unfortunately not supported']
57
+ end
58
+ end
59
+
60
+ context 'error translation for message' do
61
+ let(:translation) do
62
+ %q{
63
+ lhs:
64
+ errors:
65
+ messages:
66
+ unsupported_property_value: 'This value is sadly not supported'
67
+ }
68
+ end
69
+
70
+ it 'translates errors automatically when they are around' do
71
+ expect(errors[:name]).to eq ['This value is sadly not supported']
72
+ end
73
+ end
74
+
75
+ context 'error translation for attributes' do
76
+ let(:translation) do
77
+ %q{
78
+ lhs:
79
+ errors:
80
+ attributes:
81
+ name:
82
+ unsupported_property_value: 'This value is not supported – bummer'
83
+ }
84
+ end
85
+
86
+ it 'translates errors automatically when they are around' do
87
+ expect(errors[:name]).to eq ['This value is not supported – bummer']
88
+ end
89
+ end
90
+
91
+ context 'error translation for fallback message' do
92
+ let(:translation) do
93
+ %q{
94
+ lhs:
95
+ errors:
96
+ fallback_message: 'This value is wrong'
97
+ }
98
+ end
99
+
100
+ it 'translates errors automatically when they are around' do
101
+ expect(errors[:name]).to eq ['This value is wrong']
102
+ end
103
+ end
104
+
105
+ context 'detailed record attribute over other translations' do
106
+ let(:translation) do
107
+ %q{
108
+ lhs:
109
+ errors:
110
+ fallback_message: 'This value is wrong'
111
+ attributes:
112
+ name:
113
+ unsupported_property_value: 'This value is not supported – bummer'
114
+ messages:
115
+ unsupported_property_value: 'This value is sadly not supported'
116
+ records:
117
+ record:
118
+ unsupported_property_value: 'This value is unfortunately not supported'
119
+ attributes:
120
+ name:
121
+ unsupported_property_value: 'This value is not supported'
122
+ }
123
+ end
124
+
125
+ it 'takes detailed record attribute over other translations' do
126
+ expect(errors[:name]).to eq ['This value is not supported']
127
+ end
128
+ end
129
+
130
+ context 'record translations over global messages, attributes and fallback' do
131
+ let(:translation) do
132
+ %q{
133
+ lhs:
134
+ errors:
135
+ fallback_message: 'This value is wrong'
136
+ attributes:
137
+ name:
138
+ unsupported_property_value: 'This value is not supported – bummer'
139
+ messages:
140
+ unsupported_property_value: 'This value is sadly not supported'
141
+ records:
142
+ record:
143
+ unsupported_property_value: 'This value is unfortunately not supported'
144
+ }
145
+ end
146
+
147
+ it 'takes detailed record attribute over other translations' do
148
+ expect(errors[:name]).to eq ['This value is unfortunately not supported']
149
+ end
150
+ end
151
+
152
+ context 'global message translation over attributes and fallback' do
153
+ let(:translation) do
154
+ %q{
155
+ lhs:
156
+ errors:
157
+ fallback_message: 'This value is wrong'
158
+ attributes:
159
+ name:
160
+ unsupported_property_value: 'This value is not supported – bummer'
161
+ messages:
162
+ unsupported_property_value: 'This value is sadly not supported'
163
+ }
164
+ end
165
+
166
+ it 'takes detailed record attribute over other translations' do
167
+ expect(errors[:name]).to eq ['This value is sadly not supported']
168
+ end
169
+ end
170
+
171
+ context 'global attributes over fallback' do
172
+ let(:translation) do
173
+ %q{
174
+ lhs:
175
+ errors:
176
+ fallback_message: 'This value is wrong'
177
+ attributes:
178
+ name:
179
+ unsupported_property_value: 'This value is not supported – bummer'
180
+ }
181
+ end
182
+
183
+ it 'takes detailed record attribute over other translations' do
184
+ expect(errors[:name]).to eq ['This value is not supported – bummer']
185
+ end
186
+ end
187
+
188
+ context 'no translation' do
189
+ let(:translation) do
190
+ %q{}
191
+ end
192
+
193
+ it 'takes no translation but keeps on storing the error message/code' do
194
+ expect(errors[:name]).to eq ['UNSUPPORTED_PROPERTY_VALUE']
195
+ end
196
+ end
197
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.1.0
4
+ version: 11.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
@@ -307,6 +307,7 @@ files:
307
307
  - spec/item/respond_to_spec.rb
308
308
  - spec/item/save_spec.rb
309
309
  - spec/item/setter_spec.rb
310
+ - spec/item/translate_errors_spec.rb
310
311
  - spec/item/update_spec.rb
311
312
  - spec/item/validation_spec.rb
312
313
  - spec/pagination/pages_left_spec.rb
@@ -471,6 +472,7 @@ test_files:
471
472
  - spec/item/respond_to_spec.rb
472
473
  - spec/item/save_spec.rb
473
474
  - spec/item/setter_spec.rb
475
+ - spec/item/translate_errors_spec.rb
474
476
  - spec/item/update_spec.rb
475
477
  - spec/item/validation_spec.rb
476
478
  - spec/pagination/pages_left_spec.rb