browse-everything 0.15.1 → 0.16.0

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.
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