asset_cloud 2.7.0 → 2.7.2
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.
- 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
|
|