lhs 7.1.0 → 7.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 +74 -0
- data/lib/lhs/collection.rb +5 -0
- data/lib/lhs/concerns/collection/internal_collection.rb +2 -1
- data/lib/lhs/concerns/item/validation.rb +2 -11
- data/lib/lhs/concerns/proxy/create.rb +43 -0
- data/lib/lhs/concerns/proxy/link.rb +24 -0
- data/lib/lhs/item.rb +5 -0
- data/lib/lhs/proxy.rb +11 -5
- data/lib/lhs/version.rb +1 -1
- data/spec/proxy/create_sub_resource_spec.rb +180 -0
- data/spec/proxy/load_spec.rb +13 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2de08930a39d1136d185c43d33b8353abe09847d
|
4
|
+
data.tar.gz: 0ff2a9b46b4d66aece4ec6c7eeb33b5124511a5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 047e5066a227d3631690a4f61d90c21fe9ca8424ee0361713a552700ca54f890fbb7f4de58654de3b12ac8f819e6fe1a673c4588a89d9aee61221fb9c89e414f
|
7
|
+
data.tar.gz: 8ca3222a86205b07a1e853073f365729137c941642c4b500f359c4a9b70dd68d3d4e8463deec067fb46c51ce988136cd8675e5f82fb79b9cf2b26d26cfff0ae8
|
data/README.md
CHANGED
@@ -282,6 +282,80 @@ When creation fails, the object contains errors. It provides them through the `e
|
|
282
282
|
record.errors.message # ratings must be set when review or name or review_title is set | The property value is required; it cannot be null, empty, or blank."
|
283
283
|
```
|
284
284
|
|
285
|
+
## Create records through associations (nested resources)
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
class Review < LHS::Record
|
289
|
+
endpoint ':service/reviews'
|
290
|
+
end
|
291
|
+
|
292
|
+
class Comment < LHS::Record
|
293
|
+
endpoint ':service/reviews/:review_id/comments'
|
294
|
+
end
|
295
|
+
```
|
296
|
+
|
297
|
+
### Item
|
298
|
+
```ruby
|
299
|
+
review = Review.find(1)
|
300
|
+
# Review#1
|
301
|
+
# :href => ':service/reviews/1
|
302
|
+
# :text => 'Simply awesome'
|
303
|
+
# :comment => { :href => ':service/reviews/1/comments }
|
304
|
+
|
305
|
+
review.comment.create(text: 'Thank you!')
|
306
|
+
# Comment#1
|
307
|
+
# :href => ':service/reviews/1/comments
|
308
|
+
# :text => 'Thank you!'
|
309
|
+
|
310
|
+
review
|
311
|
+
# Review#1
|
312
|
+
# :href => ':service/reviews/1
|
313
|
+
# :text => 'Simply awesome'
|
314
|
+
# :comment => { :href => ':service/reviews/1/comments, :text => 'Thank you!' }
|
315
|
+
```
|
316
|
+
|
317
|
+
If the item already exists `ArgumentError` is raised.
|
318
|
+
|
319
|
+
### Expanded collection
|
320
|
+
```ruby
|
321
|
+
review = Review.includes(:comments).find(1)
|
322
|
+
# Review#1
|
323
|
+
# :href => ':service/reviews/1'
|
324
|
+
# :text => 'Simply awesome'
|
325
|
+
# :comments => { :href => ':service/reviews/1/comments, :items => [] }
|
326
|
+
|
327
|
+
review.comments.create(text: 'Thank you!')
|
328
|
+
# Comment#1
|
329
|
+
# :href => ':service/reviews/1/comments/1'
|
330
|
+
# :text => 'Thank you!'
|
331
|
+
|
332
|
+
review
|
333
|
+
# Review#1
|
334
|
+
# :href => ':service/reviews/1'
|
335
|
+
# :text => 'Simply awesome'
|
336
|
+
# :comments => { :href => ':service/reviews/1/comments, :items => [{ :href => ':service/reviews/1/comments/1', :text => 'Thank you!' }] }
|
337
|
+
```
|
338
|
+
|
339
|
+
### Not expanded collection
|
340
|
+
```ruby
|
341
|
+
review = Review.find(1)
|
342
|
+
# Review#1
|
343
|
+
# :href => ':service/reviews/1'
|
344
|
+
# :text => 'Simply awesome'
|
345
|
+
# :comments => { :href => ':service/reviews/1/comments' }
|
346
|
+
|
347
|
+
review.comments.create(text: 'Thank you!')
|
348
|
+
# Comment#1
|
349
|
+
# :href => ':service/reviews/1/comments/1'
|
350
|
+
# :text => 'Thank you!'
|
351
|
+
|
352
|
+
review
|
353
|
+
# Review#1
|
354
|
+
# :href => ':service/reviews/1
|
355
|
+
# :text => 'Simply awesome'
|
356
|
+
# :comments => { :href => ':service/reviews/1/comments', :items => [{ :href => ':service/reviews/1/comments/1', :text => 'Thank you!' }] }
|
357
|
+
```
|
358
|
+
|
285
359
|
## Build new records
|
286
360
|
|
287
361
|
Build and persist new items from scratch are done either with `new` or it's alias `build`.
|
data/lib/lhs/collection.rb
CHANGED
@@ -5,6 +5,7 @@ Dir[File.dirname(__FILE__) + '/concerns/collection/*.rb'].each { |file| require
|
|
5
5
|
# that contains multiple items
|
6
6
|
class LHS::Collection < LHS::Proxy
|
7
7
|
include InternalCollection
|
8
|
+
include Create
|
8
9
|
|
9
10
|
delegate :select, :length, :size, to: :_collection
|
10
11
|
delegate :_record, :_raw, to: :_data
|
@@ -28,6 +29,10 @@ class LHS::Collection < LHS::Proxy
|
|
28
29
|
true
|
29
30
|
end
|
30
31
|
|
32
|
+
def item?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
31
36
|
protected
|
32
37
|
|
33
38
|
def method_missing(name, *args, &block)
|
@@ -12,7 +12,8 @@ class LHS::Collection < LHS::Proxy
|
|
12
12
|
include Enumerable
|
13
13
|
|
14
14
|
attr_accessor :raw
|
15
|
-
delegate :length, :size, :last, :sample, :[], :present?, :blank?, :empty?,
|
15
|
+
delegate :length, :size, :last, :sample, :[], :present?, :blank?, :empty?,
|
16
|
+
:<<, :push, to: :raw
|
16
17
|
|
17
18
|
def initialize(raw, parent, record)
|
18
19
|
self.raw = raw
|
@@ -32,7 +32,7 @@ class LHS::Item < LHS::Proxy
|
|
32
32
|
|
33
33
|
def merge_validation_params!(endpoint)
|
34
34
|
validates_params = endpoint.options[:validates].select { |key, _| key.to_sym != :path }
|
35
|
-
params = endpoint.options.fetch(:params, {}).merge(
|
35
|
+
params = endpoint.options.fetch(:params, {}).merge(params_from_link)
|
36
36
|
params = params.merge(validates_params) if validates_params.is_a?(Hash)
|
37
37
|
params
|
38
38
|
end
|
@@ -50,20 +50,11 @@ class LHS::Item < LHS::Proxy
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def validation_endpoint
|
53
|
-
endpoint =
|
53
|
+
endpoint = endpoint_from_link if _data.href # take embeded first
|
54
54
|
endpoint ||= _data._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
|
58
58
|
end
|
59
|
-
|
60
|
-
def embeded_endpoint
|
61
|
-
LHS::Endpoint.for_url(_data.href)
|
62
|
-
end
|
63
|
-
|
64
|
-
def params_from_embeded_href
|
65
|
-
return {} if !_data.href || !embeded_endpoint
|
66
|
-
LHC::Endpoint.values_as_params(embeded_endpoint.url, _data.href)
|
67
|
-
end
|
68
59
|
end
|
69
60
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class LHS::Proxy
|
4
|
+
|
5
|
+
module Create
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def create(data = {}, options = nil)
|
9
|
+
record_creation!(options) do
|
10
|
+
record_from_link.create(
|
11
|
+
data,
|
12
|
+
options_for_creation(options)
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create!(data = {}, options = nil)
|
18
|
+
record_creation!(options) do
|
19
|
+
record_from_link.create!(
|
20
|
+
data,
|
21
|
+
options_for_creation(options)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def record_creation!(options)
|
29
|
+
raise(ArgumentError, 'Record already exists') if _raw.keys != [:href] && item?
|
30
|
+
|
31
|
+
record = yield
|
32
|
+
# Needed to handle unexpanded collection which looks the same as item
|
33
|
+
reload!(options) if record.errors.empty?
|
34
|
+
record
|
35
|
+
end
|
36
|
+
|
37
|
+
def options_for_creation(options)
|
38
|
+
return options if params_from_link.blank?
|
39
|
+
options = {} if options.blank?
|
40
|
+
options.deep_merge(params: params_from_link)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
# require File.dirname(__FILE__) + '/../../proxy'
|
3
|
+
|
4
|
+
class LHS::Proxy
|
5
|
+
|
6
|
+
module Link
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def record_from_link
|
12
|
+
LHS::Record.for_url(_data.href)
|
13
|
+
end
|
14
|
+
|
15
|
+
def endpoint_from_link
|
16
|
+
LHS::Endpoint.for_url(_data.href)
|
17
|
+
end
|
18
|
+
|
19
|
+
def params_from_link
|
20
|
+
return {} if !_data.href || !endpoint_from_link
|
21
|
+
LHC::Endpoint.values_as_params(endpoint_from_link.url, _data.href)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/lhs/item.rb
CHANGED
@@ -4,6 +4,7 @@ Dir[File.dirname(__FILE__) + '/concerns/item/*.rb'].each { |file| require file }
|
|
4
4
|
# An item is a concrete record.
|
5
5
|
# It can be part of another proxy like collection.
|
6
6
|
class LHS::Item < LHS::Proxy
|
7
|
+
include Create
|
7
8
|
include Destroy
|
8
9
|
include Save
|
9
10
|
include Update
|
@@ -21,6 +22,10 @@ class LHS::Item < LHS::Proxy
|
|
21
22
|
super(data)
|
22
23
|
end
|
23
24
|
|
25
|
+
def collection?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
24
29
|
def item?
|
25
30
|
true
|
26
31
|
end
|
data/lib/lhs/proxy.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + '/concerns/proxy/*.rb'].each { |file| require file }
|
2
|
+
|
1
3
|
# Proxy makes different kind of data accessible
|
2
4
|
# If href is present it also alows loading/reloading
|
3
5
|
class LHS::Proxy
|
4
6
|
|
7
|
+
include Create
|
8
|
+
include Link
|
9
|
+
|
5
10
|
# prevent clashing with attributes of underlying data
|
6
11
|
attr_accessor :_data, :_loaded
|
7
12
|
|
@@ -10,17 +15,18 @@ class LHS::Proxy
|
|
10
15
|
self._loaded = false
|
11
16
|
end
|
12
17
|
|
13
|
-
def load!
|
18
|
+
def load!(options = nil)
|
14
19
|
return self if _loaded
|
15
|
-
reload!
|
20
|
+
reload!(options)
|
16
21
|
end
|
17
22
|
|
18
|
-
def reload!
|
23
|
+
def reload!(options = nil)
|
19
24
|
raise 'No href found' unless _data.href
|
20
|
-
|
25
|
+
options = {} if options.blank?
|
26
|
+
|
27
|
+
data = _data.class.request(options.merge(url: _data.href, method: :get))
|
21
28
|
_data.merge_raw!(data)
|
22
29
|
self._loaded = true
|
23
30
|
self
|
24
31
|
end
|
25
|
-
|
26
32
|
end
|
data/lib/lhs/version.rb
CHANGED
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Item do
|
4
|
+
before(:each) do
|
5
|
+
class Feedback < LHS::Record
|
6
|
+
endpoint 'http://datastore/v2/feedbacks/:id'
|
7
|
+
end
|
8
|
+
|
9
|
+
class Review < LHS::Record
|
10
|
+
endpoint 'http://datastore/v2/feedbacks/:feedback_id/reviews'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'create sub-resource' do
|
15
|
+
let!(:create_review_request) do
|
16
|
+
stub_request(:post, "http://datastore/v2/feedbacks/1/reviews")
|
17
|
+
.to_return(body: {
|
18
|
+
href: 'http://datastore/v2/feedbacks/1/reviews/1',
|
19
|
+
title: 'Simply awesome'
|
20
|
+
}.to_json)
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'for a nested item' do
|
24
|
+
let(:feedback) { Feedback.find(1) }
|
25
|
+
let(:review) do
|
26
|
+
feedback.review.create(
|
27
|
+
title: 'Simply awesome'
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1/reviews")
|
33
|
+
.to_return(body: {
|
34
|
+
href: 'http://datastore/v2/feedbacks/1/reviews',
|
35
|
+
title: 'Simply awesome'
|
36
|
+
}.to_json)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'without the object' do
|
40
|
+
before(:each) do
|
41
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1")
|
42
|
+
.to_return(body: {
|
43
|
+
review: {
|
44
|
+
href: 'http://datastore/v2/feedbacks/1/reviews'
|
45
|
+
}
|
46
|
+
}.to_json)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'creates an item' do
|
50
|
+
review
|
51
|
+
assert_requested(create_review_request)
|
52
|
+
|
53
|
+
expect(feedback.review.title).to eq 'Simply awesome'
|
54
|
+
expect(review.title).to eq 'Simply awesome'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with existing item' do
|
59
|
+
before(:each) do
|
60
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1")
|
61
|
+
.to_return(body: {
|
62
|
+
review: {
|
63
|
+
href: 'http://datastore/v2/feedbacks/1/reviews',
|
64
|
+
title: 'Simply awesome'
|
65
|
+
}
|
66
|
+
}.to_json)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'raises error' do
|
70
|
+
expect { review }.to raise_error(ArgumentError)
|
71
|
+
|
72
|
+
assert_not_requested(create_review_request)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'for a nested collection' do
|
78
|
+
let(:review) do
|
79
|
+
feedback.reviews.create(
|
80
|
+
title: 'Simply awesome'
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
before do
|
85
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1/reviews")
|
86
|
+
.to_return(body: {
|
87
|
+
items: [{
|
88
|
+
href: 'http://datastore/v2/feedbacks/1/reviews/1',
|
89
|
+
title: 'Simply awesome'
|
90
|
+
}]
|
91
|
+
}.to_json)
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when expanded' do
|
95
|
+
before(:each) do
|
96
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1")
|
97
|
+
.to_return(body: {
|
98
|
+
reviews: {
|
99
|
+
href: 'http://datastore/v2/feedbacks/1/reviews',
|
100
|
+
items: []
|
101
|
+
}
|
102
|
+
}.to_json)
|
103
|
+
end
|
104
|
+
|
105
|
+
let(:feedback) { Feedback.includes(:reviews).find(1) }
|
106
|
+
|
107
|
+
it 'creates an item' do
|
108
|
+
review
|
109
|
+
assert_requested(create_review_request)
|
110
|
+
|
111
|
+
expect(feedback.reviews.first.title).to eq 'Simply awesome'
|
112
|
+
expect(review.title).to eq 'Simply awesome'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when not expanded' do
|
117
|
+
before(:each) do
|
118
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1")
|
119
|
+
.to_return(body: {
|
120
|
+
reviews: {
|
121
|
+
href: 'http://datastore/v2/feedbacks/1/reviews'
|
122
|
+
}
|
123
|
+
}.to_json)
|
124
|
+
end
|
125
|
+
|
126
|
+
let(:feedback) { Feedback.find(1) }
|
127
|
+
|
128
|
+
it 'creates an item' do
|
129
|
+
review
|
130
|
+
assert_requested(create_review_request)
|
131
|
+
|
132
|
+
expect(feedback.reviews.first.title).to eq 'Simply awesome'
|
133
|
+
expect(review.title).to eq 'Simply awesome'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'error messages' do
|
140
|
+
let!(:create_review_request) do
|
141
|
+
stub_request(:post, "http://datastore/v2/feedbacks/1/reviews")
|
142
|
+
.to_return(
|
143
|
+
status: 400,
|
144
|
+
body: {
|
145
|
+
status: 400,
|
146
|
+
message: 'Validation failed',
|
147
|
+
field_errors: [{
|
148
|
+
code: 'UNSATISFIED_PROPERTY_VALUE_MAXIMUM_LENGTH',
|
149
|
+
path: ['title'],
|
150
|
+
message: 'Title is too long'
|
151
|
+
}]
|
152
|
+
}.to_json
|
153
|
+
)
|
154
|
+
end
|
155
|
+
|
156
|
+
let(:feedback) { Feedback.find(1) }
|
157
|
+
let(:review) do
|
158
|
+
feedback.review.create(
|
159
|
+
title: 'Simply awesome'
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
before do
|
164
|
+
stub_request(:get, "http://datastore/v2/feedbacks/1")
|
165
|
+
.to_return(body: {
|
166
|
+
review: {
|
167
|
+
href: 'http://datastore/v2/feedbacks/1/reviews'
|
168
|
+
}
|
169
|
+
}.to_json)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'are propagated when creation fails' do
|
173
|
+
review
|
174
|
+
assert_requested(create_review_request)
|
175
|
+
|
176
|
+
expect(review.title).to eq 'Simply awesome'
|
177
|
+
expect(review.errors.messages[:title]).to include('UNSATISFIED_PROPERTY_VALUE_MAXIMUM_LENGTH')
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/spec/proxy/load_spec.rb
CHANGED
@@ -54,10 +54,22 @@ describe LHS::Proxy do
|
|
54
54
|
AnotherRecord.new(href: 'http://datastore/v2/feedbacks')
|
55
55
|
end
|
56
56
|
|
57
|
-
it '
|
57
|
+
it 'applies endpoint options on load!' do
|
58
58
|
stub_request(:get, 'http://datastore/v2/feedbacks?color=blue')
|
59
59
|
.to_return(body: {}.to_json)
|
60
60
|
record.load!
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
context 'per request options' do
|
65
|
+
let(:record) do
|
66
|
+
Record.new(href: 'http://datastore/v2/feedbacks')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'applies options passed to load' do
|
70
|
+
stub_request(:get, 'http://datastore/v2/feedbacks?color=blue')
|
71
|
+
.to_return(body: {}.to_json)
|
72
|
+
record.load!(params: { color: 'blue' })
|
73
|
+
end
|
74
|
+
end
|
63
75
|
end
|
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: 7.
|
4
|
+
version: 7.2.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-12-
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|
@@ -202,6 +202,8 @@ files:
|
|
202
202
|
- lib/lhs/concerns/item/save.rb
|
203
203
|
- lib/lhs/concerns/item/update.rb
|
204
204
|
- lib/lhs/concerns/item/validation.rb
|
205
|
+
- lib/lhs/concerns/proxy/create.rb
|
206
|
+
- lib/lhs/concerns/proxy/link.rb
|
205
207
|
- lib/lhs/concerns/record/all.rb
|
206
208
|
- lib/lhs/concerns/record/batch.rb
|
207
209
|
- lib/lhs/concerns/record/chainable.rb
|
@@ -301,6 +303,7 @@ files:
|
|
301
303
|
- spec/item/update_spec.rb
|
302
304
|
- spec/item/validation_spec.rb
|
303
305
|
- spec/pagination/pages_left_spec.rb
|
306
|
+
- spec/proxy/create_sub_resource_spec.rb
|
304
307
|
- spec/proxy/load_spec.rb
|
305
308
|
- spec/rails_helper.rb
|
306
309
|
- spec/record/all_spec.rb
|
@@ -373,7 +376,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
373
376
|
requirements:
|
374
377
|
- Ruby >= 2.0.0
|
375
378
|
rubyforge_project:
|
376
|
-
rubygems_version: 2.
|
379
|
+
rubygems_version: 2.5.2
|
377
380
|
signing_key:
|
378
381
|
specification_version: 4
|
379
382
|
summary: Rails gem providing an easy, active-record-like interface for http json services
|
@@ -451,6 +454,7 @@ test_files:
|
|
451
454
|
- spec/item/update_spec.rb
|
452
455
|
- spec/item/validation_spec.rb
|
453
456
|
- spec/pagination/pages_left_spec.rb
|
457
|
+
- spec/proxy/create_sub_resource_spec.rb
|
454
458
|
- spec/proxy/load_spec.rb
|
455
459
|
- spec/rails_helper.rb
|
456
460
|
- spec/record/all_spec.rb
|