asset_cloud 2.7.1 → 2.7.3
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/dependabot.yml +6 -0
- data/.github/workflows/ci.yml +21 -7
- data/.github/workflows/cla.yml +22 -0
- data/.gitignore +0 -1
- data/.rubocop.yml +0 -1
- data/.ruby-version +1 -0
- data/Gemfile +5 -3
- data/Gemfile.lock +180 -0
- data/History.md +9 -0
- data/README.rdoc +1 -3
- data/Rakefile +18 -16
- data/asset_cloud.gemspec +19 -18
- data/dev.yml +1 -2
- 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 +24 -16
- 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 +24 -22
- 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 +65 -39
- 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 +13 -36
- data/.github/probots.yml +0 -2
- data/.rubocop_todo.yml +0 -326
data/spec/bucket_chain_spec.rb
CHANGED
@@ -1,93 +1,98 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
2
|
|
4
|
-
|
5
|
-
bucket :stuff, AssetCloud::BucketChain.chain(AssetCloud::MemoryBucket,
|
6
|
-
AssetCloud::MemoryBucket,
|
7
|
-
AssetCloud::FileSystemBucket)
|
3
|
+
require "spec_helper"
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class ChainedCloud < AssetCloud::Base
|
6
|
+
bucket :stuff, AssetCloud::BucketChain.chain(
|
7
|
+
AssetCloud::MemoryBucket,
|
8
|
+
AssetCloud::MemoryBucket,
|
9
|
+
AssetCloud::FileSystemBucket,
|
10
|
+
)
|
11
|
+
|
12
|
+
bucket :versioned_stuff, AssetCloud::BucketChain.chain(
|
13
|
+
AssetCloud::FileSystemBucket,
|
14
|
+
AssetCloud::VersionedMemoryBucket,
|
15
|
+
AssetCloud::MemoryBucket,
|
16
|
+
)
|
12
17
|
end
|
13
18
|
|
14
19
|
describe AssetCloud::BucketChain do
|
15
|
-
directory = File.dirname(__FILE__) +
|
20
|
+
directory = File.dirname(__FILE__) + "/files"
|
16
21
|
|
17
22
|
before(:each) do
|
18
|
-
@cloud = ChainedCloud.new(directory,
|
23
|
+
@cloud = ChainedCloud.new(directory, "http://assets/files")
|
19
24
|
@bucket_chain = @cloud.buckets[:stuff]
|
20
25
|
@chained_buckets = @bucket_chain.chained_buckets
|
21
|
-
@chained_buckets.each { |b| b.ls(
|
26
|
+
@chained_buckets.each { |b| b.ls("stuff").each(&:delete) }
|
22
27
|
|
23
28
|
@versioned_stuff = @cloud.buckets[:versioned_stuff]
|
24
29
|
end
|
25
30
|
|
26
31
|
describe ".chain" do
|
27
|
-
it
|
32
|
+
it "should take multiple Bucket classes and return a new Bucket class" do
|
28
33
|
expect(@bucket_chain).to(be_a_kind_of(AssetCloud::BucketChain))
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
37
|
describe "#write" do
|
33
|
-
it
|
38
|
+
it "should write to each sub-bucket when everything is kosher and return the result of the first write" do
|
34
39
|
@chained_buckets.each do |bucket|
|
35
|
-
expect(bucket).to(receive(:write).with(
|
40
|
+
expect(bucket).to(receive(:write).with("stuff/foo", "successful creation").and_return("successful creation"))
|
36
41
|
end
|
37
42
|
|
38
|
-
expect(@bucket_chain.write(
|
43
|
+
expect(@bucket_chain.write("stuff/foo", "successful creation")).to(eq("successful creation"))
|
39
44
|
end
|
40
|
-
it
|
41
|
-
expect(@chained_buckets.last).to(receive(:write).with(
|
45
|
+
it "should roll back creation-writes and re-raise an error when a bucket raises one" do
|
46
|
+
expect(@chained_buckets.last).to(receive(:write).with("stuff/foo", "unsuccessful creation").and_raise("hell"))
|
42
47
|
@chained_buckets[0..-2].each do |bucket|
|
43
|
-
expect(bucket).to(receive(:write).with(
|
44
|
-
expect(bucket).to(receive(:delete).with(
|
48
|
+
expect(bucket).to(receive(:write).with("stuff/foo", "unsuccessful creation").and_return(true))
|
49
|
+
expect(bucket).to(receive(:delete).with("stuff/foo").and_return(true))
|
45
50
|
end
|
46
51
|
|
47
|
-
expect { @bucket_chain.write(
|
52
|
+
expect { @bucket_chain.write("stuff/foo", "unsuccessful creation") }.to(raise_error(RuntimeError))
|
48
53
|
end
|
49
|
-
it
|
50
|
-
@bucket_chain.write(
|
54
|
+
it "should roll back update-writes and re-raise an error when a bucket raises one" do
|
55
|
+
@bucket_chain.write("stuff/foo", "original value")
|
51
56
|
|
52
|
-
expect(@chained_buckets.last).to(receive(:write).with(
|
57
|
+
expect(@chained_buckets.last).to(receive(:write).with("stuff/foo", "new value").and_raise("hell"))
|
53
58
|
|
54
|
-
expect { @bucket_chain.write(
|
59
|
+
expect { @bucket_chain.write("stuff/foo", "new value") }.to(raise_error(RuntimeError))
|
55
60
|
@chained_buckets.each do |bucket|
|
56
|
-
expect(bucket.read(
|
61
|
+
expect(bucket.read("stuff/foo")).to(eq("original value"))
|
57
62
|
end
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
66
|
describe "#delete" do
|
62
|
-
it
|
63
|
-
@bucket_chain.write(
|
67
|
+
it "should delete from each sub-bucket when everything is kosher" do
|
68
|
+
@bucket_chain.write("stuff/foo", "successful deletion comin' up")
|
64
69
|
|
65
70
|
@chained_buckets.each do |bucket|
|
66
|
-
expect(bucket).to(receive(:delete).with(
|
71
|
+
expect(bucket).to(receive(:delete).with("stuff/foo").and_return(true))
|
67
72
|
end
|
68
73
|
|
69
|
-
@bucket_chain.delete(
|
74
|
+
@bucket_chain.delete("stuff/foo")
|
70
75
|
end
|
71
|
-
it
|
72
|
-
@bucket_chain.write(
|
76
|
+
it "should roll back deletions and re-raise an error when a bucket raises one" do
|
77
|
+
@bucket_chain.write("stuff/foo", "this deletion will fail")
|
73
78
|
|
74
|
-
expect(@chained_buckets.last).to(receive(:delete).with(
|
79
|
+
expect(@chained_buckets.last).to(receive(:delete).with("stuff/foo").and_raise("hell"))
|
75
80
|
@chained_buckets[0..-2].each do |bucket|
|
76
|
-
expect(bucket).to(receive(:delete).with(
|
77
|
-
expect(bucket).to(receive(:write).with(
|
81
|
+
expect(bucket).to(receive(:delete).with("stuff/foo").and_return(true))
|
82
|
+
expect(bucket).to(receive(:write).with("stuff/foo", "this deletion will fail").and_return(true))
|
78
83
|
end
|
79
84
|
|
80
|
-
expect { @bucket_chain.delete(
|
85
|
+
expect { @bucket_chain.delete("stuff/foo") }.to(raise_error(RuntimeError))
|
81
86
|
end
|
82
87
|
end
|
83
88
|
|
84
89
|
describe "#read" do
|
85
|
-
it
|
86
|
-
expect(@chained_buckets[0]).to(receive(:read).with(
|
90
|
+
it "should read from only the first available sub-bucket" do
|
91
|
+
expect(@chained_buckets[0]).to(receive(:read).with("stuff/foo").and_raise(NotImplementedError))
|
87
92
|
expect(@chained_buckets[0]).to(receive(:ls).with(nil).and_raise(NoMethodError))
|
88
93
|
expect(@chained_buckets[0]).to(receive(:stat).and_return(:metadata))
|
89
94
|
|
90
|
-
expect(@chained_buckets[1]).to(receive(:read).with(
|
95
|
+
expect(@chained_buckets[1]).to(receive(:read).with("stuff/foo").and_return("bar"))
|
91
96
|
expect(@chained_buckets[1]).to(receive(:ls).with(nil).and_return(:some_assets))
|
92
97
|
expect(@chained_buckets[1]).not_to(receive(:stat))
|
93
98
|
|
@@ -97,59 +102,59 @@ describe AssetCloud::BucketChain do
|
|
97
102
|
expect(bucket).not_to(receive(:stat))
|
98
103
|
end
|
99
104
|
|
100
|
-
expect(@bucket_chain.read(
|
105
|
+
expect(@bucket_chain.read("stuff/foo")).to(eq("bar"))
|
101
106
|
expect(@bucket_chain.ls).to(eq(:some_assets))
|
102
107
|
expect(@bucket_chain.stat).to(eq(:metadata))
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
106
111
|
describe "#read_version" do
|
107
|
-
it
|
112
|
+
it "should read from only the first available sub-bucket" do
|
108
113
|
buckets = @versioned_stuff.chained_buckets
|
109
114
|
|
110
|
-
expect(buckets[1]).to(receive(:read_version).with(
|
115
|
+
expect(buckets[1]).to(receive(:read_version).with("stuff/foo", 3).and_return("bar"))
|
111
116
|
expect(buckets.last).not_to(receive(:read_version))
|
112
117
|
|
113
|
-
expect(@versioned_stuff.read_version(
|
118
|
+
expect(@versioned_stuff.read_version("stuff/foo", 3)).to(eq("bar"))
|
114
119
|
end
|
115
120
|
end
|
116
121
|
|
117
122
|
describe "#versions" do
|
118
|
-
it
|
123
|
+
it "should read from only the first available sub-bucket" do
|
119
124
|
buckets = @versioned_stuff.chained_buckets
|
120
125
|
|
121
|
-
expect(buckets[1]).to(receive(:versions).with(
|
126
|
+
expect(buckets[1]).to(receive(:versions).with("versioned_stuff/foo").and_return([1, 2, 3]))
|
122
127
|
expect(buckets.last).not_to(receive(:versions))
|
123
128
|
|
124
|
-
expect(@versioned_stuff.versions(
|
129
|
+
expect(@versioned_stuff.versions("versioned_stuff/foo")).to(eq([1, 2, 3]))
|
125
130
|
end
|
126
131
|
end
|
127
132
|
|
128
133
|
describe "with versioned buckets" do
|
129
|
-
it
|
130
|
-
|
131
|
-
@cloud[
|
134
|
+
it "should store and retrieve versions seamlessly" do
|
135
|
+
["one", "two", "three"].each do |content|
|
136
|
+
@cloud["versioned_stuff/foo"] = content
|
132
137
|
end
|
133
|
-
asset = @cloud[
|
134
|
-
expect(asset.value).to(eq(
|
135
|
-
expect(asset.rollback(1).value).to(eq(
|
138
|
+
asset = @cloud["versioned_stuff/foo"]
|
139
|
+
expect(asset.value).to(eq("three"))
|
140
|
+
expect(asset.rollback(1).value).to(eq("one"))
|
136
141
|
expect(asset.versions).to(eq([1, 2, 3]))
|
137
|
-
asset.value =
|
142
|
+
asset.value = "four"
|
138
143
|
asset.store
|
139
144
|
expect(asset.versions).to(eq([1, 2, 3, 4]))
|
140
145
|
end
|
141
146
|
end
|
142
147
|
|
143
|
-
describe
|
144
|
-
it
|
148
|
+
describe "#respond_to?" do
|
149
|
+
it "should return true if any chained buckets respond to the given method" do
|
145
150
|
expect(@bucket_chain.respond_to?(:foo)).to(eq(false))
|
146
151
|
expect(@chained_buckets[1]).to(receive(:respond_to?).with(:bar).and_return(true))
|
147
152
|
expect(@bucket_chain.respond_to?(:bar)).to(eq(true))
|
148
153
|
end
|
149
154
|
end
|
150
155
|
|
151
|
-
describe
|
152
|
-
it
|
156
|
+
describe "#method_missing" do
|
157
|
+
it "should try each bucket" do
|
153
158
|
expect(@chained_buckets[1]).to(receive(:buzz).and_return(true))
|
154
159
|
expect(@chained_buckets[2]).not_to(receive(:buzz))
|
155
160
|
expect(@bucket_chain.buzz).to(eq(true))
|
data/spec/bucket_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "spec_helper"
|
3
4
|
|
4
5
|
describe AssetCloud::Bucket do
|
5
6
|
before do
|
@@ -8,19 +9,19 @@ describe AssetCloud::Bucket do
|
|
8
9
|
|
9
10
|
describe "operations not supported" do
|
10
11
|
it "#ls not supported" do
|
11
|
-
expect { @bucket.ls(
|
12
|
+
expect { @bucket.ls("foo") }.to(raise_error(NotImplementedError))
|
12
13
|
end
|
13
14
|
|
14
15
|
it "#read(key) not supported" do
|
15
|
-
expect { @bucket.read(
|
16
|
+
expect { @bucket.read("foo") }.to(raise_error(NotImplementedError))
|
16
17
|
end
|
17
18
|
|
18
19
|
it "#write(key, data) not supported" do
|
19
|
-
expect { @bucket.write(
|
20
|
+
expect { @bucket.write("foo", "bar") }.to(raise_error(NotImplementedError))
|
20
21
|
end
|
21
22
|
|
22
23
|
it "#delete(key) not supported" do
|
23
|
-
expect { @bucket.delete(
|
24
|
+
expect { @bucket.delete("foo") }.to(raise_error(NotImplementedError))
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
data/spec/callbacks_spec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'spec_helper'
|
3
2
|
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
class AfterStoreCallback
|
6
|
-
|
6
|
+
class << self
|
7
|
+
def after_store(*args); end
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
class CallbackAsset < AssetCloud::Asset
|
@@ -14,22 +16,28 @@ class CallbackAsset < AssetCloud::Asset
|
|
14
16
|
after_validate :add_spice
|
15
17
|
validate :valid_value
|
16
18
|
|
19
|
+
before_validate(&:proc_executed_before)
|
20
|
+
after_validate(&:proc_executed_after)
|
21
|
+
|
17
22
|
after_store ::AfterStoreCallback
|
18
23
|
|
24
|
+
def proc_executed_before(*args); end
|
25
|
+
def proc_executed_after(*args); end
|
26
|
+
|
19
27
|
private
|
20
28
|
|
21
29
|
def callback_before_delete(*args); end
|
22
30
|
|
23
31
|
def make_value_valid
|
24
|
-
self.value =
|
32
|
+
self.value = "valid"
|
25
33
|
end
|
26
34
|
|
27
35
|
def add_spice
|
28
|
-
self.value +=
|
36
|
+
self.value += " spice"
|
29
37
|
end
|
30
38
|
|
31
39
|
def valid_value
|
32
|
-
add_error('value is not "valid"') unless value ==
|
40
|
+
add_error('value is not "valid"') unless value == "valid"
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
@@ -59,89 +67,107 @@ class MethodRecordingCloud < AssetCloud::Base
|
|
59
67
|
before_write :callback_before_write
|
60
68
|
after_write :callback_before_write
|
61
69
|
|
62
|
-
def
|
63
|
-
@run_callbacks <<
|
70
|
+
def callback_before_write(*)
|
71
|
+
@run_callbacks << __method__
|
64
72
|
end
|
65
73
|
end
|
66
74
|
|
67
75
|
describe CallbackCloud do
|
68
76
|
before do
|
69
|
-
@fs = CallbackCloud.new(File.dirname(__FILE__) +
|
70
|
-
@fs.write(
|
77
|
+
@fs = CallbackCloud.new(File.dirname(__FILE__) + "/files", "http://assets/")
|
78
|
+
@fs.write("tmp/file.txt", "foo")
|
71
79
|
end
|
72
80
|
|
73
81
|
it "should invoke callbacks after store" do
|
74
|
-
expect(@fs).to(receive(:callback_before_write).with(
|
75
|
-
expect(@fs).to(receive(:callback_after_write).with(
|
82
|
+
expect(@fs).to(receive(:callback_before_write).with("tmp/file.txt", "text").and_return(true))
|
83
|
+
expect(@fs).to(receive(:callback_after_write).with("tmp/file.txt", "text").and_return(true))
|
76
84
|
|
77
|
-
expect(@fs.write(
|
78
|
-
expect(@fs.read(
|
85
|
+
expect(@fs.write("tmp/file.txt", "text")).to(eq(true))
|
86
|
+
expect(@fs.read("tmp/file.txt")).to(eq("text"))
|
79
87
|
end
|
80
88
|
|
81
89
|
it "should invoke callbacks after delete" do
|
82
|
-
expect(@fs).to(receive(:callback_before_delete).with(
|
83
|
-
expect(@fs).to(receive(:callback_after_delete).with(
|
90
|
+
expect(@fs).to(receive(:callback_before_delete).with("tmp/file.txt").and_return(true))
|
91
|
+
expect(@fs).to(receive(:callback_after_delete).with("tmp/file.txt").and_return(true))
|
84
92
|
|
85
|
-
expect(@fs.delete(
|
93
|
+
expect(@fs.delete("tmp/file.txt")).to(eq("foo"))
|
86
94
|
end
|
87
95
|
|
88
96
|
it "should not invoke other callbacks when a before_ filter returns false" do
|
89
97
|
expect(@fs).to(receive(:callback_before_delete)
|
90
|
-
.with(
|
98
|
+
.with("tmp/file.txt")
|
91
99
|
.and_return(false))
|
92
100
|
expect(@fs).not_to(receive(:callback_after_delete))
|
93
101
|
|
94
|
-
expect(@fs.delete(
|
102
|
+
expect(@fs.delete("tmp/file.txt")).to(eq(nil))
|
95
103
|
end
|
96
104
|
|
97
105
|
it "should invoke callbacks even when constructing a new asset" do
|
98
|
-
expect(@fs).to(receive(:callback_before_write).with(
|
99
|
-
expect(@fs).to(receive(:callback_after_write).with(
|
106
|
+
expect(@fs).to(receive(:callback_before_write).with("tmp/file.txt", "hello").and_return(true))
|
107
|
+
expect(@fs).to(receive(:callback_after_write).with("tmp/file.txt", "hello").and_return(true))
|
100
108
|
|
101
|
-
asset = @fs.build(
|
102
|
-
asset.value =
|
109
|
+
asset = @fs.build("tmp/file.txt")
|
110
|
+
asset.value = "hello"
|
103
111
|
expect(asset.store).to(eq(true))
|
104
112
|
end
|
105
113
|
end
|
106
114
|
|
107
115
|
describe MethodRecordingCloud do
|
108
116
|
before do
|
109
|
-
@fs = MethodRecordingCloud.new(File.dirname(__FILE__) +
|
117
|
+
@fs = MethodRecordingCloud.new(File.dirname(__FILE__) + "/files", "http://assets/")
|
110
118
|
@fs.run_callbacks = []
|
111
119
|
end
|
112
120
|
|
113
|
-
it
|
114
|
-
@fs.write(
|
121
|
+
it "should record event when invoked" do
|
122
|
+
@fs.write("tmp/file.txt", "random data")
|
115
123
|
expect(@fs.run_callbacks).to(eq([:callback_before_write, :callback_before_write]))
|
116
124
|
end
|
117
125
|
|
118
|
-
it
|
119
|
-
@fs[
|
126
|
+
it "should record event when assignment operator is used" do
|
127
|
+
@fs["tmp/file.txt"] = "random data"
|
120
128
|
expect(@fs.run_callbacks).to(eq([:callback_before_write, :callback_before_write]))
|
121
129
|
end
|
122
130
|
end
|
123
131
|
|
124
132
|
describe CallbackAsset do
|
125
133
|
before(:each) do
|
126
|
-
@fs = BasicCloud.new(File.dirname(__FILE__) +
|
127
|
-
@fs.write(
|
128
|
-
@asset = @fs.asset_at(
|
134
|
+
@fs = BasicCloud.new(File.dirname(__FILE__) + "/files", "http://assets/")
|
135
|
+
@fs.write("callback_assets/foo", "bar")
|
136
|
+
@asset = @fs.asset_at("callback_assets/foo")
|
129
137
|
end
|
130
138
|
|
131
139
|
it "should run before_validate, then validate, then after validate, then before_store, then store" do
|
132
140
|
expect(@asset).to(receive(:callback_before_store).and_return(true))
|
133
141
|
expect(@asset).not_to(receive(:callback_after_delete))
|
134
142
|
|
135
|
-
@asset.value =
|
143
|
+
@asset.value = "foo"
|
144
|
+
expect(@asset.store).to(eq(true))
|
145
|
+
expect(@asset.value).to(eq("valid spice"))
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should run before_validate with procs" do
|
149
|
+
expect(@asset).to(receive(:callback_before_store).and_return(true))
|
150
|
+
expect(@asset).to(receive(:proc_executed_before))
|
151
|
+
|
152
|
+
@asset.value = "foo"
|
153
|
+
|
154
|
+
expect(@asset.store).to(eq(true))
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should run after_validate with procs" do
|
158
|
+
expect(@asset).to(receive(:callback_before_store).and_return(true))
|
159
|
+
expect(@asset).to(receive(:proc_executed_after))
|
160
|
+
|
161
|
+
@asset.value = "foo"
|
162
|
+
|
136
163
|
expect(@asset.store).to(eq(true))
|
137
|
-
expect(@asset.value).to(eq('valid spice'))
|
138
164
|
end
|
139
165
|
|
140
166
|
it "should run its after_delete callback after delete is called" do
|
141
167
|
expect(@asset).not_to(receive(:callback_before_store))
|
142
168
|
expect(@asset).to(receive(:callback_after_delete).and_return(true))
|
143
169
|
|
144
|
-
expect(@asset.delete).to(eq(
|
170
|
+
expect(@asset.delete).to(eq("bar"))
|
145
171
|
end
|
146
172
|
|
147
173
|
it "not invoke other callbacks when a before_ filter returns false" do
|
@@ -152,13 +178,13 @@ describe CallbackAsset do
|
|
152
178
|
end
|
153
179
|
|
154
180
|
it "should invoke after_store callback defined in separate class" do
|
155
|
-
local_fs = BasicCloud.new(File.dirname(__FILE__) +
|
156
|
-
local_fs.write(
|
157
|
-
local_asset = local_fs.asset_at(
|
158
|
-
|
181
|
+
local_fs = BasicCloud.new(File.dirname(__FILE__) + "/files", "http://assets/")
|
182
|
+
local_fs.write("callback_assets/foo", "bar")
|
183
|
+
local_asset = local_fs.asset_at("callback_assets/foo")
|
184
|
+
|
159
185
|
expect(local_asset).to(receive(:callback_before_store).and_return(true))
|
160
|
-
expect(
|
161
|
-
|
186
|
+
expect(AfterStoreCallback).to(receive(:after_store))
|
187
|
+
|
162
188
|
expect(local_asset.store).to(eq(true))
|
163
189
|
end
|
164
190
|
end
|
data/spec/file_system_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "fileutils"
|
4
5
|
|
5
6
|
class FileSystemCloud < AssetCloud::Base
|
6
7
|
bucket AssetCloud::InvalidBucket
|
@@ -9,64 +10,64 @@ class FileSystemCloud < AssetCloud::Base
|
|
9
10
|
end
|
10
11
|
|
11
12
|
describe FileSystemCloud do
|
12
|
-
directory = File.dirname(__FILE__) +
|
13
|
+
directory = File.dirname(__FILE__) + "/files"
|
13
14
|
|
14
15
|
before do
|
15
|
-
@fs = FileSystemCloud.new(directory,
|
16
|
-
FileUtils.mkdir_p(directory +
|
16
|
+
@fs = FileSystemCloud.new(directory, "http://assets/files")
|
17
|
+
FileUtils.mkdir_p(directory + "/tmp")
|
17
18
|
end
|
18
19
|
|
19
20
|
after do
|
20
|
-
FileUtils.rm_rf(directory +
|
21
|
+
FileUtils.rm_rf(directory + "/tmp")
|
21
22
|
end
|
22
23
|
|
23
24
|
it "should use invalid bucket for random directories" do
|
24
|
-
expect(@fs.bucket_for(
|
25
|
+
expect(@fs.bucket_for("does-not-exist/file.txt")).to(be_an_instance_of(AssetCloud::InvalidBucket))
|
25
26
|
end
|
26
27
|
|
27
28
|
it "should use filesystem bucket for products/ and tmp/ directories" do
|
28
|
-
expect(@fs.bucket_for(
|
29
|
-
expect(@fs.bucket_for(
|
29
|
+
expect(@fs.bucket_for("products/file.txt")).to(be_an_instance_of(AssetCloud::FileSystemBucket))
|
30
|
+
expect(@fs.bucket_for("tmp/file.txt")).to(be_an_instance_of(AssetCloud::FileSystemBucket))
|
30
31
|
end
|
31
32
|
|
32
33
|
it "should return Asset for existing files" do
|
33
|
-
expect(@fs[
|
34
|
-
expect(@fs[
|
34
|
+
expect(@fs["products/key.txt"].exist?).to(eq(true))
|
35
|
+
expect(@fs["products/key.txt"]).to(be_an_instance_of(AssetCloud::Asset))
|
35
36
|
end
|
36
37
|
|
37
38
|
it "should be able to test if a file exists or not" do
|
38
|
-
expect(@fs.stat(
|
39
|
-
expect(@fs.stat(
|
39
|
+
expect(@fs.stat("products/key.txt").exist?).to(eq(true))
|
40
|
+
expect(@fs.stat("products/key2.txt").exist?).to(eq(false))
|
40
41
|
end
|
41
42
|
|
42
43
|
it "should be able to list files" do
|
43
|
-
expect(@fs.ls(
|
44
|
+
expect(@fs.ls("products").collect(&:key)).to(eq(["products/key.txt"]))
|
44
45
|
end
|
45
46
|
|
46
|
-
describe
|
47
|
+
describe "when modifying file system" do
|
47
48
|
it "should call write after storing an asset" do
|
48
|
-
expect(@fs.buckets[:tmp]).to(receive(:write).with(
|
49
|
+
expect(@fs.buckets[:tmp]).to(receive(:write).with("tmp/new_file.test", "hello world").and_return(true))
|
49
50
|
|
50
|
-
@fs.build(
|
51
|
+
@fs.build("tmp/new_file.test", "hello world").store
|
51
52
|
end
|
52
53
|
|
53
54
|
it "should be able to create new files" do
|
54
|
-
@fs.build(
|
55
|
+
@fs.build("tmp/new_file.test", "hello world").store
|
55
56
|
|
56
|
-
expect(@fs.stat(
|
57
|
+
expect(@fs.stat("tmp/new_file.test").exist).to(eq(true))
|
57
58
|
end
|
58
59
|
|
59
60
|
it "should be able to create new files with simple assignment" do
|
60
|
-
@fs[
|
61
|
+
@fs["tmp/new_file.test"] = "hello world"
|
61
62
|
|
62
|
-
expect(@fs.stat(
|
63
|
+
expect(@fs.stat("tmp/new_file.test").exist).to(eq(true))
|
63
64
|
end
|
64
65
|
|
65
66
|
it "should create directories as needed" do
|
66
|
-
@fs.build(
|
67
|
+
@fs.build("tmp/new_file.test", "hello world").store
|
67
68
|
|
68
|
-
expect(@fs[
|
69
|
-
expect(@fs[
|
69
|
+
expect(@fs["tmp/new_file.test"].exist?).to(eq(true))
|
70
|
+
expect(@fs["tmp/new_file.test"].value).to(eq("hello world"))
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
data/spec/find_free_key_spec.rb
CHANGED
@@ -1,44 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
class FindFreeKey
|
6
6
|
extend AssetCloud::FreeKeyLocator
|
7
7
|
end
|
8
8
|
|
9
|
-
describe "FreeFilenameLocator",
|
9
|
+
describe "FreeFilenameLocator", "when asked to return a free key such as the one passed in" do
|
10
10
|
it "should simply return the key if it happens to be free" do
|
11
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
11
|
+
expect(FindFreeKey).to(receive(:exist?).with("free.txt").and_return(false))
|
12
12
|
|
13
|
-
expect(FindFreeKey.find_free_key_like(
|
13
|
+
expect(FindFreeKey.find_free_key_like("free.txt")).to(eq("free.txt"))
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should append a UUID to the key before the extension if key is taken" do
|
17
|
-
allow(SecureRandom).to(receive(:uuid).and_return(
|
18
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
19
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
17
|
+
allow(SecureRandom).to(receive(:uuid).and_return("moo"))
|
18
|
+
expect(FindFreeKey).to(receive(:exist?).with("free.txt").and_return(true))
|
19
|
+
expect(FindFreeKey).to(receive(:exist?).with("free_moo.txt").and_return(false))
|
20
20
|
|
21
|
-
expect(FindFreeKey.find_free_key_like(
|
21
|
+
expect(FindFreeKey.find_free_key_like("free.txt")).to(eq("free_moo.txt"))
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should not strip any directory information from the key" do
|
25
|
-
allow(SecureRandom).to(receive(:uuid).and_return(
|
26
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
27
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
25
|
+
allow(SecureRandom).to(receive(:uuid).and_return("moo"))
|
26
|
+
expect(FindFreeKey).to(receive(:exist?).with("products/images/image.gif").and_return(true))
|
27
|
+
expect(FindFreeKey).to(receive(:exist?).with("products/images/image_moo.gif").and_return(false))
|
28
28
|
|
29
|
-
expect(FindFreeKey.find_free_key_like(
|
29
|
+
expect(FindFreeKey.find_free_key_like("products/images/image.gif")).to(eq("products/images/image_moo.gif"))
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should raise an exception if the randomly chosen value (after 10 attempts) is also taken" do
|
33
33
|
allow(FindFreeKey).to(receive(:exist?).and_return(true))
|
34
|
-
expect { FindFreeKey.find_free_key_like(
|
34
|
+
expect { FindFreeKey.find_free_key_like("free.txt") }.to(raise_error(StandardError))
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should append a UUID to the key before the extensions if the force_uuid option is passed" do
|
38
|
-
expect(FindFreeKey).to(receive(:exist?).with(
|
39
|
-
|
40
|
-
allow(SecureRandom).to(receive(:uuid).and_return('as-in-beer'))
|
38
|
+
expect(FindFreeKey).to(receive(:exist?).with("free_as-in-beer.txt").and_return(false))
|
39
|
+
allow(SecureRandom).to(receive(:uuid).and_return("as-in-beer"))
|
41
40
|
|
42
|
-
expect(FindFreeKey.find_free_key_like(
|
41
|
+
expect(FindFreeKey.find_free_key_like("free.txt", force_uuid: true)).to(eq("free_as-in-beer.txt"))
|
43
42
|
end
|
44
43
|
end
|