rest-in-peace 1.4.0 → 2.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 +15 -0
- data/README.md +75 -2
- data/VERSION +1 -1
- data/lib/rest_in_peace/active_model_api.rb +72 -0
- data/lib/rest_in_peace/definition_proxy/attributes_definitions.rb +20 -0
- data/lib/rest_in_peace/definition_proxy/collection_method_definitions.rb +1 -0
- data/lib/rest_in_peace/definition_proxy/resource_method_definitions.rb +7 -8
- data/lib/rest_in_peace/definition_proxy.rb +21 -0
- data/lib/rest_in_peace/faraday/raise_errors_middleware.rb +34 -0
- data/lib/rest_in_peace/faraday/ssl_config_creator.rb +66 -0
- data/lib/rest_in_peace/response_converter.rb +28 -12
- data/lib/rest_in_peace/template_sanitizer.rb +1 -1
- data/lib/rest_in_peace.rb +45 -9
- data/rest-in-peace.gemspec +5 -3
- data/spec/rest_in_peace/active_model_api_spec.rb +201 -0
- data/spec/rest_in_peace/definition_proxy/attributes_definitions_spec.rb +36 -0
- data/spec/rest_in_peace/definition_proxy/collection_method_definitions_spec.rb +7 -2
- data/spec/rest_in_peace/definition_proxy/resource_method_definitions_spec.rb +69 -13
- data/spec/rest_in_peace/definition_proxy_spec.rb +34 -1
- data/spec/rest_in_peace/response_converter_spec.rb +22 -5
- data/spec/rest_in_peace/template_sanitizer_spec.rb +12 -0
- data/spec/rest_in_peace_spec.rb +140 -7
- data/spec/spec_helper.rb +4 -1
- metadata +51 -18
- data/lib/rest_in_peace/ssl_config_creator.rb +0 -59
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'rest_in_peace'
|
2
|
+
require 'rest_in_peace/active_model_api'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
describe RESTinPeace do
|
6
|
+
let(:api_double) { double('IamAnAPI') }
|
7
|
+
let(:response) { OpenStruct.new(body: 'string!') }
|
8
|
+
let(:extended_class) do
|
9
|
+
Class.new do
|
10
|
+
include RESTinPeace
|
11
|
+
|
12
|
+
rest_in_peace do
|
13
|
+
attributes do
|
14
|
+
read :id, :name
|
15
|
+
write :description, :title
|
16
|
+
end
|
17
|
+
|
18
|
+
resource do
|
19
|
+
put :save, '/class/:id'
|
20
|
+
post :create, '/class'
|
21
|
+
end
|
22
|
+
|
23
|
+
acts_as_active_model
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:id) { 1 }
|
29
|
+
let(:name) { 'pony one' }
|
30
|
+
let(:description) { nil }
|
31
|
+
let(:attributes) do
|
32
|
+
{
|
33
|
+
id: id,
|
34
|
+
name: name,
|
35
|
+
description: description,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
let(:instance) { extended_class.new(attributes) }
|
39
|
+
|
40
|
+
context 'class methods' do
|
41
|
+
describe '::acts_as_active_model' do
|
42
|
+
context 'missing save method' do
|
43
|
+
let(:extended_class) do
|
44
|
+
Class.new do
|
45
|
+
include RESTinPeace
|
46
|
+
rest_in_peace do
|
47
|
+
acts_as_active_model
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'raises an error when no save method specified' do
|
53
|
+
expect { extended_class.new }.to raise_error(RESTinPeace::ActiveModelAPI::MissingMethod)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'missing create method' do
|
58
|
+
let(:extended_class) do
|
59
|
+
Class.new do
|
60
|
+
include RESTinPeace
|
61
|
+
rest_in_peace do
|
62
|
+
resource do
|
63
|
+
put :save, '/yolo'
|
64
|
+
end
|
65
|
+
acts_as_active_model
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'raises an error when no create method specified' do
|
71
|
+
expect { extended_class.new }.to raise_error(RESTinPeace::ActiveModelAPI::MissingMethod)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '::model_name' do
|
77
|
+
before do
|
78
|
+
def extended_class.model_name
|
79
|
+
ActiveModel::Name.new(self, nil, 'TemporaryClassForTests')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
specify { expect(extended_class.model_name).to eq('TemporaryClassForTests') }
|
83
|
+
specify { expect(extended_class.model_name).to respond_to(:route_key) }
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'validation handling' do
|
87
|
+
specify { expect(extended_class).to respond_to(:human_attribute_name).with(2).arguments }
|
88
|
+
specify { expect(extended_class.human_attribute_name(:description)).to eq('description') }
|
89
|
+
|
90
|
+
specify { expect(extended_class).to respond_to(:lookup_ancestors).with(0).arguments }
|
91
|
+
specify { expect(extended_class.lookup_ancestors).to eq([extended_class]) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'instance methods' do
|
96
|
+
before do
|
97
|
+
extended_class.api = api_double
|
98
|
+
allow(api_double).to receive(:put).and_return(response)
|
99
|
+
allow(api_double).to receive(:post).and_return(response)
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#changed?' do
|
103
|
+
context 'a new instance' do
|
104
|
+
specify { expect(instance.changed?).to eq(false) }
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'a modified instance' do
|
108
|
+
before do
|
109
|
+
instance.description = 'new value'
|
110
|
+
end
|
111
|
+
specify { expect(instance.changed?).to eq(true) }
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'a saved instance' do
|
115
|
+
before do
|
116
|
+
instance.description = 'new value'
|
117
|
+
instance.save
|
118
|
+
end
|
119
|
+
specify { expect(instance.changed?).to eq(false) }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'attribute methods' do
|
124
|
+
specify { expect(instance).to respond_to(:description_changed?) }
|
125
|
+
specify { expect(instance).to respond_to(:title_changed?) }
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#to_key' do
|
129
|
+
specify { expect(instance.to_key).to eq([1]) }
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#persisted?' do
|
133
|
+
context 'persisted model' do
|
134
|
+
specify { expect(instance.persisted?).to eq(true) }
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'not yet persisted model' do
|
138
|
+
let(:id) { nil }
|
139
|
+
specify { expect(instance.persisted?).to eq(false) }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#save' do
|
144
|
+
context 'without errors' do
|
145
|
+
let(:response) { OpenStruct.new(body: { name: 'new name from api' }) }
|
146
|
+
|
147
|
+
specify { expect { instance.save }.to_not raise_error }
|
148
|
+
specify { expect(instance.save.object_id).to eq(instance.object_id) }
|
149
|
+
specify { expect { instance.save }.to change(instance, :name) }
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'with errors' do
|
153
|
+
before do
|
154
|
+
instance.description = 'value!'
|
155
|
+
end
|
156
|
+
let(:response) { OpenStruct.new(body: { errors: { 'description' => ['is not empty'] } }) }
|
157
|
+
|
158
|
+
specify { expect { instance.save }.to change { instance.errors.any? } }
|
159
|
+
specify { expect { instance.save }.to_not change { instance.description } }
|
160
|
+
specify { expect { instance.save }.to_not change { instance.name } }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe '#create' do
|
165
|
+
context 'without errors' do
|
166
|
+
let(:response) { OpenStruct.new(body: { name: 'new name from api' }) }
|
167
|
+
|
168
|
+
specify { expect { instance.create }.to_not raise_error }
|
169
|
+
specify { expect(instance.create.object_id).to eq(instance.object_id) }
|
170
|
+
specify { expect { instance.create }.to change(instance, :name) }
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'with errors' do
|
174
|
+
before do
|
175
|
+
instance.description = 'value!'
|
176
|
+
end
|
177
|
+
let(:response) { OpenStruct.new(body: { errors: { 'description' => ['is not empty'] } }) }
|
178
|
+
|
179
|
+
specify { expect { instance.create }.to change { instance.errors.any? } }
|
180
|
+
specify { expect { instance.create }.to_not change { instance.description } }
|
181
|
+
specify { expect { instance.create }.to_not change { instance.name } }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe 'validation handling' do
|
186
|
+
let(:description) { 'desc' }
|
187
|
+
|
188
|
+
specify { expect(instance).to respond_to(:read_attribute_for_validation).with(1).argument }
|
189
|
+
specify { expect(instance.read_attribute_for_validation(:description)).to eq('desc') }
|
190
|
+
|
191
|
+
describe '#errors' do
|
192
|
+
specify { expect(instance.errors).to be_instance_of(ActiveModel::Errors) }
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#errors=' do
|
196
|
+
let(:errors) { { description: ['must not be empty'] } }
|
197
|
+
specify { expect { instance.errors = errors }.to change { instance.errors.count } }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rest_in_peace'
|
2
|
+
require 'rest_in_peace/definition_proxy/attributes_definitions'
|
3
|
+
|
4
|
+
describe RESTinPeace::DefinitionProxy::AttributesDefinitions do
|
5
|
+
let(:target) do
|
6
|
+
Class.new do
|
7
|
+
include RESTinPeace
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:instance_of_target) { target.new }
|
11
|
+
let(:definitions) { described_class.new(target) }
|
12
|
+
|
13
|
+
subject { definitions }
|
14
|
+
|
15
|
+
describe '#read' do
|
16
|
+
it 'defines a getter for the given attributes' do
|
17
|
+
expect { subject.read(:id) }.to change { instance_of_target.respond_to?(:id) }.from(false).to(true)
|
18
|
+
end
|
19
|
+
it 'does not define a setter for the given attributes' do
|
20
|
+
expect { subject.read(:id) }.to_not change { instance_of_target.respond_to?(:id=) }.from(false)
|
21
|
+
end
|
22
|
+
specify { expect { subject.read(:id) }.to change { target.rip_attributes[:read] }.from([]).to([:id]) }
|
23
|
+
specify { expect { subject.read(:id) }.to_not change { target.rip_attributes[:write] }.from([]) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#write' do
|
27
|
+
it 'defines a getter for the given attributes' do
|
28
|
+
expect { subject.write(:id) }.to change { instance_of_target.respond_to?(:id) }.from(false).to(true)
|
29
|
+
end
|
30
|
+
it 'defines a setter for the given attributes' do
|
31
|
+
expect { subject.write(:id) }.to change { instance_of_target.respond_to?(:id=) }.from(false).to(true)
|
32
|
+
end
|
33
|
+
specify { expect { subject.write(:id) }.to change { target.rip_attributes[:read] }.from([]).to([:id]) }
|
34
|
+
specify { expect { subject.write(:id) }.to change { target.rip_attributes[:write] }.from([]).to([:id]) }
|
35
|
+
end
|
36
|
+
end
|
@@ -5,9 +5,8 @@ describe RESTinPeace::DefinitionProxy::CollectionMethodDefinitions do
|
|
5
5
|
let(:method_name) { :find }
|
6
6
|
let(:url_template) { '/a/:id' }
|
7
7
|
let(:default_params) { {} }
|
8
|
-
let(:struct) { Struct.new(:id, :name) }
|
9
8
|
let(:target) do
|
10
|
-
Class.new
|
9
|
+
Class.new do
|
11
10
|
include RESTinPeace
|
12
11
|
end
|
13
12
|
end
|
@@ -71,6 +70,12 @@ describe RESTinPeace::DefinitionProxy::CollectionMethodDefinitions do
|
|
71
70
|
target.find(id: 1)
|
72
71
|
expect(default_params).to eq({ per_page: 250 })
|
73
72
|
end
|
73
|
+
|
74
|
+
it 'raises an error when param is not a hash' do
|
75
|
+
subject.get(:find, '/a/:id', default_params)
|
76
|
+
|
77
|
+
expect { target.find(1) }.to raise_error(RESTinPeace::DefinitionProxy::InvalidArgument)
|
78
|
+
end
|
74
79
|
end
|
75
80
|
|
76
81
|
context 'without any attributes' do
|
@@ -2,10 +2,16 @@ require 'rest_in_peace'
|
|
2
2
|
require 'rest_in_peace/definition_proxy/resource_method_definitions'
|
3
3
|
|
4
4
|
describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
5
|
-
let(:struct) { Struct.new(:id, :name) }
|
6
5
|
let(:target) do
|
7
|
-
Class.new
|
6
|
+
Class.new do
|
8
7
|
include RESTinPeace
|
8
|
+
rest_in_peace do
|
9
|
+
attributes do
|
10
|
+
read :id
|
11
|
+
write :name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
9
15
|
end
|
10
16
|
end
|
11
17
|
let(:instance) { target.new }
|
@@ -16,6 +22,7 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
16
22
|
|
17
23
|
before do
|
18
24
|
allow(RESTinPeace::ApiCall).to receive(:new).and_return(api_call_double)
|
25
|
+
allow(api_call_double).to receive(http_verb)
|
19
26
|
end
|
20
27
|
|
21
28
|
shared_examples_for 'an instance method' do
|
@@ -28,21 +35,30 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
28
35
|
subject.send(http_verb, method_name, url_template)
|
29
36
|
expect(target.rip_registry[:resource]).to eq([method: http_verb, name: method_name, url: url_template])
|
30
37
|
end
|
38
|
+
end
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
|
40
|
+
shared_examples_for 'an instance method with parameters' do
|
41
|
+
describe 'parameter and arguments handling' do
|
42
|
+
it 'uses the attributes of the class' do
|
43
|
+
expect(RESTinPeace::ApiCall).to receive(:new).
|
44
|
+
with(target.api, url_template, instance, instance.hash_for_updates).
|
45
|
+
and_return(api_call_double)
|
46
|
+
|
47
|
+
subject.send(http_verb, method_name, url_template)
|
48
|
+
instance.send(method_name)
|
35
49
|
end
|
50
|
+
end
|
51
|
+
end
|
36
52
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
shared_examples_for 'an instance method without parameters' do
|
54
|
+
describe 'parameter and arguments handling' do
|
55
|
+
it 'provides the id only' do
|
56
|
+
expect(RESTinPeace::ApiCall).to receive(:new).
|
57
|
+
with(target.api, url_template, instance, id: instance.id).
|
58
|
+
and_return(api_call_double)
|
42
59
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
60
|
+
subject.send(http_verb, method_name, url_template)
|
61
|
+
instance.send(method_name)
|
46
62
|
end
|
47
63
|
end
|
48
64
|
end
|
@@ -53,6 +69,14 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
53
69
|
let(:method_name) { :reload }
|
54
70
|
let(:url_template) { '/a/:id' }
|
55
71
|
end
|
72
|
+
|
73
|
+
describe 'the created method' do
|
74
|
+
it_behaves_like 'an instance method with parameters' do
|
75
|
+
let(:http_verb) { :get }
|
76
|
+
let(:method_name) { :reload }
|
77
|
+
let(:url_template) { '/a/:id' }
|
78
|
+
end
|
79
|
+
end
|
56
80
|
end
|
57
81
|
|
58
82
|
context '#patch' do
|
@@ -61,6 +85,14 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
61
85
|
let(:method_name) { :save }
|
62
86
|
let(:url_template) { '/a/:id' }
|
63
87
|
end
|
88
|
+
|
89
|
+
describe 'the created method' do
|
90
|
+
it_behaves_like 'an instance method with parameters' do
|
91
|
+
let(:http_verb) { :patch }
|
92
|
+
let(:method_name) { :save }
|
93
|
+
let(:url_template) { '/a/:id' }
|
94
|
+
end
|
95
|
+
end
|
64
96
|
end
|
65
97
|
|
66
98
|
context '#post' do
|
@@ -69,6 +101,14 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
69
101
|
let(:method_name) { :create }
|
70
102
|
let(:url_template) { '/a/:id' }
|
71
103
|
end
|
104
|
+
|
105
|
+
describe 'the created method' do
|
106
|
+
it_behaves_like 'an instance method with parameters' do
|
107
|
+
let(:http_verb) { :post }
|
108
|
+
let(:method_name) { :create }
|
109
|
+
let(:url_template) { '/a/:id' }
|
110
|
+
end
|
111
|
+
end
|
72
112
|
end
|
73
113
|
|
74
114
|
context '#put' do
|
@@ -77,6 +117,14 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
77
117
|
let(:method_name) { :update }
|
78
118
|
let(:url_template) { '/a/:id' }
|
79
119
|
end
|
120
|
+
|
121
|
+
describe 'the created method' do
|
122
|
+
it_behaves_like 'an instance method with parameters' do
|
123
|
+
let(:http_verb) { :put }
|
124
|
+
let(:method_name) { :update }
|
125
|
+
let(:url_template) { '/a/:id' }
|
126
|
+
end
|
127
|
+
end
|
80
128
|
end
|
81
129
|
|
82
130
|
context '#delete' do
|
@@ -85,6 +133,14 @@ describe RESTinPeace::DefinitionProxy::ResourceMethodDefinitions do
|
|
85
133
|
let(:method_name) { :destroy }
|
86
134
|
let(:url_template) { '/a/:id' }
|
87
135
|
end
|
136
|
+
|
137
|
+
describe 'the created method' do
|
138
|
+
it_behaves_like 'an instance method without parameters' do
|
139
|
+
let(:http_verb) { :delete }
|
140
|
+
let(:method_name) { :destroy }
|
141
|
+
let(:url_template) { '/a/:id' }
|
142
|
+
end
|
143
|
+
end
|
88
144
|
end
|
89
145
|
|
90
146
|
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'rest_in_peace'
|
1
2
|
require 'rest_in_peace/definition_proxy'
|
3
|
+
require 'ostruct'
|
2
4
|
|
3
5
|
describe RESTinPeace::DefinitionProxy do
|
4
6
|
let(:resource_definitions) { object_double(RESTinPeace::DefinitionProxy::ResourceMethodDefinitions) }
|
5
7
|
let(:collection_definitions) { object_double(RESTinPeace::DefinitionProxy::CollectionMethodDefinitions) }
|
6
|
-
let(:
|
8
|
+
let(:attributes_definitions) { object_double(RESTinPeace::DefinitionProxy::AttributesDefinitions) }
|
9
|
+
let(:target) { double('Target') }
|
7
10
|
let(:proxy) { RESTinPeace::DefinitionProxy.new(target) }
|
8
11
|
let(:test_proc) { ->() {} }
|
9
12
|
|
@@ -14,6 +17,8 @@ describe RESTinPeace::DefinitionProxy do
|
|
14
17
|
to receive(:new).with(target).and_return(resource_definitions)
|
15
18
|
allow(RESTinPeace::DefinitionProxy::CollectionMethodDefinitions).
|
16
19
|
to receive(:new).with(target).and_return(collection_definitions)
|
20
|
+
allow(RESTinPeace::DefinitionProxy::AttributesDefinitions).
|
21
|
+
to receive(:new).with(target).and_return(attributes_definitions)
|
17
22
|
end
|
18
23
|
|
19
24
|
describe '#resource' do
|
@@ -33,4 +38,32 @@ describe RESTinPeace::DefinitionProxy do
|
|
33
38
|
subject.collection(&test_proc)
|
34
39
|
end
|
35
40
|
end
|
41
|
+
|
42
|
+
describe '#attributes' do
|
43
|
+
it 'forwards the given block to a attributes method definition' do
|
44
|
+
expect(attributes_definitions).to receive(:instance_eval) do |&block|
|
45
|
+
expect(block).to be_instance_of(Proc)
|
46
|
+
end
|
47
|
+
subject.attributes(&test_proc)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#namespace_attributes_with' do
|
52
|
+
let(:target) do
|
53
|
+
Class.new do
|
54
|
+
include RESTinPeace
|
55
|
+
end
|
56
|
+
end
|
57
|
+
it 'configures the namespace' do
|
58
|
+
expect { subject.namespace_attributes_with(:blubb) }.
|
59
|
+
to change { target.rip_namespace }.from(nil).to(:blubb)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#acts_as_active_model' do
|
64
|
+
it 'includes RESTinPeace::ActiveModelAPI' do
|
65
|
+
expect(target).to receive(:include).with(RESTinPeace::ActiveModelAPI)
|
66
|
+
subject.acts_as_active_model
|
67
|
+
end
|
68
|
+
end
|
36
69
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rest_in_peace'
|
1
2
|
require 'rest_in_peace/response_converter'
|
2
3
|
require 'ostruct'
|
3
4
|
|
@@ -6,6 +7,16 @@ describe RESTinPeace::ResponseConverter do
|
|
6
7
|
let(:element2) { { name: 'test2' } }
|
7
8
|
let(:response) { OpenStruct.new(body: response_body) }
|
8
9
|
let(:converter) { RESTinPeace::ResponseConverter.new(response, klass) }
|
10
|
+
let(:extended_class) do
|
11
|
+
Class.new do
|
12
|
+
include RESTinPeace
|
13
|
+
rest_in_peace do
|
14
|
+
attributes do
|
15
|
+
read :name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
9
20
|
|
10
21
|
describe '#result' do
|
11
22
|
subject { converter.result }
|
@@ -13,13 +24,14 @@ describe RESTinPeace::ResponseConverter do
|
|
13
24
|
shared_examples_for 'an array input' do
|
14
25
|
let(:response_body) { [element1, element2] }
|
15
26
|
specify { expect(subject).to be_instance_of(Array) }
|
16
|
-
specify { expect(subject).to
|
27
|
+
specify { expect(subject.first).to be_instance_of(extended_class) }
|
28
|
+
specify { expect(subject.map(&:name)).to eq(%w(test1 test2)) }
|
17
29
|
end
|
18
30
|
|
19
31
|
shared_examples_for 'a hash input' do
|
20
32
|
let(:response_body) { element1 }
|
21
|
-
specify { expect(subject).to be_instance_of(
|
22
|
-
specify { expect(subject).to eq(
|
33
|
+
specify { expect(subject).to be_instance_of(extended_class) }
|
34
|
+
specify { expect(subject.name).to eq('test1') }
|
23
35
|
end
|
24
36
|
|
25
37
|
shared_examples_for 'a string input' do
|
@@ -28,8 +40,13 @@ describe RESTinPeace::ResponseConverter do
|
|
28
40
|
specify { expect(subject).to eq('yolo binary stuff') }
|
29
41
|
end
|
30
42
|
|
43
|
+
shared_examples_for 'an unknown input do' do
|
44
|
+
let(:response_body) { Object }
|
45
|
+
specify { expect { subject }.to raise_error(RESTinPeace::ResponseConverter::UnknownConvertStrategy) }
|
46
|
+
end
|
47
|
+
|
31
48
|
context 'given type is a class' do
|
32
|
-
let(:klass) {
|
49
|
+
let(:klass) { extended_class }
|
33
50
|
context 'input is an array' do
|
34
51
|
it_behaves_like 'an array input'
|
35
52
|
end
|
@@ -44,7 +61,7 @@ describe RESTinPeace::ResponseConverter do
|
|
44
61
|
end
|
45
62
|
|
46
63
|
context 'given type is an instance' do
|
47
|
-
let(:klass) {
|
64
|
+
let(:klass) { extended_class.new }
|
48
65
|
context 'input is an array' do
|
49
66
|
it_behaves_like 'an array input'
|
50
67
|
end
|
@@ -19,6 +19,18 @@ describe RESTinPeace::TemplateSanitizer do
|
|
19
19
|
specify { expect(subject).to eq('/a/1/b/2') }
|
20
20
|
end
|
21
21
|
|
22
|
+
context 'tokens with substrings' do
|
23
|
+
let(:params) { { element: 'asd', element_id: 1 } }
|
24
|
+
let(:url_template) { '/a/:element/b/:element_id' }
|
25
|
+
specify { expect(subject).to eq('/a/asd/b/1') }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'tokens with substrings, reverse order' do
|
29
|
+
let(:params) { { element: 'asd', element_id: 1 } }
|
30
|
+
let(:url_template) { '/a/:element_id/b/:element' }
|
31
|
+
specify { expect(subject).to eq('/a/1/b/asd') }
|
32
|
+
end
|
33
|
+
|
22
34
|
context 'incomplete params' do
|
23
35
|
let(:params) { {} }
|
24
36
|
let(:url_template) { '/a/:id' }
|