asset_cloud 2.7.1 → 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 +20 -5
- data/.github/workflows/cla.yml +22 -0
- data/.rubocop.yml +3 -1
- data/Gemfile +5 -3
- data/History.md +4 -0
- 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 +7 -3
- 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 +41 -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 +9 -32
- data/.github/probots.yml +0 -2
- data/.rubocop_todo.yml +0 -326
@@ -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
|
|