sq-asset_sync 2.0.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 (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +42 -0
  5. data/Appraisals +15 -0
  6. data/CHANGELOG.md +738 -0
  7. data/Gemfile +7 -0
  8. data/README.md +466 -0
  9. data/Rakefile +44 -0
  10. data/asset_sync.gemspec +38 -0
  11. data/docs/heroku.md +36 -0
  12. data/gemfiles/rails_3.1.gemfile +10 -0
  13. data/gemfiles/rails_3.2.gemfile +10 -0
  14. data/gemfiles/rails_4.0.gemfile +10 -0
  15. data/gemfiles/rails_4.1.gemfile +10 -0
  16. data/kochiku.yml +7 -0
  17. data/lib/asset_sync.rb +15 -0
  18. data/lib/asset_sync/asset_sync.rb +73 -0
  19. data/lib/asset_sync/config.rb +226 -0
  20. data/lib/asset_sync/engine.rb +53 -0
  21. data/lib/asset_sync/multi_mime.rb +16 -0
  22. data/lib/asset_sync/railtie.rb +5 -0
  23. data/lib/asset_sync/storage.rb +291 -0
  24. data/lib/asset_sync/version.rb +3 -0
  25. data/lib/generators/asset_sync/install_generator.rb +67 -0
  26. data/lib/generators/asset_sync/templates/asset_sync.rb +41 -0
  27. data/lib/generators/asset_sync/templates/asset_sync.yml +43 -0
  28. data/lib/tasks/asset_sync.rake +30 -0
  29. data/script/ci +31 -0
  30. data/spec/dummy_app/Rakefile +30 -0
  31. data/spec/dummy_app/app/assets/javascripts/application.js +1 -0
  32. data/spec/fixtures/aws_with_yml/config/asset_sync.yml +25 -0
  33. data/spec/fixtures/google_with_yml/config/asset_sync.yml +19 -0
  34. data/spec/fixtures/rackspace_with_yml/config/asset_sync.yml +20 -0
  35. data/spec/fixtures/with_invalid_yml/config/asset_sync.yml +24 -0
  36. data/spec/integration/aws_integration_spec.rb +77 -0
  37. data/spec/spec_helper.rb +64 -0
  38. data/spec/unit/asset_sync_spec.rb +257 -0
  39. data/spec/unit/google_spec.rb +142 -0
  40. data/spec/unit/multi_mime_spec.rb +48 -0
  41. data/spec/unit/rackspace_spec.rb +90 -0
  42. data/spec/unit/railsless_spec.rb +72 -0
  43. data/spec/unit/storage_spec.rb +244 -0
  44. metadata +248 -0
@@ -0,0 +1,142 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AssetSync do
4
+ include_context "mock Rails without_yml"
5
+
6
+ describe 'with initializer' do
7
+ before(:each) do
8
+ AssetSync.config = AssetSync::Config.new
9
+ AssetSync.configure do |config|
10
+ config.fog_provider = 'Google'
11
+ config.google_storage_access_key_id = 'aaaa'
12
+ config.google_storage_secret_access_key = 'bbbb'
13
+ config.fog_directory = 'mybucket'
14
+ config.existing_remote_files = "keep"
15
+ end
16
+ end
17
+
18
+ it "should configure provider as Google" do
19
+ expect(AssetSync.config.fog_provider).to eq('Google')
20
+ expect(AssetSync.config).to be_google
21
+ end
22
+
23
+ it "should should keep existing remote files" do
24
+ expect(AssetSync.config.existing_remote_files?).to eq(true)
25
+ end
26
+
27
+ it "should configure google_storage_access_key_id" do
28
+ expect(AssetSync.config.google_storage_access_key_id).to eq("aaaa")
29
+ end
30
+
31
+ it "should configure google_storage_secret_access_key" do
32
+ expect(AssetSync.config.google_storage_secret_access_key).to eq("bbbb")
33
+ end
34
+
35
+ it "should configure fog_directory" do
36
+ expect(AssetSync.config.fog_directory).to eq("mybucket")
37
+ end
38
+
39
+ it "should configure existing_remote_files" do
40
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
41
+ end
42
+
43
+ it "should default gzip_compression to false" do
44
+ expect(AssetSync.config.gzip_compression).to be_falsey
45
+ end
46
+
47
+ it "should default manifest to false" do
48
+ expect(AssetSync.config.manifest).to be_falsey
49
+ end
50
+ end
51
+
52
+ describe 'from yml' do
53
+ before(:each) do
54
+ set_rails_root('google_with_yml')
55
+ AssetSync.config = AssetSync::Config.new
56
+ end
57
+
58
+ it "should configure google_storage_access_key_id" do
59
+ expect(AssetSync.config.google_storage_access_key_id).to eq("xxxx")
60
+ end
61
+
62
+ it "should configure google_storage_secret_access_key" do
63
+ expect(AssetSync.config.google_storage_secret_access_key).to eq("zzzz")
64
+ end
65
+
66
+ it "should configure google_storage_access_key" do
67
+ expect(AssetSync.config.fog_directory).to eq("rails_app_test")
68
+ end
69
+
70
+ it "should configure google_storage_access_key" do
71
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
72
+ end
73
+
74
+ it "should default gzip_compression to false" do
75
+ expect(AssetSync.config.gzip_compression).to be_falsey
76
+ end
77
+
78
+ it "should default manifest to false" do
79
+ expect(AssetSync.config.manifest).to be_falsey
80
+ end
81
+ end
82
+
83
+ describe 'with no configuration' do
84
+ before(:each) do
85
+ AssetSync.config = AssetSync::Config.new
86
+ end
87
+
88
+ it "should be invalid" do
89
+ expect{ AssetSync.sync }.to raise_error()
90
+ end
91
+ end
92
+
93
+ describe 'with fail_silent configuration' do
94
+ before(:each) do
95
+ allow(AssetSync).to receive(:stderr).and_return(StringIO.new)
96
+ AssetSync.config = AssetSync::Config.new
97
+ AssetSync.configure do |config|
98
+ config.fail_silently = true
99
+ end
100
+ end
101
+
102
+ it "should not raise an invalid exception" do
103
+ expect{ AssetSync.sync }.not_to raise_error()
104
+ end
105
+ end
106
+
107
+ describe 'with gzip_compression enabled' do
108
+ before(:each) do
109
+ AssetSync.config = AssetSync::Config.new
110
+ AssetSync.config.gzip_compression = true
111
+ end
112
+
113
+ it "config.gzip? should be true" do
114
+ expect(AssetSync.config.gzip?).to be_truthy
115
+ end
116
+ end
117
+
118
+ describe 'with manifest enabled' do
119
+ before(:each) do
120
+ AssetSync.config = AssetSync::Config.new
121
+ AssetSync.config.manifest = true
122
+ end
123
+
124
+ it "config.manifest should be true" do
125
+ expect(AssetSync.config.manifest).to be_truthy
126
+ end
127
+
128
+ it "config.manifest_path should default to public/assets.." do
129
+ expect(AssetSync.config.manifest_path).to match(/public\/assets\/manifest.yml/)
130
+ end
131
+
132
+ it "config.manifest_path should default to public/assets.." do
133
+ Rails.application.config.assets.manifest = "/var/assets"
134
+ expect(AssetSync.config.manifest_path).to eq("/var/assets/manifest.yml")
135
+ end
136
+
137
+ it "config.manifest_path should default to public/custom_assets.." do
138
+ Rails.application.config.assets.prefix = 'custom_assets'
139
+ expect(AssetSync.config.manifest_path).to match(/public\/custom_assets\/manifest.yml/)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AssetSync::MultiMime do
4
+
5
+ before(:each) do
6
+ Object.send(:remove_const, :Rails) if defined?(Rails)
7
+ Object.send(:remove_const, :Mime) if defined?(Mime)
8
+ Object.send(:remove_const, :Rack) if defined?(Rack)
9
+ end
10
+
11
+ after(:each) do
12
+ Object.send(:remove_const, :Rails) if defined?(Rails)
13
+ Object.send(:remove_const, :Mime) if defined?(Mime)
14
+ Object.send(:remove_const, :Rack) if defined?(Rack)
15
+ end
16
+
17
+ after(:all) do
18
+ require 'mime/types'
19
+ end
20
+
21
+ describe 'Mime::Type' do
22
+
23
+ it 'should detect mime type' do
24
+ require 'rails'
25
+ expect(AssetSync::MultiMime.lookup('css')).to eq("text/css")
26
+ end
27
+
28
+ end
29
+
30
+ describe 'Rack::Mime' do
31
+
32
+ it 'should detect mime type' do
33
+ require 'rack/mime'
34
+ expect(AssetSync::MultiMime.lookup('css')).to eq("text/css")
35
+ end
36
+
37
+ end
38
+
39
+ describe 'MIME::Types' do
40
+
41
+ it 'should detect mime type' do
42
+ require 'mime/types'
43
+ expect(AssetSync::MultiMime.lookup('css')).to eq("text/css")
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AssetSync do
4
+ include_context "mock Rails"
5
+
6
+ describe 'using Rackspace with initializer' do
7
+ before(:each) do
8
+ set_rails_root('without_yml')
9
+ AssetSync.config = AssetSync::Config.new
10
+ AssetSync.configure do |config|
11
+ config.fog_provider = 'Rackspace'
12
+ config.fog_directory = 'mybucket'
13
+ config.fog_region = 'dunno'
14
+ config.rackspace_username = 'aaaa'
15
+ config.rackspace_api_key = 'bbbb'
16
+ config.existing_remote_files = 'keep'
17
+ end
18
+ end
19
+
20
+ it "should configure provider as Rackspace" do
21
+ expect(AssetSync.config.fog_provider).to eq('Rackspace')
22
+ expect(AssetSync.config).to be_rackspace
23
+ end
24
+
25
+ it "should keep existing remote files" do
26
+ expect(AssetSync.config.existing_remote_files?).to eq(true)
27
+ end
28
+
29
+ it "should configure rackspace_username" do
30
+ expect(AssetSync.config.rackspace_username).to eq("aaaa")
31
+ end
32
+
33
+ it "should configure rackspace_api_key" do
34
+ expect(AssetSync.config.rackspace_api_key).to eq("bbbb")
35
+ end
36
+
37
+ it "should configure fog_directory" do
38
+ expect(AssetSync.config.fog_directory).to eq("mybucket")
39
+ end
40
+
41
+ it "should configure fog_region" do
42
+ expect(AssetSync.config.fog_region).to eq("dunno")
43
+ end
44
+
45
+ it "should configure existing_remote_files" do
46
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
47
+ end
48
+
49
+ it "should configure existing_remote_files" do
50
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
51
+ end
52
+
53
+ it "should default rackspace_auth_url to false" do
54
+ expect(AssetSync.config.rackspace_auth_url).to be_falsey
55
+ end
56
+
57
+ end
58
+
59
+ describe 'using Rackspace from yml' do
60
+
61
+ before(:each) do
62
+ set_rails_root('rackspace_with_yml')
63
+ AssetSync.config = AssetSync::Config.new
64
+ end
65
+
66
+ it "should keep existing remote files" do
67
+ expect(AssetSync.config.existing_remote_files?).to eq(true)
68
+ end
69
+
70
+ it "should configure rackspace_username" do
71
+ expect(AssetSync.config.rackspace_username).to eq("xxxx")
72
+ end
73
+
74
+ it "should configure rackspace_api_key" do
75
+ expect(AssetSync.config.rackspace_api_key).to eq("zzzz")
76
+ end
77
+
78
+ it "should configure fog_directory" do
79
+ expect(AssetSync.config.fog_directory).to eq("rails_app_test")
80
+ end
81
+
82
+ it "should configure fog_region" do
83
+ expect(AssetSync.config.fog_region).to eq("eu-west-1")
84
+ end
85
+
86
+ it "should configure existing_remote_files" do
87
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AssetSync do
4
+ include_context "mock without Rails"
5
+
6
+ describe 'with initializer' do
7
+ before(:each) do
8
+ AssetSync.config = AssetSync::Config.new
9
+ AssetSync.configure do |config|
10
+ config.fog_provider = 'AWS'
11
+ config.aws_access_key_id = 'aaaa'
12
+ config.aws_secret_access_key = 'bbbb'
13
+ config.fog_directory = 'mybucket'
14
+ config.fog_region = 'eu-west-1'
15
+ config.existing_remote_files = "keep"
16
+ config.prefix = "assets"
17
+ config.public_path = Pathname("./public")
18
+ end
19
+ end
20
+
21
+ it "should have prefix of assets" do
22
+ expect(AssetSync.config.prefix).to eq("assets")
23
+ end
24
+
25
+ it "should have prefix of assets" do
26
+ expect(AssetSync.config.public_path.to_s).to eq("./public")
27
+ end
28
+
29
+ it "should default AssetSync to enabled" do
30
+ expect(AssetSync.config.enabled?).to be_truthy
31
+ expect(AssetSync.enabled?).to be_truthy
32
+ end
33
+
34
+ it "should configure provider as AWS" do
35
+ expect(AssetSync.config.fog_provider).to eq('AWS')
36
+ expect(AssetSync.config).to be_aws
37
+ end
38
+
39
+ it "should should keep existing remote files" do
40
+ expect(AssetSync.config.existing_remote_files?).to eq(true)
41
+ end
42
+
43
+ it "should configure aws_access_key" do
44
+ expect(AssetSync.config.aws_access_key_id).to eq("aaaa")
45
+ end
46
+
47
+ it "should configure aws_secret_access_key" do
48
+ expect(AssetSync.config.aws_secret_access_key).to eq("bbbb")
49
+ end
50
+
51
+ it "should configure aws_access_key" do
52
+ expect(AssetSync.config.fog_directory).to eq("mybucket")
53
+ end
54
+
55
+ it "should configure fog_region" do
56
+ expect(AssetSync.config.fog_region).to eq("eu-west-1")
57
+ end
58
+
59
+ it "should configure existing_remote_files" do
60
+ expect(AssetSync.config.existing_remote_files).to eq("keep")
61
+ end
62
+
63
+ it "should default gzip_compression to false" do
64
+ expect(AssetSync.config.gzip_compression).to be_falsey
65
+ end
66
+
67
+ it "should default manifest to false" do
68
+ expect(AssetSync.config.manifest).to be_falsey
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,244 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AssetSync::Storage do
4
+ include_context "mock Rails without_yml"
5
+
6
+ describe '#upload_files' do
7
+ before(:each) do
8
+ @local_files = ["local_image2.jpg", "assets/manifest-abc.json", "local_image1.jpg", "local_stylesheet1.css", "local_stylesheet2.css"]
9
+ @remote_files = ["local_image.jpg", "local_stylesheet1.css"]
10
+ @config = AssetSync::Config.new
11
+ end
12
+
13
+ it 'always uploads the manifest last', test: true do
14
+ expect(@config).to receive(:manifest_digest_path).and_return('assets/manifest-abc.json')
15
+
16
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
17
+
18
+ storage = AssetSync::Storage.new(@config)
19
+ allow(storage).to receive(:local_files).and_return(@local_files)
20
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
21
+ expect(storage).to receive(:upload_file).ordered.with('local_image2.jpg')
22
+ expect(storage).to receive(:upload_file).ordered.with('local_image1.jpg')
23
+ expect(storage).to receive(:upload_file).ordered.with('local_stylesheet2.css')
24
+ expect(storage).to receive(:upload_file).ordered.with('assets/manifest.json')
25
+ expect(storage).to receive(:upload_file).ordered.with('assets/manifest-abc.json')
26
+
27
+ storage.upload_files
28
+ end
29
+
30
+ context 'with the manifest on the remote', test: true do
31
+ before do
32
+ @remote_files << 'manifest-abc.json'
33
+ end
34
+
35
+ it 'does not upload' do
36
+ expect(@config).to receive(:manifest_digest_path).and_return('assets/manifest-abc.json')
37
+
38
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
39
+
40
+ storage = AssetSync::Storage.new(@config)
41
+
42
+ conn_mock = double
43
+ allow(storage).to receive(:connection).and_return(conn_mock)
44
+ expect(conn_mock).to receive(:head_object).with(@config.fog_directory, 'assets/manifest-abc.json').and_return(
45
+ double(headers: { 'Last-Modified' => CGI.rfc1123_date(Time.now.utc) })
46
+ )
47
+ allow(storage).to receive(:local_files).and_return(@local_files)
48
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
49
+ expect(storage).to_not receive(:upload_file)
50
+
51
+ storage.upload_files
52
+ end
53
+ end
54
+
55
+ it 'should overwrite all remote files if set to ignore' do
56
+ @config.existing_remote_files = 'ignore'
57
+ storage = AssetSync::Storage.new(@config)
58
+ allow(storage).to receive(:local_files).and_return(@local_files)
59
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
60
+
61
+ @local_files.each do |file|
62
+ expect(storage).to receive(:upload_file).with(file)
63
+ end
64
+
65
+ expect(storage).to receive(:upload_file).ordered.with('assets/manifest.json')
66
+ storage.upload_files
67
+ end
68
+
69
+ it 'should allow force overwriting of specific files' do
70
+ @config.always_upload = ['local_image.jpg']
71
+
72
+ storage = AssetSync::Storage.new(@config)
73
+ allow(storage).to receive(:local_files).and_return(@local_files)
74
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
75
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
76
+
77
+ (@local_files - @remote_files + storage.always_upload_files).each do |file|
78
+ expect(storage).to receive(:upload_file).with(file)
79
+ end
80
+
81
+ expect(storage).to receive(:upload_file).ordered.with('assets/manifest.json')
82
+ storage.upload_files
83
+ end
84
+
85
+ it 'should allow to ignore files' do
86
+ @config.ignored_files = ['local_image1.jpg', /local_stylesheet\d\.css/]
87
+
88
+ storage = AssetSync::Storage.new(@config)
89
+ allow(storage).to receive(:local_files).and_return(@local_files)
90
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
91
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
92
+
93
+ (@local_files - @remote_files - storage.ignored_files + storage.always_upload_files).each do |file|
94
+ expect(storage).to receive(:upload_file).with(file)
95
+ end
96
+
97
+ expect(storage).to receive(:upload_file).ordered.with('assets/manifest.json')
98
+ storage.upload_files
99
+ end
100
+
101
+ it 'should upload updated non-fingerprinted files' do
102
+ @local_files = [
103
+ 'public/image.png',
104
+ 'public/image-82389298328.png',
105
+ 'public/image-a8389f9h324.png',
106
+ 'public/application.js',
107
+ 'public/application-b3389d983k1.js',
108
+ 'public/application-ac387d53f31.js',
109
+ 'public',
110
+ ]
111
+ @remote_files = [
112
+ 'public/image.png',
113
+ 'public/image-a8389f9h324.png',
114
+ 'public/application.js',
115
+ 'public/application-b3389d983k1.js',
116
+ ]
117
+
118
+ storage = AssetSync::Storage.new(@config)
119
+ allow(storage).to receive(:local_files).and_return(@local_files)
120
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
121
+ allow(File).to receive(:file?).and_return(true) # Pretend they all exist
122
+
123
+ updated_nonfingerprinted_files = [
124
+ 'public/image.png',
125
+ 'public/application.js',
126
+ ]
127
+ (@local_files - @remote_files + updated_nonfingerprinted_files).each do |file|
128
+ expect(storage).to receive(:upload_file).with(file)
129
+ end
130
+ storage.upload_files
131
+ end
132
+
133
+ it 'should correctly set expire date' do
134
+ local_files = ['file1.jpg', 'file1-1234567890abcdef1234567890abcdef.jpg',
135
+ 'file1-1234567890abcdef1234567890abcdef.jpg.gz']
136
+ local_files += ['dir1/dir2/file2.jpg', 'dir1/dir2/file2-1234567890abcdef1234567890abcdef.jpg',
137
+ 'dir1/dir2/file2-1234567890abcdef1234567890abcdef.jpg.gz']
138
+ remote_files = []
139
+ storage = AssetSync::Storage.new(@config)
140
+ allow(storage).to receive(:local_files).and_return(local_files)
141
+ allow(storage).to receive(:get_remote_files).and_return(remote_files)
142
+ allow(File).to receive(:file?).and_return(true)
143
+ allow(File).to receive(:open).and_return(nil)
144
+
145
+ def check_file(file)
146
+ case file[:key]
147
+ when 'file1.jpg'
148
+ when 'dir1/dir2/file2.jpg'
149
+ !expect(file).not_to include(:cache_control, :expires)
150
+ when %r|file1-1234567890abcdef1234567890abcdef\.jpg|
151
+ when %r|dir1/dir2/file2-1234567890abcdef1234567890abcdef\.jpg|
152
+ expect(file).to include(:cache_control, :expires)
153
+ file.should include(:cache_control, :expires)
154
+ else
155
+ fail
156
+ end
157
+ end
158
+
159
+ files = double()
160
+ local_files.count.times do
161
+ expect(files).to receive(:create) { |file| check_file(file) }
162
+ end
163
+ allow(storage).to receive_message_chain(:bucket, :files).and_return(files)
164
+ storage.upload_files
165
+ end
166
+
167
+ it "shoud invalidate files" do
168
+ @config.cdn_distribution_id = "1234"
169
+ @config.invalidate = ['local_image1.jpg']
170
+ @config.fog_provider = 'AWS'
171
+
172
+ storage = AssetSync::Storage.new(@config)
173
+ allow(storage).to receive(:local_files).and_return(@local_files)
174
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
175
+ allow(storage).to receive(:upload_file).and_return(true)
176
+
177
+ mock_cdn = double
178
+ expect(Fog::CDN).to receive(:new).and_return(mock_cdn)
179
+ expect(mock_cdn).to receive(:post_invalidation).with("1234", ["/assets/local_image1.jpg"]).and_return(double({:body => {:id => '1234'}}))
180
+
181
+ storage.upload_files
182
+ end
183
+ end
184
+
185
+ describe '#upload_file' do
186
+ before(:each) do
187
+ # Object#remove_const does not remove the loaded
188
+ # file from the $" variable
189
+ #Object.send(:remove_const, :MIME) if defined?(MIME)
190
+ mime_types = $".grep(/mime\/types/).first
191
+ $".delete(mime_types)
192
+ require 'mime/types'
193
+ @config = AssetSync::Config.new
194
+ end
195
+
196
+ it 'accepts custom headers per file' do
197
+ @config.custom_headers = {
198
+ "local_image2.jpg" => {
199
+ :cache_control => 'max-age=0'
200
+ }
201
+ }
202
+ storage = AssetSync::Storage.new(@config)
203
+ allow(storage).to receive(:local_files).and_return(@local_files)
204
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
205
+ allow(File).to receive(:open).and_return('file') # Pretend they all exist
206
+
207
+ bucket = double
208
+ files = double
209
+
210
+ allow(storage).to receive(:bucket).and_return(bucket)
211
+ allow(bucket).to receive(:files).and_return(files)
212
+
213
+ expect(files).to receive(:create) do |argument|
214
+ expect(argument[:cache_control]).to eq('max-age=0')
215
+ end
216
+ storage.upload_file('assets/local_image2.jpg')
217
+ end
218
+
219
+ it 'accepts custom headers with a regular expression' do
220
+ @config.custom_headers = {
221
+ ".*\.jpg" => {
222
+ :cache_control => 'max-age=0'
223
+ }
224
+ }
225
+ storage = AssetSync::Storage.new(@config)
226
+ allow(storage).to receive(:local_files).and_return(@local_files)
227
+ allow(storage).to receive(:get_remote_files).and_return(@remote_files)
228
+ allow(File).to receive(:open).and_return('file') # Pretend they all exist
229
+ bucket = double
230
+ files = double
231
+ allow(storage).to receive(:bucket).and_return(bucket)
232
+ allow(bucket).to receive(:files).and_return(files)
233
+
234
+ expect(files).to receive(:create) do |argument|
235
+ expect(argument[:cache_control]).to eq('max-age=0')
236
+ end
237
+ storage.upload_file('assets/some_longer_path/local_image2.jpg')
238
+ end
239
+
240
+ after(:each) do
241
+ #Object.send(:remove_const, :MIME) if defined?(MIME)
242
+ end
243
+ end
244
+ end