opium 1.3.5 → 1.4.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/.travis.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +337 -2
- data/lib/generators/opium/templates/config.yml +22 -8
- data/lib/opium/config.rb +9 -7
- data/lib/opium/model/connectable.rb +5 -1
- data/lib/opium/version.rb +1 -1
- data/opium.gemspec +1 -1
- data/spec/opium/config/opium.yml +3 -1
- data/spec/opium/config_spec.rb +41 -33
- data/spec/opium/file_spec.rb +73 -73
- data/spec/opium/model/connectable_spec.rb +95 -51
- metadata +4 -4
data/spec/opium/file_spec.rb
CHANGED
@@ -8,61 +8,61 @@ describe Opium::File do
|
|
8
8
|
f.write Base64.decode64('R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7')
|
9
9
|
end
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
let(:location) { 'http://files.example.com/1234-file.gif' }
|
13
|
-
|
13
|
+
|
14
14
|
it { expect( described_class ).to respond_to(:upload, :to_ruby, :to_parse).with(1).argument }
|
15
15
|
it { is_expected.to respond_to( :delete, :name, :url, :mime_type, :to_parse ) }
|
16
|
-
|
16
|
+
|
17
17
|
describe '.upload' do
|
18
18
|
subject { described_class }
|
19
19
|
let(:upload_options) { {} }
|
20
20
|
let(:result) { subject.upload( gif_file, upload_options ) }
|
21
|
-
|
21
|
+
|
22
22
|
before do
|
23
23
|
stub_request( :post, %r{https://api\.parse\.com/1/files/.+} ).
|
24
|
-
with(
|
25
|
-
body: "
|
24
|
+
with(
|
25
|
+
body: "GIF89a\x15\x00\x04\x00\x80\x00\x00#-0\xFF\xFF\xFF!\xF9\x04\x01\x00\x00\x01\x00,\x00\x00\x00\x00\x15\x00\x04\x00\x00\x02\r\x8C\x8F\x01\xC9\xAD\xB0\x9C\x83T2\x8AY\x01\x00;".force_encoding('ASCII-8BIT'),
|
26
26
|
headers: {content_type: 'image/gif', x_parse_application_id: 'PARSE_APP_ID', x_parse_rest_api_key: 'PARSE_API_KEY'}
|
27
27
|
).to_return(status: 201, body: ->(request) { { url: location, name: "1234-#{ ::File.basename(request.uri) }" }.to_json }, headers: { content_type: 'application/json', location: location })
|
28
28
|
end
|
29
|
-
|
30
|
-
context 'when the upload completes' do
|
29
|
+
|
30
|
+
context 'when the upload completes' do
|
31
31
|
it { expect { result }.to_not raise_exception }
|
32
32
|
it { expect( result ).to be_a Opium::File }
|
33
33
|
it { expect( result.url ).to_not be_nil }
|
34
34
|
it { expect( result.name ).to_not be_nil }
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
context 'with a :original_filename option' do
|
38
38
|
let(:upload_options) { { original_filename: 'chunky_bacon.jpg' } }
|
39
|
-
|
39
|
+
|
40
40
|
it { expect { result }.to_not raise_exception }
|
41
41
|
it 'preferentially uses the :original_filename' do
|
42
42
|
expect( result.name ).to end_with 'chunky_bacon.jpg'
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
context 'with non-standard characters in filename' do
|
47
47
|
let(:upload_options) { { original_filename: 'chunky&bacon$with cheddar@cheese.jpg' } }
|
48
|
-
|
48
|
+
|
49
49
|
it { expect { result }.to_not raise_exception }
|
50
50
|
it 'paramterizes the name' do
|
51
51
|
expect( result.name ).to end_with 'chunky-bacon-with-cheddar-cheese.jpg'
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
context 'when executed' do
|
56
56
|
let(:upload_options) { { sent_headers: true } }
|
57
|
-
|
57
|
+
|
58
58
|
it { expect { result }.to_not raise_exception }
|
59
59
|
it { expect( result.keys ).to include( 'Content-Length' ) }
|
60
60
|
it { expect( result['Content-Length'] ).to eq gif_file.size.to_s }
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
context 'with a :content_type option' do
|
64
64
|
let(:upload_options) { { content_type: 'image/png', sent_headers: true } }
|
65
|
-
|
65
|
+
|
66
66
|
it { expect { result }.to_not raise_exception }
|
67
67
|
it { expect( result ).to have_key( 'Content-Type') }
|
68
68
|
it 'sends the given :content_type value' do
|
@@ -71,10 +71,10 @@ describe Opium::File do
|
|
71
71
|
it { expect( result.keys ).to include( 'X-Parse-Rest-Api-Key' )}
|
72
72
|
it { expect( result.keys ).to_not include( 'X-Parse-Master-Key' )}
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
context 'without a :content_type option' do
|
76
76
|
let(:upload_options) { { sent_headers: true } }
|
77
|
-
|
77
|
+
|
78
78
|
it { expect { result }.to_not raise_exception }
|
79
79
|
it { expect( result ).to have_key( 'Content-Type' ) }
|
80
80
|
it 'sends the proper content_type' do
|
@@ -84,76 +84,76 @@ describe Opium::File do
|
|
84
84
|
it { expect( result.keys ).to_not include( 'X-Parse-Master-Key' )}
|
85
85
|
end
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
describe '.to_ruby' do
|
89
89
|
subject { described_class }
|
90
|
-
|
90
|
+
|
91
91
|
let(:result) { subject.to_ruby( object ) }
|
92
|
-
|
92
|
+
|
93
93
|
context 'when given a hash with __type: "File"' do
|
94
94
|
let(:object) { { __type: 'File', url: location, name: 'chunky_bacon.jpg' } }
|
95
|
-
|
95
|
+
|
96
96
|
it { expect { result }.to_not raise_exception }
|
97
97
|
it { expect( result ).to be_a Opium::File }
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
context 'when given a hash with just a :url and :name' do
|
101
101
|
let(:object) { { url: location, name: 'chunky_bacon.jpg' } }
|
102
|
-
|
102
|
+
|
103
103
|
it { expect { result }.to_not raise_exception }
|
104
104
|
it { expect( result ).to be_a Opium::File }
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
context 'when given a hash with __type != "File"' do
|
108
108
|
let(:object) { { __type: 'Pointer' } }
|
109
|
-
|
109
|
+
|
110
110
|
it { expect { result }.to raise_exception }
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
context 'when given an Opium::File' do
|
114
114
|
let(:object) { Opium::File.new( url: location, name: 'chunky_bacon.jpg' ) }
|
115
|
-
|
115
|
+
|
116
116
|
it { expect { result }.to_not raise_exception }
|
117
117
|
it { expect( result ).to be_a Opium::File }
|
118
118
|
it { expect( result ).to eq object }
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
context 'when given nil' do
|
122
122
|
let(:object) { nil }
|
123
|
-
|
123
|
+
|
124
124
|
it { expect { result }.to_not raise_exception }
|
125
125
|
it { expect( result ).to be_nil }
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
context 'when given a JSON string' do
|
129
129
|
let(:object) { { url: location, name: 'chunky_bacon.jpg' }.to_json }
|
130
|
-
|
130
|
+
|
131
131
|
it { expect { result }.to_not raise_exception }
|
132
132
|
it { expect( result ).to be_a Opium::File }
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
context 'when given an empty string' do
|
136
136
|
let(:object) { '' }
|
137
|
-
|
137
|
+
|
138
138
|
it { expect { result }.to_not raise_exception }
|
139
139
|
it { expect( result ).to be_nil }
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
142
|
context 'when not given a hash' do
|
143
143
|
let(:object) { 42 }
|
144
|
-
|
144
|
+
|
145
145
|
it { expect { result }.to raise_exception }
|
146
146
|
end
|
147
147
|
end
|
148
|
-
|
148
|
+
|
149
149
|
describe '.to_parse' do
|
150
150
|
subject { described_class }
|
151
|
-
|
151
|
+
|
152
152
|
let(:result) { described_class.to_parse( object ) }
|
153
|
-
|
153
|
+
|
154
154
|
context 'when given an Opium::File' do
|
155
155
|
let(:object) { subject.new( url: location, name: 'chunky_bacon.jpg' ) }
|
156
|
-
|
156
|
+
|
157
157
|
it { expect { result }.to_not raise_exception }
|
158
158
|
it { expect( result ).to be_a Hash }
|
159
159
|
it { expect( result ).to have_key '__type' }
|
@@ -162,51 +162,51 @@ describe Opium::File do
|
|
162
162
|
expect( result ).to eq( '__type' => 'File', 'name' => 'chunky_bacon.jpg' )
|
163
163
|
end
|
164
164
|
end
|
165
|
-
|
165
|
+
|
166
166
|
context 'when given nil' do
|
167
167
|
let(:object) { nil }
|
168
|
-
|
168
|
+
|
169
169
|
it { expect { result }.to_not raise_exception }
|
170
170
|
it { expect( result ).to be_nil }
|
171
171
|
end
|
172
|
-
|
172
|
+
|
173
173
|
context 'when given anything else' do
|
174
174
|
let(:object) { 42 }
|
175
|
-
|
175
|
+
|
176
176
|
it { expect { result }.to raise_exception }
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
context '#initialize' do
|
181
181
|
let(:filename) { 'file.png' }
|
182
182
|
let(:location) { 'http://files.example.com/1234-file.png' }
|
183
183
|
subject { described_class.new( __type: 'File', url: location, name: filename ) }
|
184
|
-
|
185
|
-
it 'sets the url' do
|
184
|
+
|
185
|
+
it 'sets the url' do
|
186
186
|
expect( subject.url ).to eq location
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
it 'sets the name' do
|
190
190
|
expect( subject.name ).to eq filename
|
191
191
|
end
|
192
|
-
|
192
|
+
|
193
193
|
it 'infers the mime_type' do
|
194
194
|
expect( subject.mime_type ).to eq 'image/png'
|
195
195
|
end
|
196
196
|
end
|
197
|
-
|
197
|
+
|
198
198
|
describe '#delete' do
|
199
199
|
subject { described_class.new( url: location, name: 'chunky_bacon.jpg' ) }
|
200
|
-
|
200
|
+
|
201
201
|
before do
|
202
202
|
stub_request(:delete, "https://api.parse.com/1/files/chunky_bacon.jpg").
|
203
203
|
with(:headers => {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Master-Key'=>'PARSE_MASTER_KEY'}).
|
204
204
|
to_return(:status => 200, :body => "{}", :headers => { content_type: 'application/json' })
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
let(:delete_options) { {} }
|
208
208
|
let(:result) { subject.delete( delete_options ) }
|
209
|
-
|
209
|
+
|
210
210
|
context 'with a name' do
|
211
211
|
it { expect { result }.to_not raise_exception }
|
212
212
|
it 'freezes the Opium::File' do
|
@@ -214,28 +214,28 @@ describe Opium::File do
|
|
214
214
|
expect( subject ).to be_frozen
|
215
215
|
end
|
216
216
|
end
|
217
|
-
|
217
|
+
|
218
218
|
context 'without a name' do
|
219
219
|
subject { described_class.new }
|
220
|
-
|
220
|
+
|
221
221
|
it { expect { result }.to raise_exception }
|
222
222
|
end
|
223
|
-
|
223
|
+
|
224
224
|
context 'when executed' do
|
225
225
|
let(:delete_options) { { sent_headers: true } }
|
226
|
-
|
226
|
+
|
227
227
|
it { expect { result }.to_not raise_exception }
|
228
228
|
it { expect( result.keys ).to include( 'X-Parse-Master-Key' ) }
|
229
229
|
it { expect( result.keys ).to_not include( 'X-Parse-Rest-Api-Key' ) }
|
230
230
|
end
|
231
231
|
end
|
232
|
-
|
232
|
+
|
233
233
|
describe '#to_parse' do
|
234
234
|
let(:result) { subject.to_parse }
|
235
|
-
|
235
|
+
|
236
236
|
context 'when #name has a value' do
|
237
237
|
subject { described_class.new( url: location, name: 'chunky_bacon.jpg' ) }
|
238
|
-
|
238
|
+
|
239
239
|
it { expect { result }.to_not raise_exception }
|
240
240
|
it { expect( result ).to be_a Hash }
|
241
241
|
it { expect( result ).to have_key '__type' }
|
@@ -244,62 +244,62 @@ describe Opium::File do
|
|
244
244
|
expect( result ).to eq( '__type' => 'File', 'name' => 'chunky_bacon.jpg' )
|
245
245
|
end
|
246
246
|
end
|
247
|
-
|
247
|
+
|
248
248
|
context 'when #name is empty' do
|
249
249
|
subject { described_class.new }
|
250
|
-
|
250
|
+
|
251
251
|
it { expect { result }.to raise_exception }
|
252
252
|
end
|
253
253
|
end
|
254
|
-
|
254
|
+
|
255
255
|
describe '#inspect' do
|
256
256
|
context 'with data' do
|
257
257
|
let(:filename) { 'file.gif' }
|
258
258
|
let(:mime) { 'image/gif' }
|
259
|
-
|
259
|
+
|
260
260
|
subject { described_class.new( url: location, name: filename ) }
|
261
261
|
|
262
262
|
it 'has the values for all components' do
|
263
263
|
expect( subject.inspect ).to eq %{#<Opium::File name="#{ filename }" url="#{ location }" mime_type="#{ mime }">}
|
264
264
|
end
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
context 'without data' do
|
268
268
|
subject { described_class.new }
|
269
|
-
|
269
|
+
|
270
270
|
it 'has nil values for all components' do
|
271
271
|
expect( subject.inspect ).to eq '#<Opium::File name=nil url=nil mime_type=nil>'
|
272
272
|
end
|
273
273
|
end
|
274
274
|
end
|
275
|
-
|
275
|
+
|
276
276
|
context 'when used as a field type' do
|
277
277
|
before do
|
278
278
|
stub_const( 'Game', Class.new do
|
279
279
|
include Opium::Model
|
280
280
|
field :cover_image, type: Opium::File
|
281
281
|
end )
|
282
|
-
|
282
|
+
|
283
283
|
stub_request(:get, "https://api.parse.com/1/classes/Game/abcd1234").
|
284
284
|
with(:headers => {'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Rest-Api-Key'=>'PARSE_API_KEY'}).
|
285
285
|
to_return(:status => 200, :body => { objectId: 'abcd1234', coverImage: { __type: 'File', name: 'chunky_bacon.jpg', url: location }, createdAt: '2015-01-01T12:00:00Z' }.to_json, :headers => { content_type: 'application/json' })
|
286
|
-
|
286
|
+
|
287
287
|
stub_request(:post, "https://api.parse.com/1/classes/Game").
|
288
288
|
with(
|
289
289
|
:body => "{\"coverImage\":{\"__type\":\"File\",\"name\":\"chunky_bacon.jpg\"}}",
|
290
290
|
:headers => {'Content-Type'=>'application/json', 'X-Parse-Application-Id'=>'PARSE_APP_ID', 'X-Parse-Rest-Api-Key'=>'PARSE_API_KEY'}).
|
291
291
|
to_return(:status => 200, :body => { objectId: 'abcd1234', createdAt: '2015-01-01T12:00:00Z' }.to_json, :headers => { content_type: 'application/json' })
|
292
|
-
|
292
|
+
|
293
293
|
end
|
294
|
-
|
294
|
+
|
295
295
|
it 'is retrievable as an Opium::File' do
|
296
296
|
game = Game.find('abcd1234')
|
297
297
|
expect( game.cover_image ).to be_a Opium::File
|
298
298
|
end
|
299
|
-
|
299
|
+
|
300
300
|
it 'is persistable as a Parse File object hash' do
|
301
301
|
game = Game.new cover_image: Opium::File.new( url: location, name: 'chunky_bacon.jpg' )
|
302
302
|
expect { game.save! }.to_not raise_exception
|
303
303
|
end
|
304
304
|
end
|
305
|
-
end
|
305
|
+
end
|
@@ -7,63 +7,107 @@ describe Opium::Model::Connectable do
|
|
7
7
|
stub('model_name').and_return(ActiveModel::Name.new(klass, nil, 'Model'))
|
8
8
|
end )
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
after do
|
12
12
|
Opium::Model::Criteria.models.clear
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
subject { Model }
|
16
16
|
let( :response ) { double('Response').tap {|r| allow(r).to receive(:body) } }
|
17
|
-
|
17
|
+
|
18
|
+
it { is_expected.to respond_to( :parse_server_url ) }
|
18
19
|
it { is_expected.to respond_to( :connection, :reset_connection! ) }
|
19
20
|
it { is_expected.to respond_to( :object_prefix, :no_object_prefix! ) }
|
20
21
|
it { is_expected.to respond_to( :as_resource, :resource_name ).with(1).argument }
|
21
22
|
it { is_expected.to respond_to( :http_get, :http_post, :http_delete ).with(1).argument }
|
22
23
|
it { is_expected.to respond_to( :http_put ).with(2).arguments }
|
23
24
|
it { is_expected.to respond_to( :requires_heightened_privileges!, :requires_heightened_privileges?, :has_heightened_privileges? ) }
|
24
|
-
|
25
|
+
|
26
|
+
describe '.parse_server_url' do
|
27
|
+
after do
|
28
|
+
Opium.reset
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with a default config' do
|
32
|
+
it { expect( subject.parse_server_url ).to eq 'https://api.parse.com/1' }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with altered server settings' do
|
36
|
+
before do
|
37
|
+
Opium.configure do |config|
|
38
|
+
config.server_url = 'https://example.com'
|
39
|
+
config.mount_point = '/parse'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it { expect( subject.parse_server_url ).to eq 'https://example.com/parse' }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
25
47
|
describe '.object_prefix' do
|
26
48
|
it { expect( subject.object_prefix ).to eq 'classes' }
|
27
49
|
end
|
28
|
-
|
50
|
+
|
51
|
+
describe '.connection' do
|
52
|
+
after do
|
53
|
+
Opium.reset
|
54
|
+
subject.reset_connection!
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with a default config' do
|
58
|
+
it { expect( subject.connection.url_prefix ).to eq ::URI.join( 'https://api.parse.com/1' ) }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with altered server settings' do
|
62
|
+
before do
|
63
|
+
Opium.configure do |config|
|
64
|
+
config.server_url = 'https://example.com'
|
65
|
+
config.mount_point = '/parse'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it { expect( subject.connection.url_prefix ).to eq ::URI.join( 'https://example.com/parse' ) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
29
73
|
describe '.reset_connection!' do
|
30
74
|
it { expect { subject.reset_connection! }.to change( subject, :connection ) }
|
31
75
|
end
|
32
|
-
|
76
|
+
|
33
77
|
describe '.no_object_prefix!' do
|
34
78
|
after do
|
35
79
|
Model.instance_variable_set :@object_prefix, nil
|
36
80
|
end
|
37
|
-
|
81
|
+
|
38
82
|
it 'has an empty object_prefix' do
|
39
83
|
expect { subject.no_object_prefix! }.to change( subject, :object_prefix ).from( 'classes' ).to( '' )
|
40
84
|
end
|
41
85
|
end
|
42
|
-
|
86
|
+
|
43
87
|
describe '.as_resource' do
|
44
88
|
it { expect { subject.as_resource }.to raise_exception(ArgumentError) }
|
45
89
|
it do
|
46
90
|
expect {|b| subject.as_resource( :masked, &b ) }.to yield_control
|
47
91
|
end
|
48
|
-
|
92
|
+
|
49
93
|
it { expect { subject.as_resource( :masked ) {} }.to_not change( subject, :resource_name ) }
|
50
|
-
|
94
|
+
|
51
95
|
it 'changes the .resource_name within a block' do
|
52
96
|
subject.as_resource( :masked ) do
|
53
97
|
expect( subject.resource_name ).to eq 'masked'
|
54
98
|
end
|
55
99
|
end
|
56
100
|
end
|
57
|
-
|
101
|
+
|
58
102
|
describe '.resource_name' do
|
59
103
|
it 'is based off the class name' do
|
60
104
|
subject.resource_name.should == 'classes/Model'
|
61
105
|
end
|
62
|
-
|
106
|
+
|
63
107
|
it 'is able to include a resource id' do
|
64
108
|
subject.resource_name('abc123').should == 'classes/Model/abc123'
|
65
109
|
end
|
66
|
-
|
110
|
+
|
67
111
|
it 'demodulizes the model_name' do
|
68
112
|
namespaced_model = subject
|
69
113
|
namespaced_model.stub(:model_name).and_return(ActiveModel::Name.new(subject, nil, 'Namespace::Model'))
|
@@ -72,110 +116,110 @@ describe Opium::Model::Connectable do
|
|
72
116
|
namespaced_model.resource_name.should == 'classes/Model'
|
73
117
|
end
|
74
118
|
end
|
75
|
-
|
119
|
+
|
76
120
|
shared_examples_for 'a sent-headers response' do |method, *args|
|
77
121
|
let(:options) { args.last.is_a?(Hash) ? args.pop : {} }
|
78
122
|
let(:params) { args.push options.merge( sent_headers: true ) }
|
79
123
|
let(:request) { subject.send( :"http_#{method}", *params ) }
|
80
|
-
|
124
|
+
|
81
125
|
it { expect { request }.to_not raise_exception }
|
82
|
-
|
126
|
+
|
83
127
|
it { expect( request ).to be_a(Hash) }
|
84
|
-
|
128
|
+
|
85
129
|
if [:put, :post].include? method
|
86
130
|
context 'when including a JSON encoded body' do
|
87
131
|
it { expect( request ).to have_key 'Content-Type' }
|
88
132
|
it { expect( request['Content-Type'] ).to eq 'application/json' }
|
89
133
|
end
|
90
134
|
end
|
91
|
-
|
135
|
+
|
92
136
|
context 'when not .requires_heightened_prvileges?' do
|
93
137
|
before { subject.instance_variable_set :@requires_heightened_privileges, nil }
|
94
|
-
|
138
|
+
|
95
139
|
it { expect( subject.requires_heightened_privileges? ).to eq false }
|
96
|
-
|
140
|
+
|
97
141
|
it { expect( request.keys ).to include( 'X-Parse-Application-Id', 'X-Parse-Rest-Api-Key' ) }
|
98
142
|
it { expect( request.keys ).to_not include( 'X-Parse-Master-Key', 'X-Parse-Session-Token' ) }
|
99
143
|
end
|
100
|
-
|
144
|
+
|
101
145
|
unless method == :get
|
102
146
|
context 'when .requires_heightened_privileges?' do
|
103
147
|
subject do
|
104
148
|
Model.requires_heightened_privileges!
|
105
149
|
Model.send( :"http_#{method}", *params )
|
106
150
|
end
|
107
|
-
|
151
|
+
|
108
152
|
after { Model.instance_variable_set :@requires_heightened_privileges, nil }
|
109
|
-
|
153
|
+
|
110
154
|
it { expect( subject.keys ).to include( 'X-Parse-Application-Id', 'X-Parse-Master-Key' ) }
|
111
155
|
it { expect( subject.keys ).to_not include( 'X-Parse-Rest-Api-Key', 'X-Parse-Session-Token' ) }
|
112
156
|
end
|
113
157
|
end
|
114
158
|
end
|
115
|
-
|
159
|
+
|
116
160
|
describe '.http_get' do
|
117
161
|
before do
|
118
162
|
stub_request( :get, %r{https://api.parse.com/1/classes/Model(\?.+)?} ).
|
119
163
|
to_return( status: 200, body: { objectId: 'abc123' }.to_json, headers: { 'Content-Type' => 'application/json' } )
|
120
164
|
end
|
121
|
-
|
165
|
+
|
122
166
|
it 'executes a :get on :connection' do
|
123
167
|
subject.connection.should_receive(:get) { response }.with( 'classes/Model' )
|
124
168
|
subject.http_get
|
125
169
|
end
|
126
|
-
|
170
|
+
|
127
171
|
it 'uses a resource id if passed an :id option' do
|
128
172
|
subject.connection.should_receive(:get) { response }.with( 'classes/Model/abcd1234' )
|
129
173
|
subject.http_get id: 'abcd1234'
|
130
174
|
end
|
131
|
-
|
175
|
+
|
132
176
|
it 'returns a raw response if passed :raw_response' do
|
133
177
|
subject.http_get( raw_response: true ).should be_a( Faraday::Response )
|
134
178
|
end
|
135
|
-
|
179
|
+
|
136
180
|
it 'sets params for everything within the :query hash' do
|
137
181
|
response = subject.http_get query: { keys: 'title,price', order: '-title', limit: 5 }, raw_response: true
|
138
182
|
request_params = response.env.url.query.split('&').map {|p| p.split('=')}
|
139
183
|
request_params.should =~ { 'keys' => 'title%2Cprice', 'order' => '-title', 'limit' => '5' }
|
140
184
|
end
|
141
|
-
|
185
|
+
|
142
186
|
it 'special cases a :query key of "where", making it json encoded' do
|
143
187
|
criteria = { price: { '$lte' => 5 } }
|
144
188
|
response = subject.http_get query: { where: criteria }, raw_response: true
|
145
189
|
query = URI.decode response.env.url.query
|
146
190
|
query.should == "where=#{criteria.to_json}"
|
147
191
|
end
|
148
|
-
|
192
|
+
|
149
193
|
it_behaves_like 'a sent-headers response', :get
|
150
194
|
end
|
151
|
-
|
195
|
+
|
152
196
|
describe '.http_post' do
|
153
197
|
it 'executes a :post on :connection' do
|
154
198
|
subject.connection.should_receive(:post) { response }
|
155
199
|
subject.http_post( {} )
|
156
200
|
end
|
157
|
-
|
201
|
+
|
158
202
|
it_behaves_like 'a sent-headers response', :post, {}, {}
|
159
203
|
end
|
160
|
-
|
204
|
+
|
161
205
|
describe '.http_put' do
|
162
206
|
it 'executes a :put on :connection' do
|
163
207
|
subject.connection.should_receive(:put) { response }
|
164
208
|
subject.http_put( 'abcd1234', {} )
|
165
209
|
end
|
166
|
-
|
210
|
+
|
167
211
|
it_behaves_like 'a sent-headers response', :put, 'abcd1234', {}, {}
|
168
212
|
end
|
169
|
-
|
213
|
+
|
170
214
|
describe '.http_delete' do
|
171
215
|
it 'executes a :delete on :connection' do
|
172
216
|
subject.connection.should_receive(:delete) { response }
|
173
217
|
subject.http_delete( 'abcd1234' )
|
174
218
|
end
|
175
|
-
|
219
|
+
|
176
220
|
it_behaves_like 'a sent-headers response', :delete, 'abcd1234'
|
177
221
|
end
|
178
|
-
|
222
|
+
|
179
223
|
describe '.requires_heightened_privileges!' do
|
180
224
|
shared_examples_for 'it has heightened privileges on' do |method, *args|
|
181
225
|
before do
|
@@ -189,52 +233,52 @@ describe Opium::Model::Connectable do
|
|
189
233
|
)
|
190
234
|
).to_return(:status => 200, :body => "{}", :headers => {content_type: 'application/json'})
|
191
235
|
end
|
192
|
-
|
236
|
+
|
193
237
|
it "causes :http_#{method} to add a master-key header" do
|
194
238
|
subject.requires_heightened_privileges!
|
195
239
|
expect { subject.send( :"http_#{method}", *args ) }.to_not raise_exception
|
196
240
|
end
|
197
241
|
end
|
198
|
-
|
242
|
+
|
199
243
|
after { subject.instance_variable_set :@requires_heightened_privileges, nil }
|
200
|
-
|
244
|
+
|
201
245
|
it { subject.requires_heightened_privileges!.should == true }
|
202
|
-
|
246
|
+
|
203
247
|
it_behaves_like 'it has heightened privileges on', :post, {}
|
204
248
|
it_behaves_like 'it has heightened privileges on', :put, 'abcd1234', {}
|
205
249
|
it_behaves_like 'it has heightened privileges on', :delete, 'abcd1234'
|
206
250
|
end
|
207
|
-
|
251
|
+
|
208
252
|
describe '.requires_heightened_privileges?' do
|
209
253
|
after { subject.instance_variable_set :@requires_heightened_privileges, nil }
|
210
|
-
|
254
|
+
|
211
255
|
it { subject.requires_heightened_privileges?.should == false }
|
212
|
-
|
256
|
+
|
213
257
|
it 'is true if privileges have been raised' do
|
214
258
|
subject.requires_heightened_privileges!
|
215
259
|
subject.requires_heightened_privileges?.should == true
|
216
260
|
end
|
217
261
|
end
|
218
|
-
|
262
|
+
|
219
263
|
describe '.with_heightened_privileges' do
|
220
264
|
it { expect {|b| subject.with_heightened_privileges &b}.to yield_control }
|
221
|
-
|
265
|
+
|
222
266
|
it 'has heightened privileges within the block' do
|
223
267
|
subject.with_heightened_privileges do
|
224
268
|
expect( subject ).to have_heightened_privileges
|
225
269
|
end
|
226
270
|
end
|
227
|
-
|
271
|
+
|
228
272
|
it 'does not have heightened privileges outside the block' do
|
229
273
|
subject.with_heightened_privileges {}
|
230
|
-
expect( subject ).to_not have_heightened_privileges
|
274
|
+
expect( subject ).to_not have_heightened_privileges
|
231
275
|
end
|
232
|
-
|
276
|
+
|
233
277
|
it 'turns off heightened privileges on exceptions' do
|
234
278
|
expect { subject.with_heightened_privileges { raise 'expected' } }.to raise_exception
|
235
279
|
expect( subject ).to_not have_heightened_privileges
|
236
280
|
end
|
237
|
-
|
281
|
+
|
238
282
|
it 'keeps the previous value of requires_heightened_privileges? after the block' do
|
239
283
|
subject.requires_heightened_privileges!
|
240
284
|
subject.with_heightened_privileges {}
|
@@ -242,4 +286,4 @@ describe Opium::Model::Connectable do
|
|
242
286
|
subject.instance_variable_set :@requires_heightened_privileges, nil
|
243
287
|
end
|
244
288
|
end
|
245
|
-
end
|
289
|
+
end
|