ddy_remote_resource 0.4.11 → 1.0.0.rc1
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/Gemfile +2 -0
- data/Guardfile +3 -0
- data/lib/remote_resource.rb +77 -34
- data/lib/remote_resource/base.rb +20 -8
- data/lib/remote_resource/connection.rb +26 -5
- data/lib/remote_resource/connection_options.rb +5 -3
- data/lib/remote_resource/querying/finder_methods.rb +3 -3
- data/lib/remote_resource/querying/persistence_methods.rb +17 -12
- data/lib/remote_resource/request.rb +96 -62
- data/lib/remote_resource/response.rb +5 -1
- data/lib/remote_resource/rest.rb +13 -17
- data/lib/remote_resource/url_naming.rb +4 -10
- data/lib/remote_resource/url_naming_determination.rb +1 -3
- data/lib/remote_resource/util.rb +64 -0
- data/lib/remote_resource/version.rb +1 -1
- data/remote_resource.gemspec +2 -2
- data/spec/fixtures/text_file.txt +1 -0
- data/spec/integration/all_spec.rb +166 -0
- data/spec/integration/collection_prefix_spec.rb +99 -0
- data/spec/integration/create_spec.rb +181 -0
- data/spec/integration/destroy_spec.rb +252 -0
- data/spec/integration/find_by_spec.rb +168 -0
- data/spec/integration/find_spec.rb +139 -0
- data/spec/integration/headers_spec.rb +222 -0
- data/spec/integration/naming_spec.rb +138 -0
- data/spec/integration/save_spec.rb +320 -0
- data/spec/integration/update_attributes_spec.rb +221 -0
- data/spec/integration/where_spec.rb +152 -0
- data/spec/lib/extensions/ethon/easy/queryable_spec.rb +4 -4
- data/spec/lib/remote_resource/base_spec.rb +54 -110
- data/spec/lib/remote_resource/builder_spec.rb +1 -1
- data/spec/lib/remote_resource/collection_spec.rb +1 -1
- data/spec/lib/remote_resource/connection_options_spec.rb +20 -17
- data/spec/lib/remote_resource/connection_spec.rb +36 -27
- data/spec/lib/remote_resource/querying/finder_methods_spec.rb +199 -72
- data/spec/lib/remote_resource/querying/persistence_methods_spec.rb +228 -220
- data/spec/lib/remote_resource/request_spec.rb +313 -342
- data/spec/lib/remote_resource/response_spec.rb +9 -3
- data/spec/lib/remote_resource/rest_spec.rb +11 -11
- data/spec/lib/remote_resource/url_naming_determination_spec.rb +1 -1
- data/spec/lib/remote_resource/url_naming_spec.rb +7 -22
- data/spec/lib/remote_resource/util_spec.rb +56 -0
- data/spec/lib/remote_resource/version_spec.rb +2 -3
- data/spec/spec_helper.rb +37 -0
- metadata +33 -22
- data/lib/remote_resource/http_errors.rb +0 -33
- data/lib/remote_resource/response_handeling.rb +0 -48
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe RemoteResource::Connection do
|
3
|
+
RSpec.describe RemoteResource::Connection do
|
4
4
|
|
5
5
|
module RemoteResource
|
6
6
|
class ConnectionDummy
|
@@ -20,42 +20,51 @@ describe RemoteResource::Connection do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
describe '.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
dummy_class.content_type = '.html'
|
29
|
-
|
30
|
-
expect(dummy_class.content_type).to eql '.html'
|
23
|
+
describe '.default_headers' do
|
24
|
+
it 'returns an empty Hash' do
|
25
|
+
expect(dummy_class.default_headers).to eql({})
|
26
|
+
end
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
29
|
+
describe '.content_type=' do
|
30
|
+
it 'warns that the method is deprecated' do
|
31
|
+
expect(dummy_class).to receive(:warn).with('[DEPRECATION] `.content_type=` is deprecated. Please use `.extension=` instead.')
|
32
|
+
dummy_class.content_type = '.json'
|
34
33
|
end
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
describe '.content_type' do
|
37
|
+
it 'warns that the method is deprecated' do
|
38
|
+
expect(dummy_class).to receive(:warn).with('[DEPRECATION] `.content_type` is deprecated. Please use `.extension` instead.')
|
39
|
+
dummy_class.content_type
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe '.
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
describe '.extra_headers=' do
|
44
|
+
it 'warns that the method is deprecated' do
|
45
|
+
expect(dummy_class).to receive(:warn).with('[DEPRECATION] `.extra_headers=` is deprecated. Please overwrite the .headers method to set custom headers.')
|
46
|
+
dummy_class.extra_headers = '.json'
|
47
|
+
end
|
48
|
+
end
|
47
49
|
|
48
|
-
|
50
|
+
describe '.extra_headers' do
|
51
|
+
it 'warns that the method is deprecated' do
|
52
|
+
expect(dummy_class).to receive(:warn).with('[DEPRECATION] `.extra_headers` is deprecated. Please overwrite the .headers method to set custom headers.')
|
53
|
+
dummy_class.extra_headers
|
54
|
+
end
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
|
57
|
+
describe '.headers=' do
|
58
|
+
it 'warns that the method is not used to set custom headers' do
|
59
|
+
expect(dummy_class).to receive(:warn).with('[WARNING] `.headers=` can not be used to set custom headers. Please overwrite the .headers method to set custom headers.')
|
60
|
+
dummy_class.headers = { 'Foo' => 'Bar' }
|
52
61
|
end
|
62
|
+
end
|
53
63
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
64
|
+
describe '.headers' do
|
65
|
+
it 'returns an empty Hash' do
|
66
|
+
expect(dummy_class.headers).to eql({})
|
58
67
|
end
|
59
68
|
end
|
60
69
|
|
61
|
-
end
|
70
|
+
end
|
@@ -1,138 +1,265 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe RemoteResource::Querying::FinderMethods do
|
3
|
+
RSpec.describe RemoteResource::Querying::FinderMethods do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
class FinderMethodsDummy
|
8
|
-
include RemoteResource::Base
|
5
|
+
class Post
|
6
|
+
include RemoteResource::Base
|
9
7
|
|
10
|
-
|
8
|
+
self.site = 'https://www.example.com'
|
9
|
+
self.collection = true
|
10
|
+
self.root_element = :data
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
attribute :title, String
|
13
|
+
attribute :body, String
|
14
|
+
attribute :featured, Boolean
|
15
|
+
attribute :created_at, Time
|
14
16
|
end
|
15
17
|
|
16
|
-
let(:dummy_class) { RemoteResource::Querying::FinderMethodsDummy }
|
17
|
-
let(:dummy) { dummy_class.new }
|
18
|
-
|
19
18
|
describe '.find' do
|
20
|
-
let(:
|
19
|
+
let(:response_body) do
|
20
|
+
{
|
21
|
+
data: {
|
22
|
+
id: 12,
|
23
|
+
title: 'Lorem Ipsum',
|
24
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
25
|
+
featured: true,
|
26
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
|
31
|
+
let!(:expected_request) do
|
32
|
+
mock_request = stub_request(:get, 'https://www.example.com/posts/12.json')
|
33
|
+
mock_request.to_return(status: 200, body: response_body.to_json)
|
34
|
+
mock_request
|
25
35
|
end
|
26
36
|
|
27
|
-
it 'performs
|
28
|
-
|
29
|
-
expect(
|
30
|
-
expect_any_instance_of(RemoteResource::Request).to receive(:perform).and_call_original
|
31
|
-
dummy_class.find('12')
|
37
|
+
it 'performs the HTTP request' do
|
38
|
+
Post.find(12)
|
39
|
+
expect(expected_request).to have_been_requested
|
32
40
|
end
|
33
41
|
|
34
|
-
it 'builds the resource
|
35
|
-
|
36
|
-
|
42
|
+
it 'builds the correct resource' do
|
43
|
+
post = Post.find(12)
|
44
|
+
|
45
|
+
aggregate_failures do
|
46
|
+
expect(post.id).to eql 12
|
47
|
+
expect(post.title).to eql 'Lorem Ipsum'
|
48
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
49
|
+
expect(post.featured).to eql true
|
50
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
51
|
+
end
|
37
52
|
end
|
38
53
|
|
39
54
|
it 'does NOT change the given connection_options' do
|
40
55
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
41
56
|
|
42
|
-
expect {
|
57
|
+
expect { Post.find(12, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
43
58
|
end
|
44
59
|
|
45
|
-
|
46
|
-
it 'performs a RemoteResource::Request with params' do
|
47
|
-
stub_request(:get, 'https://foobar.com/finder_methods_dummy/12.json?skip_associations=true').to_return(status: 200, body: {}.to_json)
|
48
|
-
expect(RemoteResource::Request).to receive(:new).with(dummy_class, :get, { id: '12' }, { params: { skip_associations: true }, no_attributes: true }).and_call_original
|
49
|
-
expect_any_instance_of(RemoteResource::Request).to receive(:perform).and_call_original
|
50
|
-
dummy_class.find('12', params: { skip_associations: true })
|
51
|
-
end
|
60
|
+
xcontext 'return value #success? and NOT #success?' do
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
55
64
|
describe '.find_by' do
|
56
|
-
let(:
|
57
|
-
|
58
|
-
|
65
|
+
let(:response_body) do
|
66
|
+
{
|
67
|
+
data: {
|
68
|
+
id: 12,
|
69
|
+
title: 'Lorem Ipsum',
|
70
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
71
|
+
featured: true,
|
72
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
73
|
+
}
|
74
|
+
}
|
59
75
|
end
|
60
76
|
|
61
|
-
|
62
|
-
|
63
|
-
|
77
|
+
let!(:expected_request) do
|
78
|
+
mock_request = stub_request(:get, 'https://www.example.com/posts/current.json')
|
79
|
+
mock_request.with(query: { title: 'Lorem Ipsum', featured: true })
|
80
|
+
mock_request.to_return(status: 200, body: response_body.to_json)
|
81
|
+
mock_request
|
64
82
|
end
|
65
83
|
|
66
|
-
it 'performs
|
67
|
-
|
68
|
-
|
69
|
-
dummy_class.find_by params
|
84
|
+
it 'performs the HTTP request' do
|
85
|
+
Post.find_by({ title: 'Lorem Ipsum', featured: true }, path_postfix: '/current')
|
86
|
+
expect(expected_request).to have_been_requested
|
70
87
|
end
|
71
88
|
|
72
|
-
it 'builds the resource
|
73
|
-
|
74
|
-
|
89
|
+
it 'builds the correct resource' do
|
90
|
+
post = Post.find_by({ title: 'Lorem Ipsum', featured: true }, path_postfix: '/current')
|
91
|
+
|
92
|
+
aggregate_failures do
|
93
|
+
expect(post.id).to eql 12
|
94
|
+
expect(post.title).to eql 'Lorem Ipsum'
|
95
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
96
|
+
expect(post.featured).to eql true
|
97
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'does NOT change the given params' do
|
102
|
+
params = { title: 'Lorem Ipsum', featured: true }
|
103
|
+
|
104
|
+
expect { Post.find_by(params, path_postfix: '/current') }.not_to change { params }.from(params.dup)
|
75
105
|
end
|
76
106
|
|
77
107
|
it 'does NOT change the given connection_options' do
|
78
|
-
|
108
|
+
params = { title: 'Lorem Ipsum', featured: true }
|
109
|
+
connection_options = { path_postfix: '/current', headers: { 'Foo' => 'Bar' } }
|
110
|
+
|
111
|
+
expect { Post.find_by(params, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
112
|
+
end
|
79
113
|
|
80
|
-
|
114
|
+
xcontext 'return value #success? and NOT #success?' do
|
81
115
|
end
|
82
116
|
end
|
83
117
|
|
84
118
|
describe '.all' do
|
85
|
-
let(:
|
119
|
+
let(:response_body) do
|
120
|
+
{
|
121
|
+
data: [
|
122
|
+
{
|
123
|
+
id: 12,
|
124
|
+
title: 'Lorem Ipsum',
|
125
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
126
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
127
|
+
},
|
128
|
+
{
|
129
|
+
id: 14,
|
130
|
+
title: 'Mauris Purus',
|
131
|
+
body: 'Mauris purus urna, ultrices et suscipit ut, faucibus eget mauris.',
|
132
|
+
created_at: Time.new(2015, 12, 11, 11, 32, 0),
|
133
|
+
},
|
134
|
+
{
|
135
|
+
id: 16,
|
136
|
+
title: 'Vestibulum Commodo',
|
137
|
+
body: 'Vestibulum commodo fringilla suscipit.',
|
138
|
+
created_at: Time.new(2016, 2, 6, 18, 45, 0),
|
139
|
+
},
|
140
|
+
]
|
141
|
+
}
|
142
|
+
end
|
86
143
|
|
87
|
-
|
88
|
-
|
89
|
-
|
144
|
+
let!(:expected_request) do
|
145
|
+
mock_request = stub_request(:get, 'https://www.example.com/posts.json')
|
146
|
+
mock_request.to_return(status: 200, body: response_body.to_json)
|
147
|
+
mock_request
|
90
148
|
end
|
91
149
|
|
92
|
-
it 'performs
|
93
|
-
|
94
|
-
|
95
|
-
dummy_class.all
|
150
|
+
it 'performs the HTTP request' do
|
151
|
+
Post.all
|
152
|
+
expect(expected_request).to have_been_requested
|
96
153
|
end
|
97
154
|
|
98
|
-
it 'builds the
|
99
|
-
|
100
|
-
|
155
|
+
it 'builds the correct collection of resources' do
|
156
|
+
posts = Post.all
|
157
|
+
|
158
|
+
aggregate_failures do
|
159
|
+
expect(posts).to respond_to :each
|
160
|
+
expect(posts).to all(be_a(Post))
|
161
|
+
expect(posts.size).to eql 3
|
162
|
+
|
163
|
+
expect(posts[0].id).to eql 12
|
164
|
+
expect(posts[0].title).to eql 'Lorem Ipsum'
|
165
|
+
expect(posts[0].body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
166
|
+
expect(posts[0].created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
167
|
+
expect(posts[1].id).to eql 14
|
168
|
+
expect(posts[1].title).to eql 'Mauris Purus'
|
169
|
+
expect(posts[1].body).to eql 'Mauris purus urna, ultrices et suscipit ut, faucibus eget mauris.'
|
170
|
+
expect(posts[1].created_at).to eql Time.new(2015, 12, 11, 11, 32, 0)
|
171
|
+
expect(posts[2].id).to eql 16
|
172
|
+
expect(posts[2].title).to eql 'Vestibulum Commodo'
|
173
|
+
expect(posts[2].body).to eql 'Vestibulum commodo fringilla suscipit.'
|
174
|
+
expect(posts[2].created_at).to eql Time.new(2016, 2, 6, 18, 45, 0)
|
175
|
+
end
|
101
176
|
end
|
102
177
|
|
103
178
|
it 'does NOT change the given connection_options' do
|
104
179
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
105
180
|
|
106
|
-
expect {
|
181
|
+
expect { Post.all(connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
182
|
+
end
|
183
|
+
|
184
|
+
xcontext 'return value #success? and NOT #success?' do
|
107
185
|
end
|
108
186
|
end
|
109
187
|
|
110
188
|
describe '.where' do
|
111
|
-
let(:
|
112
|
-
|
113
|
-
|
189
|
+
let(:response_body) do
|
190
|
+
{
|
191
|
+
data: [
|
192
|
+
{
|
193
|
+
id: 12,
|
194
|
+
title: 'Lorem Ipsum',
|
195
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
196
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
197
|
+
},
|
198
|
+
{
|
199
|
+
id: 14,
|
200
|
+
title: 'Mauris Purus',
|
201
|
+
body: 'Mauris purus urna, ultrices et suscipit ut, faucibus eget mauris.',
|
202
|
+
created_at: Time.new(2015, 12, 11, 11, 32, 0),
|
203
|
+
},
|
204
|
+
{
|
205
|
+
id: 16,
|
206
|
+
title: 'Vestibulum Commodo',
|
207
|
+
body: 'Vestibulum commodo fringilla suscipit.',
|
208
|
+
created_at: Time.new(2016, 2, 6, 18, 45, 0),
|
209
|
+
},
|
210
|
+
]
|
211
|
+
}
|
212
|
+
end
|
213
|
+
|
214
|
+
let!(:expected_request) do
|
215
|
+
mock_request = stub_request(:get, 'https://www.example.com/posts.json')
|
216
|
+
mock_request.with(query: { pseudonym: 'pseudonym' })
|
217
|
+
mock_request.to_return(status: 200, body: response_body.to_json)
|
218
|
+
mock_request
|
114
219
|
end
|
115
220
|
|
116
|
-
|
117
|
-
|
118
|
-
|
221
|
+
it 'performs the HTTP request' do
|
222
|
+
Post.where({ pseudonym: 'pseudonym' })
|
223
|
+
expect(expected_request).to have_been_requested
|
119
224
|
end
|
120
225
|
|
121
|
-
it '
|
122
|
-
|
123
|
-
|
124
|
-
|
226
|
+
it 'builds the correct collection of resources' do
|
227
|
+
posts = Post.where({ pseudonym: 'pseudonym' })
|
228
|
+
|
229
|
+
aggregate_failures do
|
230
|
+
expect(posts).to respond_to :each
|
231
|
+
expect(posts).to all(be_a(Post))
|
232
|
+
expect(posts.size).to eql 3
|
233
|
+
|
234
|
+
expect(posts[0].id).to eql 12
|
235
|
+
expect(posts[0].title).to eql 'Lorem Ipsum'
|
236
|
+
expect(posts[0].body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
237
|
+
expect(posts[0].created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
238
|
+
expect(posts[1].id).to eql 14
|
239
|
+
expect(posts[1].title).to eql 'Mauris Purus'
|
240
|
+
expect(posts[1].body).to eql 'Mauris purus urna, ultrices et suscipit ut, faucibus eget mauris.'
|
241
|
+
expect(posts[1].created_at).to eql Time.new(2015, 12, 11, 11, 32, 0)
|
242
|
+
expect(posts[2].id).to eql 16
|
243
|
+
expect(posts[2].title).to eql 'Vestibulum Commodo'
|
244
|
+
expect(posts[2].body).to eql 'Vestibulum commodo fringilla suscipit.'
|
245
|
+
expect(posts[2].created_at).to eql Time.new(2016, 2, 6, 18, 45, 0)
|
246
|
+
end
|
125
247
|
end
|
126
248
|
|
127
|
-
it '
|
128
|
-
|
129
|
-
|
249
|
+
it 'does NOT change the given params' do
|
250
|
+
params = { pseudonym: 'pseudonym' }
|
251
|
+
|
252
|
+
expect { Post.where(params) }.not_to change { params }.from(params.dup)
|
130
253
|
end
|
131
254
|
|
132
255
|
it 'does NOT change the given connection_options' do
|
256
|
+
params = { pseudonym: 'pseudonym' }
|
133
257
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
134
258
|
|
135
|
-
expect {
|
259
|
+
expect { Post.where(params, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
260
|
+
end
|
261
|
+
|
262
|
+
xcontext 'return value #success? and NOT #success?' do
|
136
263
|
end
|
137
264
|
end
|
138
265
|
|
@@ -1,342 +1,350 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe RemoteResource::Querying::PersistenceMethods do
|
3
|
+
RSpec.describe RemoteResource::Querying::PersistenceMethods do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
class PersistenceMethodsDummy
|
8
|
-
include RemoteResource::Base
|
5
|
+
class Post
|
6
|
+
include RemoteResource::Base
|
9
7
|
|
10
|
-
|
8
|
+
self.site = 'https://www.example.com'
|
9
|
+
self.collection = true
|
10
|
+
self.root_element = :data
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
attribute :title, String
|
13
|
+
attribute :body, String
|
14
|
+
attribute :featured, Boolean
|
15
|
+
attribute :created_at, Time
|
16
16
|
end
|
17
17
|
|
18
|
-
let(:dummy_class) { RemoteResource::Querying::PersistenceMethodsDummy }
|
19
|
-
let(:dummy) { dummy_class.new }
|
20
|
-
|
21
18
|
describe '.create' do
|
22
|
-
let(:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
19
|
+
let(:response_body) do
|
20
|
+
{
|
21
|
+
data: {
|
22
|
+
id: 12,
|
23
|
+
title: 'Lorem Ipsum',
|
24
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
25
|
+
featured: true,
|
26
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
let!(:expected_request) do
|
32
|
+
mock_request = stub_request(:post, 'https://www.example.com/posts.json')
|
33
|
+
mock_request.to_return(status: 201, body: JSON.generate(response_body))
|
34
|
+
mock_request
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'performs the HTTP request' do
|
38
|
+
Post.create(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true)
|
39
|
+
expect(expected_request).to have_been_requested
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'builds the correct resource' do
|
43
|
+
post = Post.create(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true)
|
44
|
+
|
45
|
+
aggregate_failures do
|
46
|
+
expect(post.persisted?).to eql true
|
47
|
+
expect(post.id).to eql 12
|
48
|
+
expect(post.title).to eql 'Lorem Ipsum'
|
49
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
50
|
+
expect(post.featured).to eql true
|
51
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
52
|
+
end
|
46
53
|
end
|
47
54
|
|
48
55
|
it 'does NOT change the given attributes' do
|
49
|
-
|
56
|
+
attributes = { title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true }
|
57
|
+
|
58
|
+
expect { Post.create(attributes) }.not_to change { attributes }.from(attributes.dup)
|
50
59
|
end
|
51
60
|
|
52
61
|
it 'does NOT change the given connection_options' do
|
62
|
+
attributes = { title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true }
|
53
63
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
54
64
|
|
55
|
-
expect {
|
65
|
+
expect { Post.create(attributes, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
66
|
+
end
|
67
|
+
|
68
|
+
xcontext 'return value #success? and NOT #success?' do
|
56
69
|
end
|
57
70
|
end
|
58
71
|
|
59
72
|
describe '.destroy' do
|
60
|
-
let(:
|
61
|
-
|
62
|
-
before do
|
63
|
-
allow_any_instance_of(dummy_class).to receive(:handle_response)
|
64
|
-
allow_any_instance_of(RemoteResource::Request).to receive(:perform) { response }
|
73
|
+
let(:response_body) do
|
74
|
+
{}
|
65
75
|
end
|
66
76
|
|
67
|
-
|
68
|
-
|
69
|
-
|
77
|
+
let!(:expected_request) do
|
78
|
+
mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
|
79
|
+
mock_request.to_return(status: 204, body: response_body.to_json)
|
80
|
+
mock_request
|
70
81
|
end
|
71
82
|
|
72
|
-
it 'performs
|
73
|
-
|
74
|
-
|
75
|
-
dummy_class.destroy('15')
|
83
|
+
it 'performs the HTTP request' do
|
84
|
+
Post.destroy(12)
|
85
|
+
expect(expected_request).to have_been_requested
|
76
86
|
end
|
77
87
|
|
78
|
-
it '
|
79
|
-
|
80
|
-
|
88
|
+
it 'builds the correct non-persistent resource' do
|
89
|
+
post = Post.destroy(12)
|
90
|
+
|
91
|
+
aggregate_failures do
|
92
|
+
expect(post.id).to eql 12
|
93
|
+
expect(post.persisted?).to eql false
|
94
|
+
end
|
81
95
|
end
|
82
96
|
|
83
97
|
it 'does NOT change the given connection_options' do
|
84
98
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
85
99
|
|
86
|
-
expect {
|
100
|
+
expect { Post.destroy(12, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
87
101
|
end
|
88
102
|
|
89
|
-
|
90
|
-
let(:response) { { status: 200, body: '' } }
|
91
|
-
before { allow_any_instance_of(RemoteResource::Request).to receive(:perform).and_call_original }
|
92
|
-
|
93
|
-
it 'generates correct request url' do
|
94
|
-
stub_request(:delete, 'https://foobar.com/persistence_methods_dummy/15.json').with(body: nil).to_return(response)
|
95
|
-
dummy_class.destroy('15')
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'includes params' do
|
99
|
-
stub_request(:delete, 'https://foobar.com/persistence_methods_dummy/15.json?pseudonym=3s8e3j').with(body: nil).to_return(response)
|
100
|
-
dummy_class.destroy('15', params: { pseudonym: '3s8e3j' })
|
101
|
-
end
|
103
|
+
xcontext 'return value #success? and NOT #success?' do
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
105
107
|
describe '#update_attributes' do
|
106
|
-
let(:
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
108
|
+
let(:response_body) do
|
109
|
+
{
|
110
|
+
data: {
|
111
|
+
id: 12,
|
112
|
+
title: 'Aliquam lobortis',
|
113
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
114
|
+
featured: true,
|
115
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
116
|
+
}
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when resource is persisted' do
|
121
|
+
let(:resource) { Post.new(id: 12, title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true, created_at: Time.new(2015, 10, 4, 9, 30, 0)) }
|
122
|
+
|
123
|
+
let!(:expected_request) do
|
124
|
+
mock_request = stub_request(:patch, 'https://www.example.com/posts/12.json')
|
125
|
+
mock_request.to_return(status: 201, body: JSON.generate(response_body))
|
126
|
+
mock_request
|
125
127
|
end
|
126
128
|
|
127
|
-
it '
|
128
|
-
|
129
|
-
|
129
|
+
it 'performs the HTTP request' do
|
130
|
+
resource.update_attributes(title: 'Aliquam lobortis', featured: true)
|
131
|
+
expect(expected_request).to have_been_requested
|
130
132
|
end
|
131
133
|
|
132
|
-
it '
|
133
|
-
|
134
|
-
end
|
134
|
+
it 'builds the correct resource' do
|
135
|
+
resource.update_attributes(title: 'Aliquam lobortis', featured: true)
|
135
136
|
|
136
|
-
|
137
|
-
connection_options = { headers: { 'Foo' => 'Bar' } }
|
138
|
-
|
139
|
-
expect { dummy.update_attributes(attributes, connection_options) }.not_to change { connection_options }.from({ headers: { 'Foo' => 'Bar' } })
|
140
|
-
end
|
141
|
-
end
|
137
|
+
post = resource
|
142
138
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
139
|
+
aggregate_failures do
|
140
|
+
expect(post.persisted?).to eql true
|
141
|
+
expect(post.id).to eql 12
|
142
|
+
expect(post.title).to eql 'Aliquam lobortis'
|
143
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
144
|
+
expect(post.featured).to eql true
|
145
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
146
|
+
end
|
147
147
|
end
|
148
148
|
|
149
149
|
it 'does NOT change the given attributes' do
|
150
|
-
|
150
|
+
attributes = { title: 'Aliquam lobortis', featured: true }
|
151
|
+
|
152
|
+
expect { resource.update_attributes(attributes) }.not_to change { attributes }.from(attributes.dup)
|
151
153
|
end
|
152
154
|
|
153
155
|
it 'does NOT change the given connection_options' do
|
156
|
+
attributes = { title: 'Aliquam lobortis', featured: true }
|
154
157
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
155
158
|
|
156
|
-
expect {
|
159
|
+
expect { resource.update_attributes(attributes, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
157
160
|
end
|
158
|
-
end
|
159
|
-
|
160
|
-
context 'when the save was successful' do
|
161
|
-
it 'returns the resource' do
|
162
|
-
allow(dummy).to receive(:success?) { true }
|
163
161
|
|
164
|
-
|
162
|
+
xcontext 'return value #success? and NOT #success?' do
|
165
163
|
end
|
166
164
|
end
|
167
165
|
|
168
|
-
context 'when
|
169
|
-
|
170
|
-
allow(dummy).to receive(:success?) { false }
|
166
|
+
context 'when resource is NOT persisted' do
|
167
|
+
let(:resource) { Post.new(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: true) }
|
171
168
|
|
172
|
-
|
169
|
+
let!(:expected_request) do
|
170
|
+
mock_request = stub_request(:post, 'https://www.example.com/posts.json')
|
171
|
+
mock_request.to_return(status: 201, body: JSON.generate(response_body))
|
172
|
+
mock_request
|
173
173
|
end
|
174
|
-
end
|
175
|
-
end
|
176
174
|
|
177
|
-
|
178
|
-
|
175
|
+
it 'performs the HTTP request' do
|
176
|
+
resource.update_attributes(title: 'Aliquam lobortis', featured: true)
|
177
|
+
expect(expected_request).to have_been_requested
|
178
|
+
end
|
179
179
|
|
180
|
-
|
181
|
-
|
182
|
-
allow(dummy).to receive(:success?)
|
183
|
-
end
|
180
|
+
it 'builds the correct resource' do
|
181
|
+
resource.update_attributes(title: 'Aliquam lobortis', featured: true)
|
184
182
|
|
185
|
-
|
186
|
-
expect(dummy).to receive(:create_or_update).with(attributes, {})
|
187
|
-
dummy.save
|
188
|
-
end
|
183
|
+
post = resource
|
189
184
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
185
|
+
aggregate_failures do
|
186
|
+
expect(post.persisted?).to eql true
|
187
|
+
expect(post.id).to eql 12
|
188
|
+
expect(post.title).to eql 'Aliquam lobortis'
|
189
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
190
|
+
expect(post.featured).to eql true
|
191
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
192
|
+
end
|
193
|
+
end
|
195
194
|
|
196
|
-
|
197
|
-
|
198
|
-
allow(dummy).to receive(:success?) { true }
|
195
|
+
it 'does NOT change the given attributes' do
|
196
|
+
attributes = { title: 'Aliquam lobortis', featured: true }
|
199
197
|
|
200
|
-
expect(
|
198
|
+
expect { resource.update_attributes(attributes) }.not_to change { attributes }.from(attributes.dup)
|
201
199
|
end
|
202
|
-
end
|
203
200
|
|
204
|
-
|
205
|
-
|
206
|
-
|
201
|
+
it 'does NOT change the given connection_options' do
|
202
|
+
attributes = { title: 'Aliquam lobortis', featured: true }
|
203
|
+
connection_options = { headers: { 'Foo' => 'Bar' } }
|
207
204
|
|
208
|
-
expect(
|
205
|
+
expect { resource.update_attributes(attributes, connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
209
206
|
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
describe '#create_or_update' do
|
214
|
-
let(:response) { instance_double(RemoteResource::Response) }
|
215
207
|
|
216
|
-
|
217
|
-
|
218
|
-
allow_any_instance_of(RemoteResource::Request).to receive(:perform) { response }
|
208
|
+
xcontext 'return value #success? and NOT #success?' do
|
209
|
+
end
|
219
210
|
end
|
211
|
+
end
|
220
212
|
|
221
|
-
|
222
|
-
|
223
|
-
|
213
|
+
describe '#save' do
|
214
|
+
let(:response_body) do
|
215
|
+
{
|
216
|
+
data: {
|
217
|
+
id: 12,
|
218
|
+
title: 'Lorem Ipsum',
|
219
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
220
|
+
featured: false,
|
221
|
+
created_at: Time.new(2015, 10, 4, 9, 30, 0),
|
222
|
+
}
|
223
|
+
}
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'when resource is persisted' do
|
227
|
+
let(:resource) { Post.new(id: 12, title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: false, created_at: Time.new(2015, 10, 4, 9, 30, 0)) }
|
228
|
+
|
229
|
+
let!(:expected_request) do
|
230
|
+
mock_request = stub_request(:patch, 'https://www.example.com/posts/12.json')
|
231
|
+
mock_request.to_return(status: 200, body: JSON.generate(response_body))
|
232
|
+
mock_request
|
224
233
|
end
|
225
234
|
|
226
|
-
it 'performs
|
227
|
-
|
228
|
-
|
229
|
-
dummy.create_or_update attributes
|
235
|
+
it 'performs the HTTP request' do
|
236
|
+
resource.save
|
237
|
+
expect(expected_request).to have_been_requested
|
230
238
|
end
|
231
239
|
|
232
|
-
it '
|
233
|
-
|
234
|
-
dummy.create_or_update attributes
|
235
|
-
end
|
240
|
+
it 'builds the correct resource' do
|
241
|
+
resource.save
|
236
242
|
|
237
|
-
|
238
|
-
|
243
|
+
post = resource
|
244
|
+
|
245
|
+
aggregate_failures do
|
246
|
+
expect(post.persisted?).to eql true
|
247
|
+
expect(post.id).to eql 12
|
248
|
+
expect(post.title).to eql 'Lorem Ipsum'
|
249
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
250
|
+
expect(post.featured).to eql false
|
251
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
252
|
+
end
|
239
253
|
end
|
240
254
|
|
241
255
|
it 'does NOT change the given connection_options' do
|
242
256
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
243
257
|
|
244
|
-
expect {
|
258
|
+
expect { resource.save(connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
245
259
|
end
|
246
|
-
end
|
247
260
|
|
248
|
-
|
249
|
-
let(:attributes) do
|
250
|
-
{ name: 'Mies' }
|
261
|
+
xcontext 'return value #success? and NOT #success?' do
|
251
262
|
end
|
263
|
+
end
|
252
264
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
265
|
+
context 'when resource is NOT persisted' do
|
266
|
+
let(:resource) { Post.new(title: 'Lorem Ipsum', body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', featured: false) }
|
267
|
+
|
268
|
+
let!(:expected_request) do
|
269
|
+
mock_request = stub_request(:post, 'https://www.example.com/posts.json')
|
270
|
+
mock_request.to_return(status: 201, body: JSON.generate(response_body))
|
271
|
+
mock_request
|
257
272
|
end
|
258
273
|
|
259
|
-
it '
|
260
|
-
|
261
|
-
|
274
|
+
it 'performs the HTTP request' do
|
275
|
+
resource.save
|
276
|
+
expect(expected_request).to have_been_requested
|
262
277
|
end
|
263
278
|
|
264
|
-
it '
|
265
|
-
|
279
|
+
it 'builds the correct resource' do
|
280
|
+
resource.save
|
281
|
+
|
282
|
+
post = resource
|
283
|
+
|
284
|
+
aggregate_failures do
|
285
|
+
expect(post.persisted?).to eql true
|
286
|
+
expect(post.id).to eql 12
|
287
|
+
expect(post.title).to eql 'Lorem Ipsum'
|
288
|
+
expect(post.body).to eql 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
|
289
|
+
expect(post.featured).to eql false
|
290
|
+
expect(post.created_at).to eql Time.new(2015, 10, 4, 9, 30, 0)
|
291
|
+
end
|
266
292
|
end
|
267
293
|
|
268
294
|
it 'does NOT change the given connection_options' do
|
269
295
|
connection_options = { headers: { 'Foo' => 'Bar' } }
|
270
296
|
|
271
|
-
expect {
|
297
|
+
expect { resource.save(connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
298
|
+
end
|
299
|
+
|
300
|
+
xcontext 'return value #success? and NOT #success?' do
|
272
301
|
end
|
273
302
|
end
|
274
303
|
end
|
275
304
|
|
276
305
|
describe '#destroy' do
|
277
|
-
let(:
|
306
|
+
let(:resource) { Post.new(id: 12) }
|
278
307
|
|
279
|
-
let(:
|
280
|
-
|
281
|
-
before do
|
282
|
-
allow(dummy).to receive(:handle_response) { dummy }
|
283
|
-
allow_any_instance_of(RemoteResource::Request).to receive(:perform) { response }
|
284
|
-
allow(dummy).to receive(:success?)
|
308
|
+
let(:response_body) do
|
309
|
+
{}
|
285
310
|
end
|
286
311
|
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
312
|
+
let!(:expected_request) do
|
313
|
+
mock_request = stub_request(:delete, 'https://www.example.com/posts/12.json')
|
314
|
+
mock_request.to_return(status: 204, body: response_body.to_json)
|
315
|
+
mock_request
|
291
316
|
end
|
292
317
|
|
293
|
-
it '
|
294
|
-
|
295
|
-
|
318
|
+
it 'performs the HTTP request' do
|
319
|
+
resource.destroy
|
320
|
+
expect(expected_request).to have_been_requested
|
296
321
|
end
|
297
322
|
|
298
|
-
it '
|
299
|
-
|
300
|
-
|
301
|
-
expect { dummy.destroy(connection_options) }.not_to change { connection_options }.from({ headers: { 'Foo' => 'Bar' } })
|
302
|
-
end
|
323
|
+
it 'builds the correct non-persistent resource' do
|
324
|
+
resource.destroy
|
303
325
|
|
304
|
-
|
305
|
-
let(:response) { { status: 200, body: '' } }
|
306
|
-
before { allow_any_instance_of(RemoteResource::Request).to receive(:perform).and_call_original }
|
307
|
-
|
308
|
-
it 'generates correct request url' do
|
309
|
-
stub_request(:delete, 'https://foobar.com/persistence_methods_dummy/18.json').with(body: nil).to_return(response)
|
310
|
-
dummy.destroy
|
311
|
-
end
|
326
|
+
post = resource
|
312
327
|
|
313
|
-
|
314
|
-
|
315
|
-
|
328
|
+
aggregate_failures do
|
329
|
+
expect(post.id).to eql 12
|
330
|
+
expect(post.persisted?).to eql false
|
316
331
|
end
|
317
332
|
end
|
318
333
|
|
319
|
-
|
320
|
-
|
321
|
-
allow(dummy).to receive(:success?) { true }
|
334
|
+
it 'does NOT change the given connection_options' do
|
335
|
+
connection_options = { headers: { 'Foo' => 'Bar' } }
|
322
336
|
|
323
|
-
|
324
|
-
end
|
337
|
+
expect { resource.destroy(connection_options) }.not_to change { connection_options }.from(connection_options.dup)
|
325
338
|
end
|
326
339
|
|
327
|
-
|
328
|
-
it 'returns false' do
|
329
|
-
allow(dummy).to receive(:success?) { false }
|
330
|
-
|
331
|
-
expect(dummy.destroy).to eql false
|
332
|
-
end
|
340
|
+
xcontext 'return value #success? and NOT #success?' do
|
333
341
|
end
|
334
342
|
|
335
343
|
context 'when the id is NOT present' do
|
336
|
-
let(:
|
344
|
+
let(:resource) { Post.new }
|
337
345
|
|
338
346
|
it 'raises the RemoteResource::IdMissingError error' do
|
339
|
-
expect {
|
347
|
+
expect { resource.destroy }.to raise_error(RemoteResource::IdMissingError, "`id` is missing from resource")
|
340
348
|
end
|
341
349
|
end
|
342
350
|
end
|