cloudapp 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|