browse-everything 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +61 -9
  3. data/.rubocop_todo.yml +2 -15
  4. data/.travis.yml +19 -19
  5. data/CONTRIBUTING.md +6 -6
  6. data/Gemfile +12 -8
  7. data/README.md +30 -0
  8. data/Rakefile +2 -1
  9. data/app/assets/javascripts/browse_everything/behavior.js.coffee +5 -0
  10. data/app/controllers/browse_everything_controller.rb +75 -23
  11. data/app/helpers/browse_everything_helper.rb +2 -8
  12. data/app/helpers/font_awesome_version_helper.rb +9 -8
  13. data/app/services/browse_everything_session.rb +10 -0
  14. data/app/services/browse_everything_session/provider_session.rb +42 -0
  15. data/app/services/browser_factory.rb +25 -0
  16. data/app/views/browse_everything/_files.html.erb +56 -6
  17. data/browse-everything.gemspec +29 -25
  18. data/config/routes.rb +7 -2
  19. data/lib/browse-everything.rb +2 -0
  20. data/lib/browse_everything.rb +45 -12
  21. data/lib/browse_everything/auth/google/credentials.rb +28 -0
  22. data/lib/browse_everything/auth/google/request_parameters.rb +61 -0
  23. data/lib/browse_everything/browser.rb +11 -4
  24. data/lib/browse_everything/driver/authentication_factory.rb +22 -0
  25. data/lib/browse_everything/driver/base.rb +72 -19
  26. data/lib/browse_everything/driver/box.rb +46 -17
  27. data/lib/browse_everything/driver/dropbox.rb +36 -10
  28. data/lib/browse_everything/driver/file_system.rb +14 -26
  29. data/lib/browse_everything/driver/google_drive.rb +187 -54
  30. data/lib/browse_everything/driver/s3.rb +81 -75
  31. data/lib/browse_everything/engine.rb +3 -2
  32. data/lib/browse_everything/file_entry.rb +3 -1
  33. data/lib/browse_everything/retriever.rb +103 -31
  34. data/lib/browse_everything/version.rb +3 -1
  35. data/lib/generators/browse_everything/assets_generator.rb +3 -2
  36. data/lib/generators/browse_everything/config_generator.rb +11 -9
  37. data/lib/generators/browse_everything/install_generator.rb +3 -2
  38. data/lib/generators/browse_everything/templates/browse_everything_providers.yml.example +12 -11
  39. data/spec/controllers/browse_everything_controller_spec.rb +80 -0
  40. data/spec/features/select_files_spec.rb +13 -13
  41. data/spec/features/test_compiling_stylesheets_spec.rb +2 -0
  42. data/spec/fixtures/vcr_cassettes/google_drive.yml +331 -0
  43. data/spec/fixtures/vcr_cassettes/retriever.yml +93 -0
  44. data/spec/helper/browse_everything_controller_helper_spec.rb +21 -7
  45. data/spec/javascripts/jasmine_spec.rb +2 -0
  46. data/spec/javascripts/support/jasmine_helper.rb +1 -0
  47. data/spec/lib/browse_everything/auth/google/credentials_spec.rb +41 -0
  48. data/spec/{unit → lib/browse_everything}/browse_everything_helper_spec.rb +2 -0
  49. data/spec/lib/browse_everything/browser_spec.rb +109 -0
  50. data/spec/{unit → lib/browse_everything/driver}/base_spec.rb +5 -4
  51. data/spec/{unit → lib/browse_everything/driver}/box_spec.rb +20 -5
  52. data/spec/{unit → lib/browse_everything/driver}/dropbox_spec.rb +15 -18
  53. data/spec/{unit → lib/browse_everything/driver}/file_system_spec.rb +32 -26
  54. data/spec/lib/browse_everything/driver/google_drive_spec.rb +171 -0
  55. data/spec/{unit → lib/browse_everything/driver}/s3_spec.rb +38 -21
  56. data/spec/lib/browse_everything/driver_spec.rb +38 -0
  57. data/spec/{unit → lib/browse_everything}/file_entry_spec.rb +4 -1
  58. data/spec/lib/browse_everything/retriever_spec.rb +200 -0
  59. data/spec/lib/browse_everything_spec.rb +67 -0
  60. data/spec/services/browse_everything_session/provider_session_spec.rb +50 -0
  61. data/spec/services/browser_factory_spec.rb +40 -0
  62. data/spec/spec_helper.rb +39 -18
  63. data/spec/support/app/controllers/file_handler_controller.rb +4 -4
  64. data/spec/support/app/views/file_handler/main.html.erb +1 -1
  65. data/spec/support/capybara.rb +17 -0
  66. data/spec/support/rake.rb +3 -1
  67. data/spec/support/wait_for_ajax.rb +14 -0
  68. data/spec/test_app_templates/Gemfile.extra +1 -0
  69. data/spec/test_app_templates/lib/generators/test_app_generator.rb +10 -4
  70. data/spec/views/browse_everything/{_file.html.erb_spec.rb → _files.html.erb_spec.rb} +24 -18
  71. data/tasks/ci.rake +2 -0
  72. metadata +159 -107
  73. data/app/views/browse_everything/_file.html.erb +0 -52
  74. data/app/views/browse_everything/resolve.html.erb +0 -1
  75. data/spec/unit/browser_spec.rb +0 -76
  76. data/spec/unit/retriever_spec.rb +0 -109
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe BrowseEverything do
4
+ describe '.configure' do
5
+
6
+ let(:config) do
7
+ {
8
+ dropbox: {
9
+ app_key: 'test-key',
10
+ app_secret: 'test-secret'
11
+ },
12
+ box: {
13
+ client_id: 'test-id',
14
+ client_secret: 'test-secret'
15
+ },
16
+ google_drive: {
17
+ client_id: 'test-id',
18
+ client_secret: 'test-secret'
19
+ }
20
+ }
21
+ end
22
+ before do
23
+ BrowseEverything.configure(config)
24
+ end
25
+ it 'registers the configuration for the drivers' do
26
+ expect(BrowseEverything.config).to be_a ActiveSupport::HashWithIndifferentAccess
27
+
28
+ expect(BrowseEverything.config).to include 'dropbox'
29
+ expect(BrowseEverything.config['dropbox']).to include({ 'app_key' => 'test-key' })
30
+ expect(BrowseEverything.config['dropbox']).to include({ 'app_secret' => 'test-secret' })
31
+
32
+ expect(BrowseEverything.config).to include 'box'
33
+ expect(BrowseEverything.config['box']).to include({ 'client_id' => 'test-id' })
34
+ expect(BrowseEverything.config['box']).to include({ 'client_secret' => 'test-secret' })
35
+
36
+ expect(BrowseEverything.config).to include 'google_drive'
37
+ expect(BrowseEverything.config['google_drive']).to include({ 'client_id' => 'test-id' })
38
+ expect(BrowseEverything.config['google_drive']).to include({ 'client_secret' => 'test-secret' })
39
+ end
40
+
41
+ context 'with an entry for the drop_box provider' do
42
+ let(:config) do
43
+ {
44
+ drop_box: {
45
+ app_key: 'test-key',
46
+ app_secret: 'test-secret'
47
+ }
48
+ }
49
+ end
50
+
51
+ it 'logs a deprecation warning and sets it to the dropbox key' do
52
+ expect(BrowseEverything.config).not_to include 'drop_box'
53
+ expect(BrowseEverything.config).to include 'dropbox'
54
+ expect(BrowseEverything.config['dropbox']).to include({ 'app_key' => 'test-key' })
55
+ expect(BrowseEverything.config['dropbox']).to include({ 'app_secret' => 'test-secret' })
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'with an unsupported or invalid configuration' do
61
+ let(:config) { 1234 }
62
+
63
+ it 'raises an initialization error' do
64
+ expect { BrowseEverything.configure(config) }.to raise_error(BrowseEverything::InitializationError, 'Unrecognized configuration: 1234')
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe BrowseEverythingSession::ProviderSession do
4
+ subject(:provider_session) { described_class.new(session: session, name: name) }
5
+
6
+ let(:session) { instance_double(ActionDispatch::Request::Session) }
7
+ let(:name) { 'test_session' }
8
+
9
+ describe '.for' do
10
+ it 'provides a new session object' do
11
+ expect(described_class.for(session: session, name: name)).to be_a described_class
12
+ end
13
+ end
14
+
15
+ describe '.token' do
16
+ before do
17
+ allow(session).to receive(:[]=)
18
+ allow(session).to receive(:[]).and_return('test-token')
19
+ provider_session.token = 'test-token'
20
+ end
21
+ it 'sets and accesses the access token' do
22
+ expect(provider_session.token).to eq 'test-token'
23
+ expect(session).to have_received(:[]).with('test_session_token')
24
+ end
25
+ end
26
+
27
+ describe '.code' do
28
+ before do
29
+ allow(session).to receive(:[]=)
30
+ allow(session).to receive(:[]).and_return('test-code')
31
+ provider_session.code = 'test-code'
32
+ end
33
+ it 'sets and accesses the access code' do
34
+ expect(provider_session.code).to eq 'test-code'
35
+ expect(session).to have_received(:[]).with('test_session_code')
36
+ end
37
+ end
38
+
39
+ describe '.data' do
40
+ before do
41
+ allow(session).to receive(:[]=)
42
+ allow(session).to receive(:[]).and_return('test' => 'data')
43
+ provider_session.data = { 'test' => 'data' }
44
+ end
45
+ it 'sets and accesses the access data' do
46
+ expect(provider_session.data).to eq('test' => 'data')
47
+ expect(session).to have_received(:[]).with('test_session_data')
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowserFactory do
6
+ subject(:browser_factory) { described_class.new }
7
+
8
+ let(:session) { instance_double(BrowseEverythingSession::ProviderSession) }
9
+ let(:provider_session_class) { class_double(BrowseEverythingSession::ProviderSession).as_stubbed_const(transfer_nested_constants: true) }
10
+ let(:provider_session) { instance_double(BrowseEverythingSession::ProviderSession) }
11
+ let(:provider) { instance_double(BrowseEverything::Driver::Base) }
12
+ let(:browser_class) { class_double(BrowseEverything::Browser).as_stubbed_const(transfer_nested_constants: true) }
13
+ let(:browser) { instance_double(BrowseEverything::Browser) }
14
+
15
+ before do
16
+ allow(provider).to receive(:key).and_return('test-provider')
17
+ allow(provider).to receive(:token=)
18
+ allow(browser).to receive(:providers).and_return('test-provider' => provider)
19
+ allow(browser_class).to receive(:new).and_return(browser)
20
+ allow(provider_session).to receive(:token).and_return('test-token')
21
+ allow(provider_session_class).to receive(:for).and_return(provider_session)
22
+ end
23
+
24
+ describe '.for' do
25
+ it 'retrieves a driver by name' do
26
+ expect(described_class.for(name: 'test-provider')).to eq provider
27
+ end
28
+ end
29
+
30
+ describe '.build' do
31
+ before do
32
+ described_class.build(session: session, url_options: url_options)
33
+ end
34
+
35
+ it 'initializes a Browser Object and provides it with a sessionized access token' do
36
+ expect(browser_class).to have_received(:new).with(url_options)
37
+ expect(provider_session_class).to have_received(:for).with(session: session, name: 'test-provider'.to_sym)
38
+ end
39
+ end
40
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,22 +1,46 @@
1
+ # frozen_string_literal: true
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require "bundler/setup"
4
+
5
+ def coverage_needed?
6
+ ENV['COVERAGE'] || ENV['TRAVIS']
7
+ end
8
+
9
+ if coverage_needed?
10
+ require 'simplecov'
11
+ require 'coveralls'
12
+ SimpleCov.root(File.expand_path('../..', __FILE__))
13
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
14
+ [
15
+ SimpleCov::Formatter::HTMLFormatter,
16
+ Coveralls::SimpleCov::Formatter
17
+ ]
18
+ )
19
+ SimpleCov.start('rails') do
20
+ add_filter '/.internal_test_app'
21
+ add_filter '/lib/browse_everything/engine.rb'
22
+ add_filter '/lib/browse_everything/version.rb'
23
+ add_filter '/lib/generators'
24
+ add_filter '/spec'
25
+ add_filter '/tasks'
26
+ end
27
+ end
28
+
1
29
  require 'engine_cart'
2
30
  require File.expand_path('config/environment', EngineCart.destination)
31
+ EngineCart.load_application!
32
+
33
+ require 'capybara/rails'
34
+ require 'capybara/rspec'
3
35
  require 'rspec'
4
36
  require 'rspec/rails'
5
37
  require 'rspec/its'
6
- require 'webmock/rspec'
7
- require 'simplecov'
8
38
  require 'vcr'
9
- require 'capybara/rails'
10
- require 'capybara/rspec'
11
- require 'support/rake'
12
- require 'coveralls'
13
-
14
- Coveralls.wear!
15
- EngineCart.load_application!
39
+ require 'webmock/rspec'
16
40
 
17
- SimpleCov.start do
18
- add_filter '/spec/'
19
- end
41
+ # Requires supporting ruby files with custom matchers and macros, etc,
42
+ # in spec/support/ and its subdirectories.
43
+ Dir[Pathname.new(File.expand_path('support/**/*.rb', __dir__))].each { |f| require f }
20
44
 
21
45
  VCR.configure do |c|
22
46
  c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
@@ -25,14 +49,11 @@ VCR.configure do |c|
25
49
  c.ignore_localhost = true
26
50
  end
27
51
 
28
- Capybara.default_driver = :rack_test # This is a faster driver
29
- Capybara.javascript_driver = :poltergeist # This is slower
30
- Capybara.default_max_wait_time = ENV['TRAVIS'] ? 30 : 15
31
-
32
52
  RSpec.configure do |config|
33
53
  config.expect_with :rspec do |c|
34
- c.syntax = [:should, :expect]
54
+ c.syntax = %i[should expect]
35
55
  end
56
+ config.include WaitForAjax, type: :feature
36
57
  end
37
58
 
38
59
  module BrowserConfigHelper
@@ -46,7 +67,7 @@ module BrowserConfigHelper
46
67
 
47
68
  def stub_configuration
48
69
  BrowseEverything.configure('file_system' => {
49
- home: File.expand_path('../fixtures/file_system', __FILE__)
70
+ home: File.expand_path('fixtures/file_system', __dir__)
50
71
  },
51
72
  'box' => {
52
73
  client_id: 'BoxClientId',
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class FileHandlerController < ApplicationController
2
- def index
3
- end
4
+ def index; end
4
5
 
5
- def main
6
- end
6
+ def main; end
7
7
 
8
8
  def update
9
9
  render json: params[:selected_files].to_json
@@ -6,7 +6,7 @@
6
6
  <%= form_tag('/file', id: 'main_form', method: 'post') do %>
7
7
  <%= button_tag("Browse", type: 'button', class: 'btn btn-large btn-success', id: "browse-btn",
8
8
  'data-toggle' => 'browse-everything', 'data-route' => browse_everything_engine.root_path,
9
- 'data-target' => '#main_form' ) %>
9
+ 'data-target' => '#main_form') %>
10
10
  <%= button_tag("Submit", type: 'submit', class: 'btn btn-large btn-primary', id: "submit-btn") %>
11
11
  <% end %>
12
12
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'selenium-webdriver'
4
+
5
+ Capybara.javascript_driver = :headless_chrome
6
+
7
+ Capybara.register_driver :headless_chrome do |app|
8
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
9
+ chromeOptions: { args: %w[headless disable-gpu no-sandbox] }
10
+ )
11
+
12
+ Capybara::Selenium::Driver.new(app,
13
+ browser: :chrome,
14
+ desired_capabilities: capabilities)
15
+ end
16
+
17
+ Capybara.default_max_wait_time = 5
data/spec/support/rake.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
 
3
5
  module RakeHelper
@@ -29,7 +31,7 @@ module RakeHelper
29
31
  rescue SystemExit => e
30
32
  puts "error = #{e.inspect}"
31
33
  end
32
- return "Output: #{out.string}\n Errors:#{err.string}"
34
+ "Output: #{out.string}\n Errors:#{err.string}"
33
35
  ensure
34
36
  $stdout = STDOUT
35
37
  $stdout = STDERR
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WaitForAjax
4
+ def wait_for_ajax
5
+ Timeout.timeout(Capybara.default_max_wait_time) do
6
+ loop until finished_all_ajax_requests?
7
+ end
8
+ sleep 1
9
+ end
10
+
11
+ def finished_all_ajax_requests?
12
+ page.evaluate_script('jQuery.active').zero?
13
+ end
14
+ end
@@ -1 +1,2 @@
1
1
  gem 'jquery-rails'
2
+ gem 'puma-rails'
@@ -1,7 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators'
2
4
 
3
5
  class TestAppGenerator < Rails::Generators::Base
4
- source_root File.expand_path('../../../../spec/support', __FILE__)
6
+ source_root File.expand_path('../../../../spec/test_app_templates/', __FILE__)
7
+
8
+ def install_engine
9
+ generate 'browse_everything:install -f'
10
+ end
5
11
 
6
12
  def run_config_generator
7
13
  generate 'browse_everything:config'
@@ -42,8 +48,8 @@ class TestAppGenerator < Rails::Generators::Base
42
48
  end
43
49
 
44
50
  def create_test_route
45
- copy_file 'app/controllers/file_handler_controller.rb', 'app/controllers/file_handler_controller.rb'
46
- copy_file 'app/views/file_handler/main.html.erb', 'app/views/file_handler/main.html.erb'
47
- copy_file 'app/views/file_handler/index.html.erb', 'app/views/file_handler/index.html.erb'
51
+ copy_file '../support/app/controllers/file_handler_controller.rb', 'app/controllers/file_handler_controller.rb'
52
+ copy_file '../support/app/views/file_handler/main.html.erb', 'app/views/file_handler/main.html.erb'
53
+ copy_file '../support/app/views/file_handler/index.html.erb', 'app/views/file_handler/index.html.erb'
48
54
  end
49
55
  end
@@ -1,17 +1,20 @@
1
- describe 'browse_everything/_file.html.erb', type: :view do
1
+ # frozen_string_literal: true
2
+
3
+ describe 'browse_everything/_files.html.erb', type: :view do
2
4
  let(:file) do
3
5
  BrowseEverything::FileEntry.new(
4
6
  'file_id_01234', 'my_provider:/location/pa/th/file.m4v',
5
- 'file.m4v', 1024 * 1024 * 1024, Time.now, false
7
+ 'file.m4v', 1024 * 1024 * 1024, Time.current, false
6
8
  )
7
9
  end
8
10
  let(:container) do
9
11
  BrowseEverything::FileEntry.new(
10
12
  'dir_id_01234', 'my_provider:/location/pa/th/dir',
11
- 'dir', 0, Time.now, true
13
+ 'dir', 0, Time.current, true
12
14
  )
13
15
  end
14
- let(:provider) { double('provider') }
16
+
17
+ let(:provider) { instance_double(BrowseEverything::Driver::Base) }
15
18
  let(:page) { Capybara::Node::Simple.new(rendered) }
16
19
 
17
20
  before do
@@ -21,15 +24,21 @@ describe 'browse_everything/_file.html.erb', type: :view do
21
24
  allow(view).to receive(:parent).and_return('parent')
22
25
  allow(view).to receive(:provider_name).and_return('my provider')
23
26
  allow(provider).to receive(:config).and_return(config)
27
+
28
+ allow(view).to receive(:provider_contents).and_return provider_contents
24
29
  end
25
30
 
26
31
  describe 'a file' do
32
+ let(:config) { {} }
33
+ let(:provider_contents) { [file] }
34
+
27
35
  before do
28
36
  allow(view).to receive(:file).and_return(file)
29
37
  render
30
38
  end
31
- context 'file not too big' do
39
+ context 'when a file is not too big' do
32
40
  let(:config) { { max_upload_file_size: (5 * 1024 * 1024 * 1024) } }
41
+
33
42
  it 'draws link' do
34
43
  expect(page).to have_selector('a.ev-link')
35
44
  end
@@ -39,38 +48,35 @@ describe 'browse_everything/_file.html.erb', type: :view do
39
48
  end
40
49
  end
41
50
 
42
- context 'max not configured' do
43
- let(:config) { {} }
51
+ context 'when a maximum file size is not configured' do
44
52
  it 'draws link' do
45
53
  expect(page).to have_selector('a.ev-link')
46
54
  end
47
55
  end
48
56
 
49
- context 'file too big' do
57
+ context 'when a file is too big' do
50
58
  let(:config) { { max_upload_file_size: 1024 } }
59
+
51
60
  it 'draws link' do
52
61
  expect(page).not_to have_selector('a.ev-link')
53
62
  end
54
63
  end
55
64
 
56
- context 'multi-select' do
57
- let(:config) { {} }
58
- it 'does not have a checkbox' do
59
- expect(page).not_to have_selector('input.ev-select-all')
60
- end
65
+ it 'does not have a checkbox' do
66
+ expect(page).not_to have_selector('input.ev-select-all')
61
67
  end
62
68
  end
63
69
 
64
70
  describe 'a directory' do
71
+ let(:provider_contents) { [container] }
72
+
65
73
  before do
66
74
  allow(view).to receive(:file).and_return(container)
67
75
  render
68
76
  end
69
- context 'multi-select' do
70
- let(:config) { {} }
71
- it 'has the select-all checkbox' do
72
- expect(page).to have_selector('input.ev-select-all')
73
- end
77
+
78
+ it 'has the select-all checkbox' do
79
+ expect(page).to have_selector('input.ev-select-all')
74
80
  end
75
81
  end
76
82
  end