asset_cloud 2.7.0 → 2.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +42 -0
- data/.github/workflows/cla.yml +22 -0
- data/.rubocop.yml +3 -1
- data/Gemfile +5 -3
- data/History.md +8 -0
- data/README.rdoc +3 -4
- data/Rakefile +18 -16
- data/asset_cloud.gemspec +19 -18
- data/dev.yml +1 -1
- data/lib/asset_cloud/asset.rb +17 -13
- data/lib/asset_cloud/asset_extension.rb +27 -15
- data/lib/asset_cloud/base.rb +77 -72
- data/lib/asset_cloud/bucket.rb +5 -2
- data/lib/asset_cloud/buckets/active_record_bucket.rb +16 -14
- data/lib/asset_cloud/buckets/blackhole_bucket.rb +2 -0
- data/lib/asset_cloud/buckets/bucket_chain.rb +38 -31
- data/lib/asset_cloud/buckets/file_system_bucket.rb +14 -15
- data/lib/asset_cloud/buckets/gcs_bucket.rb +6 -8
- data/lib/asset_cloud/buckets/invalid_bucket.rb +9 -6
- data/lib/asset_cloud/buckets/memory_bucket.rb +7 -4
- data/lib/asset_cloud/buckets/s3_bucket.rb +11 -8
- data/lib/asset_cloud/buckets/versioned_memory_bucket.rb +4 -2
- data/lib/asset_cloud/callbacks.rb +9 -5
- data/lib/asset_cloud/free_key_locator.rb +6 -6
- data/lib/asset_cloud/metadata.rb +11 -7
- data/lib/asset_cloud/validations.rb +9 -5
- data/lib/asset_cloud.rb +23 -21
- data/spec/active_record_bucket_spec.rb +27 -26
- data/spec/asset_cloud/metadata_spec.rb +4 -2
- data/spec/asset_extension_spec.rb +17 -16
- data/spec/asset_spec.rb +27 -21
- data/spec/base_spec.rb +93 -92
- data/spec/blackhole_bucket_spec.rb +12 -11
- data/spec/bucket_chain_spec.rb +61 -56
- data/spec/bucket_spec.rb +6 -5
- data/spec/callbacks_spec.rb +52 -32
- data/spec/file_system_spec.rb +25 -24
- data/spec/find_free_key_spec.rb +16 -17
- data/spec/gcs_bucket_remote_spec.rb +23 -22
- data/spec/gcs_bucket_spec.rb +48 -60
- data/spec/memory_bucket_spec.rb +12 -11
- data/spec/mock_s3_interface.rb +17 -6
- data/spec/remote_s3_bucket_spec.rb +31 -28
- data/spec/s3_bucket_spec.rb +19 -17
- data/spec/spec_helper.rb +8 -7
- data/spec/validations_spec.rb +13 -12
- data/spec/versioned_memory_bucket_spec.rb +11 -10
- metadata +10 -33
- data/.github/probots.yml +0 -2
- data/.rubocop_todo.yml +0 -326
- data/.travis.yml +0 -12
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "aws-sdk-s3"
|
2
4
|
|
3
5
|
module AssetCloud
|
4
6
|
class S3Bucket < Bucket
|
@@ -18,7 +20,7 @@ module AssetCloud
|
|
18
20
|
options[:range] = http_byte_range(options[:range]) if options[:range]
|
19
21
|
|
20
22
|
bucket = cloud.s3_bucket(key)
|
21
|
-
if encryption_key = options.delete(:encryption_key)
|
23
|
+
if (encryption_key = options.delete(:encryption_key))
|
22
24
|
bucket = encrypted_bucket(bucket, encryption_key)
|
23
25
|
end
|
24
26
|
|
@@ -33,7 +35,7 @@ module AssetCloud
|
|
33
35
|
options = options.dup
|
34
36
|
|
35
37
|
bucket = cloud.s3_bucket(key)
|
36
|
-
if encryption_key = options.delete(:encryption_key)
|
38
|
+
if (encryption_key = options.delete(:encryption_key))
|
37
39
|
bucket = encrypted_bucket(bucket, encryption_key)
|
38
40
|
end
|
39
41
|
|
@@ -63,7 +65,7 @@ module AssetCloud
|
|
63
65
|
client: Aws::S3::Encryption::Client.new(
|
64
66
|
client: source_bucket.client,
|
65
67
|
encryption_key: key,
|
66
|
-
)
|
68
|
+
),
|
67
69
|
).bucket(source_bucket.name)
|
68
70
|
end
|
69
71
|
|
@@ -73,21 +75,22 @@ module AssetCloud
|
|
73
75
|
|
74
76
|
def absolute_key(key = nil)
|
75
77
|
if key.to_s.starts_with?(path_prefix)
|
76
|
-
|
78
|
+
key
|
77
79
|
else
|
78
80
|
args = [path_prefix]
|
79
81
|
args << key.to_s if key
|
80
|
-
args.join(
|
82
|
+
args.join("/")
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
86
|
def relative_key(key)
|
85
|
-
key =~
|
87
|
+
key =~ %r{^#{path_prefix}/(.+)} ? Regexp.last_match(1) : key
|
86
88
|
end
|
87
89
|
|
88
90
|
def http_byte_range(range)
|
89
91
|
# follows https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
|
90
|
-
return "bytes=#{[range.begin, range.max].join(
|
92
|
+
return "bytes=#{[range.begin, range.max].join("-")}" if range.is_a?(Range)
|
93
|
+
|
91
94
|
range
|
92
95
|
end
|
93
96
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AssetCloud
|
2
4
|
class VersionedMemoryBucket < MemoryBucket
|
3
|
-
|
4
5
|
def read(key)
|
5
|
-
raise AssetCloud::AssetNotFoundError, key unless @memory.
|
6
|
+
raise AssetCloud::AssetNotFoundError, key unless @memory.key?(key)
|
7
|
+
|
6
8
|
read_version(key, latest_version(key))
|
7
9
|
end
|
8
10
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AssetCloud
|
2
4
|
module Callbacks
|
3
5
|
extend ActiveSupport::Concern
|
@@ -50,7 +52,7 @@ module AssetCloud
|
|
50
52
|
def extension_module
|
51
53
|
@extension_module ||= begin
|
52
54
|
mod = Module.new
|
53
|
-
|
55
|
+
const_set(:AssetCloudCallbacks, mod)
|
54
56
|
prepend(mod)
|
55
57
|
mod
|
56
58
|
end
|
@@ -59,17 +61,19 @@ module AssetCloud
|
|
59
61
|
|
60
62
|
def execute_callbacks(symbol, args)
|
61
63
|
callbacks_for(symbol).each do |callback|
|
62
|
-
|
63
64
|
result = case callback
|
64
65
|
when Symbol
|
65
66
|
send(callback, *args)
|
66
67
|
when Proc, Method
|
67
68
|
callback.call(self, *args)
|
68
69
|
else
|
69
|
-
if callback.respond_to?(
|
70
|
-
callback.send(
|
70
|
+
if callback.respond_to?(symbol)
|
71
|
+
callback.send(symbol, self, *args)
|
71
72
|
else
|
72
|
-
raise StandardError,
|
73
|
+
raise StandardError,
|
74
|
+
"Callbacks must be a symbol denoting the method to call, " \
|
75
|
+
"a string to be evaluated, a block to be invoked, " \
|
76
|
+
"or an object responding to the callback method."
|
73
77
|
end
|
74
78
|
end
|
75
79
|
return false if result == false
|
@@ -1,26 +1,26 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "securerandom"
|
4
4
|
|
5
|
+
module AssetCloud
|
5
6
|
module FreeKeyLocator
|
6
|
-
|
7
7
|
def find_free_key_like(key, options = {})
|
8
8
|
# Check weather the suggested key name is free. If so we
|
9
9
|
# simply return it.
|
10
10
|
|
11
|
-
if !exist?(key)
|
11
|
+
if !options[:force_uuid] && !exist?(key)
|
12
12
|
key
|
13
13
|
else
|
14
14
|
ext = File.extname(key)
|
15
15
|
dirname = File.dirname(key)
|
16
|
-
base = dirname ==
|
16
|
+
base = dirname == "." ? File.basename(key, ext) : File.join(File.dirname(key), File.basename(key, ext))
|
17
17
|
base = base.gsub(/_[\h]{8}-[\h]{4}-4[\h]{3}-[\h]{4}-[\h]{12}/, "")
|
18
18
|
|
19
19
|
# Attach UUID to avoid name collision
|
20
20
|
key = "#{base}_#{SecureRandom.uuid}#{ext}"
|
21
21
|
return key unless exist?(key)
|
22
22
|
|
23
|
-
raise StandardError,
|
23
|
+
raise StandardError, "Filesystem out of free filenames"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/asset_cloud/metadata.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AssetCloud
|
2
4
|
class Metadata
|
3
5
|
attr_accessor :exist, :size, :created_at, :updated_at, :value_hash, :checksum
|
4
6
|
|
5
7
|
def new?
|
6
|
-
!
|
8
|
+
!exist
|
7
9
|
end
|
8
10
|
|
9
11
|
def exist?
|
10
|
-
|
12
|
+
exist
|
11
13
|
end
|
12
14
|
|
13
15
|
# rubocop:disable Metrics/ParameterLists
|
@@ -21,12 +23,14 @@ module AssetCloud
|
|
21
23
|
end
|
22
24
|
# rubocop:enable Metrics/ParameterLists
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
class << self
|
27
|
+
def existing
|
28
|
+
new(true)
|
29
|
+
end
|
27
30
|
|
28
|
-
|
29
|
-
|
31
|
+
def non_existing
|
32
|
+
new(false)
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
def inspect
|
@@ -1,9 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AssetCloud
|
2
4
|
module Validations
|
3
|
-
|
4
|
-
base
|
5
|
-
|
6
|
-
|
5
|
+
class << self
|
6
|
+
def included(base)
|
7
|
+
base.send(:alias_method, :store_without_validation, :store)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
base.prepend(PrependedMethods)
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
module PrependedMethods
|
@@ -15,7 +19,7 @@ module AssetCloud
|
|
15
19
|
|
16
20
|
module ClassMethods
|
17
21
|
def validate(*extra_validations, &block)
|
18
|
-
validations =
|
22
|
+
validations = _callbacks[:validate] || []
|
19
23
|
validations += extra_validations
|
20
24
|
validations << block if block_given?
|
21
25
|
|
data/lib/asset_cloud.rb
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "addressable"
|
4
|
+
require "active_support"
|
3
5
|
|
4
6
|
# Core
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
7
|
+
require "asset_cloud/asset"
|
8
|
+
require "asset_cloud/metadata"
|
9
|
+
require "asset_cloud/bucket"
|
10
|
+
require "asset_cloud/buckets/active_record_bucket"
|
11
|
+
require "asset_cloud/buckets/blackhole_bucket"
|
12
|
+
require "asset_cloud/buckets/bucket_chain"
|
13
|
+
require "asset_cloud/buckets/file_system_bucket"
|
14
|
+
require "asset_cloud/buckets/invalid_bucket"
|
15
|
+
require "asset_cloud/buckets/memory_bucket"
|
16
|
+
require "asset_cloud/buckets/versioned_memory_bucket"
|
17
|
+
require "asset_cloud/base"
|
16
18
|
|
17
19
|
# S3
|
18
|
-
require
|
20
|
+
require "asset_cloud/buckets/s3_bucket"
|
19
21
|
|
20
22
|
# GCS
|
21
|
-
require
|
23
|
+
require "asset_cloud/buckets/gcs_bucket"
|
22
24
|
|
23
25
|
# Extensions
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
26
|
+
require "asset_cloud/free_key_locator"
|
27
|
+
require "asset_cloud/callbacks"
|
28
|
+
require "asset_cloud/validations"
|
27
29
|
|
28
|
-
require
|
30
|
+
require "asset_cloud/asset_extension"
|
29
31
|
|
30
32
|
AssetCloud::Base.class_eval do
|
31
33
|
include AssetCloud::FreeKeyLocator
|
@@ -56,9 +58,9 @@ AssetCloud::Asset.class_eval do
|
|
56
58
|
|
57
59
|
def valid_key
|
58
60
|
if key.blank?
|
59
|
-
add_error
|
61
|
+
add_error("key cannot be empty")
|
60
62
|
elsif !valid_key_path?(key)
|
61
|
-
add_error
|
63
|
+
add_error("#{key.inspect} contains illegal characters")
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
MockRecords = Object.new
|
5
6
|
|
6
7
|
class MockActiveRecordBucket < AssetCloud::ActiveRecordBucket
|
7
|
-
self.key_attribute =
|
8
|
-
self.value_attribute =
|
8
|
+
self.key_attribute = "name"
|
9
|
+
self.value_attribute = "body"
|
9
10
|
|
10
11
|
protected
|
11
12
|
|
@@ -19,24 +20,24 @@ class RecordCloud < AssetCloud::Base
|
|
19
20
|
end
|
20
21
|
|
21
22
|
describe AssetCloud::ActiveRecordBucket do
|
22
|
-
directory = File.dirname(__FILE__) +
|
23
|
+
directory = File.dirname(__FILE__) + "/files"
|
23
24
|
|
24
25
|
before do
|
25
|
-
@cloud = RecordCloud.new(directory,
|
26
|
+
@cloud = RecordCloud.new(directory, "http://assets/files")
|
26
27
|
@bucket = @cloud.buckets[:stuff]
|
27
28
|
end
|
28
29
|
|
29
|
-
describe
|
30
|
+
describe "#ls" do
|
30
31
|
before do
|
31
32
|
expect(MockRecords).to(receive(:connection).and_return(@mock_connection = double("connection")))
|
32
|
-
expect(@mock_connection).to(receive(:quote_column_name).with(
|
33
|
-
expect(@mock_record = double("record")).to(receive(:name).and_return(
|
33
|
+
expect(@mock_connection).to(receive(:quote_column_name).with("name").and_return("`name`"))
|
34
|
+
expect(@mock_record = double("record")).to(receive(:name).and_return("stuff/a1"))
|
34
35
|
end
|
35
36
|
|
36
37
|
it "should return a list of assets which start with the given prefix" do
|
37
38
|
expect(MockRecords).to(receive(:all).with(conditions: ["`name` LIKE ?", "stuff/a%"]).and_return([@mock_record]))
|
38
39
|
|
39
|
-
expect(@bucket.ls(
|
40
|
+
expect(@bucket.ls("stuff/a").size).to(eq(1))
|
40
41
|
end
|
41
42
|
|
42
43
|
it "should return a list of all assets when a prefix is not given" do
|
@@ -46,47 +47,47 @@ describe AssetCloud::ActiveRecordBucket do
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
describe
|
50
|
+
describe "#read" do
|
50
51
|
it "should return the value of a key when it exists" do
|
51
|
-
expect(@mock_record = double("record")).to(receive(:body).and_return(
|
52
|
-
expect(MockRecords).to(receive(:first).with(conditions: {
|
52
|
+
expect(@mock_record = double("record")).to(receive(:body).and_return("foo"))
|
53
|
+
expect(MockRecords).to(receive(:first).with(conditions: { "name" => "stuff/a1" }).and_return(@mock_record))
|
53
54
|
|
54
|
-
@bucket.read(
|
55
|
+
@bucket.read("stuff/a1")
|
55
56
|
end
|
56
57
|
it "should raise AssetNotFoundError when nothing is there" do
|
57
|
-
expect(MockRecords).to(receive(:first).with(conditions: {
|
58
|
+
expect(MockRecords).to(receive(:first).with(conditions: { "name" => "stuff/a1" }).and_return(nil))
|
58
59
|
|
59
|
-
expect { @bucket.read(
|
60
|
+
expect { @bucket.read("stuff/a1") }.to(raise_error(AssetCloud::AssetNotFoundError))
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
|
-
describe
|
64
|
+
describe "#write" do
|
64
65
|
it "should write to the DB" do
|
65
|
-
expect(@mock_record = double("record")).to(receive(:body=).with(
|
66
|
+
expect(@mock_record = double("record")).to(receive(:body=).with("foo").and_return("foo"))
|
66
67
|
expect(@mock_record).to(receive(:save!).and_return(true))
|
67
|
-
expect(MockRecords).to(receive(:find_or_initialize_by_name).with(
|
68
|
+
expect(MockRecords).to(receive(:find_or_initialize_by_name).with("stuff/a1").and_return(@mock_record))
|
68
69
|
|
69
|
-
@bucket.write(
|
70
|
+
@bucket.write("stuff/a1", "foo")
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
describe
|
74
|
+
describe "#delete" do
|
74
75
|
it "should destroy records" do
|
75
76
|
expect(@mock_record = double("record")).to(receive(:destroy).and_return(true))
|
76
|
-
expect(MockRecords).to(receive(:first).with(conditions: {
|
77
|
+
expect(MockRecords).to(receive(:first).with(conditions: { "name" => "stuff/a1" }).and_return(@mock_record))
|
77
78
|
|
78
|
-
@bucket.delete(
|
79
|
+
@bucket.delete("stuff/a1")
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
82
|
-
describe
|
83
|
+
describe "#stat" do
|
83
84
|
it "should return appropriate metadata" do
|
84
85
|
expect(@mock_record = double("record")).to(receive(:created_at).and_return(1982))
|
85
86
|
expect(@mock_record).to(receive(:updated_at).and_return(2002))
|
86
|
-
expect(@mock_record).to(receive(:body).and_return(
|
87
|
-
expect(MockRecords).to(receive(:first).with(conditions: {
|
87
|
+
expect(@mock_record).to(receive(:body).and_return("foo"))
|
88
|
+
expect(MockRecords).to(receive(:first).with(conditions: { "name" => "stuff/a1" }).and_return(@mock_record))
|
88
89
|
|
89
|
-
metadata = @bucket.stat(
|
90
|
+
metadata = @bucket.stat("stuff/a1")
|
90
91
|
expect(metadata.created_at).to(eq(1982))
|
91
92
|
expect(metadata.updated_at).to(eq(2002))
|
92
93
|
expect(metadata.size).to(eq(3))
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
class NoCatsAsset < AssetCloud::Asset
|
5
6
|
validate :no_cats
|
@@ -8,7 +9,7 @@ class NoCatsAsset < AssetCloud::Asset
|
|
8
9
|
private
|
9
10
|
|
10
11
|
def no_cats
|
11
|
-
add_error(
|
12
|
+
add_error("no cats allowed!") if value =~ /cat/i
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
@@ -53,33 +54,33 @@ describe "AssetExtension" do
|
|
53
54
|
include AssetCloud
|
54
55
|
|
55
56
|
before do
|
56
|
-
@cloud = CatsAndDogsCloud.new(File.dirname(__FILE__) +
|
57
|
+
@cloud = CatsAndDogsCloud.new(File.dirname(__FILE__) + "/files", "http://assets/")
|
57
58
|
end
|
58
59
|
|
59
60
|
describe "applicability" do
|
60
61
|
it "should work" do
|
61
|
-
asset = @cloud[
|
62
|
+
asset = @cloud["cat_pen/cats.xml"]
|
62
63
|
expect(XmlAssetExtension.applies_to_asset?(asset)).to(eq(true))
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
67
|
describe "validations" do
|
67
68
|
it "should be added to assets in the right bucket with the right extension" do
|
68
|
-
asset = @cloud[
|
69
|
-
asset.value =
|
69
|
+
asset = @cloud["cat_pen/cats.css"]
|
70
|
+
asset.value = "foo"
|
70
71
|
expect(asset.store).to(eq(false))
|
71
72
|
expect(asset.errors).to(eq(["not enough curly brackets!"]))
|
72
73
|
end
|
73
74
|
|
74
75
|
it "should not squash existing validations on the asset" do
|
75
|
-
asset = @cloud[
|
76
|
-
asset.value =
|
76
|
+
asset = @cloud["dog_pound/cats.xml"]
|
77
|
+
asset.value = "cats!"
|
77
78
|
expect(asset.store).to(eq(false))
|
78
|
-
expect(asset.errors).to(eq([
|
79
|
+
expect(asset.errors).to(eq(["no cats allowed!", "not enough angle brackets!"]))
|
79
80
|
end
|
80
81
|
|
81
82
|
it "should not apply to non-matching assets or those in exempted buckets" do
|
82
|
-
asset = @cloud[
|
83
|
+
asset = @cloud["cat_pen/cats.xml"]
|
83
84
|
asset.value = "xml"
|
84
85
|
expect(asset.store).to(eq(true))
|
85
86
|
end
|
@@ -87,20 +88,20 @@ describe "AssetExtension" do
|
|
87
88
|
|
88
89
|
describe "callbacks" do
|
89
90
|
it "should run alongside the asset's callbacks" do
|
90
|
-
asset = @cloud[
|
91
|
+
asset = @cloud["dog_pound/dogs.xml"]
|
91
92
|
expect(asset).to(receive(:asset_callback))
|
92
93
|
expect(asset.extensions.first).to(receive(:xml_callback))
|
93
|
-
asset.value =
|
94
|
+
asset.value = "<dogs/>"
|
94
95
|
expect(asset.store).to(eq(true))
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
98
99
|
describe "#method_missing" do
|
99
100
|
it "should try to run method on extensions" do
|
100
|
-
asset = @cloud[
|
101
|
-
asset.value =
|
101
|
+
asset = @cloud["dog_pound/dogs.xml"]
|
102
|
+
asset.value = "dogs"
|
102
103
|
asset.turn_into_xml
|
103
|
-
expect(asset.value).to(eq(
|
104
|
+
expect(asset.value).to(eq("<xml>dogs</xml>"))
|
104
105
|
end
|
105
106
|
|
106
107
|
it "does not swallow NotImplementedError" do
|
@@ -108,7 +109,7 @@ describe "AssetExtension" do
|
|
108
109
|
raise NotImplementedError
|
109
110
|
end
|
110
111
|
|
111
|
-
asset = @cloud[
|
112
|
+
asset = @cloud["dog_pound/dogs.xml"]
|
112
113
|
|
113
114
|
expect(asset).to(respond_to(:my_unimplemented_extension))
|
114
115
|
expect { asset.my_unimplemented_extension }.to(raise_error(NotImplementedError))
|
data/spec/asset_spec.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
describe "Asset" do
|
5
6
|
include AssetCloud
|
6
7
|
|
7
8
|
before do
|
8
|
-
@cloud = double(
|
9
|
+
@cloud = double("Cloud", asset_extension_classes_for_bucket: [])
|
9
10
|
end
|
10
11
|
|
11
12
|
describe "when first created (without a value)" do
|
@@ -18,7 +19,7 @@ describe "Asset" do
|
|
18
19
|
end
|
19
20
|
|
20
21
|
it "should have a key" do
|
21
|
-
expect(@asset.key).to(eq(
|
22
|
+
expect(@asset.key).to(eq("products/key.txt"))
|
22
23
|
end
|
23
24
|
|
24
25
|
it "should have a value of nil" do
|
@@ -26,23 +27,23 @@ describe "Asset" do
|
|
26
27
|
end
|
27
28
|
|
28
29
|
it "should have a basename" do
|
29
|
-
expect(@asset.basename).to(eq(
|
30
|
+
expect(@asset.basename).to(eq("key.txt"))
|
30
31
|
end
|
31
32
|
|
32
33
|
it "should have a basename without ext (if required)" do
|
33
|
-
expect(@asset.basename_without_ext).to(eq(
|
34
|
+
expect(@asset.basename_without_ext).to(eq("key"))
|
34
35
|
end
|
35
36
|
|
36
37
|
it "should have an ext" do
|
37
|
-
expect(@asset.extname).to(eq(
|
38
|
+
expect(@asset.extname).to(eq(".txt"))
|
38
39
|
end
|
39
40
|
|
40
41
|
it "should have a relative_key_without_ext" do
|
41
|
-
expect(@asset.relative_key_without_ext).to(eq(
|
42
|
+
expect(@asset.relative_key_without_ext).to(eq("key"))
|
42
43
|
end
|
43
44
|
|
44
45
|
it "should have a bucket_name" do
|
45
|
-
expect(@asset.bucket_name).to(eq(
|
46
|
+
expect(@asset.bucket_name).to(eq("products"))
|
46
47
|
end
|
47
48
|
|
48
49
|
it "should have a bucket" do
|
@@ -51,9 +52,9 @@ describe "Asset" do
|
|
51
52
|
end
|
52
53
|
|
53
54
|
it "should store data to the bucket" do
|
54
|
-
expect(@cloud).to(receive(:write).with("products/key.txt",
|
55
|
+
expect(@cloud).to(receive(:write).with("products/key.txt", "value"))
|
55
56
|
|
56
|
-
@asset.value =
|
57
|
+
@asset.value = "value"
|
57
58
|
@asset.store
|
58
59
|
end
|
59
60
|
|
@@ -82,17 +83,17 @@ describe "Asset" do
|
|
82
83
|
end
|
83
84
|
|
84
85
|
it "should have a relative_key_without_ext" do
|
85
|
-
expect(@asset.relative_key_without_ext).to(eq(
|
86
|
+
expect(@asset.relative_key_without_ext).to(eq("retail/key"))
|
86
87
|
end
|
87
88
|
|
88
89
|
it "should have a relative_key" do
|
89
|
-
expect(@asset.relative_key).to(eq(
|
90
|
+
expect(@asset.relative_key).to(eq("retail/key.txt"))
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
93
94
|
describe "when first created with value" do
|
94
95
|
before do
|
95
|
-
@asset = AssetCloud::Asset.new(@cloud, "products/key.txt",
|
96
|
+
@asset = AssetCloud::Asset.new(@cloud, "products/key.txt", "value")
|
96
97
|
end
|
97
98
|
|
98
99
|
it "should be return new_asset? => true" do
|
@@ -100,7 +101,7 @@ describe "Asset" do
|
|
100
101
|
end
|
101
102
|
|
102
103
|
it "should have a value of 'value'" do
|
103
|
-
expect(@asset.value).to(eq(
|
104
|
+
expect(@asset.value).to(eq("value"))
|
104
105
|
end
|
105
106
|
|
106
107
|
it "should return false when asked if it exists because its still a new_asset" do
|
@@ -110,18 +111,23 @@ describe "Asset" do
|
|
110
111
|
it "should not try to read data from bucket if its a new_asset" do
|
111
112
|
expect(@cloud).to(receive(:read).never)
|
112
113
|
|
113
|
-
expect(@asset.value).to(eq(
|
114
|
+
expect(@asset.value).to(eq("value"))
|
114
115
|
end
|
115
116
|
|
116
117
|
it "should write data to the bucket" do
|
117
|
-
expect(@cloud).to(receive(:write).with("products/key.txt",
|
118
|
+
expect(@cloud).to(receive(:write).with("products/key.txt", "value"))
|
118
119
|
@asset.store
|
119
120
|
end
|
120
121
|
end
|
121
122
|
|
122
123
|
describe "when fetched from the bucket" do
|
123
124
|
before do
|
124
|
-
@asset = AssetCloud::Asset.at(
|
125
|
+
@asset = AssetCloud::Asset.at(
|
126
|
+
@cloud,
|
127
|
+
"products/key.txt",
|
128
|
+
"value",
|
129
|
+
AssetCloud::Metadata.new(true, "value".size, Time.now, Time.now),
|
130
|
+
)
|
125
131
|
end
|
126
132
|
|
127
133
|
it "should be return new_asset? => false" do
|
@@ -133,7 +139,7 @@ describe "Asset" do
|
|
133
139
|
end
|
134
140
|
|
135
141
|
it "should read the value from the bucket" do
|
136
|
-
expect(@asset.value).to(eq(
|
142
|
+
expect(@asset.value).to(eq("value"))
|
137
143
|
end
|
138
144
|
|
139
145
|
it "should simply ignore calls to delete" do
|
@@ -143,13 +149,13 @@ describe "Asset" do
|
|
143
149
|
end
|
144
150
|
|
145
151
|
it "should ask the bucket to create a full url" do
|
146
|
-
expect(@cloud).to(receive(:url_for).with(
|
152
|
+
expect(@cloud).to(receive(:url_for).with("products/key.txt", {}).and_return("http://assets/products/key.txt"))
|
147
153
|
|
148
|
-
expect(@asset.url).to(eq(
|
154
|
+
expect(@asset.url).to(eq("http://assets/products/key.txt"))
|
149
155
|
end
|
150
156
|
|
151
157
|
it "should ask the bucket whether or not it is versioned" do
|
152
|
-
bucket = double(
|
158
|
+
bucket = double("Bucket")
|
153
159
|
expect(@cloud).to(receive(:buckets).and_return(products: bucket))
|
154
160
|
expect(bucket).to(receive(:versioned?).and_return(true))
|
155
161
|
|