lhs 6.8.2 → 7.0.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 +7 -6
- data/lib/lhs/concerns/item/validation.rb +36 -21
- data/lib/lhs/concerns/record/endpoints.rb +9 -0
- data/lib/lhs/version.rb +1 -1
- data/spec/item/validation_spec.rb +71 -88
- data/spec/record/options_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa6cec36b44adf1e4a4ec191be5ddadeade8df99
|
4
|
+
data.tar.gz: 504a4cbb77242734dc54a9545d8871325ff1467b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2980127f21442628806801f96bf5cae65b7fd426a45639b739831e2f9cf06480c2f2fb0d4317b5d7604e6f68703d2306113371ca360be92bcc5ddc497301d90c
|
7
|
+
data.tar.gz: f61ba980791188f4bed6dd59c3f67c9334f77871fa60e5e97c3bba4b2142346ee3b8d799293ec348405cb85b4af8a53353943b932293da5b910512da14a0562f
|
data/README.md
CHANGED
@@ -538,11 +538,11 @@ or with parameters:
|
|
538
538
|
|
539
539
|
In order to validate LHS::Records before persisting them, you can use the `valid?` (`validate` alias) method.
|
540
540
|
|
541
|
-
The specific endpoint has to support validations
|
541
|
+
The specific endpoint has to support validations without peristance. An endpoint has to be enabled (opt-in) for validations in the service configuration.
|
542
542
|
|
543
543
|
```ruby
|
544
544
|
class User < LHS::Record
|
545
|
-
endpoint ':service/v2/users', validates:
|
545
|
+
endpoint ':service/v2/users', validates: { params: { persist: false } }
|
546
546
|
end
|
547
547
|
|
548
548
|
user = User.build(email: 'im not an email address')
|
@@ -551,12 +551,13 @@ unless user.valid?
|
|
551
551
|
end
|
552
552
|
```
|
553
553
|
|
554
|
-
|
554
|
+
The parameters passed to the `validates` endpoint option are used to perform the validation:
|
555
555
|
|
556
556
|
```ruby
|
557
|
-
|
558
|
-
endpoint ':service/v2/users', validates:
|
559
|
-
|
557
|
+
endpoint ':service/v2/users', validates: { params: { persist: false } } # will add ?persist=false to the request
|
558
|
+
endpoint ':service/v2/users', validates: { params: { publish: false } } # will add ?publish=false to the request
|
559
|
+
endpoint ':service/v2/users', validates: { params: { validates: true } } # will add ?validates=true to the request
|
560
|
+
endpoint ':service/v2/users', validates: { path: 'validate' } # will perform a validation via :service/v2/users/validate
|
560
561
|
```
|
561
562
|
|
562
563
|
## Custom validation errors
|
@@ -8,32 +8,47 @@ class LHS::Item < LHS::Proxy
|
|
8
8
|
def valid?(options = {})
|
9
9
|
options ||= {}
|
10
10
|
self.errors = nil
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
params =
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
method: :post,
|
22
|
-
params: params,
|
23
|
-
body: _data.to_json,
|
24
|
-
headers: { 'Content-Type' => 'application/json' }
|
25
|
-
)
|
26
|
-
)
|
27
|
-
true
|
28
|
-
rescue LHC::Error => e
|
29
|
-
self.errors = LHS::Errors.new(e.response)
|
30
|
-
false
|
31
|
-
end
|
11
|
+
endpoint = validation_endpoint
|
12
|
+
raise 'No endpoint found to perform validations! See here: https://github.com/local-ch/lhs#validation' unless endpoint
|
13
|
+
record = LHS::Record.for_url(endpoint.url)
|
14
|
+
params = merge_validation_params!(endpoint)
|
15
|
+
url = validation_url(endpoint)
|
16
|
+
run_validation!(record, options, url, params)
|
17
|
+
true
|
18
|
+
rescue LHC::Error => e
|
19
|
+
self.errors = LHS::Errors.new(e.response)
|
20
|
+
false
|
32
21
|
end
|
33
22
|
alias validate valid?
|
34
23
|
|
35
24
|
private
|
36
25
|
|
26
|
+
def validation_url(endpoint)
|
27
|
+
url = endpoint.url
|
28
|
+
action = endpoint.options[:validates][:path].presence
|
29
|
+
url = "#{url}/#{action}" if action.present?
|
30
|
+
url
|
31
|
+
end
|
32
|
+
|
33
|
+
def merge_validation_params!(endpoint)
|
34
|
+
validates_params = endpoint.options[:validates].select { |key, _| key.to_sym != :path }
|
35
|
+
params = endpoint.options.fetch(:params, {}).merge(params_from_embeded_href)
|
36
|
+
params = params.merge(validates_params) if validates_params.is_a?(Hash)
|
37
|
+
params
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_validation!(record, options, url, params)
|
41
|
+
record.request(
|
42
|
+
options.merge(
|
43
|
+
url: url,
|
44
|
+
method: :post,
|
45
|
+
params: params,
|
46
|
+
body: _data.to_json,
|
47
|
+
headers: { 'Content-Type' => 'application/json' }
|
48
|
+
)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
37
52
|
def validation_endpoint
|
38
53
|
endpoint = embeded_endpoint if _data.href # take embeded first
|
39
54
|
endpoint ||= _data._record.find_endpoint(_data._raw)
|
@@ -17,6 +17,7 @@ class LHS::Record
|
|
17
17
|
class_attribute :endpoints unless defined? endpoints
|
18
18
|
self.endpoints ||= []
|
19
19
|
self.endpoints = endpoints.clone
|
20
|
+
validates_deprecation_check!(options)
|
20
21
|
endpoint = LHC::Endpoint.new(url, options)
|
21
22
|
sanity_check(endpoint)
|
22
23
|
endpoints.push(endpoint)
|
@@ -63,6 +64,14 @@ class LHS::Record
|
|
63
64
|
|
64
65
|
private
|
65
66
|
|
67
|
+
def validates_deprecation_check!(options)
|
68
|
+
return unless options.present?
|
69
|
+
return unless options[:validates].present?
|
70
|
+
return if options[:validates].is_a?(Hash)
|
71
|
+
return if !options[:validates].is_a?(TrueClass) && options[:validates].match(%r{^\/})
|
72
|
+
raise 'Validates with either true or a simple string is deprecated! See here: https://github.com/local-ch/lhs#validation'
|
73
|
+
end
|
74
|
+
|
66
75
|
# Finds the best endpoint.
|
67
76
|
# The best endpoint is the one where all placeholders are interpolated.
|
68
77
|
def find_best_endpoint(params)
|
data/lib/lhs/version.rb
CHANGED
@@ -1,130 +1,113 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
|
3
3
|
describe LHS::Item do
|
4
|
-
let(:
|
5
|
-
|
6
|
-
let(:validation_parameter) { 'persist' }
|
7
|
-
|
8
|
-
let(:mock_validation) do
|
9
|
-
successful_validation
|
4
|
+
let(:user) do
|
5
|
+
User.build(email: 'steve@local.ch')
|
10
6
|
end
|
11
7
|
|
12
|
-
let(:
|
13
|
-
|
8
|
+
let(:record) do
|
9
|
+
Record.build(number: '123456')
|
14
10
|
end
|
15
11
|
|
16
|
-
|
17
|
-
|
12
|
+
context 'deprecation warning for old syntax' do
|
13
|
+
it 'throws errors when using validates with the old syntax' do
|
14
|
+
expect(lambda do
|
15
|
+
class User < LHS::Record
|
16
|
+
endpoint 'http://datastore/v2/users', validates: true
|
17
|
+
end
|
18
|
+
end).to raise_error 'Validates with either true or a simple string is deprecated! See here: https://github.com/local-ch/lhs#validation'
|
19
|
+
expect(lambda do
|
20
|
+
class Record < LHS::Record
|
21
|
+
endpoint 'http://datastore/v2/records', validates: 'publish'
|
22
|
+
end
|
23
|
+
end).to raise_error 'Validates with either true or a simple string is deprecated! See here: https://github.com/local-ch/lhs#validation'
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
|
-
context '
|
21
|
-
let(:validation_parameter) { 'publish' }
|
22
|
-
|
27
|
+
context 'passing validation parameters' do
|
23
28
|
let(:user) do
|
24
29
|
User.build(email: 'steve@local.ch')
|
25
30
|
end
|
26
31
|
|
27
|
-
|
28
|
-
LHC.config.placeholder('datastore', datastore)
|
32
|
+
it 'validates {publish: false}' do
|
29
33
|
class User < LHS::Record
|
30
|
-
endpoint '
|
34
|
+
endpoint 'http://datastore/v2/users', validates: { params: { publish: false } }
|
31
35
|
end
|
32
|
-
|
33
|
-
|
34
|
-
it 'validates' do
|
36
|
+
stub_request(:post, "http://datastore/v2/users?publish=false").to_return(body: {}.to_json)
|
35
37
|
expect(user.valid?).to eq true
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
39
|
-
|
40
|
-
before(:each) do
|
41
|
-
LHC.config.placeholder('datastore', datastore)
|
40
|
+
it 'validates {persist: false}' do
|
42
41
|
class User < LHS::Record
|
43
|
-
endpoint '
|
42
|
+
endpoint 'http://datastore/v2/users', validates: { params: { persist: false } }
|
44
43
|
end
|
44
|
+
stub_request(:post, "http://datastore/v2/users?persist=false").to_return(body: {}.to_json)
|
45
|
+
expect(user.valid?).to eq true
|
45
46
|
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
status: 400,
|
51
|
-
body: {
|
52
|
-
field_errors: [{ code: "UNSUPPORTED_PROPERTY_VALUE", "path" => ["email"] }]
|
53
|
-
}.to_json
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
context 'valid data' do
|
58
|
-
let(:user) do
|
59
|
-
User.build(email: 'steve@local.ch')
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'validates' do
|
63
|
-
expect(user.valid?).to eq true
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'turns to be invalid if validating on changed, invalid data' do
|
67
|
-
expect(user.valid?).to eq true
|
68
|
-
user.email = 'not a valid email'
|
69
|
-
failing_validation
|
70
|
-
expect(user.valid?).to eq false
|
71
|
-
expect(user.errors[:email]).to be
|
48
|
+
it 'validates {validates: true}' do
|
49
|
+
class User < LHS::Record
|
50
|
+
endpoint 'http://datastore/v2/users', validates: { params: { validates: true } }
|
72
51
|
end
|
52
|
+
stub_request(:post, "http://datastore/v2/users?validates=true").to_return(body: {}.to_json)
|
53
|
+
expect(user.valid?).to eq true
|
73
54
|
end
|
74
55
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
let(:mock_validation) do
|
81
|
-
failing_validation
|
56
|
+
it 'validates /validate' do
|
57
|
+
class User < LHS::Record
|
58
|
+
endpoint 'http://datastore/v2/users', validates: { path: 'validate' }
|
82
59
|
end
|
60
|
+
stub_request(:post, "http://datastore/v2/users/validate").to_return(body: {}.to_json)
|
61
|
+
expect(user.valid?).to eq true
|
62
|
+
end
|
63
|
+
end
|
83
64
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
65
|
+
context 'errors object' do
|
66
|
+
let(:validation_errors) { { field_errors: [{ code: "UNSUPPORTED_PROPERTY_VALUE", "path" => ["email"] }] } }
|
67
|
+
let(:successful_validation) do
|
68
|
+
stub_request(:post, "http://datastore/v2/users?persist=false").to_return(body: {}.to_json)
|
69
|
+
end
|
70
|
+
let(:failing_validation) do
|
71
|
+
stub_request(:post, "http://datastore/v2/users?persist=false")
|
72
|
+
.to_return(status: 400, body: validation_errors.to_json)
|
73
|
+
end
|
88
74
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
successful_validation
|
93
|
-
expect(user.valid?).to eq true
|
94
|
-
expect(user.errors).to be_nil
|
75
|
+
before(:each) do
|
76
|
+
class User < LHS::Record
|
77
|
+
endpoint 'http://datastore/v2/users', validates: { params: { persist: false } }
|
95
78
|
end
|
96
79
|
end
|
97
80
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
81
|
+
it 'provides validation errors through the error object' do
|
82
|
+
successful_validation
|
83
|
+
expect(user.valid?).to eq true
|
84
|
+
user.email = 'not a valid email'
|
85
|
+
failing_validation
|
86
|
+
expect(user.valid?).to eq false
|
87
|
+
expect(user.errors[:email]).to be
|
88
|
+
end
|
104
89
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
90
|
+
it 'gets reset when revalidation' do
|
91
|
+
failing_validation
|
92
|
+
expect(user.valid?).to eq false
|
93
|
+
user.email = 'steve@local.ch'
|
94
|
+
successful_validation
|
95
|
+
expect(user.valid?).to eq true
|
96
|
+
expect(user.errors).to be_nil
|
110
97
|
end
|
111
98
|
end
|
112
99
|
|
113
|
-
context '
|
100
|
+
context 'endpoint does not support validations' do
|
114
101
|
before(:each) do
|
115
|
-
class
|
116
|
-
endpoint '
|
117
|
-
endpoint 'http://datastore/v2/records/:id', validates: true
|
102
|
+
class Favorite < LHS::Record
|
103
|
+
endpoint ':datastore/v2/favorites'
|
118
104
|
end
|
119
|
-
stub_request(:get, "http://datastore/v2/records/1")
|
120
|
-
.to_return(body: { href: 'http://datastore/v2/records/1' }.to_json)
|
121
|
-
stub_request(:post, "http://datastore/v2/records/1?persist=false")
|
122
|
-
.to_return(body: {}.to_json)
|
123
105
|
end
|
124
106
|
|
125
|
-
it '
|
126
|
-
|
127
|
-
|
107
|
+
it 'fails when trying to use an endpoint for validations that does not support it' do
|
108
|
+
expect(lambda do
|
109
|
+
Favorite.build.valid?
|
110
|
+
end).to raise_error('Endpoint does not support validations!')
|
128
111
|
end
|
129
112
|
end
|
130
113
|
end
|
data/spec/record/options_spec.rb
CHANGED
@@ -8,11 +8,11 @@ describe LHS::Record do
|
|
8
8
|
before(:each) do
|
9
9
|
LHC.config.placeholder('datastore', datastore)
|
10
10
|
class Record < LHS::Record
|
11
|
-
endpoint ':datastore/records', validates:
|
11
|
+
endpoint ':datastore/records', validates: { persist: false }
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
let(:options) { { auth: { bearer: '123' }, validates:
|
15
|
+
let(:options) { { auth: { bearer: '123' }, validates: { persist: false } } }
|
16
16
|
let(:params) { { name: 'Steve' } }
|
17
17
|
|
18
18
|
context 'options' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|