browse-everything 0.16.1 → 1.0.0.rc1
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +3 -0
- data/CODE_OF_CONDUCT.md +36 -0
- data/CONTRIBUTING.md +21 -19
- data/Gemfile +1 -0
- data/README.md +29 -9
- data/SUPPORT.md +5 -0
- data/app/controllers/browse_everything_controller.rb +7 -3
- data/app/views/browse_everything/_files.html.erb +14 -6
- data/app/views/browse_everything/index.html.erb +7 -1
- data/browse-everything.gemspec +5 -5
- data/lib/browse_everything/driver/base.rb +1 -1
- data/lib/browse_everything/driver/box.rb +4 -14
- data/lib/browse_everything/driver/dropbox.rb +34 -11
- data/lib/browse_everything/driver/google_drive.rb +2 -2
- data/lib/browse_everything/driver/s3.rb +8 -14
- data/lib/browse_everything/retriever.rb +4 -5
- data/lib/browse_everything/version.rb +1 -1
- data/lib/generators/browse_everything/templates/browse_everything_providers.yml.example +2 -2
- data/spec/controllers/browse_everything_controller_spec.rb +8 -1
- data/spec/lib/browse_everything/driver/box_spec.rb +114 -34
- data/spec/lib/browse_everything/driver/dropbox_spec.rb +53 -5
- data/spec/lib/browse_everything/driver/google_drive_spec.rb +41 -4
- data/spec/lib/browse_everything/driver/s3_spec.rb +27 -18
- data/spec/lib/browse_everything/retriever_spec.rb +65 -2
- data/spec/spec_helper.rb +4 -9
- data/spec/support/capybara.rb +14 -10
- metadata +31 -37
- data/spec/fixtures/vcr_cassettes/box.yml +0 -498
- data/spec/fixtures/vcr_cassettes/dropbox.yml +0 -282
- data/spec/fixtures/vcr_cassettes/google_drive.yml +0 -331
- data/spec/fixtures/vcr_cassettes/retriever.yml +0 -170
@@ -120,7 +120,7 @@ module BrowseEverything
|
|
120
120
|
|
121
121
|
# Provides a URL for authorizing against Google Drive
|
122
122
|
# @return [String] the URL
|
123
|
-
def auth_link
|
123
|
+
def auth_link(*_args)
|
124
124
|
Addressable::URI.parse(authorizer.get_authorization_url)
|
125
125
|
end
|
126
126
|
|
@@ -175,7 +175,7 @@ module BrowseEverything
|
|
175
175
|
# @param params [Hash] HTTP response passed to the OAuth callback
|
176
176
|
# @param _data [Object,nil] an unused parameter
|
177
177
|
# @return [String] a new access token
|
178
|
-
def connect(params, _data)
|
178
|
+
def connect(params, _data, _url_options)
|
179
179
|
@code = params[:code]
|
180
180
|
authorize!
|
181
181
|
end
|
@@ -8,7 +8,7 @@ module BrowseEverything
|
|
8
8
|
class S3 < Base
|
9
9
|
DEFAULTS = { response_type: :signed_url, expires_in: 14400 }.freeze
|
10
10
|
RESPONSE_TYPES = %i[signed_url public_url s3_uri].freeze
|
11
|
-
CONFIG_KEYS = %i[bucket].freeze
|
11
|
+
CONFIG_KEYS = %i[bucket region].freeze
|
12
12
|
|
13
13
|
class << self
|
14
14
|
attr_accessor :authentication_klass
|
@@ -21,9 +21,10 @@ module BrowseEverything
|
|
21
21
|
attr_reader :entries
|
22
22
|
|
23
23
|
def initialize(config, *args)
|
24
|
-
if config.key?(:signed_url)
|
25
|
-
warn '[DEPRECATION] Amazon S3 driver: `:signed_url` is deprecated. Please use
|
26
|
-
|
24
|
+
if config.key?(:signed_url)
|
25
|
+
warn '[DEPRECATION] Amazon S3 driver: `:signed_url` is deprecated. Please use `response_type :signed_url` instead.'
|
26
|
+
response_type = config.delete(:signed_url) ? :signed_url : :public_url
|
27
|
+
config[:response_type] = response_type
|
27
28
|
end
|
28
29
|
merged_config = DEFAULTS.merge(config)
|
29
30
|
self.class.authentication_klass ||= self.class.default_authentication_klass
|
@@ -45,7 +46,8 @@ module BrowseEverything
|
|
45
46
|
# @return [Array<BrowseEverything::FileEntry>]
|
46
47
|
def contents(path = '')
|
47
48
|
path = File.join(path, '') unless path.empty?
|
48
|
-
|
49
|
+
@entries = []
|
50
|
+
|
49
51
|
generate_listing(path)
|
50
52
|
@sorter.call(@entries)
|
51
53
|
end
|
@@ -111,15 +113,6 @@ module BrowseEverything
|
|
111
113
|
@client ||= authenticate
|
112
114
|
end
|
113
115
|
|
114
|
-
def init_entries(path)
|
115
|
-
@entries = if path.empty?
|
116
|
-
[]
|
117
|
-
else
|
118
|
-
[BrowseEverything::FileEntry.new(Pathname(path).join('..').to_s, '', '..',
|
119
|
-
0, Time.current, true)]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
116
|
def entry_for(name, size, date, dir)
|
124
117
|
BrowseEverything::FileEntry.new(name, [key, name].join(':'), File.basename(name), size, date, dir)
|
125
118
|
end
|
@@ -138,6 +131,7 @@ module BrowseEverything
|
|
138
131
|
end
|
139
132
|
|
140
133
|
def generate_listing(path)
|
134
|
+
client
|
141
135
|
listing = client.list_objects(bucket: config[:bucket], delimiter: '/', prefix: full_path(path))
|
142
136
|
add_directories(listing)
|
143
137
|
add_files(listing, path)
|
@@ -70,7 +70,7 @@ module BrowseEverything
|
|
70
70
|
end
|
71
71
|
|
72
72
|
download_options = extract_download_options(options)
|
73
|
-
url = download_options
|
73
|
+
url = download_options[:url]
|
74
74
|
|
75
75
|
case url.scheme
|
76
76
|
when 'file'
|
@@ -91,8 +91,7 @@ module BrowseEverything
|
|
91
91
|
url = options.fetch('url')
|
92
92
|
|
93
93
|
# This avoids the potential for a KeyError
|
94
|
-
headers = options.fetch('
|
95
|
-
headers.each_pair { |k, v| headers[k] = v.tr('+', ' ') }
|
94
|
+
headers = options.fetch('headers', {}) || {}
|
96
95
|
|
97
96
|
file_size_value = options.fetch('file_size', 0)
|
98
97
|
file_size = file_size_value.to_i
|
@@ -131,9 +130,9 @@ module BrowseEverything
|
|
131
130
|
url = options.fetch(:url)
|
132
131
|
retrieved = 0
|
133
132
|
|
134
|
-
request = Typhoeus::Request.new(url.to_s, headers: headers)
|
133
|
+
request = Typhoeus::Request.new(url.to_s, method: :get, headers: headers)
|
135
134
|
request.on_headers do |response|
|
136
|
-
raise DownloadError.new("#{self.class}: Failed to download #{url}", response) unless response.code == 200
|
135
|
+
raise DownloadError.new("#{self.class}: Failed to download #{url}: Status Code: #{response.code}", response) unless response.code == 200
|
137
136
|
end
|
138
137
|
request.on_body do |chunk|
|
139
138
|
retrieved += chunk.bytesize
|
@@ -3,8 +3,8 @@
|
|
3
3
|
# The file_system provider can be a path to any directory on the server where your application is running.
|
4
4
|
#
|
5
5
|
# dropbox:
|
6
|
-
#
|
7
|
-
#
|
6
|
+
# client_id: YOUR_DROPBOX_APP_KEY
|
7
|
+
# client_secret: YOUR_DROPBOX_APP_SECRET
|
8
8
|
# box:
|
9
9
|
# client_id: YOUR_BOX_CLIENT_ID
|
10
10
|
# client_secret: YOUR_BOX_CLIENT_SECRET
|
@@ -15,6 +15,13 @@ RSpec.describe BrowseEverythingController, type: :controller do
|
|
15
15
|
|
16
16
|
describe '#auth' do
|
17
17
|
let(:provider_session) { instance_double(BrowseEverythingSession::ProviderSession) }
|
18
|
+
let(:connector_response_url_options) do
|
19
|
+
{
|
20
|
+
protocol: 'http://',
|
21
|
+
host: 'test.host',
|
22
|
+
port: 80
|
23
|
+
}
|
24
|
+
end
|
18
25
|
|
19
26
|
before do
|
20
27
|
allow(controller).to receive(:params).and_return('code' => 'test-code')
|
@@ -24,7 +31,7 @@ RSpec.describe BrowseEverythingController, type: :controller do
|
|
24
31
|
end
|
25
32
|
|
26
33
|
it 'retrieves the authorization code from the parameters' do
|
27
|
-
expect(provider).to have_received(:connect).with({ 'code' => 'test-code' }, nil)
|
34
|
+
expect(provider).to have_received(:connect).with({ 'code' => 'test-code' }, nil, connector_response_url_options)
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
include BrowserConfigHelper
|
4
4
|
|
5
|
-
describe BrowseEverything::Driver::Box
|
5
|
+
describe BrowseEverything::Driver::Box do
|
6
|
+
subject { provider }
|
7
|
+
|
6
8
|
let(:browser) { BrowseEverything::Browser.new(url_options) }
|
7
9
|
let(:provider) { browser.providers['box'] }
|
8
10
|
let(:auth_params) do
|
@@ -11,31 +13,27 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
|
|
11
13
|
'state' => 'box'
|
12
14
|
}
|
13
15
|
end
|
14
|
-
|
15
|
-
# To re-record the VCR responses, you will need to substitute the 'token' and 'refresh_token' values with the
|
16
|
-
# actual tokens returned from Box.
|
17
|
-
#
|
18
|
-
# The easiest way to do this is output @token to the Rails log from the box_client method:
|
19
|
-
#
|
20
|
-
# def box_client
|
21
|
-
# Rails.logger.info(@token)
|
22
|
-
# [...]
|
23
|
-
#
|
24
|
-
# Make sure you have the internal_test_app built and have copied your client id and secret to the yaml config file.
|
25
|
-
# With the test app running, you can authenticate to your Box account to browse files, and should see the
|
26
|
-
# tokens listed in the Rails log. Once you have copied the new tokens, the spec test will run and use your tokens
|
27
|
-
# to authenticate to Box. To record the new responses replace `record: :none` with `record: :all`.
|
28
16
|
let(:token) do
|
29
17
|
{
|
30
18
|
'token' => 'TOKEN',
|
31
19
|
'refresh_token' => 'REFRESH_TOKEN'
|
32
20
|
}
|
33
21
|
end
|
34
|
-
|
35
|
-
subject { provider }
|
22
|
+
let(:oauth_response_body) { '{"access_token":"TOKEN","expires_in":3762,"restricted_to":[],"refresh_token":"REFRESH_TOKEN","token_type":"bearer"}' }
|
36
23
|
|
37
24
|
before do
|
38
25
|
stub_configuration
|
26
|
+
|
27
|
+
stub_request(
|
28
|
+
:post,
|
29
|
+
'https://www.box.com/api/oauth2/token'
|
30
|
+
).to_return(
|
31
|
+
body: oauth_response_body,
|
32
|
+
status: 200,
|
33
|
+
headers: {
|
34
|
+
'Content-Type' => 'application/json'
|
35
|
+
}
|
36
|
+
)
|
39
37
|
end
|
40
38
|
|
41
39
|
after do
|
@@ -48,7 +46,7 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
|
|
48
46
|
|
49
47
|
describe '#validate_config' do
|
50
48
|
it 'raises and error with an incomplete configuration' do
|
51
|
-
expect {
|
49
|
+
expect { described_class.new({}) }.to raise_error(BrowseEverything::InitializationError)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
|
@@ -92,14 +90,42 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
|
|
92
90
|
end
|
93
91
|
|
94
92
|
it 'registers new tokens' do
|
95
|
-
provider.connect(auth_params, 'data')
|
93
|
+
provider.connect(auth_params, 'data', nil)
|
96
94
|
expect(provider).to have_received(:register_access_token).with(kind_of(OAuth2::AccessToken))
|
97
95
|
end
|
98
96
|
end
|
99
97
|
|
100
98
|
describe '#contents' do
|
101
|
-
|
99
|
+
let(:folders_response_body) do
|
100
|
+
'{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files","created_at":null,"modified_at":null,"description":"","size":28747877,"path_collection":{"total_count":0,"entries":[]},"created_by":{"type":"user","id":"","name":"","login":""},"modified_by":{"type":"user","id":"225383863","name":"ADAM GARNER WEAD","login":"agw13@psu.edu"},"trashed_at":null,"purged_at":null,"content_created_at":null,"content_modified_at":null,"owned_by":{"type":"user","id":"225383863","name":"ADAM GARNER WEAD","login":"agw13@psu.edu"},"shared_link":null,"folder_upload_email":null,"parent":null,"item_status":"active","item_collection":{"total_count":13,"entries":[{"type":"folder","id":"20375782799","sequence_id":"0","etag":"0","name":"A very looooooooooooong box folder, why so loooooooong Lets make it even longer to show how far it gets sent to the side"},{"type":"folder","id":"2571160559","sequence_id":"0","etag":"0","name":"Apps Team - Shared"},{"type":"folder","id":"20194542723","sequence_id":"0","etag":"0","name":"DSRD - W Pattee 3"},{"type":"folder","id":"20284062015","sequence_id":"0","etag":"0","name":"My Box Notes"},{"type":"folder","id":"11305958926","sequence_id":"0","etag":"0","name":"PCDM-Sufia"},{"type":"folder","id":"4227519189","sequence_id":"0","etag":"0","name":"refactor"},{"type":"folder","id":"2459961273","sequence_id":"0","etag":"0","name":"SaS - Development Team"},{"type":"folder","id":"3399219062","sequence_id":"0","etag":"0","name":"Scholarsphere - Migration"},{"type":"folder","id":"1168461187","sequence_id":"0","etag":"0","name":"test"},{"type":"folder","id":"3055812547","sequence_id":"0","etag":"0","name":"UX Artifacts"},{"type":"file","id":"25581309763","file_version":{"type":"file_version","id":"23869158869","sha1":"4604bbe44fdcdd4afef3c666cf582e3773960954"},"sequence_id":"1","etag":"1","sha1":"4604bbe44fdcdd4afef3c666cf582e3773960954","name":"failed.tar.gz"},{"type":"file","id":"25588823531","file_version":{"type":"file_version","id":"23877641673","sha1":"abd18ce0a685a27b464fb05f27af5a84f9ec9be7"},"sequence_id":"1","etag":"1","sha1":"abd18ce0a685a27b464fb05f27af5a84f9ec9be7","name":"scholarsphere_5712md360.xml"},{"type":"file","id":"113711622968","file_version":{"type":"file_version","id":"122136107320","sha1":"da39a3ee5e6b4b0d3255bfef95601890afd80709"},"sequence_id":"0","etag":"0","sha1":"da39a3ee5e6b4b0d3255bfef95601890afd80709","name":"test.txt"}],"offset":0,"limit":100,"order":[{"by":"type","direction":"ASC"},{"by":"name","direction":"ASC"}]}}'
|
101
|
+
end
|
102
|
+
let(:folders_items_response_body) do
|
103
|
+
'{"total_count":13,"entries":[{"type":"folder","id":"20375782799","etag":"0","name":"A very looooooooooooong box folder, why so loooooooong Lets make it even longer to show how far it gets sent to the side","size":0,"created_at":"2017-03-01T04:15:15-08:00"},{"type":"folder","id":"2571160559","etag":"0","name":"Apps Team - Shared","size":1249,"created_at":"2014-10-15T13:00:29-07:00"},{"type":"folder","id":"20194542723","etag":"0","name":"DSRD - W Pattee 3","size":2949416,"created_at":"2017-02-27T08:17:21-08:00"},{"type":"folder","id":"20284062015","etag":"0","name":"My Box Notes","size":0,"created_at":"2017-02-28T08:52:26-08:00"},{"type":"folder","id":"11305958926","etag":"0","name":"PCDM-Sufia","size":650658,"created_at":"2016-09-14T09:14:25-07:00"},{"type":"folder","id":"4227519189","etag":"0","name":"refactor","size":8766,"created_at":"2015-08-14T07:53:56-07:00"},{"type":"folder","id":"2459961273","etag":"0","name":"SaS - Development Team","size":152720753,"created_at":"2014-09-17T13:39:31-07:00"},{"type":"folder","id":"3399219062","etag":"0","name":"Scholarsphere - Migration","size":270984,"created_at":"2015-04-07T13:17:51-07:00"},{"type":"folder","id":"1168461187","etag":"0","name":"test","size":20625445557,"created_at":"2013-09-19T12:57:59-07:00"},{"type":"folder","id":"3055812547","etag":"0","name":"UX Artifacts","size":3801994,"created_at":"2015-02-04T08:21:16-08:00"},{"type":"file","id":"25581309763","etag":"1","name":"failed.tar.gz","size":28650839,"created_at":"2015-01-29T05:18:43-08:00"},{"type":"file","id":"25588823531","etag":"1","name":"scholarsphere_5712md360.xml","size":97038,"created_at":"2015-01-29T08:38:44-08:00"},{"type":"file","id":"113711622968","etag":"0","name":"test.txt","size":0,"created_at":"2016-12-20T07:50:30-08:00"}],"offset":0,"limit":1000,"order":[{"by":"type","direction":"ASC"},{"by":"name","direction":"ASC"}]}'
|
104
|
+
end
|
105
|
+
before do
|
106
|
+
provider.token = token
|
107
|
+
|
108
|
+
stub_request(
|
109
|
+
:get, "https://api.box.com/2.0/folders/0"
|
110
|
+
).to_return(
|
111
|
+
body: folders_response_body,
|
112
|
+
status: 200,
|
113
|
+
headers: {
|
114
|
+
'Content-Type' => 'application/json'
|
115
|
+
}
|
116
|
+
)
|
117
|
+
stub_request(
|
118
|
+
:get, "https://api.box.com/2.0/folders/0/items?fields=name,size,created_at&limit=99999&offset=0"
|
119
|
+
).to_return(
|
120
|
+
body: folders_items_response_body,
|
121
|
+
status: 200,
|
122
|
+
headers: {
|
123
|
+
'Content-Type' => 'application/json'
|
124
|
+
}
|
125
|
+
)
|
126
|
+
end
|
102
127
|
|
128
|
+
# HERE
|
103
129
|
context 'with files and folders in the root directory' do
|
104
130
|
let(:root_directory) { provider.contents('') }
|
105
131
|
let(:long_file) { root_directory[0] }
|
@@ -136,18 +162,36 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
|
|
136
162
|
end
|
137
163
|
|
138
164
|
context 'with files and folders in the SaS - Development Team directory' do
|
139
|
-
let(:
|
140
|
-
let(:
|
141
|
-
let(:apps_dir) { sas_directory[
|
142
|
-
let(:equipment) { sas_directory[
|
143
|
-
|
144
|
-
|
145
|
-
|
165
|
+
let(:folder_id) { '2459961273' }
|
166
|
+
let(:sas_directory) { provider.contents(folder_id) }
|
167
|
+
let(:apps_dir) { sas_directory[0] }
|
168
|
+
let(:equipment) { sas_directory[11] }
|
169
|
+
let(:folders_response_body) do
|
170
|
+
'{"type":"folder","id":"2459961273","sequence_id":"0","etag":"0","name":"SaS - Development Team","created_at":"2014-09-17T13:39:31-07:00","modified_at":"2017-03-17T08:41:40-07:00","description":"","size":152720753,"path_collection":{"total_count":1,"entries":[{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"}]},"created_by":{"type":"user","id":"191882215","name":"Daniel Coughlin","login":"dmc186@psu.edu"},"modified_by":{"type":"user","id":"190902775","name":"CAROLYN A COLE","login":"cam156@psu.edu"},"trashed_at":null,"purged_at":null,"content_created_at":"2014-09-17T13:39:31-07:00","content_modified_at":"2017-03-17T08:41:40-07:00","owned_by":{"type":"user","id":"191882215","name":"Daniel Coughlin","login":"dmc186@psu.edu"},"shared_link":{"url":"https:\/\/psu.box.com\/s\/8hb3e06nthwld39ehlg5","download_url":null,"vanity_url":null,"effective_access":"collaborators","is_password_enabled":false,"unshared_at":null,"download_count":0,"preview_count":0,"access":"collaborators","permissions":{"can_download":true,"can_preview":true}},"folder_upload_email":null,"parent":null,"item_status":"active","item_collection":{"total_count":17,"entries":[{"type":"folder","id":"2459974427","sequence_id":"0","etag":"0","name":"Apps&Int"},{"type":"folder","id":"11217040834","sequence_id":"0","etag":"0","name":"Credentials"},{"type":"folder","id":"5662231069","sequence_id":"0","etag":"0","name":"DevOps Presentation"},{"type":"folder","id":"8648394509","sequence_id":"0","etag":"0","name":"old"},{"type":"folder","id":"12445061821","sequence_id":"0","etag":"0","name":"Ops Plan"},{"type":"file","id":"136917954839","file_version":{"type":"file_version","id":"158227338595","sha1":"2e2124c0d6589dd05d03a854b9c5c3a68bbc4501"},"sequence_id":"17","etag":"17","sha1":"2e2124c0d6589dd05d03a854b9c5c3a68bbc4501","name":"2-17 Upcoming ScholarSphere changes.boxnote"},{"type":"file","id":"75228871930","file_version":{"type":"file_version","id":"79668751214","sha1":"43cd4ac728cef7767dc132c26b181133d867d78f"},"sequence_id":"1","etag":"1","sha1":"43cd4ac728cef7767dc132c26b181133d867d78f","name":"99bottles (1).epub"},{"type":"file","id":"72329914177","file_version":{"type":"file_version","id":"76429987577","sha1":"a3310fdad0e6c9654b19d88b35318b8cdc246379"},"sequence_id":"2","etag":"2","sha1":"a3310fdad0e6c9654b19d88b35318b8cdc246379","name":"Development Team Projects and Milestones (not downloaded).xlsx"},{"type":"file","id":"74507436394","file_version":{"type":"file_version","id":"78854145518","sha1":"589ab64efb1ba49537074fd2c56e1570a24a47b5"},"sequence_id":"7","etag":"7","sha1":"589ab64efb1ba49537074fd2c56e1570a24a47b5","name":"Development Team Projects and Milestones - Editable.xlsx"},{"type":"file","id":"72324078305","file_version":{"type":"file_version","id":"76423451525","sha1":"42c0a5a34717cd17e315653643b61d23e94b7cd7"},"sequence_id":"3","etag":"3","sha1":"42c0a5a34717cd17e315653643b61d23e94b7cd7","name":"Development Team Projects and Milestones.xlsx"},{"type":"file","id":"106651625938","file_version":{"type":"file_version","id":"114805197783","sha1":"0c1c90a0186bd3934ce3877e092a228dc1568e93"},"sequence_id":"2","etag":"2","sha1":"0c1c90a0186bd3934ce3877e092a228dc1568e93","name":"Digital Scholarship and Repository Development (DSRD) Org Chart 2016.pdf"},{"type":"file","id":"76960974625","file_version":{"type":"file_version","id":"106919307872","sha1":"74608bfb532feff774502c6132eafe9acb1e5217"},"sequence_id":"162","etag":"162","sha1":"74608bfb532feff774502c6132eafe9acb1e5217","name":"Equipment.boxnote"},{"type":"file","id":"68362464289","file_version":{"type":"file_version","id":"101137863811","sha1":"40a0a3f98926874f1ee62fd522621a4408e0058c"},"sequence_id":"8","etag":"8","sha1":"40a0a3f98926874f1ee62fd522621a4408e0058c","name":"migrationDesign.pptx"},{"type":"file","id":"99028795390","file_version":{"type":"file_version","id":"107183805224","sha1":"7044bd7f0892f915b77b914430c2915161f942d9"},"sequence_id":"37","etag":"37","sha1":"7044bd7f0892f915b77b914430c2915161f942d9","name":"Onboarding.boxnote"},{"type":"file","id":"134865535934","file_version":{"type":"file_version","id":"143971901576","sha1":"32cc33b2cd5cc46f0a3fb924b4779cc387a81018"},"sequence_id":"1","etag":"1","sha1":"32cc33b2cd5cc46f0a3fb924b4779cc387a81018","name":"passenger-test.boxnote"},{"type":"file","id":"92102699797","file_version":{"type":"file_version","id":"98754405909","sha1":"053b762f6d5752c261ef7ff6a3d776853cdb2ca3"},"sequence_id":"1","etag":"1","sha1":"053b762f6d5752c261ef7ff6a3d776853cdb2ca3","name":"sas_development_libraries_mou_2016_08_01.docx"},{"type":"file","id":"22182934895","file_version":{"type":"file_version","id":"50126669941","sha1":"8ca396b5b26ff90d625ea3a49f0cc69ad844476b"},"sequence_id":"41","etag":"41","sha1":"8ca396b5b26ff90d625ea3a49f0cc69ad844476b","name":"TimeBox.xlsx"}],"offset":0,"limit":100,"order":[{"by":"type","direction":"ASC"},{"by":"name","direction":"ASC"}]}}'
|
171
|
+
end
|
172
|
+
let(:folders_items_response_body) do
|
173
|
+
'{"total_count":17,"entries":[{"type":"folder","id":"2459974427","etag":"0","name":"Apps&Int","size":14341346,"created_at":"2014-09-17T13:42:30-07:00"},{"type":"folder","id":"11217040834","etag":"0","name":"Credentials","size":12603,"created_at":"2016-09-07T08:37:23-07:00"},{"type":"folder","id":"5662231069","etag":"0","name":"DevOps Presentation","size":128158633,"created_at":"2015-12-07T05:51:08-08:00"},{"type":"folder","id":"8648394509","etag":"0","name":"old","size":117232,"created_at":"2016-06-30T08:03:46-07:00"},{"type":"folder","id":"12445061821","etag":"0","name":"Ops Plan","size":6181924,"created_at":"2016-11-17T06:52:58-08:00"},{"type":"file","id":"136917954839","etag":"17","name":"2-17 Upcoming ScholarSphere changes.boxnote","size":1768,"created_at":"2017-02-17T09:27:57-08:00"},{"type":"file","id":"75228871930","etag":"1","name":"99bottles (1).epub","size":1013573,"created_at":"2016-07-21T03:53:01-07:00"},{"type":"file","id":"72329914177","etag":"2","name":"Development Team Projects and Milestones (not downloaded).xlsx","size":20812,"created_at":"2016-06-30T09:10:36-07:00"},{"type":"file","id":"74507436394","etag":"7","name":"Development Team Projects and Milestones - Editable.xlsx","size":21001,"created_at":"2016-07-15T11:08:54-07:00"},{"type":"file","id":"72324078305","etag":"3","name":"Development Team Projects and Milestones.xlsx","size":22410,"created_at":"2016-06-30T08:31:56-07:00"},{"type":"file","id":"106651625938","etag":"2","name":"Digital Scholarship and Repository Development (DSRD) Org Chart 2016.pdf","size":17677,"created_at":"2016-11-30T08:27:58-08:00"},{"type":"file","id":"76960974625","etag":"162","name":"Equipment.boxnote","size":10140,"created_at":"2016-08-03T12:22:39-07:00"},{"type":"file","id":"68362464289","etag":"8","name":"migrationDesign.pptx","size":47751,"created_at":"2016-06-03T03:56:54-07:00"},{"type":"file","id":"99028795390","etag":"37","name":"Onboarding.boxnote","size":4465,"created_at":"2016-10-24T11:41:47-07:00"},{"type":"file","id":"134865535934","etag":"1","name":"passenger-test.boxnote","size":4988,"created_at":"2017-02-13T10:47:38-08:00"},{"type":"file","id":"92102699797","etag":"1","name":"sas_development_libraries_mou_2016_08_01.docx","size":134018,"created_at":"2016-08-16T07:32:53-07:00"},{"type":"file","id":"22182934895","etag":"41","name":"TimeBox.xlsx","size":21864,"created_at":"2014-10-23T08:22:16-07:00"}],"offset":0,"limit":1000,"order":[{"by":"type","direction":"ASC"},{"by":"name","direction":"ASC"}]}'
|
174
|
+
end
|
146
175
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
176
|
+
before do
|
177
|
+
stub_request(
|
178
|
+
:get, "https://api.box.com/2.0/folders/#{folder_id}"
|
179
|
+
).to_return(
|
180
|
+
body: folders_response_body,
|
181
|
+
status: 200,
|
182
|
+
headers: {
|
183
|
+
'Content-Type' => 'application/json'
|
184
|
+
}
|
185
|
+
)
|
186
|
+
stub_request(
|
187
|
+
:get, "https://api.box.com/2.0/folders/#{folder_id}/items?fields=name,size,created_at&limit=99999&offset=0"
|
188
|
+
).to_return(
|
189
|
+
body: folders_items_response_body,
|
190
|
+
status: 200,
|
191
|
+
headers: {
|
192
|
+
'Content-Type' => 'application/json'
|
193
|
+
}
|
194
|
+
)
|
151
195
|
end
|
152
196
|
|
153
197
|
describe 'the second item' do
|
@@ -172,17 +216,53 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
|
|
172
216
|
end
|
173
217
|
|
174
218
|
describe '#link_for' do
|
175
|
-
before
|
219
|
+
before do
|
220
|
+
provider.token = token
|
221
|
+
|
222
|
+
# Initial request for metadata
|
223
|
+
stub_request(
|
224
|
+
:get, "https://api.box.com/2.0/files/#{file_id}"
|
225
|
+
).to_return(
|
226
|
+
body: files_response_body,
|
227
|
+
status: 200,
|
228
|
+
headers: {
|
229
|
+
'Content-Type' => 'application/json'
|
230
|
+
}
|
231
|
+
)
|
232
|
+
|
233
|
+
# Request for the content
|
234
|
+
stub_request(
|
235
|
+
:get, "https://api.box.com/2.0/files/#{file_id}/content"
|
236
|
+
).to_return(
|
237
|
+
status: 302,
|
238
|
+
headers: {
|
239
|
+
'location' => files_response_location
|
240
|
+
}
|
241
|
+
)
|
242
|
+
end
|
243
|
+
let(:link) { provider.link_for(file_id) }
|
176
244
|
|
177
245
|
context 'with a file from the root directory' do
|
178
|
-
let(:
|
246
|
+
let(:files_response_location) do
|
247
|
+
'https://dl.boxcloud.com/d/1/B7Qd7B_iwPHTU4-71W2qYoTbvAaHCPzNsy5WTFHj5XpbmydlF8ud_0n7Ji7zswdU3Kg0patL8EUXCR3cpPw1PZjp-_a1t6MoH-tX3eQeCAR080Hr-yQaEmLQ8dULnnlOhYHeYwPuRp-0gCcXCF5w3O3bE6ZHgML3SCQchPoJQlsfvcYwXZyPRFEVRNUo7qou5X9dbkMCJGmB0CsvqKTXfEs8bqbmRV4hZ5qpJbD0Jer1m4vsqu8h5VkBdMIcgFMn_D9TheZOrmQdg8ExZZVPJ7X8QjFjI707WwIl7CNYkmocCdAJnbYQljFMiQsp0wF0etUqoiskNnaJBS3NagvtvSKaX3TVfiXa87CHDwPiQ3PNJE32d49eKcBK9nLLigoX3SJOkJqMqUSXO_UAxl0bO0EszCNpaWsiQwWiG2jjB5YBfDwQbmfuSTCBPkhDjIH3S3n5cadk4H_8rvgHshYBXNJd2NshgPsYt1XIkE8qj4WznzwayZoi_2k5x4liFvs2F91anj0bPAW2Mzeyz0Pi49mythoH7Rrq_i0sbYDt3VJNyCB0wqs8xUCa38Z6NocTKrKtFHrNSyM2-g5nWsAIwGeG4L4kZ_qIq8nNL49LsntvpFmhogONBozQQCvoEj0WXqhLCxxwT4U-pZ5rCYDt6dpoNlmYv962wXUzg_s21CO96J1o9-_xKl9JxmbWPf0DDJ35gCBFWMhL6BTaLckbBrybx41luHjjDuv72CxfsqsabdyW2yDN3uoBAcXIXD7QUOACPXKHvC98kL9aXL9o9X-zt89vUP61ijizsjtoI9RQc4CrjerfnxC7jS-ER3w2nwkgOEr1wkdEvq4QabcVlyixgrRxKTmzHXa0JGfmpLdEQ821Sgi7QHOpa0l5CSZTQycnWHoMKn4f_xJo5WZLmkmNgkE2DRsok0xGVUK_lNKjrt_N9mPVAdeeXLjSyoSol2_ugU79ELQSHJKKyTFAEJOscUSseg5MtWrIOLKQY6NlAaE0Ckn7c_LX4MYaSj83F-sZouvwSRNVbTklMNkC6j2fy4kr8_T3eb_9-Df94B1867kSJzt7TjXSAxz_p9PbRuj7eY1NW15zjxtOPQpk/download'
|
248
|
+
end
|
249
|
+
let(:files_response_body) do
|
250
|
+
'{"type":"file","id":"25581309763","file_version":{"type":"file_version","id":"23869158869","sha1":"4604bbe44fdcdd4afef3c666cf582e3773960954"},"sequence_id":"1","etag":"1","sha1":"4604bbe44fdcdd4afef3c666cf582e3773960954","name":"failed.tar.gz","description":"","size":28650839,"path_collection":{"total_count":1,"entries":[{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"}]},"created_at":"2015-01-29T05:18:43-08:00","modified_at":"2015-01-29T05:18:43-08:00","trashed_at":null,"purged_at":null,"content_created_at":"2015-01-17T05:59:48-08:00","content_modified_at":"2015-01-17T06:00:03-08:00","created_by":{"type":"user","id":"225383863","name":"ADAM GARNER WEAD","login":"agw13@psu.edu"},"modified_by":{"type":"user","id":"225383863","name":"ADAM GARNER WEAD","login":"agw13@psu.edu"},"owned_by":{"type":"user","id":"225383863","name":"ADAM GARNER WEAD","login":"agw13@psu.edu"},"shared_link":{"url":"https:\/\/psu.box.com\/s\/w89hg6kf73q8fn1ww51cj92ohb6piyet","download_url":"https:\/\/psu.box.com\/shared\/static\/w89hg6kf73q8fn1ww51cj92ohb6piyet.gz","vanity_url":null,"effective_access":"open","is_password_enabled":false,"unshared_at":null,"download_count":1,"preview_count":0,"access":"open","permissions":{"can_download":true,"can_preview":true}},"parent":{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"},"item_status":"active"}'
|
251
|
+
end
|
252
|
+
let(:file_id) { '25581309763' }
|
179
253
|
|
180
254
|
specify { expect(link[0]).to start_with('https://dl.boxcloud.com/d/1') }
|
181
255
|
specify { expect(link[1]).to have_key(:expires) }
|
182
256
|
end
|
183
257
|
|
184
258
|
context 'with a file from the SaS - Development Team directory' do
|
185
|
-
let(:
|
259
|
+
let(:files_response_location) do
|
260
|
+
'https://dl.boxcloud.com/d/1/lCA2dDrIV1QAvpQLU7_mkJ0bt2Soa1dLRT6FOzmF37EfJgjRmCO-rZ0VFyKCtoHgPzRoCIHgx-IWCoV8cvtfTX4Yw--RmBLBV9f4JsK6i3LMRKQzgDMxsMu97RSmuMagV-GayR8uO6NGFBtoX81yujebVY-JRB7cxhPU0fbCxAzAnv1711_IUs6YXwhWc-rNFHrNjPsUnJLqw0soQPZqF3Q5irxJLu7traVIeoeuGSfhw-7G-qfqu4CIFonC4ktwwh8jMgN9KW712kRg61moLG6Aa6FTbdCCSt_jCwvQFVGqCz_VivfzG2_BHBqh4IhIB76DmF1ISM-jD9VToUwYfscg6BgC2fqGj6OycsuYr3v3EE0gHlPw_X2rJnq9J2M9plnnhqBvXEwoUXDqyGPvSqWBeQvrrTYfvqj7fG48tUr7RKOytc_K0B4aw9hgGUk3EaifSVWzYvXzoXBp27HFHPsssvIK8fXoSU2J3HCEsGhIDFzu3cvXyPZJV_Co1_LvivWM0AGjXhyoC8PNO5qmtrZFgCob3KlZ8BEI1yJfX_0K8wpocUJP95eBNutBhWa2DEvCK6R5OG-Z0XwrJu8XFRwPcIl3_7lSsIhsQlYA7MoJer7hhwVGAl3kPP-bFsw1et66UM6KHG2FdN2xKP10DYFqR_JrShPP8DQ-ik9-lKej_8LTfiHdf0YbkdMNKzBYlXZsiQNwd3VXdRo1Z4Uhza_XtTDcfH0uxRQyYRecHr-5lEn5iUfV1199GrTsLkcOb9ONNSTFPKW15XCLpgJm6ylSpG2JSZ6zWsGL5hUzdvMytwBCMpIj84UZuwo2RTH1ZDUJYjmHRX11rDnwe2zKMz4woYIA8RjhnYEj6d13BeBz9Fy4GgR90jmM5xHIv9fiAG_b99fpDuYvT-tccN4pdrxPf0P-kCjYAHBt7kY7ToaMWcnOf1nGdLP0oaCGHhAzN0iurjRTLRi2S4N1hsWxjoMuQqayEq15QhRujy2lTZX_XyBgrU2ZodkNsQUlaWcJ6aFT8bh48DtyQvt_xfm4jqmStageFKbydyoB8BpP6oYFAMeFlkS4A6LnXJCzpO8Q../download'
|
261
|
+
end
|
262
|
+
let(:files_response_body) do
|
263
|
+
'{"type":"file","id":"76960974625","file_version":{"type":"file_version","id":"106919307872","sha1":"74608bfb532feff774502c6132eafe9acb1e5217"},"sequence_id":"162","etag":"162","sha1":"74608bfb532feff774502c6132eafe9acb1e5217","name":"Equipment.boxnote","description":"Listing equipment we currently have","size":10140,"path_collection":{"total_count":2,"entries":[{"type":"folder","id":"0","sequence_id":null,"etag":null,"name":"All Files"},{"type":"folder","id":"2459961273","sequence_id":"0","etag":"0","name":"SaS - Development Team"}]},"created_at":"2016-08-03T12:22:39-07:00","modified_at":"2016-10-26T12:40:09-07:00","trashed_at":null,"purged_at":null,"content_created_at":"2016-08-03T12:22:39-07:00","content_modified_at":"2016-10-26T12:40:09-07:00","created_by":{"type":"user","id":"212771336","name":"NICOLE M. GAMPE","login":"nmg110@psu.edu"},"modified_by":{"type":"user","id":"208208274","name":"JUSTIN R PATTERSON","login":"jrp22@psu.edu"},"owned_by":{"type":"user","id":"191882215","name":"Daniel Coughlin","login":"dmc186@psu.edu"},"shared_link":{"url":"https:\/\/psu.box.com\/s\/uolieeszpwglsv0ipwij9ws36rrepvba","download_url":"https:\/\/psu.box.com\/shared\/static\/uolieeszpwglsv0ipwij9ws36rrepvba.boxnote","vanity_url":null,"effective_access":"open","is_password_enabled":false,"unshared_at":null,"download_count":24,"preview_count":0,"access":"open","permissions":{"can_download":true,"can_preview":true}},"parent":{"type":"folder","id":"2459961273","sequence_id":"0","etag":"0","name":"SaS - Development Team"},"item_status":"active"}'
|
264
|
+
end
|
265
|
+
let(:file_id) { '76960974625' }
|
186
266
|
|
187
267
|
specify { expect(link[0]).to start_with('https://dl.boxcloud.com/d/1') }
|
188
268
|
specify { expect(link[1]).to have_key(:expires) }
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
include BrowserConfigHelper
|
4
4
|
|
5
|
-
describe BrowseEverything::Driver::Dropbox
|
5
|
+
describe BrowseEverything::Driver::Dropbox do
|
6
6
|
let(:browser) { BrowseEverything::Browser.new(url_options) }
|
7
7
|
let(:provider) { browser.providers['dropbox'] }
|
8
8
|
let(:provider_yml) do
|
@@ -11,9 +11,22 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
|
|
11
11
|
client_secret: 'client-secret'
|
12
12
|
}
|
13
13
|
end
|
14
|
+
let(:oauth_response_body) do
|
15
|
+
'{"access_token": "test-access-token", "token_type": "bearer", "uid": "test-user-id", "account_id": "dbid:id"}'
|
16
|
+
end
|
14
17
|
|
15
18
|
before do
|
16
19
|
stub_configuration
|
20
|
+
|
21
|
+
stub_request(
|
22
|
+
:post, 'https://api.dropboxapi.com/oauth2/token'
|
23
|
+
).to_return(
|
24
|
+
body: oauth_response_body,
|
25
|
+
status: 200,
|
26
|
+
headers: {
|
27
|
+
'Content-Type' => 'text/javascript'
|
28
|
+
}
|
29
|
+
)
|
17
30
|
end
|
18
31
|
|
19
32
|
after do
|
@@ -22,11 +35,11 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
|
|
22
35
|
|
23
36
|
describe '#validate_config' do
|
24
37
|
it 'raises and error with an incomplete configuration' do
|
25
|
-
expect {
|
38
|
+
expect { described_class.new({}) }.to raise_error(BrowseEverything::InitializationError)
|
26
39
|
end
|
27
40
|
|
28
41
|
it 'raises and error with a configuration without a client secret' do
|
29
|
-
expect {
|
42
|
+
expect { described_class.new(client_id: 'test-client-id') }.to raise_error(BrowseEverything::InitializationError)
|
30
43
|
end
|
31
44
|
end
|
32
45
|
|
@@ -40,11 +53,18 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
|
|
40
53
|
|
41
54
|
context 'with a valid configuration' do
|
42
55
|
let(:driver) { described_class.new(provider_yml) }
|
56
|
+
let(:connector_response_url_options) do
|
57
|
+
{
|
58
|
+
protocol: 'http://',
|
59
|
+
host: 'test.host',
|
60
|
+
port: 80
|
61
|
+
}
|
62
|
+
end
|
43
63
|
|
44
|
-
before { driver.connect({ code: 'code' }, {}) }
|
64
|
+
before { driver.connect({ code: 'code' }, {}, connector_response_url_options) }
|
45
65
|
|
46
66
|
describe '#auth_link' do
|
47
|
-
subject { driver.auth_link }
|
67
|
+
subject { driver.auth_link(connector_response_url_options) }
|
48
68
|
|
49
69
|
it { is_expected.to start_with('https://www.dropbox.com/oauth2/authorize') }
|
50
70
|
end
|
@@ -58,6 +78,23 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
|
|
58
78
|
describe '#contents' do
|
59
79
|
context 'when in the root folder' do
|
60
80
|
let(:contents) { driver.contents }
|
81
|
+
let(:list_folder_response) do
|
82
|
+
'{"entries": [{".tag": "folder", "name": "Photos", "path_lower": "/photos", "path_display": "/Photos", "id": "id:XAAAAAAAAAALA"}, {".tag": "file", "name": "Getting Started.pdf", "path_lower": "/getting started.pdf", "path_display": "/Getting Started.pdf", "id": "id:XAAAAAAAAAAKg", "client_modified": "2012-11-10T18:33:28Z", "server_modified": "2012-11-10T18:33:27Z", "rev": "60b9427f2", "size": 249159, "content_hash": "c3dfdd86981548e48bc8efb6c4162c76ba961ec92e60f6ba26189068a41fcaf2"}], "cursor": "AAFu-_dOPQTQnqOIb9JklCPYSxWtNRrBBOU4nNkY78wTCc-ktCP4MtIoN1nmOESizkoue2dpu3FbMwDM6BQbgkLObH_Ge-H0BYaPwjfLk5cUHZHd1swkMYGLWELfX_PIHH9hCmU0C8sUL2EJ-7y6BcRFpdOvPmxiu6azVyCx_Il7kA", "has_more": false}'
|
83
|
+
end
|
84
|
+
|
85
|
+
before do
|
86
|
+
stub_request(
|
87
|
+
:post, 'https://api.dropboxapi.com/2/files/list_folder'
|
88
|
+
).with(
|
89
|
+
body: '{"recursive":false,"include_media_info":false,"include_deleted":false,"path":""}'
|
90
|
+
).to_return(
|
91
|
+
body: list_folder_response,
|
92
|
+
status: 200,
|
93
|
+
headers: {
|
94
|
+
'Content-Type' => 'application/json'
|
95
|
+
}
|
96
|
+
)
|
97
|
+
end
|
61
98
|
|
62
99
|
it 'retrieves all folders the root folders' do
|
63
100
|
expect(contents).not_to be_empty
|
@@ -75,6 +112,17 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
|
|
75
112
|
|
76
113
|
describe '#link_for' do
|
77
114
|
subject(:link_args) { driver.link_for('/Getting Started.pdf') }
|
115
|
+
before do
|
116
|
+
stub_request(
|
117
|
+
:post, 'https://content.dropboxapi.com/2/files/download'
|
118
|
+
).to_return(
|
119
|
+
body: '{"name": "Getting Started.pdf", "path_lower": "/getting started.pdf", "path_display": "/Getting Started.pdf", "id": "id:XAAAAAAAAAAKg", "client_modified": "2012-11-10T18:33:28Z", "server_modified": "2012-11-10T18:33:27Z", "rev": "60b9427f2", "size": 249159, "content_hash": "c3dfdd86981548e48bc8efb6c4162c76ba961ec92e60f6ba26189068a41fcaf2"}',
|
120
|
+
status: 200,
|
121
|
+
headers: {
|
122
|
+
'Content-Type' => 'application/json'
|
123
|
+
}
|
124
|
+
)
|
125
|
+
end
|
78
126
|
|
79
127
|
it 'provides link arguments for accessing the file' do
|
80
128
|
expect(link_args.first).to be_a String
|