cloudpt-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ module Cloudpt
2
+ module API
3
+
4
+ module Util
5
+
6
+ class << self
7
+
8
+ def escape(string)
9
+ string.gsub(/([^ a-zA-Z0-9\.\\\-\/\_]+)/) do
10
+ '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
11
+ end.gsub(' ', '%20')
12
+ end
13
+
14
+ def query(data)
15
+ data.inject([]) { |memo, entry| memo.push(entry.join('=')); memo }.join('&')
16
+ end
17
+
18
+ def remove_double_slashes(path)
19
+ path.gsub('//', '/')
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Cloudpt
2
+ module API
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ app_key: # CONSUMER KEY
2
+ app_secret: # CONSUMER SECRET
3
+ token: # ACCESS TOKEN
4
+ secret: # ACCESS SECRET
5
+ mode: # 'sandbox' or 'cloudpt'
Binary file
@@ -0,0 +1,208 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Cloudpt::API::Client do
5
+
6
+ before do
7
+ # pending
8
+ @client = Cloudpt::Spec.instance
9
+ end
10
+
11
+ describe "#initialize" do
12
+
13
+ it "has a handle to the connection" do
14
+ @client.connection.should be_an_instance_of(Cloudpt::API::Connection)
15
+ end
16
+
17
+ end
18
+
19
+ describe "#account" do
20
+
21
+ it "retrieves the account object" do
22
+ response = @client.account
23
+ response.should be_an_instance_of(Cloudpt::API::Object)
24
+ end
25
+
26
+ end
27
+
28
+ describe "#find" do
29
+
30
+ before do
31
+ @filename = "#{Cloudpt::Spec.test_dir}/spec-find-file-test-#{Time.now.to_i}.txt"
32
+ @file = @client.upload @filename, "spec file"
33
+
34
+ @dirname = "#{Cloudpt::Spec.test_dir}/spec-find-dir-test-#{Time.now.to_i}"
35
+ @dir = @client.mkdir @dirname
36
+ end
37
+
38
+ it "returns a single file" do
39
+ response = @client.find(@filename)
40
+ response.path.should == @file.path
41
+ response.should be_an_instance_of(Cloudpt::API::File)
42
+ end
43
+
44
+ it "returns a single directory" do
45
+ response = @client.find(@dirname)
46
+ response.path.should == @dir.path
47
+ response.should be_an_instance_of(Cloudpt::API::Dir)
48
+ end
49
+
50
+ end
51
+
52
+ describe "#list" do
53
+ it "lists root" do
54
+ result = @client.list("")
55
+ result.should be_an_instance_of(Array)
56
+ end
57
+ end
58
+
59
+ describe "#ls" do
60
+
61
+ it "returns an array of files and dirs" do
62
+ result = @client.ls
63
+ result.should be_an_instance_of(Array)
64
+ end
65
+
66
+ it "returns a single item array of if we ls a file" do
67
+ result = @client.ls(Cloudpt::Spec.test_dir)
68
+ first_file = result.detect { |f| f.class == Cloudpt::API::File }
69
+ result = @client.ls first_file.path
70
+ result.should be_an_instance_of(Array)
71
+ end
72
+
73
+ end
74
+
75
+ describe "#mkdir" do
76
+
77
+ it "returns an array of files and dirs" do
78
+ dirname = "#{Cloudpt::Spec.test_dir}/test-dir-#{Cloudpt::Spec.namespace}"
79
+ response = @client.mkdir dirname
80
+ response.path.should == dirname
81
+ response.should be_an_instance_of(Cloudpt::API::Dir)
82
+ end
83
+
84
+ it "creates dirs with tricky characters" do
85
+ dirname = "#{Cloudpt::Spec.test_dir}/test-dir |!@\#$%^&*{b}[].;'.,<>?: #{Cloudpt::Spec.namespace}"
86
+ response = @client.mkdir dirname
87
+ response.path.should == dirname.gsub(/[\\\:\?\*\<\>\"\|]+/, '')
88
+ response.should be_an_instance_of(Cloudpt::API::Dir)
89
+ end
90
+
91
+ it "creates dirs with utf8 characters" do
92
+ dirname = "#{Cloudpt::Spec.test_dir}/test-dir łółą #{Cloudpt::Spec.namespace}"
93
+ response = @client.mkdir dirname
94
+ response.path.should == dirname
95
+ response.should be_an_instance_of(Cloudpt::API::Dir)
96
+ end
97
+
98
+ end
99
+
100
+ describe "#upload" do
101
+
102
+ it "puts the file in Cloudpt" do
103
+ filename = "#{Cloudpt::Spec.test_dir}/test-#{Cloudpt::Spec.namespace}.txt"
104
+ response = @client.upload filename, "Some file"
105
+ response.path.should == filename
106
+ response.bytes.should == 9
107
+ end
108
+
109
+ it "uploads the file with tricky characters" do
110
+ filename = "#{Cloudpt::Spec.test_dir}/test ,|!@\#$%^&*{b}[].;'.,<>?:-#{Cloudpt::Spec.namespace}.txt"
111
+ response = @client.upload filename, "Some file"
112
+ response.path.should == filename
113
+ response.bytes.should == 9
114
+ end
115
+
116
+ it "uploads the file with utf8" do
117
+ filename = "#{Cloudpt::Spec.test_dir}/test łołąó-#{Cloudpt::Spec.namespace}.txt"
118
+ response = @client.upload filename, "Some file"
119
+ response.path.should == filename
120
+ response.bytes.should == 9
121
+ end
122
+ end
123
+
124
+ describe "#search" do
125
+
126
+ let(:term) { "searchable-test-#{Cloudpt::Spec.namespace}" }
127
+
128
+ before do
129
+ filename = "#{Cloudpt::Spec.test_dir}/searchable-test-#{Cloudpt::Spec.namespace}.txt"
130
+ @client.upload filename, "Some file"
131
+ end
132
+
133
+ after do
134
+ @response.size.should == 1
135
+ @response.first.class.should == Cloudpt::API::File
136
+ end
137
+
138
+ it "finds a file" do
139
+ @response = @client.search term, :path => "#{Cloudpt::Spec.test_dir}"
140
+ end
141
+
142
+ it "works if leading slash is present in path" do
143
+ @response = @client.search term, :path => "/#{Cloudpt::Spec.test_dir}"
144
+ end
145
+
146
+ end
147
+
148
+ describe "#copy_from_copy_ref" do
149
+
150
+ it "copies a file from a copy_ref" do
151
+ filename = "test/searchable-test-#{Cloudpt::Spec.namespace}.txt"
152
+ @client.upload filename, "Some file"
153
+ response = @client.search "searchable-test-#{Cloudpt::Spec.namespace}", :path => 'test'
154
+ ref = response.first.copy_ref['copy_ref']
155
+ @client.copy_from_copy_ref ref, "#{filename}.copied"
156
+ response = @client.search "searchable-test-#{Cloudpt::Spec.namespace}.txt.copied", :path => 'test'
157
+ response.size.should == 1
158
+ response.first.class.should == Cloudpt::API::File
159
+ end
160
+
161
+ end
162
+
163
+ describe "#download" do
164
+
165
+ it "downloads a file from Cloudpt" do
166
+ @client.upload "#{Cloudpt::Spec.test_dir}/test.txt", "Some file"
167
+ file = @client.download "#{Cloudpt::Spec.test_dir}/test.txt"
168
+ file.should == "Some file"
169
+ end
170
+
171
+ it "raises a 404 when a file is not found in Cloudpt" do
172
+ lambda {
173
+ @client.download "#{Cloudpt::Spec.test_dir}/no.txt"
174
+ }.should raise_error(Cloudpt::API::Error::NotFound)
175
+ end
176
+
177
+ end
178
+
179
+ describe "#delta" do
180
+ it "returns a cursor and list of files" do
181
+ filename = "#{Cloudpt::Spec.test_dir}/delta-test-#{Cloudpt::Spec.namespace}.txt"
182
+ @client.upload filename, 'Some file'
183
+ response = @client.delta
184
+ cursor, files = response.cursor, response.entries
185
+ cursor.should be_an_instance_of(String)
186
+ files.should be_an_instance_of(Array)
187
+ files.last.should be_an_instance_of(Cloudpt::API::File)
188
+ end
189
+
190
+ it "returns the files that have changed since the cursor was made" do
191
+ filename = "#{Cloudpt::Spec.test_dir}/delta-test-#{Cloudpt::Spec.namespace}.txt"
192
+ delete_filename = "#{Cloudpt::Spec.test_dir}/delta-test-delete-#{Cloudpt::Spec.namespace}.txt"
193
+ @client.upload delete_filename, 'Some file'
194
+ response = @client.delta
195
+ cursor, files = response.cursor, response.entries
196
+ files.last.path.should == delete_filename
197
+ files.last.destroy
198
+ @client.upload filename, 'Another file'
199
+ response = @client.delta(cursor)
200
+ cursor, files = response.cursor, response.entries
201
+ files.length.should == 2
202
+ files.first.is_deleted.should == true
203
+ files.first.path.should == delete_filename
204
+ files.last.path.should == filename
205
+ end
206
+ end
207
+
208
+ end
@@ -0,0 +1,82 @@
1
+ require "spec_helper"
2
+
3
+ describe Cloudpt::API::Connection do
4
+
5
+ before do
6
+ @connection = Cloudpt::API::Connection.new(:token => Cloudpt::Spec.token,
7
+ :secret => Cloudpt::Spec.secret)
8
+ end
9
+
10
+ describe "#request" do
11
+
12
+ it "returns a parsed response when the response is a 200" do
13
+ response = mock :code => 200, :body => '{ "a":1}'
14
+ response = @connection.request { response }
15
+ response.should be_an_instance_of(Hash)
16
+ end
17
+
18
+ it "raises a Cloudpt::API::Error::Unauthorized when the response is a 401" do
19
+ response = mock :code => 401, :body => '{ "a":1}'
20
+ lambda do
21
+ @connection.request { response }
22
+ end.should raise_error(Cloudpt::API::Error::Unauthorized)
23
+ end
24
+
25
+ it "raises a Cloudpt::API::Error::Forbidden when the response is a 403" do
26
+ response = mock :code => 403, :body => '{ "a":1}'
27
+ lambda do
28
+ @connection.request { response }
29
+ end.should raise_error(Cloudpt::API::Error::Forbidden)
30
+ end
31
+
32
+ it "raises a Cloudpt::API::Error::NotFound when the response is a 404" do
33
+ response = mock :code => 404, :body => '{ "a":1}'
34
+ lambda do
35
+ @connection.request { response }
36
+ end.should raise_error(Cloudpt::API::Error::NotFound)
37
+ end
38
+
39
+ it "raises a Cloudpt::API::Error when the response is a 3xx" do
40
+ response = mock :code => 301, :body => '{ "a":1}'
41
+ lambda do
42
+ @connection.request { response }
43
+ end.should raise_error(Cloudpt::API::Error::Redirect)
44
+ end
45
+
46
+ it "raises a Cloudpt::API::Error when the response is a 5xx" do
47
+ response = mock :code => 500, :body => '{ "a":1}'
48
+ lambda do
49
+ @connection.request { response }
50
+ end.should raise_error(Cloudpt::API::Error)
51
+ end
52
+
53
+ it "raises a Cloudpt::API::Error when the response is a 400" do
54
+ response = mock :code => 400, :body => '{ "error": "bad request" }'
55
+ lambda do
56
+ @connection.request { response }
57
+ end.should raise_error(Cloudpt::API::Error)
58
+ end
59
+
60
+ it "raises a Cloudpt::API::Error when the response is a 406" do
61
+ response = mock :code => 406, :body => '{ "error": "bad request" }'
62
+ lambda do
63
+ @connection.request { response }
64
+ end.should raise_error(Cloudpt::API::Error)
65
+ end
66
+
67
+ it "returns the raw response if :raw => true is provided" do
68
+ response = mock :code => 200, :body => '{ "something": "more" }'
69
+ response = @connection.request(:raw => true) { response }
70
+ response.should == '{ "something": "more" }'
71
+ end
72
+
73
+ end
74
+
75
+ describe "#consumer" do
76
+
77
+ it "returns an appropriate consumer object" do
78
+ @connection.consumer(:main).should be_a(::OAuth::Consumer)
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,44 @@
1
+ require "spec_helper"
2
+
3
+ describe Cloudpt::API::Dir do
4
+
5
+ before do
6
+ @client = Cloudpt::Spec.instance
7
+ @dirname = "#{Cloudpt::Spec.test_dir}/spec-dir-test-#{Time.now.to_i}"
8
+ @dir = @client.mkdir @dirname
9
+ end
10
+
11
+ after do
12
+ # @dir.delete
13
+ end
14
+
15
+ describe "#copy" do
16
+
17
+ it "copies the dir properly" do
18
+ new_dirname = @dirname + "-copied"
19
+ @dir.copy new_dirname
20
+ @dir.path.should == new_dirname
21
+ end
22
+
23
+ end
24
+
25
+ describe "#move" do
26
+
27
+ it "moves the dir properly" do
28
+ new_dirname = @dirname + "-copied"
29
+ @dir.move new_dirname
30
+ @dir.path.should == new_dirname
31
+ end
32
+
33
+ end
34
+
35
+ describe "#destroy" do
36
+
37
+ it "destroys the dir properly" do
38
+ @dir.destroy
39
+ @dir.is_deleted.should == true
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,126 @@
1
+ require "spec_helper"
2
+
3
+ describe Cloudpt::API::File do
4
+
5
+ before do
6
+ @client = Cloudpt::Spec.instance
7
+ @filename = "#{Cloudpt::Spec.test_dir}/spec-test-#{Time.now.to_i}.txt"
8
+ @file = @client.upload @filename, "spec file"
9
+ end
10
+
11
+ after do
12
+ # @file.delete
13
+ end
14
+
15
+ describe "#copy" do
16
+
17
+ it "copies the file properly" do
18
+ new_filename = @filename + ".copied"
19
+ @file.copy new_filename
20
+ @file.path.should == new_filename
21
+ end
22
+
23
+ end
24
+
25
+ describe "#move" do
26
+
27
+ it "moves the file properly" do
28
+ new_filename = @filename + ".copied"
29
+ @file.move new_filename
30
+ @file.path.should == new_filename
31
+ end
32
+
33
+ end
34
+
35
+ describe "#destroy" do
36
+
37
+ it "destroys the file properly" do
38
+ @file.destroy
39
+ @file.is_deleted.should == true
40
+ end
41
+
42
+ end
43
+
44
+ describe "#revisions" do
45
+
46
+ it "retrieves all revisions as an Array of File objects" do
47
+ @client.upload @file.path, "Updated content"
48
+
49
+ revisions = @file.revisions
50
+ revisions.size.should == 2
51
+ revisions.collect { |f| f.class }.should == [Cloudpt::API::File, Cloudpt::API::File]
52
+ end
53
+
54
+ end
55
+
56
+ describe "#restore" do
57
+
58
+ it "restores the file to a specific revision" do
59
+ old_rev = @file.rev
60
+
61
+ @client.upload @file.path, "Updated content"
62
+
63
+ file = @filename.split('/').last
64
+
65
+ found = @client.find(@file.path)
66
+
67
+ found.rev.should_not == old_rev
68
+
69
+ newer_rev = found.rev
70
+
71
+ @file.restore(old_rev)
72
+
73
+ found = @client.find(@file.path)
74
+
75
+ found.rev.should_not == old_rev
76
+ found.rev.should_not == newer_rev
77
+
78
+ end
79
+
80
+ end
81
+
82
+ describe "#share_url" do
83
+
84
+ it "returns an Url object" do
85
+
86
+ result = @file.share_url
87
+ result.should be_an_instance_of(Cloudpt::API::Object)
88
+ result.keys.sort.should == ['expires', 'url']
89
+
90
+ end
91
+
92
+ end
93
+
94
+ describe "#copy_ref" do
95
+
96
+ it "returns a copy_ref object" do
97
+
98
+ result = @file.copy_ref
99
+ result.should be_an_instance_of(Cloudpt::API::Object)
100
+ result.keys.sort.should == ['copy_ref', 'expires']
101
+
102
+ end
103
+
104
+ end
105
+
106
+ describe "#direct_url" do
107
+
108
+ it "returns an Url object" do
109
+
110
+ result = @file.direct_url
111
+ result.should be_an_instance_of(Cloudpt::API::Object)
112
+ result.keys.sort.should == ['expires', 'url']
113
+
114
+ end
115
+
116
+ end
117
+
118
+ describe "#download" do
119
+
120
+ it "should download the file" do
121
+ @file.download.should == 'spec file'
122
+ end
123
+
124
+ end
125
+
126
+ end