cloudapp-service 1.0.0.beta.1

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.
Files changed (52) hide show
  1. data/CHANGELOG.md +34 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +56 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +14 -0
  6. data/Rakefile +148 -0
  7. data/cloudapp-service.gemspec +115 -0
  8. data/lib/cloudapp/collection_json.rb +3 -0
  9. data/lib/cloudapp/collection_json/item.rb +20 -0
  10. data/lib/cloudapp/collection_json/representation.rb +74 -0
  11. data/lib/cloudapp/collection_json/template.rb +17 -0
  12. data/lib/cloudapp/collection_json/tint.rb +11 -0
  13. data/lib/cloudapp/service.rb +204 -0
  14. data/lib/cloudapp/service/authorized_representation.rb +17 -0
  15. data/lib/cloudapp/service/drop.rb +44 -0
  16. data/lib/cloudapp/service/drop_collection.rb +39 -0
  17. data/spec/cassettes/account_token.yml +88 -0
  18. data/spec/cassettes/create_bookmark.yml +132 -0
  19. data/spec/cassettes/create_bookmark_with_name.yml +133 -0
  20. data/spec/cassettes/create_bookmark_with_privacy.yml +133 -0
  21. data/spec/cassettes/delete_drop.yml +215 -0
  22. data/spec/cassettes/list_drops.yml +488 -0
  23. data/spec/cassettes/list_drops_with_bad_token.yml +45 -0
  24. data/spec/cassettes/list_drops_with_filter.yml +345 -0
  25. data/spec/cassettes/list_drops_with_limit.yml +129 -0
  26. data/spec/cassettes/privatize_drop.yml +222 -0
  27. data/spec/cassettes/publicize_drop.yml +222 -0
  28. data/spec/cassettes/purge_drops.yml +764 -0
  29. data/spec/cassettes/recover_drop.yml +309 -0
  30. data/spec/cassettes/rename_drop.yml +222 -0
  31. data/spec/cassettes/token_for_account.yml +88 -0
  32. data/spec/cassettes/token_for_account_with_bad_credentials.yml +86 -0
  33. data/spec/cassettes/trash_drop.yml +222 -0
  34. data/spec/cassettes/update_drop_bookmark_url.yml +222 -0
  35. data/spec/cassettes/update_file.yml +365 -0
  36. data/spec/cassettes/upload_file.yml +276 -0
  37. data/spec/cassettes/upload_file_with_name.yml +278 -0
  38. data/spec/cassettes/upload_file_with_privacy.yml +277 -0
  39. data/spec/cassettes/view_drop.yml +174 -0
  40. data/spec/cloudapp/authorized_representation_spec.rb +32 -0
  41. data/spec/cloudapp/collection_json/item_spec.rb +45 -0
  42. data/spec/cloudapp/collection_json/representation_spec.rb +118 -0
  43. data/spec/cloudapp/collection_json/template_spec.rb +53 -0
  44. data/spec/cloudapp/drop_collection_spec.rb +148 -0
  45. data/spec/cloudapp/drop_spec.rb +186 -0
  46. data/spec/cloudapp/service_spec.rb +321 -0
  47. data/spec/helper.rb +8 -0
  48. data/spec/integration_spec.rb +77 -0
  49. data/spec/support/files/favicon.ico +0 -0
  50. data/spec/support/stub_class_or_module.rb +22 -0
  51. data/spec/support/vcr.rb +24 -0
  52. metadata +194 -0
@@ -0,0 +1,186 @@
1
+ require 'helper'
2
+
3
+ require 'cloudapp/service/drop'
4
+ stub_class :DropContent
5
+
6
+ describe CloudApp::Drop do
7
+ let(:href) { stub :href }
8
+ let(:links) { [] }
9
+ let(:data) { {} }
10
+ let(:collection) { stub :collection }
11
+ subject {
12
+ CloudApp::Drop.new stub(:drop, href: href, links: links, data: data),
13
+ collection
14
+ }
15
+
16
+ its(:href) { should eq(href) }
17
+
18
+ describe '#data' do
19
+ let(:data) {{ name: 'Drop' }}
20
+ its(:data) { should eq(data) }
21
+
22
+ context 'with string keys' do
23
+ let(:data) {{ 'name' => 'Drop' }}
24
+ its(:data) { should eq(data) }
25
+ end
26
+ end
27
+
28
+ describe '#name' do
29
+ let(:data) {{ name: 'Drop' }}
30
+ its(:name) { should eq(data[:name]) }
31
+
32
+ context 'when nil' do
33
+ let(:data) {{ name: nil }}
34
+ let(:links) {[ stub(:link, rel: 'canonical', href: '/canonical') ]}
35
+
36
+ it 'returns the share url' do
37
+ subject.name.should eq('/canonical')
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#private?' do
43
+ describe 'a private drop' do
44
+ let(:data) {{ private: true }}
45
+ it { should be_private }
46
+ end
47
+
48
+ describe 'a public drop' do
49
+ let(:data) {{ private: false }}
50
+ it { should_not be_private }
51
+ end
52
+ end
53
+
54
+ describe '#public?' do
55
+ describe 'a private drop' do
56
+ let(:data) {{ private: true }}
57
+ it { should_not be_public }
58
+ end
59
+
60
+ describe 'a public drop' do
61
+ let(:data) {{ private: false }}
62
+ it { should be_public }
63
+ end
64
+ end
65
+
66
+ describe '#trashed?' do
67
+ describe 'an active drop' do
68
+ let(:data) {{ 'trash' => false }}
69
+ it { should_not be_trashed }
70
+ end
71
+
72
+ describe 'a trashed drop' do
73
+ let(:data) {{ 'trash' => true }}
74
+ it { should be_trashed }
75
+ end
76
+ end
77
+
78
+ describe '#created' do
79
+ let(:data) {{ created: '2012-04-01T00:00:00Z' }}
80
+ it 'parses date' do
81
+ expected = DateTime.new(2012, 4, 1)
82
+ subject.created.should eq(expected)
83
+ end
84
+ end
85
+
86
+ describe '#share_url' do
87
+ let(:links) {[
88
+ stub(:canonical, rel: 'canonical', href: '/canonical'),
89
+ stub(:alternate, rel: 'alternate', href: '/alternate')
90
+ ]}
91
+ its(:share_url) { should eq('/canonical') }
92
+ end
93
+
94
+ describe '#thumbnail_url' do
95
+ let(:links) {[
96
+ stub(:canonical, rel: 'canonical', href: '/canonical'),
97
+ stub(:icon, rel: 'icon', href: '/icon')
98
+ ]}
99
+
100
+ its(:thumbnail_url) { should eq('/icon') }
101
+
102
+ context 'without an icon link' do
103
+ let(:links) {[ stub(:canonical, rel: 'canonical', href: '/canonical') ]}
104
+ its(:thumbnail_url) { should be_nil }
105
+ end
106
+ end
107
+
108
+ describe '#embed_url' do
109
+ let(:links) {[
110
+ stub(:canonical, rel: 'canonical', href: '/canonical'),
111
+ stub(:embed, rel: 'embed', href: '/embed')
112
+ ]}
113
+ its(:embed_url) { should eq('/embed') }
114
+
115
+ context 'without an embed link' do
116
+ let(:links) {[ stub(:canonical, rel: 'canonical', href: '/canonical') ]}
117
+ its(:embed_url) { should be_nil }
118
+ end
119
+ end
120
+
121
+ describe '#download_url' do
122
+ let(:links) {[
123
+ stub(:canonical, rel: 'canonical', href: '/canonical'),
124
+ stub(:download, rel: 'download', href: '/download')
125
+ ]}
126
+ its(:download_url) { should eq('/download') }
127
+
128
+ context 'without an download link' do
129
+ let(:links) {[ stub(:canonical, rel: 'canonical', href: '/canonical') ]}
130
+ its(:download_url) { should be_nil }
131
+ end
132
+ end
133
+
134
+ describe '#privatize' do
135
+ it 'privatizes itself' do
136
+ collection.should_receive(:privatize).once.with(subject)
137
+ subject.privatize
138
+ end
139
+ end
140
+
141
+ describe '#publicize' do
142
+ it 'publicizes itself' do
143
+ collection.should_receive(:publicize).once.with(subject)
144
+ subject.publicize
145
+ end
146
+ end
147
+
148
+ describe '#toggle_privacy' do
149
+ context 'a private drop' do
150
+ let(:data) {{ 'private' => true }}
151
+ it 'publicizes itself' do
152
+ collection.should_receive(:publicize).once.with(subject)
153
+ subject.toggle_privacy
154
+ end
155
+ end
156
+
157
+ context 'a public drop' do
158
+ let(:data) {{ 'private' => false }}
159
+ it 'privatizes itself' do
160
+ collection.should_receive(:privatize).once.with(subject)
161
+ subject.toggle_privacy
162
+ end
163
+ end
164
+ end
165
+
166
+ describe '#trash' do
167
+ it 'trashes itself' do
168
+ collection.should_receive(:trash).once.with(subject)
169
+ subject.trash
170
+ end
171
+ end
172
+
173
+ describe '#recover' do
174
+ it 'recovers itself' do
175
+ collection.should_receive(:recover).once.with(subject)
176
+ subject.recover
177
+ end
178
+ end
179
+
180
+ describe '#delete' do
181
+ it 'deletes itself' do
182
+ collection.should_receive(:delete).once.with(subject)
183
+ subject.delete
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,321 @@
1
+ require 'helper'
2
+ require 'support/vcr'
3
+
4
+ require 'cloudapp/service'
5
+
6
+ describe CloudApp::Service do
7
+ let(:service) { CloudApp::Service.using_token token }
8
+ let(:token) { 'abc123' }
9
+ let(:email) { 'arthur@dent.com' }
10
+ let(:password) { 'towel' }
11
+ let(:favicon) {
12
+ Pathname('../../support/files/favicon.ico').expand_path(__FILE__)
13
+ }
14
+
15
+ after(:all) do
16
+ VCR.use_cassette('purge_drops') do
17
+ service.drops(filter: 'all').each do |drop|
18
+ service.delete_drop(drop.href)
19
+ end
20
+ end
21
+ end
22
+
23
+ describe '.token_for_account' do
24
+ subject {
25
+ VCR.use_cassette('token_for_account') {
26
+ CloudApp::Service.token_for_account email, password
27
+ }
28
+ }
29
+
30
+ it 'returns the token' do
31
+ subject.should be_a(String)
32
+ subject.should eq(token)
33
+ end
34
+
35
+ context 'with bad credentials' do
36
+ let(:password) { 'wrong' }
37
+ subject {
38
+ VCR.use_cassette('token_for_account_with_bad_credentials') {
39
+ CloudApp::Service.token_for_account email, password
40
+ }
41
+ }
42
+
43
+ it 'returns nothing' do
44
+ subject.should be_nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#account_token' do
50
+ subject {
51
+ VCR.use_cassette('account_token') {
52
+ CloudApp::Service.new.account_token email, password
53
+ }
54
+ }
55
+
56
+ it { should be_a(CloudApp::CollectionJson::Representation) }
57
+
58
+ it 'returns a single item' do
59
+ subject.should have(1).item
60
+ end
61
+
62
+ it 'returns the token' do
63
+ subject.items.first.data.should eq('token' => token)
64
+ end
65
+
66
+ context 'with bad credentials' do
67
+ let(:password) { 'wrong' }
68
+ subject {
69
+ VCR.use_cassette('token_for_account_with_bad_credentials') {
70
+ CloudApp::Service.new.account_token email, password
71
+ }
72
+ }
73
+
74
+ it { should be_unauthorized }
75
+ end
76
+ end
77
+
78
+ describe '#drops' do
79
+ subject {
80
+ VCR.use_cassette('list_drops') {
81
+ service.upload favicon
82
+ service.bookmark 'http://cl.ly'
83
+ service.drops
84
+ }
85
+ }
86
+
87
+ it { should be_a(CloudApp::DropCollection) }
88
+
89
+ context 'with filter' do
90
+ subject {
91
+ VCR.use_cassette('list_drops_with_filter') {
92
+ service.bookmark('http://cl.ly').first.trash
93
+ service.drops filter: 'trash'
94
+ }
95
+ }
96
+
97
+ it { should be_a(CloudApp::DropCollection) }
98
+
99
+ it 'returns the filtered drops' do
100
+ subject.first.should be_trashed
101
+ end
102
+ end
103
+
104
+ context 'with limit' do
105
+ subject {
106
+ VCR.use_cassette('list_drops_with_limit') {
107
+ service.drops limit: 1
108
+ }
109
+ }
110
+
111
+ it { should be_a(CloudApp::DropCollection) }
112
+ it { should have(1).item }
113
+ end
114
+
115
+ context 'with a bad token' do
116
+ let(:token) { 'wrong' }
117
+ subject {
118
+ VCR.use_cassette('list_drops_with_bad_token') {
119
+ service.drops
120
+ }
121
+ }
122
+
123
+ it { should be_a(CloudApp::DropCollection) }
124
+ it { should be_unauthorized }
125
+ end
126
+ end
127
+
128
+ describe '#drop' do
129
+ subject {
130
+ VCR.use_cassette('view_drop') {
131
+ drop = service.bookmark('http://cl.ly').first
132
+ service.drop drop.href
133
+ }
134
+ }
135
+
136
+ it { should be_a(CloudApp::DropCollection) }
137
+ it { should have(1).item }
138
+ end
139
+
140
+ describe '#bookmark' do
141
+ let(:url) { 'http://getcloudapp.com' }
142
+ subject {
143
+ VCR.use_cassette('create_bookmark') { service.bookmark(url) }
144
+ }
145
+
146
+ it { should be_a(CloudApp::DropCollection) }
147
+ it { should have(1).item }
148
+
149
+ context 'with a name' do
150
+ let(:name) { 'New Bookmark' }
151
+ subject {
152
+ VCR.use_cassette('create_bookmark_with_name') {
153
+ service.bookmark(url, name: name).first
154
+ }
155
+ }
156
+ its(:name) { should eq(name) }
157
+ end
158
+
159
+ context 'with a privacy' do
160
+ subject {
161
+ VCR.use_cassette('create_bookmark_with_privacy') {
162
+ service.bookmark(url, private: false).first
163
+ }
164
+ }
165
+ it { should_not be_private }
166
+ end
167
+ end
168
+
169
+ describe '#upload' do
170
+ subject {
171
+ VCR.use_cassette('upload_file') { service.upload(favicon) }
172
+ }
173
+
174
+ it { should be_a(CloudApp::DropCollection) }
175
+ it { should have(1).item }
176
+
177
+ context 'with a name' do
178
+ let(:name) { 'New File' }
179
+ subject {
180
+ VCR.use_cassette('upload_file_with_name') {
181
+ service.upload(favicon, name: name).first
182
+ }
183
+ }
184
+ its(:name) { should eq(name) }
185
+ end
186
+
187
+ context 'with a privacy' do
188
+ subject {
189
+ VCR.use_cassette('upload_file_with_privacy') {
190
+ service.upload(favicon, private: false).first
191
+ }
192
+ }
193
+ it { should_not be_private }
194
+ end
195
+
196
+ describe 'too large file'
197
+ end
198
+
199
+ describe '#update' do
200
+ let(:url) { 'http://getcloudapp.com' }
201
+ let(:name) { 'New Drop Name' }
202
+ subject {
203
+ VCR.use_cassette('rename_drop') {
204
+ drop = service.bookmark(url).first
205
+ service.update drop.href, name: name, private: false
206
+ }
207
+ }
208
+
209
+ it { should be_a(CloudApp::DropCollection) }
210
+ it { should have(1).item }
211
+
212
+ it 'updates the name' do
213
+ subject.first.name.should eq(name)
214
+ end
215
+
216
+ it 'updates the privacy' do
217
+ subject.first.should_not be_private
218
+ end
219
+
220
+ context 'updating bookmark link' do
221
+ subject {
222
+ VCR.use_cassette('update_drop_bookmark_url') {
223
+ drop = service.bookmark(url).first
224
+ service.update drop.href, url: 'http://example.org'
225
+ }
226
+ }
227
+
228
+ it { should be_a(CloudApp::DropCollection) }
229
+ it { should have(1).item }
230
+ end
231
+
232
+ context 'updating file' do
233
+ let(:options) {{ path: favicon }}
234
+ subject {
235
+ VCR.use_cassette('update_file') {
236
+ drop = service.bookmark(url).first
237
+ service.update drop.href, options
238
+ }
239
+ }
240
+
241
+ it { should be_a(CloudApp::DropCollection) }
242
+ it { should have(1).item }
243
+ end
244
+ end
245
+
246
+ describe '#privatize_drop' do
247
+ subject {
248
+ VCR.use_cassette('privatize_drop') {
249
+ drop = service.bookmark('http://getcloudapp.com', private: false).first
250
+ service.privatize_drop drop.href
251
+ }
252
+ }
253
+
254
+ it { should be_a(CloudApp::DropCollection) }
255
+ it { should have(1).item }
256
+
257
+ it 'privatizes the drop' do
258
+ subject.first.should be_private
259
+ end
260
+ end
261
+
262
+ describe '#publicize_drop' do
263
+ subject {
264
+ VCR.use_cassette('publicize_drop') {
265
+ drop = service.bookmark('http://getcloudapp.com').first
266
+ service.publicize_drop drop.href
267
+ }
268
+ }
269
+
270
+ it { should be_a(CloudApp::DropCollection) }
271
+ it { should have(1).item }
272
+
273
+ it 'publicizes the drop' do
274
+ subject.first.should_not be_private
275
+ end
276
+ end
277
+
278
+ describe '#trash_drop' do
279
+ subject {
280
+ VCR.use_cassette('trash_drop') {
281
+ drop = service.bookmark('http://getcloudapp.com').first
282
+ service.trash_drop drop.href
283
+ }
284
+ }
285
+
286
+ it { should be_a(CloudApp::DropCollection) }
287
+ it { should have(1).item }
288
+
289
+ it 'trashes the drop' do
290
+ subject.first.should be_trashed
291
+ end
292
+ end
293
+
294
+ describe '#recover_drop' do
295
+ subject {
296
+ VCR.use_cassette('recover_drop') {
297
+ drop = service.bookmark('http://getcloudapp.com').first
298
+ service.trash_drop drop.href
299
+ service.recover_drop drop.href
300
+ }
301
+ }
302
+
303
+ it { should be_a(CloudApp::DropCollection) }
304
+ it { should have(1).item }
305
+
306
+ it 'recovers the drop' do
307
+ subject.first.should_not be_trashed
308
+ end
309
+ end
310
+
311
+ describe '#delete_drop' do
312
+ it 'deletes the drop' do
313
+ VCR.use_cassette('delete_drop') {
314
+ @drop = service.bookmark('http://getcloudapp.com').first
315
+ service.delete_drop @drop.href
316
+
317
+ -> { service.drop @drop.href }.should raise_error(ArgumentError)
318
+ }
319
+ end
320
+ end
321
+ end