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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
 
3
5
  # Run the jasmine tests by running the jasmine:ci rake command and parses the output for failures.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Use this file to set/override Jasmine configuration options
2
3
  # You can remove it if you don't need it.
3
4
  # This file is loaded *after* jasmine.yml is interpreted.
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe BrowseEverything::Auth::Google::Credentials do
4
+ subject(:credentials) { described_class.new }
5
+
6
+ describe '#fetch_access_token' do
7
+ let(:response) { double }
8
+ before do
9
+ WebMock.disable!
10
+
11
+ allow(response).to receive(:status_code).and_return('200')
12
+ allow(response).to receive(:body).and_return('{}')
13
+ allow(response).to receive(:header).and_return({ content_type: 'application/json' })
14
+
15
+ connection = instance_double(Faraday::Connection)
16
+ allow(connection).to receive(:post).and_return(response)
17
+ faraday = class_double('Faraday').as_stubbed_const(transfer_nested_constants: true)
18
+ allow(faraday).to receive(:default_connection).and_return(connection)
19
+
20
+ end
21
+
22
+ context 'when an access has already been retrieved' do
23
+ before do
24
+ credentials.access_token = 'test-token'
25
+ end
26
+ it 'generates a Hash if an access token has already been set' do
27
+ expect(credentials.fetch_access_token).to be_a Hash
28
+ expect(credentials.fetch_access_token).to include('access_token' => 'test-token')
29
+ end
30
+ end
31
+
32
+ it 'requests a new token from the OAuth provider' do
33
+ expect(credentials.fetch_access_token).to be_a Hash
34
+ expect(credentials.fetch_access_token).to eq({})
35
+ end
36
+
37
+ after do
38
+ WebMock.enable!
39
+ end
40
+ end
41
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe BrowseEverythingHelper do
2
4
  let(:test_class) do
3
5
  Class.new do
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ include BrowserConfigHelper
4
+
5
+ describe BrowseEverything::Browser do
6
+ let(:file_config) do
7
+ "file_system:\n home: '/file/config/home'\ndropbox:\n client_id: 'DropboxId'\n client_secret: 'DropboxClientSecret'"
8
+ end
9
+
10
+ let(:global_config) do
11
+ {
12
+ file_system: {
13
+ home: '/global/config/home'
14
+ },
15
+ dropbox: {
16
+ client_id: 'DropboxId',
17
+ client_secret: 'DropboxClientSecret'
18
+ }
19
+ }
20
+ end
21
+
22
+ let(:local_config) do
23
+ {
24
+ file_system: {
25
+ home: '/local/config/home'
26
+ },
27
+ dropbox: {
28
+ client_id: 'DropboxId',
29
+ client_secret: 'DropboxClientSecret'
30
+ },
31
+ url_options: url_options
32
+ }
33
+ end
34
+
35
+ describe 'file config' do
36
+ let(:browser) { described_class.new(url_options) }
37
+
38
+ before do
39
+ BrowseEverything.config = nil
40
+ allow(File).to receive(:read).and_return file_config
41
+ end
42
+
43
+ it 'has 2 providers' do
44
+ expect(browser.providers.keys).to eq(%w[file_system dropbox])
45
+ expect(browser.providers[:file_system]).to be_a BrowseEverything::Driver::FileSystem
46
+ expect(browser.providers[:dropbox]).to be_a BrowseEverything::Driver::Dropbox
47
+ end
48
+
49
+ it 'uses the file configuration' do
50
+ expect(browser.providers[:file_system].config[:home]).to eq('/file/config/home')
51
+ expect(browser.providers['file_system'].config['home']).to eq('/file/config/home')
52
+ end
53
+ end
54
+
55
+ describe 'global config' do
56
+ let(:browser) { described_class.new(url_options) }
57
+
58
+ before { BrowseEverything.configure(global_config) }
59
+
60
+ it 'has 2 providers' do
61
+ expect(browser.providers.keys).to eq(%w[file_system dropbox])
62
+ expect(browser.providers[:file_system]).to be_a BrowseEverything::Driver::FileSystem
63
+ expect(browser.providers[:dropbox]).to be_a BrowseEverything::Driver::Dropbox
64
+ end
65
+
66
+ it 'uses the global configuration' do
67
+ expect(browser.providers[:file_system].config[:home]).to eq('/global/config/home')
68
+ expect(browser.providers['file_system'].config['home']).to eq('/global/config/home')
69
+ end
70
+ end
71
+
72
+ describe 'local config' do
73
+ let(:browser) { described_class.new(local_config) }
74
+
75
+ it 'has 2 providers' do
76
+ expect(browser.providers.keys).to eq(%w[file_system dropbox])
77
+ expect(browser.providers[:file_system]).to be_a BrowseEverything::Driver::FileSystem
78
+ expect(browser.providers[:dropbox]).to be_a BrowseEverything::Driver::Dropbox
79
+ end
80
+
81
+ it 'uses the local configuration' do
82
+ file_provider = browser.providers[:file_system]
83
+ expect(file_provider.config[:home]).to eq('/local/config/home')
84
+ expect(file_provider.config['home']).to eq('/local/config/home')
85
+ end
86
+ end
87
+
88
+ context 'with an unknown provider' do
89
+ let(:browser) do
90
+ described_class.new(foo: { key: 'bar', secret: 'baz' }, url_options: url_options)
91
+ end
92
+
93
+ before do
94
+ allow(Rails.logger).to receive(:warn)
95
+ end
96
+
97
+ it 'logs a warning' do
98
+ browser
99
+ expect(Rails.logger).to have_received(:warn).with('Unknown provider: foo')
100
+ end
101
+ end
102
+
103
+ describe '#first_provider' do
104
+ subject(:browser) { described_class.new(url_options) }
105
+ it 'retrieves the first configured provider' do
106
+ expect(browser.first_provider).to be_a BrowseEverything::Driver::FileSystem
107
+ end
108
+ end
109
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  include BrowserConfigHelper
2
4
 
3
5
  describe BrowseEverything::Driver::Base do
@@ -14,18 +16,17 @@ describe BrowseEverything::Driver::Base do
14
16
  end
15
17
  describe '#connect' do
16
18
  subject { driver.connect({}, {}) }
19
+
17
20
  it { is_expected.to be_blank }
18
21
  end
19
22
  describe '#contents' do
20
23
  subject { driver.contents('') }
24
+
21
25
  it { is_expected.to be_empty }
22
26
  end
23
- describe '#details' do
24
- subject { driver.details('/path/to/foo.txt') }
25
- it { is_expected.to be_nil }
26
- end
27
27
  describe '#link_for' do
28
28
  subject { driver.link_for('/path/to/foo.txt') }
29
+
29
30
  it { is_expected.to contain_exactly('/path/to/foo.txt', file_name: 'foo.txt') }
30
31
  end
31
32
  end
@@ -1,9 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  include BrowserConfigHelper
2
4
 
3
5
  describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :none } do
4
- before(:all) { stub_configuration }
5
- after(:all) { unstub_configuration }
6
-
7
6
  let(:browser) { BrowseEverything::Browser.new(url_options) }
8
7
  let(:provider) { browser.providers['box'] }
9
8
  let(:auth_params) do
@@ -33,7 +32,15 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
33
32
  }
34
33
  end
35
34
 
36
- subject { provider }
35
+ subject { provider }
36
+
37
+ before do
38
+ stub_configuration
39
+ end
40
+
41
+ after do
42
+ unstub_configuration
43
+ end
37
44
 
38
45
  its(:name) { is_expected.to eq('Box') }
39
46
  its(:key) { is_expected.to eq('box') }
@@ -55,6 +62,7 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
55
62
 
56
63
  describe '#authorized?' do
57
64
  subject { provider.authorized? }
65
+
58
66
  context 'when the access token is not registered' do
59
67
  it { is_expected.to be(false) }
60
68
  end
@@ -73,9 +81,13 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
73
81
  end
74
82
 
75
83
  describe '#connect' do
84
+ before do
85
+ allow(provider).to receive(:register_access_token)
86
+ end
87
+
76
88
  it 'registers new tokens' do
77
- expect(provider).to receive(:register_access_token).with(kind_of(OAuth2::AccessToken))
78
89
  provider.connect(auth_params, 'data')
90
+ expect(provider).to have_received(:register_access_token).with(kind_of(OAuth2::AccessToken))
79
91
  end
80
92
  end
81
93
 
@@ -90,6 +102,7 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
90
102
 
91
103
  describe 'the first item' do
92
104
  subject { long_file }
105
+
93
106
  its(:name) { is_expected.to start_with('A very looooooooooooong box folder') }
94
107
  its(:location) { is_expected.to eq('box:20375782799') }
95
108
  it { is_expected.to be_container }
@@ -97,6 +110,7 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
97
110
 
98
111
  describe 'the SaS - Development Team directory' do
99
112
  subject { sas_directory }
113
+
100
114
  its(:name) { is_expected.to eq('SaS - Development Team') }
101
115
  its(:location) { is_expected.to eq('box:2459961273') }
102
116
  its(:id) { is_expected.to eq('2459961273') }
@@ -105,6 +119,7 @@ describe BrowseEverything::Driver::Box, vcr: { cassette_name: 'box', record: :no
105
119
 
106
120
  describe 'a file' do
107
121
  subject { tar_file }
122
+
108
123
  its(:name) { is_expected.to eq('failed.tar.gz') }
109
124
  its(:size) { is_expected.to eq(28_650_839) }
110
125
  its(:location) { is_expected.to eq('box:25581309763') }
@@ -1,9 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  include BrowserConfigHelper
2
4
 
3
5
  describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', record: :none } do
4
- before(:all) { stub_configuration }
5
- after(:all) { unstub_configuration }
6
-
7
6
  let(:browser) { BrowseEverything::Browser.new(url_options) }
8
7
  let(:provider) { browser.providers['dropbox'] }
9
8
  let(:provider_yml) do
@@ -13,6 +12,14 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
13
12
  }
14
13
  end
15
14
 
15
+ before do
16
+ stub_configuration
17
+ end
18
+
19
+ after do
20
+ unstub_configuration
21
+ end
22
+
16
23
  describe '#validate_config' do
17
24
  it 'raises and error with an incomplete configuration' do
18
25
  expect { BrowseEverything::Driver::Dropbox.new({}) }.to raise_error(BrowseEverything::InitializationError)
@@ -25,6 +32,7 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
25
32
 
26
33
  describe 'simple properties' do
27
34
  subject { provider }
35
+
28
36
  its(:name) { is_expected.to eq('Dropbox') }
29
37
  its(:key) { is_expected.to eq('dropbox') }
30
38
  its(:icon) { is_expected.to be_a(String) }
@@ -32,20 +40,23 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
32
40
 
33
41
  context 'with a valid configuration' do
34
42
  let(:driver) { described_class.new(provider_yml) }
43
+
35
44
  before { driver.connect({ code: 'code' }, {}) }
36
45
 
37
46
  describe '#auth_link' do
38
47
  subject { driver.auth_link }
48
+
39
49
  it { is_expected.to start_with('https://www.dropbox.com/oauth2/authorize') }
40
50
  end
41
51
 
42
52
  describe '#authorized?' do
43
53
  subject { driver }
54
+
44
55
  it { is_expected.to be_authorized }
45
56
  end
46
57
 
47
58
  describe '#contents' do
48
- context 'within the root folder' do
59
+ context 'when in the root folder' do
49
60
  let(:contents) { driver.contents }
50
61
 
51
62
  it 'retrieves all folders the root folders' do
@@ -62,20 +73,6 @@ describe BrowseEverything::Driver::Dropbox, vcr: { cassette_name: 'dropbox', rec
62
73
  end
63
74
  end
64
75
 
65
- describe '#details' do
66
- subject(:file_metadata) { driver.details('/Getting Started.pdf') }
67
-
68
- it 'retrieves the metadata for a file' do
69
- expect(file_metadata).to be_a BrowseEverything::FileEntry
70
- expect(file_metadata.id).to eq '/Getting Started.pdf'
71
- expect(file_metadata.location).to eq 'dropbox:/Getting Started.pdf'
72
- expect(file_metadata.name).to eq 'Getting Started.pdf'
73
- expect(file_metadata.size).to eq 249159
74
- expect(file_metadata.mtime).to be_a Time
75
- expect(file_metadata.container?).to eq false
76
- end
77
- end
78
-
79
76
  describe '#link_for' do
80
77
  subject(:link_args) { driver.link_for('/Getting Started.pdf') }
81
78
 
@@ -1,18 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  include BrowserConfigHelper
2
4
 
3
5
  describe BrowseEverything::Driver::FileSystem do
4
- before(:all) { stub_configuration }
5
- after(:all) { unstub_configuration }
6
6
  let(:home) { File.expand_path(BrowseEverything.config['file_system'][:home]) }
7
7
  let(:browser) { BrowseEverything::Browser.new(url_options) }
8
8
  let(:provider) { browser.providers['file_system'] }
9
9
 
10
+ before do
11
+ stub_configuration
12
+ end
13
+
14
+ after do
15
+ unstub_configuration
16
+ end
17
+
10
18
  it '#validate_config' do
11
19
  expect { described_class.new({}) }.to raise_error(BrowseEverything::InitializationError)
12
20
  end
13
21
 
14
22
  describe 'simple properties' do
15
23
  subject { provider }
24
+
16
25
  its(:name) { is_expected.to eq('File System') }
17
26
  its(:key) { is_expected.to eq('file_system') }
18
27
  its(:icon) { is_expected.to be_a(String) }
@@ -20,50 +29,44 @@ describe BrowseEverything::Driver::FileSystem do
20
29
  end
21
30
 
22
31
  describe '#contents' do
23
- context 'root directory' do
32
+ context 'when in a root directory' do
24
33
  let(:contents) { provider.contents('/') }
25
- context '[0]' do
34
+
35
+ context 'when there is one directory' do
26
36
  subject { contents[0] }
37
+
27
38
  its(:name) { is_expected.to eq('dir_1') }
28
39
  specify { is_expected.to be_container }
29
40
  end
30
- context '[1]' do
41
+ context 'when there are multiple directories' do
31
42
  subject { contents[1] }
43
+
32
44
  its(:name) { is_expected.to eq('dir_2') }
33
45
  specify { is_expected.to be_container }
34
46
  end
35
- context '[2]' do
47
+ context 'when there is a PDF' do
36
48
  subject { contents[2] }
49
+
37
50
  its(:name) { is_expected.to eq('file 1.pdf') }
38
51
  its(:size) { is_expected.to eq(2256) }
39
52
  its(:location) { is_expected.to eq("file_system:#{File.join(home, 'file 1.pdf')}") }
40
53
  its(:type) { is_expected.to eq('application/pdf') }
41
54
  specify { is_expected.not_to be_container }
42
55
  end
43
- context '[3]' do
44
- subject { contents[3] }
45
- its(:name) { is_expected.to eq('file_1.pdf') }
46
- its(:size) { is_expected.to eq(2256) }
47
- its(:location) { is_expected.to eq("file_system:#{File.join(home, 'file_1.pdf')}") }
48
- its(:type) { is_expected.to eq('application/pdf') }
49
- specify { is_expected.not_to be_container }
50
- end
51
56
  end
52
57
 
53
- context 'subdirectory' do
58
+ context 'when there is a subdirectory' do
54
59
  let(:contents) { provider.contents('/dir_1') }
55
- context '[0]' do
56
- subject { contents[0] }
57
- its(:name) { is_expected.to eq('..') }
58
- specify { is_expected.to be_container }
59
- end
60
- context '[1]' do
61
- subject { contents[1] }
60
+
61
+ context 'when there is a directory' do
62
+ subject { contents.first }
63
+
62
64
  its(:name) { is_expected.to eq('dir_3') }
63
65
  specify { is_expected.to be_container }
64
66
  end
65
- context '[2]' do
66
- subject { contents[2] }
67
+ context 'when there is a text file' do
68
+ subject { contents.last }
69
+
67
70
  its(:name) { is_expected.to eq('file_2.txt') }
68
71
  its(:location) { is_expected.to eq("file_system:#{File.join(home, 'dir_1/file_2.txt')}") }
69
72
  its(:type) { is_expected.to eq('text/plain') }
@@ -71,10 +74,12 @@ describe BrowseEverything::Driver::FileSystem do
71
74
  end
72
75
  end
73
76
 
74
- context 'single file' do
77
+ context 'when there is a single file' do
75
78
  let(:contents) { provider.contents('/dir_1/dir_3/file_3.m4v') }
76
- context '[0]' do
79
+
80
+ context 'when there is a m4v file' do
77
81
  subject { contents[0] }
82
+
78
83
  its(:name) { is_expected.to eq('file_3.m4v') }
79
84
  its(:location) { is_expected.to eq("file_system:#{File.join(home, 'dir_1/dir_3/file_3.m4v')}") }
80
85
  its(:size) { is_expected.to eq(3879) }
@@ -86,6 +91,7 @@ describe BrowseEverything::Driver::FileSystem do
86
91
 
87
92
  describe "#link_for('/path/to/file')" do
88
93
  subject { provider.link_for('/path/to/file') }
94
+
89
95
  it { is_expected.to eq(['file:///path/to/file', { file_name: 'file', file_size: 0 }]) }
90
96
  end
91
97
  end