fake_dropbox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) 2011 Juliusz Gonera
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8
+
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ fake_dropbox
2
+ ============
3
+
4
+ fake_dropbox is a simple fake implementation of the Dropbox API written in Ruby
5
+ using the Sinatra framework. It can be used for developing and testing
6
+ applications that use Dropbox. There are no real authentication and users (you
7
+ are always authenticated), the server stores files on the local machine.
8
+
9
+ Can be used either as a standalone app listening on a port or intercept calls to
10
+ the real Dropbox in Ruby apps.
11
+
12
+ It partially implements [version 0](https://www.dropbox.com/developers/reference/oldapi)
13
+ of the Dropbox API which should be compatible with [version 1](https://www.dropbox.com/developers/reference/api).
14
+ If you find it useful and want to add support for more features, go ahead ;)
15
+
16
+
17
+ Installation
18
+ ------------
19
+
20
+ Using RubyGems:
21
+
22
+ gem install fake_dropbox
23
+
24
+ To get the latest development version just clone the repository:
25
+
26
+ git clone git://github.com/jgonera/fake_dropbox.git
27
+ cd fake_dropbox
28
+ gem install bundler
29
+ bundle install
30
+
31
+ Then, if you want to install it as a gem:
32
+
33
+ rake install
34
+
35
+
36
+ How to use
37
+ ----------
38
+
39
+ ### Running the server
40
+
41
+ If you installed fake_dropbox as a gem, you should be able to run:
42
+
43
+ DROPBOX_DIR=/home/joe/somedir fake_dropbox [PORT]
44
+
45
+ You have to specify an environment variable `DROPBOX_DIR` which will point the
46
+ server to the directory on which the fake API should operate. Additionally, you
47
+ can specify a custom port (default is 4321).
48
+
49
+ ### Intercepting requests in Ruby apps
50
+
51
+ You can also use this gem to intercept requests to Dropbox in your Ruby app,
52
+ without modifying any of its code or specifying a custom host or port. This
53
+ is achieved by using the [WebMock](https://github.com/bblimke/webmock) library.
54
+
55
+ The class responsible for this is `FakeDropbox::Glue`. To intercept requests to
56
+ the real Dropbox, just instantiate this class in your code:
57
+
58
+ fake_dropbox = FakeDropbox::Glue.new
59
+
60
+ You can provide an optional argument to the constructor, pointing to the
61
+ directory you want to use for your fake Dropbox:
62
+
63
+ fake_dropbox = FakeDropbox::Glue.new('/home/joe/somedir')
64
+
65
+ If you don't provide it, a temporary directory will be created in the system's
66
+ temporary path.
67
+
68
+ Moreover:
69
+
70
+ * `#dropbox_dir` returns the fake Dropbox directory.
71
+ * `#empty!` deletes everything in the `dropbox_dir` *recursively*.
72
+ Even though it should work only if the `dropbox_dir` resides inside the system's
73
+ temporary path, you should use it with caution.
74
+
75
+ A support file for Cucumber tests could look like this:
76
+
77
+ require 'fake_dropbox'
78
+
79
+ fake_dropbox = FakeDropbox::Glue.new
80
+
81
+ After do
82
+ fake_dropbox.empty!
83
+ end
84
+
85
+ ### Using without installing as a gem
86
+
87
+ If you cloned the repository and you don't want to install fake_dropbox as a
88
+ gem, you can run it using `rackup` while in the fake_dropbox directory:
89
+
90
+ DROPBOX_DIR=/home/joe/somedir rackup
91
+
92
+
93
+ Copyright
94
+ ---------
95
+
96
+ Copyright © 2011 Juliusz Gonera. fake_dropbox is released under the MIT license, see LICENSE for details.
97
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/fake_dropbox ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
3
+
4
+ if not ENV.include? 'DROPBOX_DIR'
5
+ puts "You have to specify the DROPBOX_DIR in ENV, e.g."
6
+ puts "DROPBOX_DIR=/home/joe/somedir"
7
+ exit
8
+ end
9
+
10
+ require 'rack'
11
+ require 'fake_dropbox/server'
12
+
13
+ Rack::Server.start(app: FakeDropbox::Server, Port: ARGV[0] || 4321)
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
2
+ require 'fake_dropbox/server'
3
+ run FakeDropbox::Server
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+ require "fake_dropbox/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fake_dropbox"
7
+ s.version = FakeDropbox::VERSION
8
+ s.authors = ["Juliusz Gonera"]
9
+ s.email = ["jgonera@gmail.com"]
10
+ s.homepage = "https://github.com/jgonera/fake_dropbox"
11
+ s.summary = %q{A simple fake implementation of the Dropbox API}
12
+ s.description = %q{Written in Ruby using the Sinatra framework. For development and testing purposes, no real authentication and users, stores files on the local machine. Can be used either as a standalone app listening on a port or intercept calls to the real Dropbox in Ruby apps.}
13
+
14
+ s.rubyforge_project = "fake_dropbox"
15
+ s.extra_rdoc_files = ['README.md', 'LICENSE']
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'sinatra', '~> 1.2.6'
23
+ s.add_dependency 'json', '~> 1.6.1'
24
+ s.add_dependency 'rack', '~> 1.3.2'
25
+ s.add_dependency 'rack-test', '~> 0.6.1'
26
+ s.add_dependency 'webmock', '~> 1.7.7'
27
+
28
+ s.add_development_dependency 'rspec', '~> 2.7.0'
29
+ end
@@ -0,0 +1,33 @@
1
+ require 'webmock'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+ require 'fake_dropbox/server'
5
+
6
+ module FakeDropbox
7
+ class Glue
8
+ attr_accessor :dropbox_dir
9
+
10
+ def initialize(dropbox_dir=ENV['DROPBOX_DIR'])
11
+ if dropbox_dir
12
+ raise "Directory #{dropbox_dir} doesn't exist!" unless File.exists? dropbox_dir
13
+ @dropbox_dir = dropbox_dir
14
+ else
15
+ @dropbox_dir = File.join(Dir.tmpdir, 'fake_dropbox')
16
+ Dir.mkdir(@dropbox_dir) unless File.exists? @dropbox_dir
17
+ end
18
+
19
+ ENV['DROPBOX_DIR'] = @dropbox_dir
20
+ WebMock.stub_request(:any, /.*dropbox.com.*/).to_rack(FakeDropbox::Server)
21
+ end
22
+
23
+ def empty!
24
+ if File.expand_path(@dropbox_dir).start_with? Dir.tmpdir
25
+ Dir.glob(File.join(@dropbox_dir, '*')).each do |entry|
26
+ FileUtils.remove_entry_secure entry
27
+ end
28
+ else
29
+ raise "Will not empty a directory which is outside of system's temporary path!"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,83 @@
1
+ require 'sinatra/base'
2
+ require 'json'
3
+ require 'fileutils'
4
+ require 'fake_dropbox/utils'
5
+
6
+ module FakeDropbox
7
+ class Server < Sinatra::Base
8
+ before do
9
+ if not request.path.start_with?('/__sinatra__')
10
+ @dropbox_dir = env['DROPBOX_DIR'] || ENV['DROPBOX_DIR']
11
+ raise 'no DROPBOX_DIR in ENV' if not @dropbox_dir
12
+ end
13
+ end
14
+
15
+ helpers FakeDropbox::Utils
16
+
17
+ not_found do
18
+ # only catch 404 not returned by the API
19
+ if request.env['sinatra.error'].class == Sinatra::NotFound
20
+ puts "[fake_dropbox] Unknown URI: #{request.request_method} #{request.path}"
21
+ "Unknown URI: #{request.request_method} #{request.path}"
22
+ end
23
+ end
24
+
25
+ post '/:version/oauth/request_token' do
26
+ 'oauth_token_secret=fake&oauth_token=fake'
27
+ end
28
+
29
+ post '/:version/oauth/access_token' do
30
+ 'oauth_token_secret=fake&oauth_token=fake'
31
+ end
32
+
33
+ post '/:version/files/:mode*' do
34
+ dir = File.join(@dropbox_dir, params[:splat])
35
+ return status 404 unless File.exists?(dir) and File.directory?(dir)
36
+
37
+ tempfile = params[:file][:tempfile]
38
+ filename = params[:file][:filename]
39
+ file_path = File.join(params[:splat], filename)
40
+ FileUtils.cp(tempfile.path, File.join(@dropbox_dir, file_path))
41
+ File.delete(tempfile.path) if File.exists? tempfile.path
42
+
43
+ content_type :json
44
+ metadata(file_path).to_json
45
+ end
46
+
47
+ get '/:version/files/:mode*' do
48
+ file_path = File.join(@dropbox_dir, params[:splat])
49
+ return status 404 unless File.exists?(file_path)
50
+
51
+ IO.read(file_path)
52
+ end
53
+
54
+ get '/:version/metadata/:mode*' do
55
+ content_type :json
56
+ metadata(params[:splat][0], params['list'] == 'true').to_json
57
+ end
58
+
59
+ post '/:version/fileops/create_folder' do
60
+ dir = params[:path]
61
+ dir_path = File.join(@dropbox_dir, dir)
62
+
63
+ return status 400 unless ['dropbox', 'sandbox'].include? params[:root]
64
+ return status 403 if File.exists?(dir_path)
65
+ # seems that directories are created recursively (API docs wrong?)
66
+ #return status 404 unless File.exists?(File.dirname(dir_path))
67
+
68
+ FileUtils.mkdir_p dir_path
69
+
70
+ content_type :json
71
+ metadata(dir).to_json
72
+ end
73
+
74
+ post '/:version/fileops/delete' do
75
+ entry = safe_path(params[:path])
76
+ entry_path = File.join(@dropbox_dir, entry)
77
+
78
+ return status 404 unless File.exists?(entry_path)
79
+
80
+ FileUtils.remove_entry_secure entry_path
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,40 @@
1
+ module FakeDropbox
2
+ module Utils
3
+ DATE_FORMAT = '%a, %d %b %Y %H:%M:%S %z'
4
+
5
+ def metadata(path, list=false)
6
+ full_path = File.join(@dropbox_dir, path)
7
+ path.insert(0, '/') if path[0] != '/'
8
+ bytes = File.directory?(path) ? 0 : File.size(full_path)
9
+
10
+ metadata = {
11
+ thumb_exists: false,
12
+ bytes: bytes,
13
+ modified: File.mtime(full_path).strftime(DATE_FORMAT),
14
+ path: path,
15
+ is_dir: File.directory?(full_path),
16
+ size: "#{bytes} bytes",
17
+ root: "dropbox"
18
+ }
19
+
20
+ if File.directory?(full_path)
21
+ metadata[:icon] = "folder"
22
+
23
+ if list
24
+ entries = Dir.entries(full_path).reject { |x| ['.', '..'].include? x }
25
+ metadata[:contents] = entries.map do |entry|
26
+ metadata(File.join(path, entry))
27
+ end
28
+ end
29
+ else
30
+ metadata[:icon] = "page_white"
31
+ end
32
+
33
+ metadata
34
+ end
35
+
36
+ def safe_path(path)
37
+ path.gsub(/(\.\.\/|\/\.\.)/, '')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module FakeDropbox
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "fake_dropbox/version"
2
+ require 'fake_dropbox/glue'
3
+ require 'fake_dropbox/utils'
4
+ require 'fake_dropbox/server'
5
+
@@ -0,0 +1 @@
1
+ Hello, I'm a test file
data/spec/glue_spec.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe "FakeDropbox::Glue" do
4
+ let(:stub_request) { double('stub_request').as_null_object }
5
+
6
+ before do
7
+ ENV.delete('DROPBOX_DIR')
8
+ Dir.stub(:tmpdir).and_return('/tmp')
9
+ File.stub(:exists?).and_return(true)
10
+ WebMock.stub(:stub_request).and_return(stub_request)
11
+ end
12
+
13
+ describe ".new" do
14
+ it "stubs the Dropbox requests with WebMock" do
15
+ WebMock.should_receive(:stub_request)
16
+ stub_request.should_receive(:to_rack)
17
+ FakeDropbox::Glue.new('/tmp/somethingnonexistant')
18
+ end
19
+
20
+ context "when invoked with an argument" do
21
+ it "sets the dropbox_dir" do
22
+ glue = FakeDropbox::Glue.new('/tmp/somethingnonexistant')
23
+ glue.dropbox_dir.should == '/tmp/somethingnonexistant'
24
+ ENV['DROPBOX_DIR'].should == glue.dropbox_dir
25
+ end
26
+ end
27
+
28
+ context "when invoked with no arguments" do
29
+ it "creates dropbox_dir in system temp path" do
30
+ glue = FakeDropbox::Glue.new
31
+ glue.dropbox_dir.should == '/tmp/fake_dropbox'
32
+ ENV['DROPBOX_DIR'].should == glue.dropbox_dir
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#empty!" do
38
+ context "when dropbox_dir is in temp path" do
39
+ subject { FakeDropbox::Glue.new('/tmp/somethingnonexistant') }
40
+
41
+ it "deletes the dropbox_dir and all its contents" do
42
+ Dir.should_receive(:glob).with('/tmp/somethingnonexistant/*').and_return(['sth'])
43
+ FileUtils.should_receive(:remove_entry_secure).with('sth')
44
+ subject.empty!
45
+ end
46
+ end
47
+
48
+ shared_examples_for "dangerous" do
49
+ it "does not delete the dropbox_dir" do
50
+ FileUtils.should_not_receive(:remove_entry_secure)
51
+ begin
52
+ subject.empty!
53
+ rescue
54
+ end
55
+ end
56
+
57
+ it "raises an exception" do
58
+ lambda { subject.empty! }.should raise_error
59
+ end
60
+ end
61
+
62
+ context "when dropbox_dir is not in temp path" do
63
+ subject { FakeDropbox::Glue.new('/sth') }
64
+ it_behaves_like "dangerous"
65
+ end
66
+
67
+ context "when dropbox_dir is not in temp path and is not absolute" do
68
+ subject { FakeDropbox::Glue.new('/tmp/../somethingnonexistant') }
69
+ it_behaves_like "dangerous"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'FakeDropbox::Server' do
4
+ before do
5
+ @tmpdir = Dir.mktmpdir 'fake_dropbox-test'
6
+ @env = { 'DROPBOX_DIR' => @tmpdir }
7
+ end
8
+
9
+ after do
10
+ FileUtils.remove_entry_secure @tmpdir
11
+ end
12
+
13
+ describe "POST /<version>/oauth/request_token" do
14
+ it "returns a fake OAuth request token" do
15
+ post "/0/oauth/request_token", {}, @env
16
+ #File.open('/home/julas/Desktop/aaa.html', 'w') {|f| f.write(last_response.body) }
17
+ last_response.should be_ok
18
+ last_response.body.should include 'oauth_token=', 'oauth_token_secret='
19
+ end
20
+ end
21
+
22
+ describe "POST /<version>/oauth/access_token" do
23
+ it "returns a fake OAuth access token" do
24
+ post "/0/oauth/access_token", {}, @env
25
+ last_response.should be_ok
26
+ last_response.body.should include 'oauth_token=', 'oauth_token_secret='
27
+ end
28
+ end
29
+
30
+ describe "POST /<version>/files/dropbox/<path>" do
31
+ let(:uploaded_file) { Rack::Test::UploadedFile.new(fixture_path('dummy.txt')) }
32
+ let(:params) { { file: uploaded_file } }
33
+
34
+ shared_examples_for "correct upload" do
35
+ it "saves the file in the directory" do
36
+ post "/0/files/dropbox" + path, params, @env
37
+ Dir.entries(dir).should include 'dummy.txt'
38
+ original_content = File.new(fixture_path('dummy.txt')).read
39
+ uploaded_content = File.new(File.join(dir, 'dummy.txt')).read
40
+ uploaded_content.should == original_content
41
+ end
42
+
43
+ it "deletes the temporary file (RackMultipart*)" do
44
+ post "/0/files/dropbox" + path, params, @env
45
+ tempfile = last_request.params['file'][:tempfile]
46
+ File.exists?(tempfile.path).should == false
47
+ end
48
+
49
+ it "returns file metadata" do
50
+ post "/0/files/dropbox" + path, params, @env
51
+ last_response.should be_ok
52
+ metadata = JSON.parse(last_response.body)
53
+ metadata['path'].should == path + '/dummy.txt'
54
+ metadata['modified'].should include Time.new.strftime('%a, %d %b %Y %H:%M')
55
+ end
56
+ end
57
+
58
+ context "when the path is root" do
59
+ let (:path) { '' }
60
+ let (:dir) { @tmpdir }
61
+
62
+ it_behaves_like "correct upload"
63
+ end
64
+
65
+ context "when the path is not root" do
66
+ context "when the path exists" do
67
+ let (:path) { '/somedir' }
68
+ let (:dir) { File.join(@tmpdir, path) }
69
+ before { Dir.mkdir(dir) }
70
+
71
+ it_behaves_like "correct upload"
72
+ end
73
+
74
+ context "when the path does not exist" do
75
+ it "returns error 404" do
76
+ post "/0/files/dropbox/incorrect", params, @env
77
+ last_response.status.should == 404
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "GET /<version>/files/dropbox/<path>" do
84
+ context "when the file exists" do
85
+ before do
86
+ File.open(File.join(@tmpdir, 'file.ext'), 'w') do |f|
87
+ f.write "This is a test."
88
+ end
89
+ end
90
+
91
+ it "returns file contents" do
92
+ get "/0/files/dropbox/file.ext", {}, @env
93
+ last_response.should be_ok
94
+ last_response.body.should == "This is a test."
95
+ end
96
+ end
97
+
98
+ context "when the file does not exist" do
99
+ it "returns error 404" do
100
+ get "/0/files/dropbox/none.ext", {}, @env
101
+ last_response.status.should == 404
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "GET /<version>/metadata/dropbox/<path>" do
107
+ it "returns metadata" do
108
+ File.open(File.join(@tmpdir, 'file.ext'), 'w')
109
+ get "/0/metadata/dropbox/file.ext", {}, @env
110
+ last_response.should be_ok
111
+ metadata = JSON.parse(last_response.body)
112
+ metadata['path'].should == '/file.ext'
113
+ metadata.should_not include 'contents'
114
+ end
115
+
116
+ context "when the path is a directory and want a list" do
117
+ it "returns its children metadata too" do
118
+ FileUtils.cp(fixture_path('dummy.txt'), @tmpdir)
119
+ get "/0/metadata/dropbox", {list: 'true'}, @env
120
+ metadata = JSON.parse(last_response.body)
121
+ metadata.should include 'contents'
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "POST /<version>/fileops/create_folder" do
127
+ shared_examples_for "creating folder" do
128
+ let(:params) { { path: path, root: 'dropbox' } }
129
+
130
+ it "creates a folder" do
131
+ post "/0/fileops/create_folder", params, @env
132
+ File.exists?(File.join(@tmpdir, path)).should == true
133
+ File.directory?(File.join(@tmpdir, path)).should == true
134
+ end
135
+
136
+ it "returns folder's metadata" do
137
+ metadata = post "/0/fileops/create_folder", params, @env
138
+ last_response.should be_ok
139
+ metadata = JSON.parse(last_response.body)
140
+ metadata['path'].should == path
141
+ end
142
+ end
143
+
144
+ context "when the path to the folder exists" do
145
+ let(:path) { '/somedir' }
146
+
147
+ it_behaves_like "creating folder"
148
+ end
149
+
150
+ context "when the path to the folder does not exist" do
151
+ let(:path) { '/nonexistant/somedir' }
152
+
153
+ it_behaves_like "creating folder"
154
+ end
155
+
156
+ context "when the root is neither 'dropbox' nor 'sandbox'" do
157
+ let(:params) { { path: '/somedir', root: 'wrong' } }
158
+
159
+ it "returns error 400" do
160
+ post "/0/fileops/create_folder", params, @env
161
+ last_response.status.should == 400
162
+ end
163
+ end
164
+
165
+ # seems that directories are created recursively (API docs wrong?)
166
+ # context "when the path to the folder does not exist" do
167
+ # let(:params) { { path: '/nonexistant/somedir', root: 'dropbox' } }
168
+ #
169
+ # it "returns error 404" do
170
+ # post "/0/fileops/create_folder", params, @env
171
+ # last_response.status.should == 404
172
+ # end
173
+ # end
174
+
175
+ context "when the path already exists" do
176
+ let(:params) { { path: '/somedir', root: 'dropbox' } }
177
+ before { Dir.mkdir(File.join(@tmpdir, 'somedir')) }
178
+
179
+ it "returns error 403" do
180
+ post "/0/fileops/create_folder", params, @env
181
+ last_response.status.should == 403
182
+ end
183
+ end
184
+ end
185
+
186
+ describe "POST /<version>/fileops/delete" do
187
+ let(:params) { { path: '/file.ext', root: 'dropbox' } }
188
+
189
+ context "when the path exists" do
190
+
191
+ shared_examples_for "deleting entry" do
192
+ it "removes the entry" do
193
+ post '/0/fileops/delete', params, @env
194
+ last_response.should be_ok
195
+ File.exists?(abs_path).should == false
196
+ end
197
+ end
198
+
199
+ context "when it's a non-empty directory" do
200
+ let(:params) { { path: '/somedir', root: 'dropbox' } }
201
+ let(:abs_path) { File.join(@tmpdir, params[:path]) }
202
+ before do
203
+ Dir.mkdir(abs_path)
204
+ File.open(File.join(abs_path, 'file.ext'), 'w') { |f| f.write "Test file" }
205
+ end
206
+
207
+ it_behaves_like "deleting entry"
208
+ end
209
+
210
+ context "when it's not a non-empty directory" do
211
+ let(:params) { { path: '/file.ext', root: 'dropbox' } }
212
+ let(:abs_path) { File.join(@tmpdir, params[:path]) }
213
+ before { File.open(abs_path, 'w') { |f| f.write "Test file" } }
214
+
215
+ it_behaves_like "deleting entry"
216
+ end
217
+
218
+ end
219
+
220
+ context "when the path doesn't exist" do
221
+ let(:params) { { path: '/nonexistant.ext', root: 'dropbox' } }
222
+
223
+ it "returns error 404" do
224
+ post '/0/fileops/delete', params, @env
225
+ last_response.status.should == 404
226
+ end
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,37 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rack/test'
4
+ require 'fake_dropbox'
5
+ require 'tmpdir'
6
+ require 'fileutils'
7
+
8
+ module TestHelpers
9
+ def fixture_path(filename='')
10
+ File.join(File.dirname(__FILE__), 'fixtures', filename)
11
+ end
12
+ end
13
+
14
+ RSpec.configure do |conf|
15
+ conf.include Rack::Test::Methods
16
+ conf.include TestHelpers
17
+ end
18
+
19
+ # ugly hack to show app errors when running rspec ;)
20
+ module FakeDropbox
21
+ class Server
22
+ configure :test do
23
+ disable :raise_errors
24
+ end
25
+
26
+ error do
27
+ e = env['sinatra.error']
28
+ puts e.to_s
29
+ puts e.backtrace.join("\n")
30
+ end
31
+ end
32
+ end
33
+
34
+ def app
35
+ FakeDropbox::Server
36
+ end
37
+
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ class DummyClass
4
+ include FakeDropbox::Utils
5
+
6
+ def initialize(dropbox_dir)
7
+ @dropbox_dir = dropbox_dir
8
+ end
9
+ end
10
+
11
+ describe 'FakeDropbox::Utils' do
12
+ subject { DummyClass.new(fixture_path) }
13
+
14
+ describe "#metadata" do
15
+ it "returns correct metadata" do
16
+ metadata = subject.metadata('/')
17
+ metadata.should include :thumb_exists, :bytes, :modified, :path,
18
+ :is_dir, :size, :root, :icon
19
+ end
20
+
21
+ context "when path is a file" do
22
+ it "returns file metadata" do
23
+ file_path = fixture_path('dummy.txt')
24
+ metadata = subject.metadata('dummy.txt')
25
+ metadata.should_not include :contents
26
+ metadata[:is_dir].should == false
27
+ metadata[:bytes].should == File.size(file_path)
28
+ metadata[:path].should == '/dummy.txt'
29
+ metadata[:modified].should == File.mtime(file_path).strftime(FakeDropbox::Utils::DATE_FORMAT)
30
+ end
31
+ end
32
+
33
+ context "when path is a dir" do
34
+ it "returns dir metadata" do
35
+ metadata = subject.metadata('/')
36
+ metadata[:is_dir].should == true
37
+ metadata[:bytes].should == 0
38
+ metadata[:path].should == '/'
39
+ metadata[:modified].should == File.mtime(fixture_path).strftime(FakeDropbox::Utils::DATE_FORMAT)
40
+ end
41
+
42
+ context "when list is true" do
43
+ it "returns the metadata of all its children too" do
44
+ metadata = subject.metadata('/', true)
45
+ metadata.should include :contents
46
+ metadata[:contents][0].should == subject.metadata('dummy.txt')
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#safe_path" do
53
+ it "returns a safe path" do
54
+ subject.safe_path('../aa/../bb/..').should == 'aa/bb'
55
+ end
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fake_dropbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Juliusz Gonera
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-27 00:00:00.000000000 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ requirement: &16756060 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.6
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *16756060
26
+ - !ruby/object:Gem::Dependency
27
+ name: json
28
+ requirement: &16787980 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *16787980
37
+ - !ruby/object:Gem::Dependency
38
+ name: rack
39
+ requirement: &16787520 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.3.2
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *16787520
48
+ - !ruby/object:Gem::Dependency
49
+ name: rack-test
50
+ requirement: &16787060 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.6.1
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *16787060
59
+ - !ruby/object:Gem::Dependency
60
+ name: webmock
61
+ requirement: &16786600 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 1.7.7
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *16786600
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: &16786140 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.7.0
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *16786140
81
+ description: Written in Ruby using the Sinatra framework. For development and testing
82
+ purposes, no real authentication and users, stores files on the local machine. Can
83
+ be used either as a standalone app listening on a port or intercept calls to the
84
+ real Dropbox in Ruby apps.
85
+ email:
86
+ - jgonera@gmail.com
87
+ executables:
88
+ - fake_dropbox
89
+ extensions: []
90
+ extra_rdoc_files:
91
+ - README.md
92
+ - LICENSE
93
+ files:
94
+ - .gitignore
95
+ - .rspec
96
+ - Gemfile
97
+ - LICENSE
98
+ - README.md
99
+ - Rakefile
100
+ - bin/fake_dropbox
101
+ - config.ru
102
+ - fake_dropbox.gemspec
103
+ - lib/fake_dropbox.rb
104
+ - lib/fake_dropbox/glue.rb
105
+ - lib/fake_dropbox/server.rb
106
+ - lib/fake_dropbox/utils.rb
107
+ - lib/fake_dropbox/version.rb
108
+ - spec/fixtures/dummy.txt
109
+ - spec/glue_spec.rb
110
+ - spec/server_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/utils_spec.rb
113
+ has_rdoc: true
114
+ homepage: https://github.com/jgonera/fake_dropbox
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project: fake_dropbox
134
+ rubygems_version: 1.6.2
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: A simple fake implementation of the Dropbox API
138
+ test_files: []