s3_website_monadic 0.0.15 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/bin/s3_website_monadic +11 -5
- data/build.sbt +2 -0
- data/changelog.md +10 -0
- data/lib/s3_website.rb +3 -31
- data/resources/configuration_file_template.yml +0 -2
- data/s3_website.gemspec +1 -13
- data/src/main/scala/s3/website/S3.scala +4 -3
- metadata +2 -387
- data/features/as-library.feature +0 -29
- data/features/cassettes/cucumber_tags/create-redirect.yml +0 -384
- data/features/cassettes/cucumber_tags/empty-bucket.yml +0 -89
- data/features/cassettes/cucumber_tags/new-and-changed-files.yml +0 -303
- data/features/cassettes/cucumber_tags/new-files-for-sydney.yml +0 -211
- data/features/cassettes/cucumber_tags/new-files.yml +0 -355
- data/features/cassettes/cucumber_tags/no-new-or-changed-files.yml +0 -359
- data/features/cassettes/cucumber_tags/one-file-to-delete.yml +0 -390
- data/features/cassettes/cucumber_tags/only-changed-files.yml +0 -411
- data/features/cassettes/cucumber_tags/s3-and-cloudfront-after-deleting-a-file.yml +0 -434
- data/features/cassettes/cucumber_tags/s3-and-cloudfront-when-updating-a-file.yml +0 -435
- data/features/cassettes/cucumber_tags/s3-and-cloudfront.yml +0 -290
- data/features/cloudfront.feature +0 -54
- data/features/command-line-help.feature +0 -54
- data/features/delete.feature +0 -19
- data/features/error_reporting.feature +0 -24
- data/features/instructions-for-new-user.feature +0 -154
- data/features/jekyll-support.feature +0 -20
- data/features/nanoc-support.feature +0 -20
- data/features/push.feature +0 -115
- data/features/redirects.feature +0 -14
- data/features/security.feature +0 -15
- data/features/step_definitions/steps.rb +0 -86
- data/features/support/env.rb +0 -26
- data/features/support/test_site_dirs/cdn-powered.blog.fi/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/cdn-powered.blog.fi/_site/index.html +0 -5
- data/features/support/test_site_dirs/cdn-powered.blog.fi/s3_website.yml +0 -4
- data/features/support/test_site_dirs/cdn-powered.when-deleted-a-file.blog.fi/_site/index.html +0 -10
- data/features/support/test_site_dirs/cdn-powered.when-deleted-a-file.blog.fi/s3_website.yml +0 -5
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/_site/index.html +0 -10
- data/features/support/test_site_dirs/cdn-powered.with-one-change.blog.fi/s3_website.yml +0 -4
- data/features/support/test_site_dirs/create-redirects/_site/.gitkeep +0 -0
- data/features/support/test_site_dirs/create-redirects/s3_website.yml +0 -6
- data/features/support/test_site_dirs/ignored-files.com/_site/css/styles.css +0 -4
- data/features/support/test_site_dirs/ignored-files.com/_site/index.html +0 -8
- data/features/support/test_site_dirs/ignored-files.com/s3_website.yml +0 -5
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/assets/picture.gif +0 -0
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/index-and-assets.blog.fi/_site/index.html +0 -5
- data/features/support/test_site_dirs/index-and-assets.blog.fi/s3_website.yml +0 -3
- data/features/support/test_site_dirs/jekyllrb.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/jekyllrb.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/jekyllrb.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/my.blog-with-clean-urls.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/my.blog-with-clean-urls.com/_site/index +0 -5
- data/features/support/test_site_dirs/my.blog-with-clean-urls.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/my.blog.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/my.blog.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/my.blog.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/my.sydney.blog.au/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/my.sydney.blog.au/_site/index.html +0 -5
- data/features/support/test_site_dirs/my.sydney.blog.au/s3_website.yml +0 -4
- data/features/support/test_site_dirs/nanoc.ws/public/output/css/styles.css +0 -3
- data/features/support/test_site_dirs/nanoc.ws/public/output/index.html +0 -5
- data/features/support/test_site_dirs/nanoc.ws/s3_website.yml +0 -3
- data/features/support/test_site_dirs/new-and-changed-files.com/_site/css/styles.css +0 -4
- data/features/support/test_site_dirs/new-and-changed-files.com/_site/index.html +0 -8
- data/features/support/test_site_dirs/new-and-changed-files.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/no-new-or-changed-files.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/no-new-or-changed-files.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/no-new-or-changed-files.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/only-changed-files.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/only-changed-files.com/_site/index.html +0 -9
- data/features/support/test_site_dirs/only-changed-files.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/site-that-contains-s3-website-file.com/_site/s3_website.yml +0 -3
- data/features/support/test_site_dirs/site-that-contains-s3-website-file.com/s3_website.yml +0 -3
- data/features/support/test_site_dirs/site-with-text-doc.com/_site/file.txt +0 -1
- data/features/support/test_site_dirs/site.with.css-maxage.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/site.with.css-maxage.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/site.with.css-maxage.com/s3_website.yml +0 -5
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/site.with.gzipped-and-max-aged-content.com/s3_website.yml +0 -5
- data/features/support/test_site_dirs/site.with.gzipped-html.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/site.with.gzipped-html.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/site.with.gzipped-html.com/s3_website.yml +0 -5
- data/features/support/test_site_dirs/site.with.maxage.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/site.with.maxage.com/_site/index.html +0 -5
- data/features/support/test_site_dirs/site.with.maxage.com/s3_website.yml +0 -4
- data/features/support/test_site_dirs/unpublish-a-post.com/_site/css/styles.css +0 -3
- data/features/support/test_site_dirs/unpublish-a-post.com/s3_website.yml +0 -3
- data/features/support/vcr.rb +0 -20
- data/features/website-performance.feature +0 -57
- data/lib/cloudfront/invalidator.rb +0 -37
- data/lib/s3_website/config_loader.rb +0 -55
- data/lib/s3_website/diff_helper.rb +0 -113
- data/lib/s3_website/endpoint.rb +0 -37
- data/lib/s3_website/errors.rb +0 -42
- data/lib/s3_website/keyboard.rb +0 -27
- data/lib/s3_website/parallelism.rb +0 -25
- data/lib/s3_website/retry.rb +0 -19
- data/lib/s3_website/tasks.rb +0 -36
- data/lib/s3_website/upload.rb +0 -137
- data/lib/s3_website/uploader.rb +0 -177
- data/spec/lib/cloudfront/invalidator_spec.rb +0 -60
- data/spec/lib/config_loader_spec.rb +0 -20
- data/spec/lib/endpoint_spec.rb +0 -31
- data/spec/lib/error_spec.rb +0 -21
- data/spec/lib/keyboard_spec.rb +0 -62
- data/spec/lib/parallelism_spec.rb +0 -81
- data/spec/lib/paths_spec.rb +0 -7
- data/spec/lib/retry_spec.rb +0 -34
- data/spec/lib/upload_spec.rb +0 -303
- data/spec/lib/uploader_spec.rb +0 -37
- data/spec/sample_files/hyde_site/_site/.vimrc +0 -5
- data/spec/sample_files/hyde_site/_site/css/styles.css +0 -3
- data/spec/sample_files/hyde_site/_site/index.html +0 -1
- data/spec/sample_files/hyde_site/s3_website.yml +0 -3
- data/spec/sample_files/tokyo_site/_site/.vimrc +0 -5
- data/spec/sample_files/tokyo_site/_site/css/styles.css +0 -3
- data/spec/sample_files/tokyo_site/_site/index.html +0 -1
- data/spec/sample_files/tokyo_site/s3_website.yml +0 -4
- data/spec/spec_helper.rb +0 -1
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::Cloudfront::Invalidator do
|
4
|
-
let(:config) {{
|
5
|
-
's3_id' => 'aws id',
|
6
|
-
's3_secret' => 'aws secret',
|
7
|
-
'cloudfront_distribution_id' => 'EFXX'
|
8
|
-
}}
|
9
|
-
|
10
|
-
describe 'default behaviour' do
|
11
|
-
it 'invalidates the root resource' do
|
12
|
-
invalidator = create_simple_cloudfront_invalidator(config)
|
13
|
-
invalidator.
|
14
|
-
should_receive(:invalidate).
|
15
|
-
with(['index.html', '']).
|
16
|
-
and_return(:text_report => 'report txt')
|
17
|
-
|
18
|
-
S3Website::Cloudfront::Invalidator.invalidate(config, ['index.html'])
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'option cloudfront_invalidate_root = true' do
|
23
|
-
let(:config_with_root_invalidation) {
|
24
|
-
config.merge( {
|
25
|
-
'cloudfront_invalidate_root' => true
|
26
|
-
})
|
27
|
-
}
|
28
|
-
|
29
|
-
it 'invalidates all root resources' do
|
30
|
-
invalidator = create_simple_cloudfront_invalidator(config_with_root_invalidation)
|
31
|
-
invalidator.
|
32
|
-
should_receive(:invalidate).
|
33
|
-
with(['article/', '']).
|
34
|
-
and_return(:text_report => 'report txt')
|
35
|
-
|
36
|
-
S3Website::Cloudfront::Invalidator.invalidate(config_with_root_invalidation, ['article/index.html'])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'the file name contains special characters' do
|
41
|
-
it 'encodes the file paths according to rfc1738' do
|
42
|
-
invalidator = create_simple_cloudfront_invalidator config
|
43
|
-
invalidator.
|
44
|
-
should_receive(:invalidate).
|
45
|
-
with(['article/arnold%27s%20file.html', '']).
|
46
|
-
and_return(:text_report => 'report txt')
|
47
|
-
|
48
|
-
S3Website::Cloudfront::Invalidator.invalidate(config, ["article/arnold's file.html"])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def create_simple_cloudfront_invalidator(config)
|
53
|
-
invalidator = double('invalidator')
|
54
|
-
SimpleCloudfrontInvalidator::CloudfrontClient.
|
55
|
-
should_receive(:new).
|
56
|
-
with(config['s3_id'], config['s3_secret'], config['cloudfront_distribution_id']).
|
57
|
-
and_return(invalidator)
|
58
|
-
invalidator
|
59
|
-
end
|
60
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::ConfigLoader do
|
4
|
-
it 'supports eRuby syntax in s3_website.yml' do
|
5
|
-
config = S3Website::ConfigLoader.load_configuration('spec/sample_files/hyde_site/')
|
6
|
-
config['s3_id'].should eq('hello')
|
7
|
-
config['s3_secret'].should eq('world')
|
8
|
-
config['s3_bucket'].should eq('galaxy')
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'does not define default endpoint' do
|
12
|
-
config = S3Website::ConfigLoader.load_configuration('spec/sample_files/hyde_site/')
|
13
|
-
config['s3_endpoint'].should be_nil
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'reads the S3 endpoint setting from s3_website.yml' do
|
17
|
-
config = S3Website::ConfigLoader.load_configuration('spec/sample_files/tokyo_site')
|
18
|
-
config['s3_endpoint'].should eq('ap-northeast-1')
|
19
|
-
end
|
20
|
-
end
|
data/spec/lib/endpoint_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'pp'
|
3
|
-
|
4
|
-
describe S3Website::Endpoint do
|
5
|
-
|
6
|
-
it 'uses the DEFAULT_LOCATION_CONSTRAINT constant to set the default location constraint' do
|
7
|
-
endpoint = S3Website::Endpoint.new
|
8
|
-
endpoint.location_constraint.should eq(S3Website::Endpoint::DEFAULT_LOCATION_CONSTRAINT)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'uses the "us-east-1" as the default location' do
|
12
|
-
S3Website::Endpoint::DEFAULT_LOCATION_CONSTRAINT.should eq('us-east-1')
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'takes a valid location constraint as a constructor parameter' do
|
16
|
-
endpoint = S3Website::Endpoint.new('EU')
|
17
|
-
endpoint.location_constraint.should eq('EU')
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'takes eu-west-1 as an alias for EU' do
|
21
|
-
endpoint = S3Website::Endpoint.new('eu-west-1')
|
22
|
-
endpoint.location_constraint.should eq('eu-west-1')
|
23
|
-
S3Website::Endpoint.new.location_constraints['EU'].should eq(S3Website::Endpoint.new.location_constraints['eu-west-1'])
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'fails if the location constraint is invalid' do
|
27
|
-
expect {
|
28
|
-
S3Website::Endpoint.new('andromeda')
|
29
|
-
}.to raise_error
|
30
|
-
end
|
31
|
-
end
|
data/spec/lib/error_spec.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'error reporting' do
|
4
|
-
it 'prints the class name of the error' do
|
5
|
-
S3Website::error_report(SocketError.new('network is down')).should include(
|
6
|
-
'SocketError'
|
7
|
-
)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'prints the message of the error' do
|
11
|
-
S3Website::error_report(SocketError.new('network is down')).should eq(
|
12
|
-
'network is down (SocketError)'
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
|
-
it "only prints the message if the error is an #{S3Website::S3WebsiteError}" do
|
17
|
-
S3Website::error_report(S3Website::NoWebsiteDirectoryFound.new()).should eq(
|
18
|
-
"I can't find any website. Are you in the right directory?"
|
19
|
-
)
|
20
|
-
end
|
21
|
-
end
|
data/spec/lib/keyboard_spec.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::Keyboard do
|
4
|
-
describe '.keep_or_delete' do
|
5
|
-
let(:s3_object_keys) { ['a', 'b', 'c'] }
|
6
|
-
let(:standard_input) { stub('std_in') }
|
7
|
-
|
8
|
-
it 'can delete only the first item' do
|
9
|
-
standard_input.stub(:gets).and_return("d", "K")
|
10
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
11
|
-
deleted_keys.should eq(['a'])
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'can delete only the second item' do
|
15
|
-
standard_input.stub(:gets).and_return("k", "d", "k")
|
16
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
17
|
-
deleted_keys.should eq(['b'])
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'can delete all but the first item' do
|
21
|
-
standard_input.stub(:gets).and_return("k", "D")
|
22
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
23
|
-
deleted_keys.should eq(['b', 'c'])
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'can delete all s3 objects' do
|
27
|
-
standard_input.stub(:gets).and_return("D")
|
28
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
29
|
-
deleted_keys.should eq(['a', 'b', 'c'])
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'can keep one s3 object' do
|
33
|
-
standard_input.stub(:gets).and_return("k", "d", "d")
|
34
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
35
|
-
deleted_keys.should eq(['b', 'c'])
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'can keep all s3 objects' do
|
39
|
-
standard_input.stub(:gets).and_return("k", "k", "k")
|
40
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
41
|
-
deleted_keys.should eq([])
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'can keep all s3 objects' do
|
45
|
-
standard_input.stub(:gets).and_return("K")
|
46
|
-
deleted_keys = call_keyboard(s3_object_keys, standard_input)
|
47
|
-
deleted_keys.should eq([])
|
48
|
-
end
|
49
|
-
|
50
|
-
def call_keyboard(s3_object_keys, standard_input)
|
51
|
-
deleted_keys = []
|
52
|
-
S3Website::Keyboard.if_user_confirms_delete(
|
53
|
-
s3_object_keys,
|
54
|
-
config = {},
|
55
|
-
standard_input
|
56
|
-
) { |key|
|
57
|
-
deleted_keys << key
|
58
|
-
}
|
59
|
-
deleted_keys
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::Parallelism do
|
4
|
-
context 'user has disabled parallelism' do
|
5
|
-
let(:config) {
|
6
|
-
{}
|
7
|
-
}
|
8
|
-
|
9
|
-
before(:all) {
|
10
|
-
@original_disable_state = ENV['disable_parallel_processing']
|
11
|
-
ENV['disable_parallel_processing'] = 'true'
|
12
|
-
}
|
13
|
-
|
14
|
-
after(:all) {
|
15
|
-
ENV['disable_parallel_processing'] = @original_disable_state
|
16
|
-
}
|
17
|
-
|
18
|
-
it 'runs things sequentially' do
|
19
|
-
ints = (0..100).to_a
|
20
|
-
after_processing = []
|
21
|
-
S3Website::Parallelism.each_in_parallel_or_sequentially(ints, config) { |int|
|
22
|
-
after_processing << int
|
23
|
-
}
|
24
|
-
ints.should eq(after_processing)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'user has not disabled parallelism' do
|
29
|
-
let(:config) {
|
30
|
-
{}
|
31
|
-
}
|
32
|
-
|
33
|
-
before(:all) {
|
34
|
-
@original_disable_state = ENV['disable_parallel_processing']
|
35
|
-
ENV.delete 'disable_parallel_processing'
|
36
|
-
}
|
37
|
-
|
38
|
-
after(:all) {
|
39
|
-
ENV['disable_parallel_processing'] = @original_disable_state if @original_disable_state
|
40
|
-
}
|
41
|
-
|
42
|
-
it 'runs things in parallel' do
|
43
|
-
ints = (0..100).to_a
|
44
|
-
after_processing = []
|
45
|
-
S3Website::Parallelism.each_in_parallel_or_sequentially(ints, config) { |int|
|
46
|
-
after_processing << int
|
47
|
-
}
|
48
|
-
ints.should_not eq(after_processing) # Parallel processing introduces non-determinism
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'limiting parallelism' do
|
53
|
-
shared_examples 'parallel processing' do |config|
|
54
|
-
let(:concurrency_level) {
|
55
|
-
config['concurrency_level'] || S3Website::Parallelism::DEFAULT_CONCURRENCY_LEVEL
|
56
|
-
}
|
57
|
-
|
58
|
-
before(:each) {
|
59
|
-
ints = (0..199).to_a
|
60
|
-
@after_processing = []
|
61
|
-
S3Website::Parallelism.each_in_parallel_or_sequentially(ints, config) { |int|
|
62
|
-
@after_processing << int
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
it "does at most <concurrency_level> operations in parallel" do
|
67
|
-
@after_processing.slice(0, concurrency_level).all? do |int|
|
68
|
-
int <= concurrency_level
|
69
|
-
end.should be true
|
70
|
-
@after_processing.slice(100, concurrency_level).all? do |int|
|
71
|
-
int >= 100 and int <= 100 + concurrency_level
|
72
|
-
end.should be true
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
include_examples 'parallel processing', config = {}
|
78
|
-
|
79
|
-
include_examples 'parallel processing', config = { 'concurrency_level' => 100 }
|
80
|
-
end
|
81
|
-
end
|
data/spec/lib/paths_spec.rb
DELETED
data/spec/lib/retry_spec.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::Retry do
|
4
|
-
describe ".run_with_retry" do
|
5
|
-
it "retry the operation 4 times" do
|
6
|
-
retries = 0
|
7
|
-
begin
|
8
|
-
S3Website::Retry.run_with_retry(0.001) {
|
9
|
-
retries += 1
|
10
|
-
raise Exception
|
11
|
-
}
|
12
|
-
rescue
|
13
|
-
end
|
14
|
-
retries.should be(4)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "throws an error if all retries fail" do
|
18
|
-
expect {
|
19
|
-
S3Website::Retry.run_with_retry(0.001) {
|
20
|
-
raise Exception
|
21
|
-
}
|
22
|
-
}.to raise_error(S3Website::RetryAttemptsExhaustedError)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "re-runs the block if the block throws an error" do
|
26
|
-
retries = 0
|
27
|
-
S3Website::Retry.run_with_retry(0.001) {
|
28
|
-
retries += 1
|
29
|
-
raise Exception if retries < 2
|
30
|
-
}
|
31
|
-
retries.should be(2)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/spec/lib/upload_spec.rb
DELETED
@@ -1,303 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe S3Website::Upload do
|
4
|
-
describe 'uploading blacklisted files' do
|
5
|
-
let(:blacklisted_files) {
|
6
|
-
[ 's3_website.yml' ]
|
7
|
-
}
|
8
|
-
it 'should fail if the upload file is s3_website.yml' do
|
9
|
-
blacklisted_files.each do |blacklisted_file|
|
10
|
-
expect {
|
11
|
-
S3Website::Upload.new blacklisted_file, mock(), {}, mock()
|
12
|
-
}.to raise_error "May not upload #{blacklisted_file}, because it's blacklisted"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should fail to upload configured blacklisted files' do
|
17
|
-
config = { 'exclude_from_upload' => 'vendor' }
|
18
|
-
|
19
|
-
expect {
|
20
|
-
S3Website::Upload.new "vendor/jquery/development.js", mock(), config, mock()
|
21
|
-
}.to raise_error "May not upload vendor/jquery/development.js, because it's blacklisted"
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'the uploaded file matches a value in the exclude_from_upload setting' do
|
25
|
-
it 'should fail to upload any configured blacklisted files' do
|
26
|
-
config = { 'exclude_from_upload' => ['vendor', 'tests'] }
|
27
|
-
|
28
|
-
expect {
|
29
|
-
S3Website::Upload.new "vendor/jquery/development.js", mock(), config, mock()
|
30
|
-
}.to raise_error "May not upload vendor/jquery/development.js, because it's blacklisted"
|
31
|
-
|
32
|
-
expect {
|
33
|
-
S3Website::Upload.new "tests/spec_helper.js", mock(), config, mock()
|
34
|
-
}.to raise_error "May not upload tests/spec_helper.js, because it's blacklisted"
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'supports regexes in the exclude_from_upload setting' do
|
38
|
-
config = { 'exclude_from_upload' => 'test.*' }
|
39
|
-
|
40
|
-
expect {
|
41
|
-
S3Website::Upload.new "tests/spec_helper.js", mock(), config, mock()
|
42
|
-
}.to raise_error "May not upload tests/spec_helper.js, because it's blacklisted"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe 'reduced redundancy setting' do
|
48
|
-
let(:config) {
|
49
|
-
{ 's3_reduced_redundancy' => true }
|
50
|
-
}
|
51
|
-
|
52
|
-
it 'allows storing a file under the Reduced Redundancy Storage' do
|
53
|
-
should_upload(
|
54
|
-
file = 'index.html',
|
55
|
-
site = 'features/support/test_site_dirs/my.blog.com/_site', config) { |s3_object|
|
56
|
-
s3_object.should_receive(:write).with(
|
57
|
-
anything(),
|
58
|
-
include(:reduced_redundancy => true)
|
59
|
-
)
|
60
|
-
}
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe 'content type resolving' do
|
65
|
-
it 'adds the content type of the uploaded CSS file into the S3 object' do
|
66
|
-
should_upload(
|
67
|
-
file = 'css/styles.css',
|
68
|
-
site = 'features/support/test_site_dirs/my.blog.com/_site') { |s3_object|
|
69
|
-
s3_object.should_receive(:write).with(
|
70
|
-
anything(),
|
71
|
-
include(:content_type => 'text/css; charset=utf-8')
|
72
|
-
)
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'adds the content type of the uploaded HTML file into the S3 object' do
|
77
|
-
should_upload(
|
78
|
-
file = 'index.html',
|
79
|
-
site = 'features/support/test_site_dirs/my.blog.com/_site') { |s3_object|
|
80
|
-
s3_object.should_receive(:write).with(
|
81
|
-
anything(),
|
82
|
-
include(:content_type => 'text/html; charset=utf-8')
|
83
|
-
)
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
|
-
describe 'encoding of text documents' do
|
88
|
-
it 'should mark all text documents as utf-8' do
|
89
|
-
should_upload(
|
90
|
-
file = 'file.txt',
|
91
|
-
site = 'features/support/test_site_dirs/site-with-text-doc.com/_site') { |s3_object|
|
92
|
-
s3_object.should_receive(:write).with(
|
93
|
-
anything(),
|
94
|
-
include(:content_type => 'text/plain; charset=utf-8')
|
95
|
-
)
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'the user specifies a mime-type for extensionless files' do
|
101
|
-
let(:config) {{
|
102
|
-
'extensionless_mime_type' => "text/html"
|
103
|
-
}}
|
104
|
-
|
105
|
-
it 'adds the content type of the uploaded extensionless file into the S3 object' do
|
106
|
-
should_upload(
|
107
|
-
file = 'index',
|
108
|
-
site = 'features/support/test_site_dirs/my.blog-with-clean-urls.com/_site',
|
109
|
-
config) { |s3_object|
|
110
|
-
s3_object.should_receive(:write).with(
|
111
|
-
anything(),
|
112
|
-
include(:content_type => 'text/html; charset=utf-8')
|
113
|
-
)
|
114
|
-
}
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe 'gzip compression' do
|
120
|
-
let(:config){
|
121
|
-
{
|
122
|
-
's3_reduced_redundancy' => false,
|
123
|
-
'gzip' => true
|
124
|
-
}
|
125
|
-
}
|
126
|
-
|
127
|
-
subject{ S3Website::Upload.new("index.html", mock(), config, 'features/support/test_site_dirs/my.blog.com/_site') }
|
128
|
-
|
129
|
-
describe '#gzip?' do
|
130
|
-
it 'should be false if the config does not specify gzip' do
|
131
|
-
config.delete 'gzip'
|
132
|
-
subject.should_not be_gzip
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'should be false if gzip is true but does not match a default extension' do
|
136
|
-
subject.stub(:path).and_return("index.bork")
|
137
|
-
subject.should_not be_gzip
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'should be true if gzip is true and file extension matches' do
|
141
|
-
subject.should be_gzip
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'should be true if gzip is true and file extension matches custom supplied' do
|
145
|
-
config['gzip'] = %w(.bork)
|
146
|
-
subject.stub(:path).and_return('index.bork')
|
147
|
-
subject.should be_gzip
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe '#gzipped_file' do
|
152
|
-
it 'should return a gzipped version of the file' do
|
153
|
-
gz = Zlib::GzipReader.new(subject.send(:gzipped_file))
|
154
|
-
gz.read.should == File.read('features/support/test_site_dirs/my.blog.com/_site/index.html')
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe 'gzip zopfli' do
|
160
|
-
let(:config){
|
161
|
-
{
|
162
|
-
's3_reduced_redundancy' => false,
|
163
|
-
'gzip' => true,
|
164
|
-
'gzip_zopfli' => true
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
subject{ S3Website::Upload.new("index.html", mock(), config, 'features/support/test_site_dirs/my.blog.com/_site') }
|
169
|
-
|
170
|
-
# Zopfli should be compatible with the gzip format
|
171
|
-
describe '#gzipped_file' do
|
172
|
-
it 'should return a gzipped version of the file' do
|
173
|
-
gz = Zlib::GzipReader.new(subject.send(:gzipped_file))
|
174
|
-
gz.read.should == File.read('features/support/test_site_dirs/my.blog.com/_site/index.html')
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
describe 'cache control' do
|
180
|
-
let(:config){
|
181
|
-
{
|
182
|
-
's3_reduced_redundancy' => false,
|
183
|
-
'max_age' => 300
|
184
|
-
}
|
185
|
-
}
|
186
|
-
|
187
|
-
let(:subject) {
|
188
|
-
S3Website::Upload.new(
|
189
|
-
"index.html",
|
190
|
-
mock(),
|
191
|
-
config,
|
192
|
-
'features/support/test_site_dirs/my.blog.com/_site'
|
193
|
-
)
|
194
|
-
}
|
195
|
-
|
196
|
-
describe '#cache_control?' do
|
197
|
-
it 'should be false if max_age is missing' do
|
198
|
-
config.delete 'max_age'
|
199
|
-
subject.should_not be_cache_control
|
200
|
-
end
|
201
|
-
|
202
|
-
it 'should be true if max_age is present' do
|
203
|
-
subject.should be_cache_control
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'should be true if max_age is a hash' do
|
207
|
-
config['max_age'] = {'*' => 300}
|
208
|
-
subject.should be_cache_control
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context 'the user specifies max-age as zero' do
|
213
|
-
let(:config) {{
|
214
|
-
'max_age' => 0
|
215
|
-
}}
|
216
|
-
|
217
|
-
it 'includes the no-cache declaration in the cache-control metadata' do
|
218
|
-
subject.send(:upload_options)[:cache_control].should == 'no-cache, max-age=0'
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
describe '#max_age' do
|
223
|
-
it 'should be the universal value if one is set' do
|
224
|
-
subject.send(:max_age).should == 300
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'should be the file-specific value if one is set' do
|
228
|
-
config['max_age'] = {'*index.html' => 500}
|
229
|
-
subject.send(:max_age).should == 500
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'should be zero if no file-specific value hit' do
|
233
|
-
config['max_age'] = {'*.js' => 500}
|
234
|
-
subject.send(:max_age).should == 0
|
235
|
-
end
|
236
|
-
|
237
|
-
context 'overriding the more general setting with the more specific' do
|
238
|
-
let(:config){
|
239
|
-
{
|
240
|
-
's3_reduced_redundancy' => false,
|
241
|
-
'max_age' => {
|
242
|
-
'**' => 150,
|
243
|
-
'assets/**' => 86400
|
244
|
-
}
|
245
|
-
}
|
246
|
-
}
|
247
|
-
|
248
|
-
it 'respects the most specific max-age selector' do
|
249
|
-
subject = S3Website::Upload.new(
|
250
|
-
'assets/picture.gif',
|
251
|
-
mock(),
|
252
|
-
config,
|
253
|
-
'features/support/test_site_dirs/index-and-assets.blog.fi/_site'
|
254
|
-
)
|
255
|
-
subject.send(:max_age).should == 86400
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'respects the most specific max-age selector' do
|
259
|
-
subject = S3Website::Upload.new(
|
260
|
-
'index.html',
|
261
|
-
mock(),
|
262
|
-
config,
|
263
|
-
'features/support/test_site_dirs/index-and-assets.blog.fi/_site'
|
264
|
-
)
|
265
|
-
subject.send(:max_age).should == 150
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
def should_upload(file_to_upload, site_dir, config = {})
|
272
|
-
def create_verifying_s3_client(file_to_upload, &block)
|
273
|
-
def create_objects(file_to_upload, &block)
|
274
|
-
def create_html_s3_object(file_to_upload, &block)
|
275
|
-
s3_object = stub('s3_object')
|
276
|
-
yield s3_object
|
277
|
-
s3_object
|
278
|
-
end
|
279
|
-
objects = {}
|
280
|
-
objects[file_to_upload] = create_html_s3_object(file_to_upload, &block)
|
281
|
-
objects
|
282
|
-
end
|
283
|
-
def create_bucket(file_to_upload, &block)
|
284
|
-
bucket = stub('bucket')
|
285
|
-
bucket.stub(:objects => create_objects(file_to_upload, &block))
|
286
|
-
bucket
|
287
|
-
end
|
288
|
-
buckets = stub('buckets')
|
289
|
-
buckets.stub(:[] => create_bucket(file_to_upload, &block))
|
290
|
-
s3 = stub('s3')
|
291
|
-
s3.stub(:buckets => buckets)
|
292
|
-
s3
|
293
|
-
end
|
294
|
-
|
295
|
-
s3_client = create_verifying_s3_client(file_to_upload) do |s3_object|
|
296
|
-
yield s3_object
|
297
|
-
end
|
298
|
-
S3Website::Upload.new(file_to_upload,
|
299
|
-
s3_client,
|
300
|
-
config,
|
301
|
-
site_dir).perform!
|
302
|
-
end
|
303
|
-
end
|