dugway 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +22 -0
- data/dugway.gemspec +3 -0
- data/lib/dugway/cart.rb +8 -12
- data/lib/dugway/cli/templates/Gemfile.tt +1 -1
- data/lib/dugway/cli/templates/gitignore.tt +1 -0
- data/lib/dugway/cli/templates/source/product.html +5 -3
- data/lib/dugway/cli/templates/source/stylesheets/cart.css.sass +8 -0
- data/lib/dugway/cli/templates/source/stylesheets/product.css.sass +32 -0
- data/lib/dugway/liquid/drops/cart_item_drop.rb +4 -0
- data/lib/dugway/liquid/drops/product_drop.rb +10 -6
- data/lib/dugway/liquid/drops/product_option_drop.rb +1 -1
- data/lib/dugway/liquid/drops/shipping_option_drop.rb +2 -0
- data/lib/dugway/liquid/tags/checkout_form.rb +1 -1
- data/lib/dugway/version.rb +1 -1
- data/spec/features/contact_form_spec.rb +43 -0
- data/spec/features/page_rendering_spec.rb +69 -0
- data/spec/features/shopping_spec.rb +38 -0
- data/spec/fixtures/store/products.js +1 -1
- data/spec/fixtures/store/store.js +1 -1
- data/spec/fixtures/theme/cart.html +22 -7
- data/spec/fixtures/theme/contact.html +37 -37
- data/spec/fixtures/theme/layout.html +8 -0
- data/spec/fixtures/theme/settings.json +1 -0
- data/spec/fixtures/theme/styles.css +2 -2
- data/spec/spec_helper.rb +8 -0
- data/spec/units/dugway/cart_spec.rb +204 -0
- data/spec/units/dugway/liquid/drops/account_drop_spec.rb +54 -0
- data/spec/units/dugway/liquid/drops/artist_drop_spec.rb +40 -0
- data/spec/units/dugway/liquid/drops/artists_drop_spec.rb +41 -0
- data/spec/units/dugway/liquid/drops/cart_drop_spec.rb +81 -0
- data/spec/units/dugway/liquid/drops/cart_item_drop_spec.rb +72 -0
- data/spec/units/dugway/liquid/drops/categories_drop_spec.rb +41 -0
- data/spec/units/dugway/liquid/drops/category_drop_spec.rb +40 -0
- data/spec/units/dugway/liquid/drops/contact_drop_spec.rb +124 -0
- data/spec/units/dugway/liquid/drops/country_drop_spec.rb +17 -0
- data/spec/units/dugway/liquid/drops/image_drop_spec.rb +23 -0
- data/spec/units/dugway/liquid/drops/page_drop_spec.rb +70 -0
- data/spec/units/dugway/liquid/drops/pages_drop_spec.rb +29 -0
- data/spec/units/dugway/liquid/drops/product_drop_spec.rb +269 -0
- data/spec/units/dugway/liquid/drops/product_option_drop_spec.rb +86 -0
- data/spec/units/dugway/liquid/drops/products_drop_spec.rb +127 -0
- data/spec/units/dugway/liquid/drops/shipping_option_drop_spec.rb +26 -0
- data/spec/units/dugway/liquid/drops/theme_drop_spec.rb +68 -0
- data/spec/units/dugway/store_spec.rb +27 -27
- data/spec/units/dugway/template_spec.rb +12 -0
- data/spec/units/dugway/theme_spec.rb +198 -0
- metadata +95 -57
- data/spec/units/dugway_spec.rb +0 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 753ddf37dd59de0812e32500da4fcf189b9d2f89
|
4
|
+
data.tar.gz: be0e35b01e22f044c8da70bc6888647476e38cac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9898d404fa7127e8163d712d12448052bbb845c40b03c5382a7c8b0e0bb302514dc0c5a8918c6492533f7d876e9f359f35b09dc923a30039353a515bcb72b150
|
7
|
+
data.tar.gz: ec25ce081aee329d90e937a5d40a21dd599362416a7c0a568e520e2cb825395066888faea7f4e5bcb20373a8141d1df0c6e77d3fa5157f904e0541820aeff104
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gemspec
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Big Cartel, LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/dugway.gemspec
CHANGED
@@ -41,4 +41,7 @@ Gem::Specification.new do |s|
|
|
41
41
|
s.add_development_dependency('rake', '~> 10.0.3')
|
42
42
|
s.add_development_dependency('rspec', '~> 2.12.0')
|
43
43
|
s.add_development_dependency('webmock', '~> 1.9.3')
|
44
|
+
s.add_development_dependency('json_expressions', '~> 0.8.2')
|
45
|
+
s.add_development_dependency('capybara', '~> 2.0.2')
|
46
|
+
s.add_development_dependency('simplecov', '~> 0.7.1')
|
44
47
|
end
|
data/lib/dugway/cart.rb
CHANGED
@@ -10,6 +10,10 @@ module Dugway
|
|
10
10
|
self.items = []
|
11
11
|
end
|
12
12
|
|
13
|
+
def empty?
|
14
|
+
items.empty?
|
15
|
+
end
|
16
|
+
|
13
17
|
def item_count
|
14
18
|
items.map { |item| item.quantity }.inject(:+) || 0
|
15
19
|
end
|
@@ -53,14 +57,10 @@ module Dugway
|
|
53
57
|
def update(params)
|
54
58
|
add, adds, updates = params.delete(:add), params.delete(:adds), params.delete(:update)
|
55
59
|
add_item(add) if add
|
56
|
-
|
60
|
+
add_items(adds) if adds
|
57
61
|
update_quantities(updates) if updates
|
58
62
|
end
|
59
63
|
|
60
|
-
def empty?
|
61
|
-
items.empty?
|
62
|
-
end
|
63
|
-
|
64
64
|
def as_json(options=nil)
|
65
65
|
{
|
66
66
|
:item_count => item_count,
|
@@ -83,7 +83,7 @@ module Dugway
|
|
83
83
|
product, option = Dugway.store.product_and_option(id)
|
84
84
|
|
85
85
|
if product && option
|
86
|
-
item =
|
86
|
+
item = Item.new
|
87
87
|
item.id = items.size + 1
|
88
88
|
item.name = option['name'] == 'Default' ? product['name'] : "#{ product['name'] } - #{ option['name'] }"
|
89
89
|
item.unit_price = option['price']
|
@@ -103,11 +103,7 @@ module Dugway
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def add_items(adds)
|
106
|
-
|
107
|
-
adds.each { |add| add_item(add) }
|
108
|
-
elsif adds.kind_of?(Hash)
|
109
|
-
adds.each_pair { |key, add| add_item(add.reverse_merge(:id => key)) }
|
110
|
-
end
|
106
|
+
adds.each { |add| add_item(add) }
|
111
107
|
end
|
112
108
|
|
113
109
|
def update_quantities(updates)
|
@@ -121,7 +117,7 @@ module Dugway
|
|
121
117
|
end
|
122
118
|
end
|
123
119
|
|
124
|
-
|
120
|
+
Item = Struct.new(:id, :name, :unit_price, :quantity, :product, :option) do
|
125
121
|
def price
|
126
122
|
unit_price * quantity
|
127
123
|
end
|
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gem 'dugway'
|
@@ -24,12 +24,14 @@
|
|
24
24
|
<h5>{{ product.default_price | money_with_sign }}{% if product.on_sale %} <em>On Sale{% endif %}</em></h5>
|
25
25
|
<h5>Availability</h5>
|
26
26
|
|
27
|
-
<ul>
|
27
|
+
<ul class="availability">
|
28
28
|
{% for option in product.options %}
|
29
29
|
<li>
|
30
30
|
{% unless product.has_default_option %}<span>{{ option.name }}</span>{% endunless %}
|
31
|
-
<span>{% if option.sold_out %}Sold Out{%
|
32
|
-
<
|
31
|
+
<span>{% if option.sold_out %}Sold Out{% endif %}</span>
|
32
|
+
<b>
|
33
|
+
<b style="width:{{ option.inventory }}%"></b>
|
34
|
+
</b>
|
33
35
|
</li>
|
34
36
|
{% endfor %}
|
35
37
|
</ul>
|
@@ -8,6 +8,9 @@ body#product
|
|
8
8
|
margin-right: 18px
|
9
9
|
border: 3px solid #eee
|
10
10
|
|
11
|
+
img
|
12
|
+
float: left
|
13
|
+
|
11
14
|
li.selected
|
12
15
|
border-color: #72c29b
|
13
16
|
|
@@ -17,3 +20,32 @@ body#product
|
|
17
20
|
border-right: none
|
18
21
|
margin-left: 30px
|
19
22
|
padding-left: 30px
|
23
|
+
width: 30%
|
24
|
+
|
25
|
+
form
|
26
|
+
div
|
27
|
+
float: left
|
28
|
+
margin-right: 5px
|
29
|
+
button
|
30
|
+
font-size: 12px
|
31
|
+
|
32
|
+
.availability
|
33
|
+
li
|
34
|
+
height: 16px
|
35
|
+
font-size: 11px
|
36
|
+
margin-bottom: 5px
|
37
|
+
|
38
|
+
span
|
39
|
+
display: block
|
40
|
+
float: left
|
41
|
+
width: 20%
|
42
|
+
|
43
|
+
> b
|
44
|
+
display: block
|
45
|
+
margin-left: 20%
|
46
|
+
width: 80%
|
47
|
+
|
48
|
+
b
|
49
|
+
background: #eee
|
50
|
+
display: block
|
51
|
+
height: 16px
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Dugway
|
2
2
|
module Drops
|
3
3
|
class ProductDrop < BaseDrop
|
4
|
+
def created_at
|
5
|
+
Time.parse(source['created_at'])
|
6
|
+
end
|
7
|
+
|
4
8
|
def price
|
5
9
|
nil # price is deprecated in favor of default_price
|
6
10
|
end
|
@@ -18,7 +22,7 @@ module Dugway
|
|
18
22
|
end
|
19
23
|
|
20
24
|
def has_default_option
|
21
|
-
@has_default_option ||= options.size == 1 && option.default
|
25
|
+
@has_default_option ||= options.size == 1 && option.name.downcase == 'default'
|
22
26
|
end
|
23
27
|
|
24
28
|
def option
|
@@ -30,11 +34,11 @@ module Dugway
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def options_in_stock
|
33
|
-
@options_in_stock ||= options
|
37
|
+
@options_in_stock ||= options.reject { |o| o.sold_out }
|
34
38
|
end
|
35
39
|
|
36
40
|
def shipping
|
37
|
-
@shipping ||= source['shipping'].map { |o| ShippingOptionDrop.new(o.update('product' => self)) }
|
41
|
+
@shipping ||= source['shipping'].present? ? source['shipping'].map { |o| ShippingOptionDrop.new(o.update('product' => self)) } : []
|
38
42
|
end
|
39
43
|
|
40
44
|
def image
|
@@ -70,15 +74,15 @@ module Dugway
|
|
70
74
|
end
|
71
75
|
|
72
76
|
def edit_url
|
73
|
-
|
77
|
+
'http://bigcartel.com'
|
74
78
|
end
|
75
79
|
|
76
80
|
def categories
|
77
|
-
@categories ||=
|
81
|
+
@categories ||= source['categories'].map { |c| CategoryDrop.new(c) } rescue []
|
78
82
|
end
|
79
83
|
|
80
84
|
def artists
|
81
|
-
@artists ||=
|
85
|
+
@artists ||= source['artists'].map { |a| ArtistDrop.new(a) } rescue []
|
82
86
|
end
|
83
87
|
|
84
88
|
def css_class
|
@@ -2,7 +2,7 @@ module Dugway
|
|
2
2
|
module Tags
|
3
3
|
class CheckoutForm < ::Liquid::Block
|
4
4
|
def render(context)
|
5
|
-
%{<form id="checkout_form" name="checkout_form" method="post" action="/success"
|
5
|
+
%{<form id="checkout_form" name="checkout_form" method="post" action="/success">#{ render_all(@nodelist, context) }</form>}
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
data/lib/dugway/version.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Contact form' do
|
4
|
+
scenario 'submitting the form' do
|
5
|
+
submit_contact_form
|
6
|
+
expect(page).to have_content('Your message has been sent')
|
7
|
+
end
|
8
|
+
|
9
|
+
scenario 'with a missing field' do
|
10
|
+
submit_contact_form(:name => '')
|
11
|
+
expect(page).to have_content('All fields are required')
|
12
|
+
end
|
13
|
+
|
14
|
+
scenario 'with an invalid email' do
|
15
|
+
submit_contact_form(:email => 'blah')
|
16
|
+
expect(page).to have_content('Invalid email address')
|
17
|
+
end
|
18
|
+
|
19
|
+
scenario 'with an invalid captcha' do
|
20
|
+
submit_contact_form(:captcha => 'blah')
|
21
|
+
expect(page).to have_content('Spam check was incorrect')
|
22
|
+
end
|
23
|
+
|
24
|
+
def submit_contact_form(fields={})
|
25
|
+
fields.reverse_merge!(
|
26
|
+
:name => 'Joe',
|
27
|
+
:email => 'joe@example.com',
|
28
|
+
:subject => 'Testing',
|
29
|
+
:message => 'Hi there',
|
30
|
+
:captcha => 'rQ9pC'
|
31
|
+
)
|
32
|
+
|
33
|
+
visit '/contact'
|
34
|
+
|
35
|
+
fill_in 'Name', :with => fields[:name]
|
36
|
+
fill_in 'Email', :with => fields[:email]
|
37
|
+
fill_in 'Subject', :with => fields[:subject]
|
38
|
+
fill_in 'Message', :with => fields[:message]
|
39
|
+
fill_in 'Spam check', :with => fields[:captcha]
|
40
|
+
|
41
|
+
click_button 'Send'
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Page rendering' do
|
4
|
+
scenario 'home.html' do
|
5
|
+
visit '/'
|
6
|
+
expect(page).to have_content('Dugway') # layout.html
|
7
|
+
expect(page).to have_content('My Product')
|
8
|
+
expect(page).to have_content('$10.00')
|
9
|
+
end
|
10
|
+
|
11
|
+
scenario 'products.html' do
|
12
|
+
visit '/products'
|
13
|
+
expect(page).to have_content('Dugway') # layout.html
|
14
|
+
expect(page).to have_content('Products')
|
15
|
+
expect(page).to have_content('My Product')
|
16
|
+
expect(page).to have_content('$10.00')
|
17
|
+
end
|
18
|
+
|
19
|
+
scenario 'product.html' do
|
20
|
+
visit '/product/my-product'
|
21
|
+
expect(page).to have_content('Dugway') # layout.html
|
22
|
+
expect(page).to have_content('My Product')
|
23
|
+
expect(page).to have_content('$10.00')
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario 'cart.html' do
|
27
|
+
visit '/cart'
|
28
|
+
expect(page).to have_content('Dugway') # layout.html
|
29
|
+
expect(page).to have_content('Cart')
|
30
|
+
expect(page).to have_content('Your cart is empty')
|
31
|
+
end
|
32
|
+
|
33
|
+
scenario 'success.html' do
|
34
|
+
visit '/success'
|
35
|
+
expect(page).to have_content('Dugway') # layout.html
|
36
|
+
expect(page).to have_content('Thank You. Your order has been placed.')
|
37
|
+
end
|
38
|
+
|
39
|
+
scenario 'contact.html' do
|
40
|
+
visit '/contact'
|
41
|
+
expect(page).to have_content('Dugway') # layout.html
|
42
|
+
expect(page).to have_content('Contact')
|
43
|
+
expect(page).to have_content('Spam check')
|
44
|
+
end
|
45
|
+
|
46
|
+
scenario 'maintenance.html' do
|
47
|
+
visit '/maintenance'
|
48
|
+
expect(page).to have_content('Please check back soon.')
|
49
|
+
end
|
50
|
+
|
51
|
+
scenario 'custom page' do
|
52
|
+
visit '/about-us'
|
53
|
+
expect(page).to have_content('Dugway') # layout.html
|
54
|
+
expect(page).to have_content('About Us')
|
55
|
+
expect(page).to have_content("We're really cool!")
|
56
|
+
end
|
57
|
+
|
58
|
+
scenario 'styles.css' do
|
59
|
+
visit '/styles.css'
|
60
|
+
expect(page).to have_content('height: 100%;') # one.css
|
61
|
+
expect(page).to have_content('color: red;') # two.css.sass
|
62
|
+
end
|
63
|
+
|
64
|
+
scenario 'scripts.js' do
|
65
|
+
visit '/scripts.js'
|
66
|
+
expect(page).to have_content("console.log('One')") # one.js
|
67
|
+
expect(page).to have_content("console.log('Two')") # two.js.coffee
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Shopping' do
|
4
|
+
scenario 'buying a product' do
|
5
|
+
visit '/'
|
6
|
+
expect(page).to have_content('Cart ($0.00)')
|
7
|
+
|
8
|
+
add_product_to_cart
|
9
|
+
expect(page).to have_content('Cart ($10.00)')
|
10
|
+
|
11
|
+
click_button 'Checkout'
|
12
|
+
expect(page).to have_content('One moment...')
|
13
|
+
|
14
|
+
click_button 'Checkout'
|
15
|
+
expect(page).to have_content('Thank You. Your order has been placed.')
|
16
|
+
expect(page).to have_content('Cart ($0.00)')
|
17
|
+
end
|
18
|
+
|
19
|
+
scenario 'updating a cart' do
|
20
|
+
add_product_to_cart
|
21
|
+
fill_in 'item_1_qty', :with => 3
|
22
|
+
click_button 'Update'
|
23
|
+
expect(page).to have_content('Cart ($30.00)')
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario 'removing a product' do
|
27
|
+
add_product_to_cart
|
28
|
+
fill_in 'item_1_qty', :with => 0
|
29
|
+
click_button 'Update'
|
30
|
+
expect(page).to have_content('Cart ($0.00)')
|
31
|
+
expect(page).to have_content('Your cart is empty')
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_product_to_cart
|
35
|
+
visit '/product/my-product'
|
36
|
+
click_button 'Add to Cart'
|
37
|
+
end
|
38
|
+
end
|