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 +4 -4
- data/README.md +13 -0
- data/lib/lhs/concerns/item/save.rb +4 -9
- data/lib/lhs/concerns/item/update.rb +3 -3
- data/lib/lhs/concerns/item/validation.rb +2 -2
- data/lib/lhs/concerns/proxy/errors.rb +2 -2
- data/lib/lhs/errors/base.rb +28 -7
- data/lib/lhs/proxy.rb +4 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/item/translate_errors_spec.rb +197 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec9e7eae2816a09a270575802d332cf27a0a4ae5
|
4
|
+
data.tar.gz: fee348a432bdace92a25a94a48efc319d0ed848d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
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 =
|
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
|
-
|
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,
|
19
|
-
response_data =
|
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 ||=
|
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
|
data/lib/lhs/errors/base.rb
CHANGED
@@ -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,
|
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
data/lib/lhs/version.rb
CHANGED
@@ -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.
|
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
|