cloudapp 1.0.2 → 1.1.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.
- data/CHANGELOG.md +24 -0
- data/Gemfile.lock +4 -2
- data/README.md +15 -16
- data/bin/cloudapp +71 -68
- data/cloudapp.gemspec +11 -2
- data/lib/cloudapp/config.rb +39 -0
- data/lib/cloudapp/drop.rb +5 -0
- data/lib/cloudapp/drop_content.rb +34 -0
- data/lib/cloudapp/drop_presenter.rb +5 -0
- data/lib/cloudapp/drop_service.rb +35 -1
- data/lib/cloudapp.rb +1 -1
- data/man/cloudapp.1 +49 -10
- data/man/cloudapp.1.html +21 -5
- data/man/cloudapp.1.ronn +27 -9
- data/spec/cassettes/DropContent/download.yml +116 -0
- data/spec/cassettes/DropService/drop.yml +81 -0
- data/spec/cassettes/DropService/upload_public_file.yml +1 -1
- data/spec/cloudapp/config_spec.rb +59 -0
- data/spec/cloudapp/drop_content_spec.rb +21 -0
- data/spec/cloudapp/drop_presenter_spec.rb +31 -6
- data/spec/cloudapp/drop_service_spec.rb +155 -1
- data/spec/cloudapp/drop_spec.rb +19 -0
- data/spec/support/fakefs_rspec.rb +5 -0
- metadata +43 -24
data/man/cloudapp.1.html
CHANGED
@@ -86,7 +86,8 @@
|
|
86
86
|
<p><code>cloudapp</code> [<code>--format</code>=<var>format</var>] <var>command</var> [<var>args</var>]<br />
|
87
87
|
<code>cloudapp list</code> [<code>--count</code>=<var>count</var>]<br />
|
88
88
|
<code>cloudapp bookmark</code> [<code>--private</code>] [<code>--public</code>] <var>url</var> [<var>url</var>...]<br />
|
89
|
-
<code>cloudapp upload</code> [<code>--private</code>] [<code>--public</code>] <var>file</var> [<var>file</var>...]
|
89
|
+
<code>cloudapp upload</code> [<code>--private</code>] [<code>--public</code>] <var>file</var> [<var>file</var>...]<br />
|
90
|
+
<code>cloudapp download</code> [<code>--output</code>=<var>file</var>] <var>url</var></p>
|
90
91
|
|
91
92
|
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
92
93
|
|
@@ -105,8 +106,9 @@ output to a terminal and <strong>csv</strong> when output is piped to another pr
|
|
105
106
|
<h2 id="COMMANDS">COMMANDS</h2>
|
106
107
|
|
107
108
|
<dl>
|
108
|
-
<dt><code>list</code> [<code>--count</code>=<var>count</var>]</dt><dd><p>List the most recent <var>count</var> drops. The default is to list <strong>20</strong> drops.</p></dd>
|
109
109
|
<dt><code>bookmark</code> [<code>--private</code>] [<code>--public</code>] [<var>url</var>...]</dt><dd><p>Create a new bookmark to each <var>url</var> and print each link.</p></dd>
|
110
|
+
<dt><code>download</code> [<code>--output</code>=<var>file</var>] <var>url</var></dt><dd><p>Download the file at <var>url</var> to the current directory or to <var>file</var> if present.</p></dd>
|
111
|
+
<dt><code>list</code> [<code>--count</code>=<var>count</var>]</dt><dd><p>List the most recent <var>count</var> drops. The default is to list <strong>20</strong> drops.</p></dd>
|
110
112
|
<dt><code>upload</code> [<code>--private</code>] [<code>--public</code>] <var>file</var> [<var>file</var>...]</dt><dd><p>Upload each <var>file</var> and print each link.</p></dd>
|
111
113
|
</dl>
|
112
114
|
|
@@ -114,9 +116,11 @@ output to a terminal and <strong>csv</strong> when output is piped to another pr
|
|
114
116
|
<h2 id="COMMAND-OPTIONS">COMMAND OPTIONS</h2>
|
115
117
|
|
116
118
|
<dl>
|
119
|
+
<dt><code>-n</code> <var>count</var>, <code>--count</code>=<var>count</var></dt><dd><p>Display <var>count</var> drops. (Default: <strong>20</strong>)</p></dd>
|
120
|
+
<dt><code>-o</code> <var>file</var>, <code>--output</code>=<var>file</var></dt><dd><p>Download file as <var>file</var>. (Default: current directory using the remote file's
|
121
|
+
name)</p></dd>
|
117
122
|
<dt><code>--private</code></dt><dd><p>Use a private (long) link when creating a new drop.</p></dd>
|
118
123
|
<dt><code>--public</code></dt><dd><p>Use a public (short) link when creating a new drop.</p></dd>
|
119
|
-
<dt><code>-n</code> <var>count</var>, <code>--count</code>=<var>count</var></dt><dd><p>Display <var>count</var> drops. (Default: <strong>20</strong>)</p></dd>
|
120
124
|
</dl>
|
121
125
|
|
122
126
|
|
@@ -161,13 +165,13 @@ Cover.jpeg,http://cl.ly/1x20...,1
|
|
161
165
|
Chapter 1.md,http://cl.ly/3U3d...,7
|
162
166
|
</code></pre>
|
163
167
|
|
164
|
-
<p>Share a new bookmark to
|
168
|
+
<p>Share a new bookmark to <strong>http://douglasadams.com</strong>:</p>
|
165
169
|
|
166
170
|
<pre><code>$ cloudapp bookmark http://douglasadams.com
|
167
171
|
Bookmarking http://douglasadams.com... http://cl.ly/1y0j403g3D0c0X1G0R3m
|
168
172
|
</code></pre>
|
169
173
|
|
170
|
-
<p>Share the file
|
174
|
+
<p>Share the file <strong>screenshot.png</strong>:</p>
|
171
175
|
|
172
176
|
<pre><code>$ cloudapp upload screenshot.png
|
173
177
|
Uploading screenshot.png... http://cl.ly/040u2o3X1w0z1z3n2T04
|
@@ -185,6 +189,18 @@ $ cloudapp upload screenshot.png | pbcopy
|
|
185
189
|
http://cl.ly/1y0j403g3D0c0X1G0R3m
|
186
190
|
</code></pre>
|
187
191
|
|
192
|
+
<p>Download a drop to the current direcctory:</p>
|
193
|
+
|
194
|
+
<pre><code>$ cloudapp download http://cl.ly/040u2o3X1w0z1z3n2T04
|
195
|
+
Downloading screenshot.png... done
|
196
|
+
</code></pre>
|
197
|
+
|
198
|
+
<p>Download a drop to another path:</p>
|
199
|
+
|
200
|
+
<pre><code>$ cloudapp download --output=/Users/Larry/image.png http://cl.ly/040u2o3X1w0z1z3n2T04
|
201
|
+
Downloading screenshot.png to /Users/Larry... done
|
202
|
+
</code></pre>
|
203
|
+
|
188
204
|
<h2 id="LICENSE">LICENSE</h2>
|
189
205
|
|
190
206
|
<p><code>cloudapp</code> is distributed under the <a href="https://github.com/cloudapp/cloudapp/blob/master/MIT-LICENSE">MIT license</a>.</p>
|
data/man/cloudapp.1.ronn
CHANGED
@@ -6,7 +6,8 @@ cloudapp(1) -- All the pleasures of CloudApp now at your terminal
|
|
6
6
|
`cloudapp` [`--format`=<format>] <command> [<args>]<br>
|
7
7
|
`cloudapp list` [`--count`=<count>]<br>
|
8
8
|
`cloudapp bookmark` [`--private`] [`--public`] <url> [<url>...]<br>
|
9
|
-
`cloudapp upload` [`--private`] [`--public`] <file> [<file>...]
|
9
|
+
`cloudapp upload` [`--private`] [`--public`] <file> [<file>...]<br>
|
10
|
+
`cloudapp download` [`--output`=<file>] <url>
|
10
11
|
|
11
12
|
## DESCRIPTION
|
12
13
|
|
@@ -22,26 +23,33 @@ terminal and other times it's the only tool available.
|
|
22
23
|
|
23
24
|
## COMMANDS
|
24
25
|
|
25
|
-
* `list` [`--count`=<count>]:
|
26
|
-
List the most recent <count> drops. The default is to list **20** drops.
|
27
|
-
|
28
26
|
* `bookmark` [`--private`] [`--public`] [<url>...]:
|
29
27
|
Create a new bookmark to each <url> and print each link.
|
30
28
|
|
29
|
+
* `download` [`--output`=<file>] <url>:
|
30
|
+
Download the file at <url> to the current directory or to <file> if present.
|
31
|
+
|
32
|
+
* `list` [`--count`=<count>]:
|
33
|
+
List the most recent <count> drops. The default is to list **20** drops.
|
34
|
+
|
31
35
|
* `upload` [`--private`] [`--public`] <file> [<file>...]:
|
32
36
|
Upload each <file> and print each link.
|
33
37
|
|
34
38
|
## COMMAND OPTIONS
|
35
39
|
|
40
|
+
* `-n` <count>, `--count`=<count>:
|
41
|
+
Display <count> drops. (Default: **20**)
|
42
|
+
|
43
|
+
* `-o` <file>, `--output`=<file>:
|
44
|
+
Download file as <file>. (Default: current directory using the remote file's
|
45
|
+
name)
|
46
|
+
|
36
47
|
* `--private`:
|
37
48
|
Use a private (long) link when creating a new drop.
|
38
49
|
|
39
50
|
* `--public`:
|
40
51
|
Use a public (short) link when creating a new drop.
|
41
52
|
|
42
|
-
* `-n` <count>, `--count`=<count>:
|
43
|
-
Display <count> drops. (Default: **20**)
|
44
|
-
|
45
53
|
## REQUIREMENTS
|
46
54
|
|
47
55
|
`cloudapp` requires Ruby 1.9.2 or greater.
|
@@ -80,12 +88,12 @@ List newest 5 drops in CSV format:
|
|
80
88
|
Cover.jpeg,http://cl.ly/1x20...,1
|
81
89
|
Chapter 1.md,http://cl.ly/3U3d...,7
|
82
90
|
|
83
|
-
Share a new bookmark to
|
91
|
+
Share a new bookmark to **http://douglasadams.com**:
|
84
92
|
|
85
93
|
$ cloudapp bookmark http://douglasadams.com
|
86
94
|
Bookmarking http://douglasadams.com... http://cl.ly/1y0j403g3D0c0X1G0R3m
|
87
95
|
|
88
|
-
Share the file
|
96
|
+
Share the file **screenshot.png**:
|
89
97
|
|
90
98
|
$ cloudapp upload screenshot.png
|
91
99
|
Uploading screenshot.png... http://cl.ly/040u2o3X1w0z1z3n2T04
|
@@ -100,6 +108,16 @@ Share a new bookmark and output only the URL:
|
|
100
108
|
$ cloudapp --format=csv bookmark http://douglasadams.com
|
101
109
|
http://cl.ly/1y0j403g3D0c0X1G0R3m
|
102
110
|
|
111
|
+
Download a drop to the current direcctory:
|
112
|
+
|
113
|
+
$ cloudapp download http://cl.ly/040u2o3X1w0z1z3n2T04
|
114
|
+
Downloading screenshot.png... done
|
115
|
+
|
116
|
+
Download a drop to another path:
|
117
|
+
|
118
|
+
$ cloudapp download --output=/Users/Larry/image.png http://cl.ly/040u2o3X1w0z1z3n2T04
|
119
|
+
Downloading screenshot.png to /Users/Larry... done
|
120
|
+
|
103
121
|
|
104
122
|
## LICENSE
|
105
123
|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://cl.ly/C23W/drop_presenter.rb
|
6
|
+
body: ''
|
7
|
+
headers:
|
8
|
+
Accept:
|
9
|
+
- application/json
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 302
|
13
|
+
message: Moved Temporarily
|
14
|
+
headers:
|
15
|
+
Server:
|
16
|
+
- nginx
|
17
|
+
Date:
|
18
|
+
- Fri, 17 Feb 2012 01:43:07 GMT
|
19
|
+
Content-Type:
|
20
|
+
- text/html;charset=utf-8
|
21
|
+
Connection:
|
22
|
+
- keep-alive
|
23
|
+
Vary:
|
24
|
+
- Accept
|
25
|
+
Cache-Control:
|
26
|
+
- public, max-age=900
|
27
|
+
Location:
|
28
|
+
- http://api.cld.me/C23W/drop_presenter.rb
|
29
|
+
X-Content-Digest:
|
30
|
+
- da39a3ee5e6b4b0d3255bfef95601890afd80709
|
31
|
+
X-Rack-Cache:
|
32
|
+
- stale, invalid, store
|
33
|
+
Content-Length:
|
34
|
+
- '0'
|
35
|
+
X-Varnish:
|
36
|
+
- '1852427632'
|
37
|
+
Age:
|
38
|
+
- '0'
|
39
|
+
Via:
|
40
|
+
- 1.1 varnish
|
41
|
+
body: ''
|
42
|
+
http_version:
|
43
|
+
recorded_at: Fri, 17 Feb 2012 01:43:07 GMT
|
44
|
+
- request:
|
45
|
+
method: get
|
46
|
+
uri: http://api.cld.me/C23W/drop_presenter.rb
|
47
|
+
body: ''
|
48
|
+
headers:
|
49
|
+
Accept:
|
50
|
+
- application/json
|
51
|
+
response:
|
52
|
+
status:
|
53
|
+
code: 302
|
54
|
+
message: Moved Temporarily
|
55
|
+
headers:
|
56
|
+
Cache-Control:
|
57
|
+
- no-cache
|
58
|
+
Content-Type:
|
59
|
+
- text/html; charset=utf-8
|
60
|
+
Location:
|
61
|
+
- http://f.cl.ly/items/152S3l2X1y3P2M262D3V/drop_presenter.rb
|
62
|
+
Server:
|
63
|
+
- thin 1.3.1 codename Triple Espresso
|
64
|
+
X-Runtime:
|
65
|
+
- '0.025914'
|
66
|
+
X-Ua-Compatible:
|
67
|
+
- IE=Edge,chrome=1
|
68
|
+
Transfer-Encoding:
|
69
|
+
- chunked
|
70
|
+
Connection:
|
71
|
+
- keep-alive
|
72
|
+
body: <html><body>You are being <a href="http://f.cl.ly/items/152S3l2X1y3P2M262D3V/drop_presenter.rb">redirected</a>.</body></html>
|
73
|
+
http_version:
|
74
|
+
recorded_at: Fri, 17 Feb 2012 01:44:07 GMT
|
75
|
+
- request:
|
76
|
+
method: get
|
77
|
+
uri: http://f.cl.ly/items/152S3l2X1y3P2M262D3V/drop_presenter.rb
|
78
|
+
body: ''
|
79
|
+
headers:
|
80
|
+
Accept:
|
81
|
+
- application/json
|
82
|
+
response:
|
83
|
+
status:
|
84
|
+
code: 200
|
85
|
+
message: OK
|
86
|
+
headers:
|
87
|
+
X-Amz-Id-2:
|
88
|
+
- iyFXxRKOKM5CYt1f7jI9bN8btGeacX2VeXxCIMNL2/AQNzPEH7pAIUjQ9A4Q/TYC
|
89
|
+
X-Amz-Request-Id:
|
90
|
+
- 9092E1275FD0C3F5
|
91
|
+
Date:
|
92
|
+
- Fri, 17 Feb 2012 01:44:09 GMT
|
93
|
+
Last-Modified:
|
94
|
+
- Tue, 22 Nov 2011 19:40:51 GMT
|
95
|
+
Etag:
|
96
|
+
- ! '"f24a305d5a90516f0b0877b93158ee0a"'
|
97
|
+
Accept-Ranges:
|
98
|
+
- bytes
|
99
|
+
Content-Type:
|
100
|
+
- application/ruby
|
101
|
+
Content-Length:
|
102
|
+
- '610'
|
103
|
+
Server:
|
104
|
+
- AmazonS3
|
105
|
+
body: ! "require 'delegate'\nrequire 'yajl'\n\nclass DropPresenter < SimpleDelegator\n
|
106
|
+
\ def initialize(drop, template)\n @template = template\n\n super drop\n
|
107
|
+
\ end\n\n def render_html\n if bookmark?\n @template.redirect_to_api\n
|
108
|
+
\ else\n @template.erb template_name, locals: { drop: self, body_id:
|
109
|
+
body_id }\n end\n end\n\n def render_json\n Yajl::Encoder.encode data\n
|
110
|
+
\ end\n\nprivate\n\n def template_name\n if image?\n :image\n elsif
|
111
|
+
text?\n :text\n else\n :other\n end\n end\n\n def body_id\n
|
112
|
+
\ if image?\n 'image'\n elsif text?\n 'text'\n else\n 'other'\n
|
113
|
+
\ end\n end\n\nend\n"
|
114
|
+
http_version:
|
115
|
+
recorded_at: Fri, 17 Feb 2012 01:44:08 GMT
|
116
|
+
recorded_with: VCR 2.0.0.rc1
|
@@ -0,0 +1,81 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://cl.ly/C23W
|
6
|
+
body: ''
|
7
|
+
headers:
|
8
|
+
Accept:
|
9
|
+
- application/json
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
Server:
|
16
|
+
- nginx
|
17
|
+
Date:
|
18
|
+
- Thu, 16 Feb 2012 20:19:27 GMT
|
19
|
+
Content-Type:
|
20
|
+
- application/json;charset=utf-8
|
21
|
+
Connection:
|
22
|
+
- keep-alive
|
23
|
+
Vary:
|
24
|
+
- Accept
|
25
|
+
X-Rack-Cache:
|
26
|
+
- miss
|
27
|
+
Content-Length:
|
28
|
+
- '627'
|
29
|
+
X-Varnish:
|
30
|
+
- '587912818'
|
31
|
+
Age:
|
32
|
+
- '0'
|
33
|
+
Via:
|
34
|
+
- 1.1 varnish
|
35
|
+
body: ! '{"created_at":"2011-11-22T19:40:50Z","deleted_at":null,"id":12142483,"item_type":"text","name":"drop_presenter.rb","private":false,"redirect_url":null,"remote_url":"http://f.cl.ly/items/152S3l2X1y3P2M262D3V/drop_presenter.rb","source":"Cloud/1.5.3b1
|
36
|
+
CFNetwork/520.2.5 Darwin/11.2.0 (x86_64) (MacBookPro5%2C5)","updated_at":"2012-02-16T20:09:52Z","view_counter":90,"href":"http://my.cl.ly/items/12142483","url":"http://cl.ly/C23W","content_url":"http://cl.ly/C23W/drop_presenter.rb","icon":"http://assets.my.cld.me/images/item-types/text.png","subscribed":true,"download_url":"http://api.cld.me/C23W/download/drop_presenter.rb"}'
|
37
|
+
http_version:
|
38
|
+
recorded_at: Thu, 16 Feb 2012 20:19:27 GMT
|
39
|
+
- request:
|
40
|
+
method: get
|
41
|
+
uri: http://cl.ly/nonexistent
|
42
|
+
body: ''
|
43
|
+
headers:
|
44
|
+
Accept:
|
45
|
+
- application/json
|
46
|
+
response:
|
47
|
+
status:
|
48
|
+
code: 404
|
49
|
+
message: Not Found
|
50
|
+
headers:
|
51
|
+
Server:
|
52
|
+
- nginx
|
53
|
+
Date:
|
54
|
+
- Thu, 16 Feb 2012 20:26:01 GMT
|
55
|
+
Content-Type:
|
56
|
+
- text/html;charset=utf-8
|
57
|
+
Connection:
|
58
|
+
- keep-alive
|
59
|
+
Vary:
|
60
|
+
- Accept
|
61
|
+
X-Rack-Cache:
|
62
|
+
- miss
|
63
|
+
Content-Length:
|
64
|
+
- '621'
|
65
|
+
X-Varnish:
|
66
|
+
- '2047120769'
|
67
|
+
Age:
|
68
|
+
- '0'
|
69
|
+
Via:
|
70
|
+
- 1.1 varnish
|
71
|
+
body: ! "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n\n <title>CloudApp
|
72
|
+
— Not Found</title>\n\n <link href='/favicon.ico' rel='shortcut icon'
|
73
|
+
/>\n <link href=\"/stylesheets/error.css\" rel=\"stylesheet\" type=\"text/css\"
|
74
|
+
/>\n\n <!--[if lt IE 9]>\n <script src=\"//html5shim.googlecode.com/svn/trunk/html5.js\"></script>\n
|
75
|
+
\ <![endif]-->\n </head>\n\n <body>\n <div class=\"wrapper\">\n <h1>Cloud<em>App</em></h1>\n\n
|
76
|
+
\ <h2>Sorry, no drops live here.</h2>\n\n <p>\n Perhaps the
|
77
|
+
link you clicked was broken or the owner of this drop has\n deleted it.\n
|
78
|
+
\ </p>\n </div>\n </body>\n</html>\n"
|
79
|
+
http_version:
|
80
|
+
recorded_at: Thu, 16 Feb 2012 20:26:01 GMT
|
81
|
+
recorded_with: VCR 2.0.0.rc1
|
@@ -255,7 +255,7 @@ http_interactions:
|
|
255
255
|
recorded_at: Wed, 15 Feb 2012 14:39:02 GMT
|
256
256
|
- request:
|
257
257
|
method: get
|
258
|
-
uri: https://my.cl.ly/items/s3?bucket=f.cl.ly&etag=%22567d2d49d2d30e2db956d680a4d03f25%22&key=items/2B0E373Z1J2U1u071E28/favicon.ico
|
258
|
+
uri: https://my.cl.ly/items/s3?bucket=f.cl.ly&etag=%22567d2d49d2d30e2db956d680a4d03f25%22&item%5Bprivate%5D=false&key=items/2B0E373Z1J2U1u071E28/favicon.ico
|
259
259
|
body: ''
|
260
260
|
headers:
|
261
261
|
Authorization:
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
require 'cloudapp/config'
|
5
|
+
|
6
|
+
describe CloudApp::Config do
|
7
|
+
let(:config) { {} }
|
8
|
+
let(:content) { YAML.dump(config) }
|
9
|
+
let(:path) { config_file.path }
|
10
|
+
let(:config_file) {
|
11
|
+
Tempfile.new('cloudapprc', '.').tap do |file|
|
12
|
+
file << content
|
13
|
+
file.close
|
14
|
+
end
|
15
|
+
}
|
16
|
+
|
17
|
+
describe '#new' do
|
18
|
+
subject { CloudApp::Config.new path }
|
19
|
+
|
20
|
+
describe 'an existing config file' do
|
21
|
+
let(:config) {{ token: 'token' }}
|
22
|
+
|
23
|
+
it 'reads the content' do
|
24
|
+
subject.token.should eq(config[:token])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'updates a key' do
|
28
|
+
new_token = 'new token'
|
29
|
+
subject.token = new_token
|
30
|
+
expected = YAML.dump token: new_token
|
31
|
+
|
32
|
+
content = File.open(path) {|file| file.read }
|
33
|
+
content.should eq(expected)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'clears a key' do
|
37
|
+
subject.token = nil
|
38
|
+
expected = YAML.dump({})
|
39
|
+
|
40
|
+
content = File.open(path) {|file| file.read }
|
41
|
+
content.should eq(expected)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'an empty config file' do
|
46
|
+
it 'returns nil' do
|
47
|
+
subject.token.should be_nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'a nonexistent config file' do
|
52
|
+
let(:path) { 'nonexistent' }
|
53
|
+
|
54
|
+
it 'returns nil' do
|
55
|
+
subject.token.should be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'support/vcr_rspec'
|
3
|
+
|
4
|
+
require 'cloudapp/drop_content'
|
5
|
+
|
6
|
+
describe CloudApp::DropContent do
|
7
|
+
describe '.download' do
|
8
|
+
let(:content_url) { 'http://cl.ly/C23W/drop_presenter.rb' }
|
9
|
+
let(:drop) { stub :drop, content_url: content_url }
|
10
|
+
subject {
|
11
|
+
VCR.use_cassette('DropContent/download') {
|
12
|
+
CloudApp::DropContent.download drop
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
it 'downloads content' do
|
17
|
+
expected = "require 'delegate'"
|
18
|
+
subject[0...expected.size].should == expected
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -11,10 +11,10 @@ describe CloudApp::DropPresenter do
|
|
11
11
|
let(:io) { StringIO.new }
|
12
12
|
|
13
13
|
describe 'a single line' do
|
14
|
-
subject
|
14
|
+
subject {
|
15
15
|
CloudApp::DropPresenter.print(options, &action)
|
16
16
|
io.tap(&:rewind).readlines
|
17
|
-
|
17
|
+
}
|
18
18
|
|
19
19
|
describe 'with no format' do
|
20
20
|
let(:options) {{ on: io, waiting: waiting }}
|
@@ -47,16 +47,16 @@ describe CloudApp::DropPresenter do
|
|
47
47
|
|
48
48
|
describe 'a table of data' do
|
49
49
|
let(:columns) {{ name: 'Name', url: 'Link' }}
|
50
|
-
let(:result)
|
50
|
+
let(:result) {
|
51
51
|
[ stub(:result1, name: 'Stub 1', url: 'http://stub1.com'),
|
52
52
|
stub(:result2, name: 'Stub 2', url: 'http://stub2.com') ]
|
53
|
-
|
53
|
+
}
|
54
54
|
let(:options) {{ on: io, format: format, columns: columns }}
|
55
55
|
|
56
|
-
subject
|
56
|
+
subject {
|
57
57
|
CloudApp::DropPresenter.print(options, &action)
|
58
58
|
io.tap(&:rewind).readlines
|
59
|
-
|
59
|
+
}
|
60
60
|
|
61
61
|
describe 'pretty format' do
|
62
62
|
let(:format) { :pretty }
|
@@ -91,5 +91,30 @@ describe CloudApp::DropPresenter do
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
describe 'providing multiple formats' do
|
96
|
+
let(:result) {{ pretty: 'pretty', csv: 'csv' }}
|
97
|
+
subject {
|
98
|
+
CloudApp::DropPresenter.print(options, &action)
|
99
|
+
io.tap(&:rewind).readlines
|
100
|
+
}
|
101
|
+
|
102
|
+
describe 'pretty format' do
|
103
|
+
let(:options) {{ on: io, format: :pretty }}
|
104
|
+
|
105
|
+
it 'pretty prints' do
|
106
|
+
subject.first.should eq("pretty\n")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'csv format' do
|
111
|
+
let(:options) {{ on: io, format: :csv }}
|
112
|
+
|
113
|
+
it 'prints csv' do
|
114
|
+
subject.first.should eq("csv\n")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
94
119
|
end
|
95
120
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require 'support/fakefs_rspec'
|
2
3
|
require 'support/vcr_rspec'
|
3
4
|
|
4
5
|
require 'cloudapp/drop_service'
|
5
6
|
|
6
7
|
describe CloudApp::DropService do
|
7
|
-
|
8
8
|
let(:token) { '8762f6679f8d001016b2' }
|
9
9
|
|
10
10
|
describe '.using_token' do
|
@@ -29,6 +29,160 @@ describe CloudApp::DropService do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
describe '#drop' do
|
33
|
+
let(:service) { CloudApp::DropService.new }
|
34
|
+
|
35
|
+
describe 'retrieving a drop' do
|
36
|
+
let(:url) { 'http://cl.ly/C23W' }
|
37
|
+
subject {
|
38
|
+
VCR.use_cassette('DropService/drop',
|
39
|
+
match_requests_on: [:method, :uri, :body, :headers]) {
|
40
|
+
service.drop url
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
it 'returns the drop' do
|
45
|
+
subject.should be_a(CloudApp::Drop)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'parses the response' do
|
49
|
+
subject.id.should == 12142483
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'retrieving a nonexistent drop' do
|
54
|
+
let(:url) { 'http://cl.ly/nonexistent' }
|
55
|
+
subject {
|
56
|
+
VCR.use_cassette('DropService/drop',
|
57
|
+
match_requests_on: [:method, :uri, :body, :headers]) {
|
58
|
+
service.drop url
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
it 'returns nil' do
|
63
|
+
subject.should be_nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#download_drop', :fakefs do
|
69
|
+
let(:service) { CloudApp::DropService.new }
|
70
|
+
let(:url) { 'http://cl.ly/C23W' }
|
71
|
+
let(:options) { {} }
|
72
|
+
let(:content) { 'content' }
|
73
|
+
let(:content_url) { 'http://cl.ly/C23W/drop_presenter.rb' }
|
74
|
+
let(:drop) { stub :drop, content: content,
|
75
|
+
content_url: content_url,
|
76
|
+
has_content?: true }
|
77
|
+
|
78
|
+
before do
|
79
|
+
CloudApp::DropContent.stub download: content
|
80
|
+
service.stub drop: drop
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'fetches the drop' do
|
84
|
+
CloudApp::DropContent.should_receive(:download).with(drop)
|
85
|
+
service.download_drop url, options
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns the content' do
|
89
|
+
service.download_drop(url, options).should eq(content)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'saves the file to the current directory using the remote filename' do
|
93
|
+
service.download_drop url, options
|
94
|
+
downloaded = File.open('drop_presenter.rb') {|f| f.read }
|
95
|
+
|
96
|
+
downloaded.should eq(content)
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'to a path' do
|
100
|
+
let(:options) {{ to: '/tmp/file.txt' }}
|
101
|
+
|
102
|
+
it 'saves the file to the given path' do
|
103
|
+
service.download_drop url, options
|
104
|
+
File.exist?(options[:to]).should be_true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe 'to an existing file' do
|
109
|
+
let(:options) {{ to: '/tmp/file.txt' }}
|
110
|
+
before do
|
111
|
+
Dir.mkdir '/tmp'
|
112
|
+
File.open(options[:to], 'w', 0600) {|file| file << 'existing' }
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'overwrites the file' do
|
116
|
+
service.download_drop url, options
|
117
|
+
downloaded = File.open(options[:to]) {|f| f.read }
|
118
|
+
|
119
|
+
downloaded.should eq(content)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'an unexpanded path' do
|
124
|
+
let(:options) {{ to: '~/file.txt' }}
|
125
|
+
before do
|
126
|
+
FileUtils.mkdir_p File.expand_path('~')
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'saves the file to the expanded directory' do
|
130
|
+
service.download_drop url, options
|
131
|
+
saved_path = File.expand_path(options[:to])
|
132
|
+
|
133
|
+
File.exist?(saved_path).should be_true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe 'to an existing directory' do
|
138
|
+
let(:options) {{ to: '/tmp' }}
|
139
|
+
before do
|
140
|
+
Dir.mkdir '/tmp'
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'raises an exception' do
|
144
|
+
-> { service.download_drop url, options }.
|
145
|
+
should raise_exception(Errno::EISDIR)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'a bookmark' do
|
150
|
+
let(:drop) { stub :drop, has_content?: false }
|
151
|
+
|
152
|
+
it 'raises an exception' do
|
153
|
+
-> { service.download_drop url, options }.
|
154
|
+
should raise_exception(CloudApp::DropService::NO_CONTENT)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "doesn't save a file" do
|
158
|
+
FakeFS::FileSystem.files.should be_empty
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'a file with URL-encoded name' do
|
163
|
+
let(:content_url) { 'http://cl.ly/C23W/screen%20shot.png' }
|
164
|
+
|
165
|
+
it 'decodes the filename' do
|
166
|
+
service.download_drop url, options
|
167
|
+
|
168
|
+
File.exist?('screen shot.png').should be_true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'a nonexistent drop' do
|
173
|
+
let(:drop) { nil }
|
174
|
+
|
175
|
+
it 'raises an exception' do
|
176
|
+
-> { service.download_drop url, options }.
|
177
|
+
should raise_exception(CloudApp::DropService::NO_CONTENT)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "doesn't save a file" do
|
181
|
+
FakeFS::FileSystem.files.should be_empty
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
32
186
|
describe '#drops' do
|
33
187
|
let(:service) { CloudApp::DropService.using_token token }
|
34
188
|
|