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