dugway 1.0.14 → 1.1.0
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/main.yml +1 -1
- data/README.md +9 -0
- data/lib/dugway/application.rb +1 -1
- data/lib/dugway/cli/build.rb +12 -1
- data/lib/dugway/cli/validate.rb +12 -1
- data/lib/dugway/liquid/drops/product_drop.rb +8 -0
- data/lib/dugway/liquid/drops/products_drop.rb +1 -1
- data/lib/dugway/liquid/drops/related_products_drop.rb +88 -0
- data/lib/dugway/theme.rb +70 -1
- data/lib/dugway/version.rb +1 -1
- data/spec/units/dugway/liquid/drops/product_drop_spec.rb +36 -0
- data/spec/units/dugway/liquid/drops/related_products_drop_spec.rb +80 -0
- data/spec/units/dugway/theme_spec.rb +160 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ec5c841ba4d98980fab27d7fe34b9f93c84f6fa80088e0c5ff819aa55b69d8b
|
4
|
+
data.tar.gz: 15b36e7b6cd237cec37662746ddf19303cdb224e09385d0ee3f993401c234ba7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0738d371dc90b8d86a3ad908b4095761956fae568f61f9e2e4fe63bf7044fefb35548e3fc0d0dd0ba95076945a26fec02bd7c9012dc6fb7faad077fc1ac7ca9
|
7
|
+
data.tar.gz: 6395af7c43b59c158a3aaf080437ac96a098c35bca088eb63206c2ca89b354136d15bcec5f0528ef19c761aeee80050aab2a636092d297df1d8fa5b2b07483be
|
data/.github/workflows/main.yml
CHANGED
data/README.md
CHANGED
@@ -193,6 +193,15 @@ dugway server
|
|
193
193
|
By default this will serve your theme at http://127.0.0.1:9292/. You can then stop
|
194
194
|
the server by hitting CTRL+C.
|
195
195
|
|
196
|
+
If you want to run with logging, enable it via your theme's `settings.json`
|
197
|
+
file with `"log": true`. When Dugway is running, it will then create a log
|
198
|
+
in `log/dugway.log` in your theme's directory. You can then log output
|
199
|
+
with `debug`, `info` and `warn`, such as:
|
200
|
+
|
201
|
+
```
|
202
|
+
Dugway.logger.debug("Debug statement here")
|
203
|
+
```
|
204
|
+
|
196
205
|
## Testing your theme
|
197
206
|
|
198
207
|
Part of building a great theme is making sure it works well in a variety of
|
data/lib/dugway/application.rb
CHANGED
data/lib/dugway/cli/build.rb
CHANGED
@@ -15,6 +15,11 @@ module Dugway
|
|
15
15
|
default: false,
|
16
16
|
desc: "Skip layout file data attribute validation"
|
17
17
|
|
18
|
+
class_option 'skip-options-validation',
|
19
|
+
type: :boolean,
|
20
|
+
default: false,
|
21
|
+
desc: "Skip options validation"
|
22
|
+
|
18
23
|
def self.source_root
|
19
24
|
File.join(Dir.pwd, 'source')
|
20
25
|
end
|
@@ -24,7 +29,13 @@ module Dugway
|
|
24
29
|
end
|
25
30
|
|
26
31
|
def validate
|
27
|
-
|
32
|
+
validation_options = {
|
33
|
+
validate_colors: !options['skip-color-validation'],
|
34
|
+
validate_layout_attributes: !options['skip-layout-attribute-validation'],
|
35
|
+
validate_options: !options['skip-options-validation']
|
36
|
+
}
|
37
|
+
|
38
|
+
unless theme.valid?(**validation_options)
|
28
39
|
theme.errors.each { |error| say(error, :red) }
|
29
40
|
say("\nTheme is invalid", :red)
|
30
41
|
exit(1)
|
data/lib/dugway/cli/validate.rb
CHANGED
@@ -13,8 +13,19 @@ module Dugway
|
|
13
13
|
default: false,
|
14
14
|
desc: "Skip layout file data attribute validation"
|
15
15
|
|
16
|
+
class_option 'skip-options-validation',
|
17
|
+
type: :boolean,
|
18
|
+
default: false,
|
19
|
+
desc: "Skip options validation"
|
20
|
+
|
16
21
|
def validate
|
17
|
-
|
22
|
+
validation_options = {
|
23
|
+
validate_colors: !options['skip-color-validation'],
|
24
|
+
validate_layout_attributes: !options['skip-layout-attribute-validation'],
|
25
|
+
validate_options: !options['skip-options-validation']
|
26
|
+
}
|
27
|
+
|
28
|
+
unless theme.valid?(**validation_options)
|
18
29
|
theme.errors.each { |error| say(error, :red) }
|
19
30
|
say("\nTheme is invalid", :red)
|
20
31
|
exit(1)
|
@@ -104,6 +104,14 @@ module Dugway
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
+
def related_products
|
108
|
+
@related_products ||= begin
|
109
|
+
drop = RelatedProductsDrop.new(source)
|
110
|
+
drop.context = @context if @context
|
111
|
+
drop.products
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
107
115
|
private
|
108
116
|
|
109
117
|
def price_min_max
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Dugway
|
2
|
+
module Drops
|
3
|
+
class RelatedProductsDrop < BaseDrop
|
4
|
+
def initialize(product)
|
5
|
+
super()
|
6
|
+
@product = product
|
7
|
+
end
|
8
|
+
|
9
|
+
def products
|
10
|
+
fetch_related_products
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def settings
|
16
|
+
@settings ||= theme.customization
|
17
|
+
end
|
18
|
+
|
19
|
+
def limit
|
20
|
+
@limit ||= begin
|
21
|
+
if settings
|
22
|
+
limit = settings['similar_products'] ||
|
23
|
+
settings['related_items'] ||
|
24
|
+
settings['related_products'] ||
|
25
|
+
settings['number_related_products'] ||
|
26
|
+
4
|
27
|
+
limit
|
28
|
+
else
|
29
|
+
4
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def sort_order
|
35
|
+
@sort_order ||= begin
|
36
|
+
if settings
|
37
|
+
order = settings['related_products_order'] ||
|
38
|
+
settings['similar_products_order'] ||
|
39
|
+
"position"
|
40
|
+
order
|
41
|
+
else
|
42
|
+
"position"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def fetch_related_products
|
48
|
+
return [] unless @product
|
49
|
+
|
50
|
+
category_products = sort_products(fetch_category_products).take(limit)
|
51
|
+
return category_products if category_products.size >= limit
|
52
|
+
|
53
|
+
remaining_limit = limit - category_products.size
|
54
|
+
fallback_products = sort_products(fetch_fallback_products(category_products, remaining_limit)).take(remaining_limit)
|
55
|
+
|
56
|
+
category_products + fallback_products
|
57
|
+
end
|
58
|
+
|
59
|
+
def fetch_category_products
|
60
|
+
# Filter Dugway's product data to match the categories of the current product
|
61
|
+
Dugway.store.products.select do |product|
|
62
|
+
product_cats = product['category_ids'] || []
|
63
|
+
current_cats = @product['category_ids'] || []
|
64
|
+
(product_cats & current_cats).any? && product['id'] != @product['id']
|
65
|
+
end.map { |p| ProductDrop.new(p) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def fetch_fallback_products(category_products, limit)
|
69
|
+
# Get additional products excluding already included ones
|
70
|
+
excluded_ids = category_products.map { |p| p['id'] } + [@product['id']]
|
71
|
+
Dugway.store.products
|
72
|
+
.reject { |product| excluded_ids.include?(product['id']) }
|
73
|
+
.map { |p| ProductDrop.new(p) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def sort_products(products)
|
77
|
+
case sort_order
|
78
|
+
when 'date', 'newest'
|
79
|
+
products.sort { |a,b| b.source['id'] <=> a.source['id'] }
|
80
|
+
when 'sales', 'sells', 'top-selling', 'views'
|
81
|
+
products.shuffle
|
82
|
+
else
|
83
|
+
products.sort_by { |p| p.source['position'] }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/dugway/theme.rb
CHANGED
@@ -93,7 +93,7 @@ module Dugway
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
def valid?(validate_colors: true, validate_layout_attributes: true)
|
96
|
+
def valid?(validate_colors: true, validate_layout_attributes: true, validate_options: true)
|
97
97
|
@errors = []
|
98
98
|
|
99
99
|
REQUIRED_FILES.each do |file|
|
@@ -117,12 +117,22 @@ module Dugway
|
|
117
117
|
|
118
118
|
validate_required_color_settings if validate_colors
|
119
119
|
validate_required_layout_attributes if validate_layout_attributes
|
120
|
+
validate_options_settings if validate_options
|
120
121
|
|
121
122
|
@errors.empty?
|
122
123
|
end
|
123
124
|
|
124
125
|
def validate_required_color_settings
|
126
|
+
if !settings['colors']
|
127
|
+
@errors << "Missing colors section in theme settings"
|
128
|
+
return
|
129
|
+
end
|
130
|
+
|
125
131
|
required_colors_attribute_names = THEME_COLOR_ATTRIBUTE_MAPPINGS['required_color_attributes']
|
132
|
+
if !required_colors_attribute_names
|
133
|
+
@errors << "Missing required color attributes configuration"
|
134
|
+
return
|
135
|
+
end
|
126
136
|
|
127
137
|
theme_colors = settings['colors'].map { |c| c['variable'] }
|
128
138
|
mappings = THEME_COLOR_ATTRIBUTE_MAPPINGS[name] || {}
|
@@ -154,6 +164,13 @@ module Dugway
|
|
154
164
|
@errors << "layout.html must have exactly one `data-bc-hook=\"footer\"`" if footer_hooks != 1
|
155
165
|
end
|
156
166
|
|
167
|
+
def validate_options_settings
|
168
|
+
return unless settings['options']
|
169
|
+
|
170
|
+
validate_options_descriptions
|
171
|
+
validate_options_requires
|
172
|
+
end
|
173
|
+
|
157
174
|
private
|
158
175
|
|
159
176
|
def validate_preview
|
@@ -225,6 +242,58 @@ module Dugway
|
|
225
242
|
@errors << "Duplicate style names found: #{duplicates.join(', ')}" if duplicates.any?
|
226
243
|
end
|
227
244
|
|
245
|
+
def validate_options_descriptions
|
246
|
+
missing_descriptions = settings['options'].select { |option|
|
247
|
+
option['description'].nil? || option['description'].strip.empty?
|
248
|
+
}.map { |option| option['variable'] }
|
249
|
+
|
250
|
+
@errors << "Missing descriptions for settings: #{missing_descriptions.join(', ')}" unless missing_descriptions.empty?
|
251
|
+
end
|
252
|
+
|
253
|
+
# Validate that any dependent settings are present in the theme settings
|
254
|
+
def validate_options_requires
|
255
|
+
return unless settings['options']
|
256
|
+
all_variables = settings['options'].map { |o| o['variable'] }
|
257
|
+
|
258
|
+
settings['options'].each do |option|
|
259
|
+
next unless option['requires']
|
260
|
+
|
261
|
+
# Handle case where requires is a string
|
262
|
+
if option['requires'].is_a?(String)
|
263
|
+
next if option['requires'] == 'inventory'
|
264
|
+
unless all_variables.include?(option['requires'])
|
265
|
+
@errors << "Option '#{option['variable']}' requires unknown setting '#{option['requires']}'"
|
266
|
+
end
|
267
|
+
next
|
268
|
+
end
|
269
|
+
|
270
|
+
# Validate requires is either a string or array
|
271
|
+
unless option['requires'].is_a?(Array)
|
272
|
+
@errors << "Option '#{option['variable']}' requires must be string 'inventory' or array of rules"
|
273
|
+
next
|
274
|
+
end
|
275
|
+
|
276
|
+
# Process each rule in the array
|
277
|
+
option['requires'].each do |rule|
|
278
|
+
next if rule == 'inventory'
|
279
|
+
|
280
|
+
# Extract setting name from rule
|
281
|
+
# Handle both simple cases ("show_search") and complex cases ("show_search eq true")
|
282
|
+
setting_name = if rule.include?(' ')
|
283
|
+
rule.split(/\s+/).first
|
284
|
+
else
|
285
|
+
rule
|
286
|
+
end
|
287
|
+
|
288
|
+
# Verify the referenced setting exists
|
289
|
+
unless all_variables.include?(setting_name)
|
290
|
+
@errors << "Option '#{option['variable']}' requires unknown setting '#{setting_name}'"
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
|
228
297
|
def source_dir
|
229
298
|
Dugway.source_dir
|
230
299
|
end
|
data/lib/dugway/version.rb
CHANGED
@@ -3,6 +3,19 @@ require 'spec_helper'
|
|
3
3
|
describe Dugway::Drops::ProductDrop do
|
4
4
|
let(:product) { Dugway::Drops::ProductDrop.new(Dugway.store.products.first) }
|
5
5
|
|
6
|
+
let(:related_products_mock) do
|
7
|
+
[
|
8
|
+
{ 'id' => 2, 'name' => 'Related Product 1' },
|
9
|
+
{ 'id' => 3, 'name' => 'Related Product 2' }
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow(Dugway::Drops::RelatedProductsDrop).to receive(:new)
|
15
|
+
.with(product.source, limit: 5, sort_order: nil)
|
16
|
+
.and_return(double(products: related_products_mock))
|
17
|
+
end
|
18
|
+
|
6
19
|
describe "#id" do
|
7
20
|
it "should return the product's id" do
|
8
21
|
product.id.should == 9422939
|
@@ -266,4 +279,27 @@ describe Dugway::Drops::ProductDrop do
|
|
266
279
|
end
|
267
280
|
end
|
268
281
|
end
|
282
|
+
|
283
|
+
describe "#related_products" do
|
284
|
+
let(:theme) { double('Dugway::Theme') }
|
285
|
+
let(:theme_customization) do
|
286
|
+
{
|
287
|
+
'related_items' => 5,
|
288
|
+
'related_products_order' => 'position'
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
before do
|
293
|
+
allow(Dugway).to receive(:theme).and_return(theme)
|
294
|
+
allow(theme).to receive(:customization).and_return(theme_customization)
|
295
|
+
allow(Dugway::Drops::RelatedProductsDrop).to receive(:new)
|
296
|
+
.with(product.source)
|
297
|
+
.and_return(double(products: related_products_mock))
|
298
|
+
end
|
299
|
+
|
300
|
+
it "returns the related products from RelatedProductsDrop" do
|
301
|
+
related_products = product.related_products
|
302
|
+
expect(related_products).to eq(related_products_mock)
|
303
|
+
end
|
304
|
+
end
|
269
305
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dugway::Drops::RelatedProductsDrop do
|
4
|
+
let(:product) do
|
5
|
+
{
|
6
|
+
'id' => 1,
|
7
|
+
'category_ids' => [1, 2],
|
8
|
+
'name' => 'Sample Product'
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:related_product_1) do
|
13
|
+
{
|
14
|
+
'id' => 2,
|
15
|
+
'category_ids' => [1],
|
16
|
+
'name' => 'Related Product 1'
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:related_product_2) do
|
21
|
+
{
|
22
|
+
'id' => 3,
|
23
|
+
'category_ids' => [2],
|
24
|
+
'name' => 'Related Product 2'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:unrelated_product) do
|
29
|
+
{
|
30
|
+
'id' => 4,
|
31
|
+
'category_ids' => [3],
|
32
|
+
'name' => 'Unrelated Product'
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:theme) { double('Dugway::Theme') }
|
37
|
+
let(:theme_customization) do
|
38
|
+
{
|
39
|
+
'related_items' => 2,
|
40
|
+
'related_products_order' => 'position'
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
allow(Dugway.store).to receive(:products).and_return([
|
46
|
+
product,
|
47
|
+
related_product_1,
|
48
|
+
related_product_2,
|
49
|
+
unrelated_product
|
50
|
+
])
|
51
|
+
allow(Dugway).to receive(:theme).and_return(theme)
|
52
|
+
allow(theme).to receive(:customization).and_return(theme_customization)
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:drop) { described_class.new(product) }
|
56
|
+
|
57
|
+
describe "#products" do
|
58
|
+
it "returns related products within the same categories" do
|
59
|
+
products = drop.products
|
60
|
+
expect(products.map { |p| p['id'] }).to match_array([2, 3])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "limits the number of related products returned" do
|
64
|
+
allow(theme).to receive(:customization).and_return({ 'related_items' => 1 })
|
65
|
+
products = drop.products
|
66
|
+
expect(products.size).to eq(1)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "excludes the original product from the results" do
|
70
|
+
products = drop.products
|
71
|
+
expect(products.map { |p| p['id'] }).not_to include(product['id'])
|
72
|
+
end
|
73
|
+
|
74
|
+
it "falls back to other products if category matches are insufficient" do
|
75
|
+
product['category_ids'] = [] # No categories
|
76
|
+
products = drop.products
|
77
|
+
expect(products.map { |p| p['id'] }).to match_array([2, 3])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -4,18 +4,30 @@ describe Dugway::Theme do
|
|
4
4
|
let(:theme) { Dugway.theme }
|
5
5
|
|
6
6
|
describe "#layout" do
|
7
|
+
before(:each) do
|
8
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
9
|
+
end
|
10
|
+
|
7
11
|
it "should return the theme's layout" do
|
8
12
|
theme.layout.should == read_file('layout.html')
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
12
16
|
describe "#settings" do
|
17
|
+
before(:each) do
|
18
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
19
|
+
end
|
20
|
+
|
13
21
|
it "should return a hash of the theme's settings" do
|
14
22
|
theme.settings.should == JSON.parse(read_file('settings.json'))
|
15
23
|
end
|
16
24
|
end
|
17
25
|
|
18
26
|
describe "#fonts" do
|
27
|
+
before(:each) do
|
28
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
29
|
+
end
|
30
|
+
|
19
31
|
it "should return a hash of font settings values" do
|
20
32
|
theme.fonts.should == {
|
21
33
|
'text_font' => 'Georgia',
|
@@ -25,6 +37,10 @@ describe Dugway::Theme do
|
|
25
37
|
end
|
26
38
|
|
27
39
|
describe "#images" do
|
40
|
+
before(:each) do
|
41
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
42
|
+
end
|
43
|
+
|
28
44
|
it "should return a hash of the image settings" do
|
29
45
|
theme.images.should == {
|
30
46
|
'logo' => { :url => 'images/logo_bc.png', :width => 1, :height => 1 }
|
@@ -33,6 +49,10 @@ describe Dugway::Theme do
|
|
33
49
|
end
|
34
50
|
|
35
51
|
describe "#image_sets" do
|
52
|
+
before(:each) do
|
53
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
54
|
+
end
|
55
|
+
|
36
56
|
it "should return a hash of the image set settings" do
|
37
57
|
theme.image_sets.should == {
|
38
58
|
'slideshow_images' => [
|
@@ -47,6 +67,10 @@ describe Dugway::Theme do
|
|
47
67
|
end
|
48
68
|
|
49
69
|
describe "#customization" do
|
70
|
+
before(:each) do
|
71
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
72
|
+
end
|
73
|
+
|
50
74
|
it "should return a hash of font, color, option, images and image sets settings values" do
|
51
75
|
theme.customization.should == {
|
52
76
|
'background_color' => 'white',
|
@@ -76,6 +100,8 @@ describe Dugway::Theme do
|
|
76
100
|
Dugway.stub(:theme) {
|
77
101
|
Dugway::Theme.new(:fixed_sidebar => false, :link_text_color => 'blue')
|
78
102
|
}
|
103
|
+
|
104
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
79
105
|
end
|
80
106
|
|
81
107
|
it "should merge those values into the defaults" do
|
@@ -105,18 +131,30 @@ describe Dugway::Theme do
|
|
105
131
|
end
|
106
132
|
|
107
133
|
describe "#name" do
|
134
|
+
before(:each) do
|
135
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
136
|
+
end
|
137
|
+
|
108
138
|
it "should return the theme's name" do
|
109
139
|
theme.name.should == 'Test Theme'
|
110
140
|
end
|
111
141
|
end
|
112
142
|
|
113
143
|
describe "#version" do
|
144
|
+
before(:each) do
|
145
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
146
|
+
end
|
147
|
+
|
114
148
|
it "should return the theme's version" do
|
115
149
|
theme.version.should == '1.2.3'
|
116
150
|
end
|
117
151
|
end
|
118
152
|
|
119
153
|
describe "#file_content" do
|
154
|
+
before(:each) do
|
155
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
156
|
+
end
|
157
|
+
|
120
158
|
it "should return the file content for most files" do
|
121
159
|
%w( home.html products.html screenshot.jpg ).each { |file_name|
|
122
160
|
theme.file_content(file_name).should == read_file(file_name)
|
@@ -133,6 +171,10 @@ describe Dugway::Theme do
|
|
133
171
|
end
|
134
172
|
|
135
173
|
describe "#build_file" do
|
174
|
+
before(:each) do
|
175
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
176
|
+
end
|
177
|
+
|
136
178
|
it "should return the file content for most files" do
|
137
179
|
%w( home.html products.html screenshot.jpg ).each { |file_name|
|
138
180
|
theme.build_file(file_name).should == read_file(file_name)
|
@@ -149,25 +191,55 @@ describe Dugway::Theme do
|
|
149
191
|
end
|
150
192
|
|
151
193
|
describe "#files" do
|
194
|
+
before(:each) do
|
195
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
196
|
+
end
|
197
|
+
|
152
198
|
it "should return an array of all files" do
|
153
199
|
theme.files.should =~ ["cart.html", "contact.html", "home.html", "layout.html", "maintenance.html", "product.html", "products.html", "screenshot.jpg", "settings.json", "theme.css", "theme.js", "images/logo_bc.png", "images/slideshow/1.gif", "images/slideshow/2.gif", "images/slideshow/3.gif", "images/slideshow/4.gif", "images/slideshow/5.gif", "images/small.svg", "fonts/icons.ttf", "fonts/icons.woff"]
|
154
200
|
end
|
155
201
|
end
|
156
202
|
|
157
203
|
describe "#image_files" do
|
204
|
+
before(:each) do
|
205
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
206
|
+
end
|
207
|
+
|
158
208
|
it "should return an array of all image files" do
|
159
209
|
theme.image_files.should =~ ["images/logo_bc.png", "images/slideshow/1.gif", "images/slideshow/2.gif", "images/slideshow/3.gif", "images/slideshow/4.gif", "images/slideshow/5.gif", "images/small.svg"]
|
160
210
|
end
|
161
211
|
end
|
162
212
|
|
163
213
|
describe "#font_files" do
|
214
|
+
before(:each) do
|
215
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
216
|
+
end
|
217
|
+
|
164
218
|
it "should return an array of all font files" do
|
165
219
|
theme.font_files.should include("fonts/icons.ttf", "fonts/icons.woff")
|
166
220
|
end
|
167
221
|
end
|
168
222
|
|
169
223
|
describe "#valid?" do
|
224
|
+
let(:required_colors) {[
|
225
|
+
'background_color',
|
226
|
+
'primary_text_color',
|
227
|
+
'link_text_color',
|
228
|
+
'link_hover_color',
|
229
|
+
'button_background_color',
|
230
|
+
'button_text_color',
|
231
|
+
'button_hover_background_color'
|
232
|
+
]}
|
233
|
+
|
170
234
|
it "should return true when a theme has everything it needs" do
|
235
|
+
allow(theme).to receive(:validate_required_color_settings) { true }
|
236
|
+
|
237
|
+
allow(theme).to receive(:settings).and_return({
|
238
|
+
'name' => 'Test Theme',
|
239
|
+
'version' => '1.2.3',
|
240
|
+
'colors' => required_colors.map { |color| {'variable' => color} }
|
241
|
+
})
|
242
|
+
|
171
243
|
theme.valid?.should be(true)
|
172
244
|
theme.errors.should be_empty
|
173
245
|
end
|
@@ -175,6 +247,7 @@ describe Dugway::Theme do
|
|
175
247
|
describe "when missing a required file" do
|
176
248
|
before(:each) do
|
177
249
|
theme.stub(:read_source_file).with('cart.html') { theme.unstub(:read_source_file); nil }
|
250
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
178
251
|
end
|
179
252
|
|
180
253
|
it "should not be valid" do
|
@@ -187,6 +260,7 @@ describe Dugway::Theme do
|
|
187
260
|
describe "when missing a name" do
|
188
261
|
before(:each) do
|
189
262
|
theme.stub(:name) { nil }
|
263
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
190
264
|
end
|
191
265
|
|
192
266
|
it "should not be valid" do
|
@@ -199,6 +273,7 @@ describe Dugway::Theme do
|
|
199
273
|
describe "when missing a version" do
|
200
274
|
before(:each) do
|
201
275
|
theme.stub(:version) { nil }
|
276
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
202
277
|
end
|
203
278
|
|
204
279
|
it "should not be valid" do
|
@@ -211,6 +286,7 @@ describe Dugway::Theme do
|
|
211
286
|
describe "when having an invalid version" do
|
212
287
|
before(:each) do
|
213
288
|
theme.stub(:version) { '1.3' }
|
289
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
214
290
|
end
|
215
291
|
|
216
292
|
it "should not be valid" do
|
@@ -224,6 +300,7 @@ describe Dugway::Theme do
|
|
224
300
|
before(:each) do
|
225
301
|
theme.stub(:name) { nil }
|
226
302
|
theme.stub(:version) { nil }
|
303
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
227
304
|
end
|
228
305
|
|
229
306
|
it "should return all of them" do
|
@@ -273,6 +350,7 @@ describe Dugway::Theme do
|
|
273
350
|
end
|
274
351
|
|
275
352
|
before(:each) do
|
353
|
+
allow(theme).to receive(:validate_required_color_settings) { true }
|
276
354
|
allow(theme).to receive(:name) { "Test Theme" }
|
277
355
|
allow(theme).to receive(:version) { "1.2.3" }
|
278
356
|
end
|
@@ -293,6 +371,88 @@ describe Dugway::Theme do
|
|
293
371
|
theme.errors.should include('Style in group \'Classic\' - Missing style_name')
|
294
372
|
end
|
295
373
|
end
|
374
|
+
|
375
|
+
describe "when missing option descriptions" do
|
376
|
+
before(:each) do
|
377
|
+
allow_any_instance_of(Dugway::Theme).to receive(:validate_required_color_settings) { true }
|
378
|
+
theme.stub(:settings) { {
|
379
|
+
'name' => 'Test Theme',
|
380
|
+
'version' => '1.2.3',
|
381
|
+
'colors' => [
|
382
|
+
{'variable' => 'background_color'},
|
383
|
+
{'variable' => 'primary_text_color'},
|
384
|
+
{'variable' => 'link_text_color'},
|
385
|
+
{'variable' => 'link_hover_color'},
|
386
|
+
{'variable' => 'button_background_color'},
|
387
|
+
{'variable' => 'button_text_color'},
|
388
|
+
{'variable' => 'button_hover_background_color'}
|
389
|
+
],
|
390
|
+
'options' => [{ 'variable' => 'show_search', 'label' => 'Show search' }]
|
391
|
+
} }
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should not be valid" do
|
395
|
+
theme.valid?.should be(false)
|
396
|
+
theme.errors.size.should == 1
|
397
|
+
theme.errors.first.should == 'Missing descriptions for settings: show_search'
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should be valid when skipping options validation" do
|
401
|
+
theme.valid?(validate_options: false).should be(true)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
describe "when validating option requirements" do
|
406
|
+
let(:required_colors) {[
|
407
|
+
'background_color',
|
408
|
+
'primary_text_color',
|
409
|
+
'link_text_color',
|
410
|
+
'link_hover_color',
|
411
|
+
'button_background_color',
|
412
|
+
'button_text_color',
|
413
|
+
'button_hover_background_color'
|
414
|
+
]}
|
415
|
+
|
416
|
+
it "allows options with no requires" do
|
417
|
+
settings = theme.settings.merge({
|
418
|
+
'options' => [{
|
419
|
+
'variable' => 'show_search',
|
420
|
+
'label' => 'Show search',
|
421
|
+
'description' => 'Show search in header'
|
422
|
+
}]
|
423
|
+
})
|
424
|
+
allow(theme).to receive(:settings).and_return(settings)
|
425
|
+
|
426
|
+
theme.valid?.should be(true)
|
427
|
+
theme.errors.should be_empty
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should not be valid when colors section is missing" do
|
431
|
+
allow(theme).to receive(:settings).and_return({
|
432
|
+
'name' => 'Test Theme',
|
433
|
+
'version' => '1.2.3',
|
434
|
+
'options' => []
|
435
|
+
})
|
436
|
+
|
437
|
+
theme.valid?.should be(false)
|
438
|
+
theme.errors.should include("Missing colors section in theme settings")
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should not be valid when required colors are missing" do
|
442
|
+
|
443
|
+
allow(theme).to receive(:settings).and_return({
|
444
|
+
'name' => 'Test Theme',
|
445
|
+
'version' => '1.2.3',
|
446
|
+
'colors' => [
|
447
|
+
{ 'variable' => 'background_color' }
|
448
|
+
],
|
449
|
+
'options' => []
|
450
|
+
})
|
451
|
+
|
452
|
+
theme.valid?.should be(false)
|
453
|
+
theme.errors.first.should match(/Missing required color settings:/)
|
454
|
+
end
|
455
|
+
end
|
296
456
|
end
|
297
457
|
|
298
458
|
def read_file(file_name)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dugway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Big Cartel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -490,6 +490,7 @@ files:
|
|
490
490
|
- lib/dugway/liquid/drops/product_drop.rb
|
491
491
|
- lib/dugway/liquid/drops/product_option_drop.rb
|
492
492
|
- lib/dugway/liquid/drops/products_drop.rb
|
493
|
+
- lib/dugway/liquid/drops/related_products_drop.rb
|
493
494
|
- lib/dugway/liquid/drops/shipping_option_drop.rb
|
494
495
|
- lib/dugway/liquid/drops/theme_drop.rb
|
495
496
|
- lib/dugway/liquid/drops/theme_image_sets_drop.rb
|
@@ -560,6 +561,7 @@ files:
|
|
560
561
|
- spec/units/dugway/liquid/drops/product_drop_spec.rb
|
561
562
|
- spec/units/dugway/liquid/drops/product_option_drop_spec.rb
|
562
563
|
- spec/units/dugway/liquid/drops/products_drop_spec.rb
|
564
|
+
- spec/units/dugway/liquid/drops/related_products_drop_spec.rb
|
563
565
|
- spec/units/dugway/liquid/drops/shipping_option_drop_spec.rb
|
564
566
|
- spec/units/dugway/liquid/drops/theme_drop_spec.rb
|
565
567
|
- spec/units/dugway/liquid/drops/theme_image_sets_drop_spec.rb
|
@@ -648,6 +650,7 @@ test_files:
|
|
648
650
|
- spec/units/dugway/liquid/drops/product_drop_spec.rb
|
649
651
|
- spec/units/dugway/liquid/drops/product_option_drop_spec.rb
|
650
652
|
- spec/units/dugway/liquid/drops/products_drop_spec.rb
|
653
|
+
- spec/units/dugway/liquid/drops/related_products_drop_spec.rb
|
651
654
|
- spec/units/dugway/liquid/drops/shipping_option_drop_spec.rb
|
652
655
|
- spec/units/dugway/liquid/drops/theme_drop_spec.rb
|
653
656
|
- spec/units/dugway/liquid/drops/theme_image_sets_drop_spec.rb
|