dugway 0.10.3 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 826b2f5eb8927caa43d20178107cad6e51811bb4
4
- data.tar.gz: 04baf16d2887144b19ae7664f7079df41f496577
3
+ metadata.gz: c7dcecd0162a10e803937e86ecc97601bf6ee155
4
+ data.tar.gz: 2586fa50d420763edfea6fe51effea36382efd50
5
5
  SHA512:
6
- metadata.gz: 3c1e3f431703966b86aedb8e8291c0b8d315e28e6f60f54577d589704dc6214f0bed02eb125776816abe59c94149accae6e16a1dd189cef86216292434e95de3
7
- data.tar.gz: f596dfb2520ea4f54e306c6b28ca94f676b6b1b789f1250b1676c417099c4e7593c19db3798e7b3775898cbf0b9a7f2d870c1be930d90ef42ae9371510b5b0e6
6
+ metadata.gz: 41f5dc95f6de48a0617e8cb684cb5a017d0780e872d670ef1f9da81c186cd968ccf1599dc4a5796eff931b3cb70bd5abc00484ee6503b4b33ae90adde4f69477
7
+ data.tar.gz: 8da215f70a623699c2907b8cf1a08efae0b5b0114650621310ea4534519f70d3eccfe49f9a38c4ae8df640da70307c515f799f866e934b99c014859054e9ad9b
data/.travis.yml CHANGED
@@ -2,8 +2,8 @@ language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
4
  rvm:
5
- - 1.9.3
6
5
  - 2.0
7
6
  - 2.1
7
+ - 2.2
8
8
  notifications:
9
9
  email: false
data/README.md CHANGED
@@ -2,23 +2,33 @@
2
2
 
3
3
  **_The easy way to build Big Cartel themes._**
4
4
 
5
- Dugway allows you to run your Big Cartel theme on your computer, test it in any browser, write code in your favorite editor, and use fancy new tools like CoffeeScript, Sass, and LESS. It's awesome.
5
+ Dugway allows you to run your Big Cartel theme on your computer, test it in any
6
+ browser, write code in your favorite editor, and use fancy new tools like
7
+ CoffeeScript, Sass, and LESS. It's awesome.
6
8
 
7
9
  [![Walkthrough](http://cl.ly/image/101e1z3Y3B1w/Screen%20Shot%202013-04-01%20at%205.04.40%20PM.png)](https://vimeo.com/bigcartel/dugway)
8
10
 
9
- ## Disclaimer
10
-
11
- **Dugway is a very new project and likely has several bugs, rough edges, and missing features.** If you run into something weird or have a cool idea, see if it's a [known issue](https://github.com/bigcartel/dugway/issues), and otherwise [report it](https://github.com/bigcartel/dugway/issues/new) and we'll do our best to hook you up. Thanks.
12
-
13
- ### Known Issues & Limitations
14
-
15
- * *You can't currently upload a Dugway build/zip to Big Cartel.* This is next on our list, and is what we built Dugway in preparation for. For now you'll still need to copy/paste theme pages individually in the Big Cartel admin, and host images, fonts, and JavaScript assets separately.
16
- * *Big Cartel doesn't currently support custom settings.json.* Since we don't support fully uploadable themes yet (as mentioned above), you can't currently use a custom settings.json. For now you'll need to base your theme off of one of our [default themes](https://github.com/bigcartel-themes) and its settings.json.
17
- * *Dugway doesn't currently support all discounts and shipping features.* For now it's best to test those with a live store so it can interact with actual discount and shipping information.
11
+ ## Known Issues & Limitations
12
+
13
+ * *You can't currently upload a Dugway build/zip to Big Cartel.* This is next
14
+ on our list, and is what we built Dugway in preparation for. For now you'll
15
+ still need to copy/paste theme pages individually in the Big Cartel admin,
16
+ and host images, fonts, and JavaScript assets separately.
17
+ * *Big Cartel doesn't currently support custom settings.json.* Since we don't
18
+ support fully uploadable themes yet (as mentioned above), you can't currently
19
+ use a custom settings.json. For now you'll need to base your theme off of one
20
+ of our [default themes](https://github.com/bigcartel-themes) and its
21
+ settings.json.
22
+ * *Dugway doesn't currently support all discounts and shipping features.* For
23
+ now it's best to test those with a live store so it can interact with actual
24
+ discount and shipping information.
18
25
 
19
26
  ## Install
20
27
 
21
- Dugway is Ruby gem so you'll need to have Ruby 1.9.3+ installed. Ruby is usually pre-installed on Mac OS X and Linux, and Windows users can install it using [RubyInstaller](http://rubyinstaller.org). From there, simply install the **dugway** gem from the terminal.
28
+ Dugway is Ruby gem so you'll need to have Ruby 2.0+ installed. Ruby is
29
+ usually pre-installed on Mac OS X and Linux, and Windows users can install it
30
+ using [RubyInstaller](http://rubyinstaller.org). From there, simply install the
31
+ **dugway** gem from the terminal.
22
32
 
23
33
  ```
24
34
  gem install dugway
@@ -32,7 +42,8 @@ With Dugway installed, you can now create a new theme, simply give it a name.
32
42
  dugway create mytheme
33
43
  ```
34
44
 
35
- This will create a new directory named *mytheme* that contains a few configuration files and a starter theme to get you going.
45
+ This will create a new directory named *mytheme* that contains a few
46
+ configuration files and a starter theme to get you going.
36
47
 
37
48
  ```
38
49
  mytheme
@@ -67,15 +78,30 @@ All of the assets and source code for your theme goes in the **source** director
67
78
 
68
79
  ### HTML
69
80
 
70
- Develop the HTML for your theme using our [Theme API](http://help.bigcartel.com/developers/themes/). Barebones versions of all of the required HTML pages for your theme are provided by default, so feel free to expand on those or replace them entirely.
81
+ Develop the HTML for your theme using our [Theme
82
+ API](http://help.bigcartel.com/developers/themes/). Barebones versions of all
83
+ of the required HTML pages for your theme are provided by default, so feel free
84
+ to expand on those or replace them entirely. Note that the **checkout.html**
85
+ and **success.html** pages are only used when
86
+ [PayPal Standard checkout](https://help.bigcartel.com/basics/settings/#paypal-standard) is enabled.
71
87
 
72
88
  ### CSS & JavaScript
73
89
 
74
- All CSS for your theme is handled by the **theme.css** file, and all JavaScript by **theme.js**. If you don't have much CSS or JavaScript, or you're just a glutton for punishment, you could simply put all of your code in these two files. However, we recommend you use [Sprockets](#using-sprockets) to break your code into multiple files in separate directories.
90
+ All CSS for your theme is handled by the **theme.css** file, and all JavaScript
91
+ by **theme.js**. If you don't have much CSS or JavaScript, or you're just a
92
+ glutton for punishment, you could simply put all of your code in these two
93
+ files. However, we recommend you use [Sprockets](#using-sprockets) to break
94
+ your code into multiple files in separate directories.
75
95
 
76
96
  #### Using Sprockets
77
97
 
78
- [Sprockets](https://github.com/sstephenson/sprockets) allows you to bring in CSS and JavaScript from different directories into a single file. We've created **stylesheets** and **javascripts** directories by default that you can put your code in, but you could delete those and put files anywhere you'd like. After that, use [Sprockets directives](https://github.com/sstephenson/sprockets#the-directive-processor) to package them into **theme.css** and **theme.js**.
98
+ [Sprockets](https://github.com/sstephenson/sprockets) allows you to bring in
99
+ CSS and JavaScript from different directories into a single file. We've created
100
+ **stylesheets** and **javascripts** directories by default that you can put
101
+ your code in, but you could delete those and put files anywhere you'd like.
102
+ After that, use [Sprockets
103
+ directives](https://github.com/sstephenson/sprockets#the-directive-processor)
104
+ to package them into **theme.css** and **theme.js**.
79
105
 
80
106
  ##### theme.css
81
107
 
@@ -95,39 +121,59 @@ All CSS for your theme is handled by the **theme.css** file, and all JavaScript
95
121
 
96
122
  #### Using Sass, Compass, LESS, and CoffeeScript
97
123
 
98
- Dugway also allows you to use [Sass](http://sass-lang.com) in your separate files by appending the **.sass** or **.scss** extension after **.css**. You can even use [Compass](http://compass-style.org/) right out of the box to help author your stylesheets by utilizing its mixins for CSS3, typography, and its utilities.
124
+ Dugway also allows you to use [Sass](http://sass-lang.com) in your separate
125
+ files by appending the **.sass** or **.scss** extension after **.css**. You can
126
+ even use [Compass](http://compass-style.org/) right out of the box to help
127
+ author your stylesheets by utilizing its mixins for CSS3, typography, and its
128
+ utilities.
99
129
 
100
- Prefer [LESS](http://lesscss.org)? No problem, you'll just need to create a [Gemfile like this one](https://gist.github.com/ihearithurts/5569898) in the root directory of your theme, run ```bundle install```, and append the **.less** extension to your CSS files.
130
+ Prefer [LESS](http://lesscss.org)? No problem, you'll just need to create a
131
+ [Gemfile like this one](https://gist.github.com/mattwigham/5569898) in the
132
+ root directory of your theme, run ```bundle install```, and append the
133
+ **.less** extension to your CSS files.
101
134
 
102
- And finally, for you JavaScript folks, we've baked [CoffeeScript](http://coffeescript.org) support right in. Just append the **.coffee** extension after **.js** to your separate JS files.
135
+ And finally, for you JavaScript folks, we've baked
136
+ [CoffeeScript](http://coffeescript.org) support right in. Just append the
137
+ **.coffee** extension after **.js** to your separate JS files.
103
138
 
104
139
  #### Embedding CSS & JavaScript
105
140
 
106
- You can embed the CSS and JavaScript into your theme by passing the theme variable to the [theme_css_url](http://help.bigcartel.com/developers/themes/#themecssurltheme) and [theme_js_url](http://help.bigcartel.com/developers/themes/#themejsurlname) filters.
141
+ You can embed the CSS and JavaScript into your theme by passing the theme
142
+ variable to the
143
+ [theme_css_url](http://help.bigcartel.com/developers/themes/#themecssurltheme)
144
+ and [theme_js_url](http://help.bigcartel.com/developers/themes/#themejsurlname)
145
+ filters.
107
146
 
108
147
  ##### CSS (theme.css)
109
148
 
110
- ```html
111
- <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
112
- ```
149
+ ```html <link href="{{ theme | theme_css_url }}" media="screen"
150
+ rel="stylesheet" type="text/css"> ```
113
151
 
114
152
  ##### JavaScript (theme.js)
115
153
 
116
- ```html
117
- <script src="{{ theme | theme_js_url }}" type="text/javascript"></script>
118
- ```
154
+ ```html <script src="{{ theme | theme_js_url }}"
155
+ type="text/javascript"></script> ```
119
156
 
120
157
  ### Images
121
158
 
122
- And as you've probably guessed by now, all images for your theme go in the **images** directory. You can reference an image in your code by passing its name to the [theme_image_url](http://help.bigcartel.com/developers/themes/#themeimageurlname) filter.
159
+ And as you've probably guessed by now, all images for your theme go in the
160
+ **images** directory. You can reference an image in your code by passing its
161
+ name to the
162
+ [theme_image_url](http://help.bigcartel.com/developers/themes/#themeimageurlname)
163
+ filter.
123
164
 
124
- ```
125
- {{ 'sample.png' | theme_image_url }}
126
- ```
165
+ ``` {{ 'sample.png' | theme_image_url }} ```
127
166
 
128
167
  ### Fonts
129
168
 
130
- Fonts work more or less the same as images. Place font files (say if you have created a custom icon font) in the **fonts** directory. Reference them by passing its name to the `theme_font_url` filter. Please be aware of licensing restrictions. If you're using a font from a forge and don't have permission to host the files directly or have restrictions about only making them available to certain domains, you will need to use another mechanism for hosting your fonts. Any font uploaded as part of a Dugway bundle will essentialy be publicly available and not CORS-restricted to specific domains.
169
+ Fonts work more or less the same as images. Place font files (say if you have
170
+ created a custom icon font) in the **fonts** directory. Reference them by
171
+ passing its name to the `theme_font_url` filter. Please be aware of licensing
172
+ restrictions. If you're using a font from a forge and don't have permission to
173
+ host the files directly or have restrictions about only making them available
174
+ to certain domains, you will need to use another mechanism for hosting your
175
+ fonts. Any font uploaded as part of a Dugway bundle will essentialy be publicly
176
+ available and not CORS-restricted to specific domains.
131
177
 
132
178
  ```
133
179
  {{ 'myfont.woff' | theme_font_url }}
@@ -135,31 +181,46 @@ Fonts work more or less the same as images. Place font files (say if you have cr
135
181
 
136
182
  ### Settings
137
183
 
138
- Set your theme's name, version, and customizable options in the **settings.json** file. We'll be documenting more about this soon, but for now see the starter file generated for you, and check out our [default themes](https://github.com/bigcartel-themes).
184
+ Set your theme's name, version, and customizable options in the
185
+ **settings.json** file. We'll be documenting more about this soon, but for now
186
+ see the starter file generated for you, and check out our [default
187
+ themes](https://github.com/bigcartel-themes).
139
188
 
140
189
  ## Running your theme
141
190
 
142
191
  Run your theme in any browser by starting the Dugway server:
143
192
 
144
- ```
145
- dugway server
146
- ```
193
+ ``` dugway server ```
147
194
 
148
- By default this will serve your theme at http://0.0.0.0:9292. You can then stop the server by hitting CTRL+C.
195
+ By default this will serve your theme at http://0.0.0.0:9292. You can then stop
196
+ the server by hitting CTRL+C.
149
197
 
150
198
  ### Pow
151
199
 
152
- Tired of all the manual starting and stopping? Good news, Dugway is built on top of Rack, which means you can use [Pow](http://pow.cx) on Mac. This also allows you to access your theme at a pretty URL like _mytheme.dev_.
200
+ Tired of all the manual starting and stopping? Good news, Dugway is built on
201
+ top of Rack, which means you can use [Pow](http://pow.cx) on Mac. This also
202
+ allows you to access your theme at a pretty URL like _mytheme.dev_.
153
203
 
154
204
  ## Testing your theme
155
205
 
156
- Part of building a great theme is making sure it works well in a variety of contexts and with a variety of content. Dugway makes it easy to test your theme's versatility by utilizing the **.dugway.json** file. This file will be specific to your computer for your own testing, and shouldn't be checked into source control.
206
+ Part of building a great theme is making sure it works well in a variety of
207
+ contexts and with a variety of content. Dugway makes it easy to test your
208
+ theme's versatility by utilizing the **.dugway.json** file. This file will be
209
+ specific to your computer for your own testing, and shouldn't be checked into
210
+ source control.
157
211
 
158
- *Note:* changing **.dugway.json** will require you to restart the [server](#running-your-theme).
212
+ *Note:* changing **.dugway.json** will require you to restart the
213
+ [server](#running-your-theme).
159
214
 
160
215
  ### Store content
161
216
 
162
- The best way to see your theme under a different light is by previewing it with a different store's products, categories, pages, currency, and other content. To do this, simply set the **store.subdomain** variable in **.dugway.json** to any Big Cartel store's subdomain, and Dugway will bring in their content using the standard [Big Cartel API](http://help.bigcartel.com/developers/api/). By default we use **dugway** for [dugway.bigcartel.com](http://dugway.bigcartel.com).
217
+ The best way to see your theme under a different light is by previewing it with
218
+ a different store's products, categories, pages, currency, and other content.
219
+ To do this, simply set the **store.subdomain** variable in **.dugway.json** to
220
+ any Big Cartel store's subdomain, and Dugway will bring in their content using
221
+ the standard [Big Cartel API](http://help.bigcartel.com/developers/api/). By
222
+ default we use **dugway** for
223
+ [dugway.bigcartel.com](http://dugway.bigcartel.com).
163
224
 
164
225
  ```json
165
226
  "store": {
@@ -171,7 +232,11 @@ The best way to see your theme under a different light is by previewing it with
171
232
 
172
233
  ### Store customization
173
234
 
174
- Another important thing to consider is how store owners will customize your theme. You establish what can be customized in your [settings.json](#settings) file, and Dugway allows you to simulate potential values people could choose by setting them in the **customization** variable in **.dugway.json**. By default we use the **default** values from your **[settings.json](#settings)** file.
235
+ Another important thing to consider is how store owners will customize your
236
+ theme. You establish what can be customized in your [settings.json](#settings)
237
+ file, and Dugway allows you to simulate potential values people could choose by
238
+ setting them in the **customization** variable in **.dugway.json**. By default
239
+ we use the **default** values from your **[settings.json](#settings)** file.
175
240
 
176
241
  ```json
177
242
  "customization": {
@@ -194,4 +259,5 @@ When you're finished with a new version of your theme, it's time to build it.
194
259
  dugway build
195
260
  ```
196
261
 
197
- This will create a zip file for the current version in your **build** directory containing all HTML, images, fonts, and packaged JS and CSS.
262
+ This will create a zip file for the current version in your **build** directory
263
+ containing all HTML, images, fonts, and packaged JS and CSS.
@@ -1,15 +1,13 @@
1
1
  require 'dugway/controller'
2
+ require 'dugway/contact_form_validator'
2
3
 
3
4
  module Dugway
4
5
  class Application < Controller
5
- # Home
6
6
 
7
7
  get '/' do
8
8
  render_page
9
9
  end
10
10
 
11
- # Products
12
-
13
11
  get '/products(.js)' do
14
12
  if request.html?
15
13
  render_page
@@ -19,66 +17,35 @@ module Dugway
19
17
  end
20
18
 
21
19
  get '/category/:category(.js)' do
22
- if category = store.category(params[:category])
23
- if request.html?
24
- page['name'] = category['name']
25
- render_page(:category => category)
26
- elsif request.js?
27
- render_json(store.category_products(params[:category]))
28
- end
29
- else
30
- render_not_found
31
- end
20
+ render_not_found unless category = store.category(params[:category])
21
+ render_artist_category_response(category, :category)
32
22
  end
33
23
 
34
24
  get '/artist/:artist(.js)' do
35
- if artist = store.artist(params[:artist])
36
- if request.html?
37
- page['name'] = artist['name']
38
- render_page(:artist => artist)
39
- elsif request.js?
40
- render_json(store.artist_products(params[:artist]))
41
- end
42
- else
43
- render_not_found
44
- end
25
+ render_not_found unless artist = store.artist(params[:artist])
26
+ render_artist_category_response(artist, :artist)
45
27
  end
46
28
 
47
- # Product
48
-
49
29
  get '/product/:product(.js)' do
50
- if product = store.product(params[:product])
51
- if request.html?
52
- page['name'] = product['name']
53
- render_page(:product => product)
54
- elsif request.js?
55
- render_json(product)
56
- end
57
- else
58
- render_not_found
30
+ render_not_found unless product = store.product(params[:product])
31
+ if request.html?
32
+ set_page_name_and_render_page(product, :product)
33
+ elsif request.js?
34
+ render_json(product)
59
35
  end
60
36
  end
61
37
 
62
- # Cart
63
-
64
38
  any '/cart(.js)' do
65
- if cart_params = params[:cart].try(:with_indifferent_access)
66
- cart.update(cart_params)
67
- end
39
+ cart.update(cart_params) if cart_params
40
+ redirect_to('/checkout') if params[:checkout]
68
41
 
69
- if params[:checkout]
70
- redirect_to('/checkout')
71
- else
72
- if request.html?
73
- render_page
74
- elsif request.js?
75
- render_json(cart)
76
- end
42
+ if request.html?
43
+ render_page
44
+ elsif request.js?
45
+ render_json(cart)
77
46
  end
78
47
  end
79
48
 
80
- # Checkout
81
-
82
49
  any '/checkout' do
83
50
  if cart.empty?
84
51
  error('Must have at least one product to checkout')
@@ -88,8 +55,6 @@ module Dugway
88
55
  end
89
56
  end
90
57
 
91
- # Success
92
-
93
58
  get '/success' do
94
59
  render_page
95
60
  end
@@ -100,38 +65,23 @@ module Dugway
100
65
  render_page
101
66
  end
102
67
 
103
- # Contact
104
-
105
68
  get '/contact' do
106
69
  render_page
107
70
  end
108
71
 
109
72
  post '/contact' do
110
- if [ :name, :email, :subject, :message, :captcha ].any? { |f| params[f].blank? }
111
- error('All fields are required')
112
- elsif !(params[:email] =~ /^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/)
113
- error('Invalid email address')
114
- elsif !(params[:captcha] =~ /^rQ9pC$/i)
115
- error('Spam check was incorrect')
116
- end
117
-
73
+ error(contact_form_error) if contact_form_error
118
74
  render_page
119
75
  end
120
76
 
121
- # Maintenance
122
-
123
77
  get '/maintenance' do
124
78
  render_page
125
79
  end
126
80
 
127
- # Custom page
128
-
129
81
  get '/:permalink' do
130
82
  render_page
131
83
  end
132
84
 
133
- # Assets
134
-
135
85
  get '/theme.css' do
136
86
  render_file('theme.css')
137
87
  end
@@ -143,5 +93,29 @@ module Dugway
143
93
  get %r{^/images|fonts/.+$} do
144
94
  Rack::File.new(Dugway.source_dir).call(request.env)
145
95
  end
96
+
97
+ private
98
+
99
+ def self.cart_params
100
+ params[:cart].try(:with_indifferent_access)
101
+ end
102
+
103
+ def self.contact_form_error
104
+ ContactFormValidator.new(params).error_message
105
+ end
106
+
107
+ def self.render_artist_category_response(object, type)
108
+ if request.html?
109
+ set_page_name_and_render_page(object, type)
110
+ elsif request.js?
111
+ render_json(store.send("#{type}_products", params[type]))
112
+ end
113
+ end
114
+
115
+ def self.set_page_name_and_render_page(object, type)
116
+ page['name'] = object['name']
117
+ render_page(type => object)
118
+ end
119
+
146
120
  end
147
121
  end
@@ -4,50 +4,50 @@ module Dugway
4
4
  module Cli
5
5
  class Build < Thor::Group
6
6
  include Thor::Actions
7
-
7
+
8
8
  def self.source_root
9
9
  File.join(Dir.pwd, 'source')
10
10
  end
11
-
11
+
12
12
  def self.destination_root
13
13
  File.join(Dir.pwd, 'build')
14
14
  end
15
-
15
+
16
16
  def validate
17
17
  unless theme.valid?
18
18
  theme.errors.each { |error| say(error, :red) }
19
19
  raise "Theme is invalid"
20
20
  end
21
21
  end
22
-
22
+
23
23
  def create_destination
24
24
  empty_directory self.class.destination_root
25
25
  end
26
-
26
+
27
27
  def build
28
- Zip::ZipFile.open(build_file, Zip::ZipFile::CREATE) { |zipfile|
29
- theme.files.each { |file|
30
- zipfile.get_output_stream(file) { |f|
28
+ Zip::ZipFile.open(build_file, Zip::ZipFile::CREATE) do |zipfile|
29
+ theme.files.each do |file|
30
+ zipfile.get_output_stream(file) do |f|
31
31
  f << theme.build_file(file)
32
- }
33
- }
34
- }
32
+ end
33
+ end
34
+ end
35
35
  end
36
-
36
+
37
37
  def success
38
38
  say_status(:create, "build/#{ build_name }")
39
39
  end
40
-
40
+
41
41
  private
42
-
42
+
43
43
  def theme
44
44
  @theme ||= Dugway.theme
45
45
  end
46
-
46
+
47
47
  def build_name
48
48
  @build_name ||= "#{ theme.name.parameterize }-#{ theme.version }.zip"
49
49
  end
50
-
50
+
51
51
  def build_file
52
52
  @build_file ||= File.join(self.class.destination_root, build_name)
53
53
  end
@@ -10,7 +10,7 @@
10
10
  {% endif %}
11
11
  </section>
12
12
 
13
- <section>
13
+ <div>
14
14
  <aside>
15
15
  {% case product.status %}
16
16
 
@@ -0,0 +1,39 @@
1
+ module Dugway
2
+ class ContactFormValidator
3
+
4
+ attr_accessor :params
5
+
6
+ def initialize(params)
7
+ @params = params
8
+ end
9
+
10
+ def error_message
11
+ if required_fields.any? { |f| params[f].blank? }
12
+ 'All fields are required'
13
+ elsif param_does_not_match(:email, email_format)
14
+ 'Invalid email address'
15
+ elsif param_does_not_match(:captcha, captcha_format)
16
+ 'Spam check was incorrect'
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def required_fields
23
+ [ :name, :email, :subject, :message, :captcha ]
24
+ end
25
+
26
+ def email_format
27
+ /^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/
28
+ end
29
+
30
+ def captcha_format
31
+ /^rQ9pC$/i
32
+ end
33
+
34
+ def param_does_not_match(param_name, regex)
35
+ !(params[param_name.to_sym] =~ regex)
36
+ end
37
+
38
+ end
39
+ end
@@ -1,9 +1,8 @@
1
1
  require 'rack/mount'
2
+ require 'dugway/path_interpreter'
2
3
 
3
4
  module Dugway
4
5
  class Controller
5
- PERMALINK_REGEX = %r{[a-z0-9\-_]+}
6
- FORMAT_REGEX = %r{(\.(?<format>js))?}
7
6
 
8
7
  class << self
9
8
  def routes
@@ -25,33 +24,12 @@ module Dugway
25
24
  end
26
25
  }, {
27
26
  :request_method => method,
28
- :path_info => interpret_path(path)
27
+ :path_info => PathInterpreter.new(path).call
29
28
  })
30
29
 
31
30
  routes.rehash
32
31
  end
33
32
 
34
- def interpret_path(path)
35
- if path.is_a?(String)
36
- case path
37
- # category/artist/product
38
- when %r{^/(\w+)/:(#{ PERMALINK_REGEX })\(\.js\)}
39
- %r{^/#{ $1 }/(?<#{ $2 }>#{ PERMALINK_REGEX })#{ FORMAT_REGEX }$}
40
- # products/cart
41
- when %r{^/(\w+)\(\.js\)$}
42
- %r{^/#{ $1 }#{ FORMAT_REGEX }$}
43
- # custom pages
44
- when %r{^/:(#{ PERMALINK_REGEX })}
45
- %r{^/(?<#{ $1 }>#{ PERMALINK_REGEX })$}
46
- # everything else
47
- else
48
- %r{^#{ path }$}
49
- end
50
- else
51
- path
52
- end
53
- end
54
-
55
33
  def get(path, &block)
56
34
  route('GET', path, &block)
57
35
  end
@@ -142,4 +120,5 @@ module Dugway
142
120
  self.class.routes.call(env)
143
121
  end
144
122
  end
123
+
145
124
  end
@@ -12,13 +12,13 @@ module Dugway
12
12
  html << %(<span class="previous disabled">#{ prev_label }</span>)
13
13
  end
14
14
 
15
- paginate['parts'].each { |part|
15
+ paginate['parts'].each do |part|
16
16
  if part['is_link']
17
17
  html << %(<a href="#{ part['url'] }">#{ part['title'] }</a>)
18
18
  else
19
19
  html << %(<span class="#{ part['title'] == paginate['current_page'].to_s ? 'current' : 'gap' }">#{ part['title'] }</span>)
20
20
  end
21
- }
21
+ end
22
22
 
23
23
  next_label = next_label.blank? ? paginate['next']['title'] : next_label
24
24
  if paginate['next']['is_link']
@@ -8,47 +8,14 @@ module Dugway
8
8
  content_tag :a, text, options
9
9
  end
10
10
 
11
- # To get max_w-100
12
- # Eg product.primary_image | product_image_url | constrain : '100'
13
- # To get max_h-100
14
- # Eg product.primary_image | product_image_url | constrain : '-', '100'
15
- # To get max_h-100+max_w-100
16
- # Eg product.primary_image | product_image_url | constrain : '100', '100'
17
11
  def constrain(url = nil, width = 0, height = 0)
18
- if url
19
- parsed_url = URI.parse(url)
20
- path_parts = parsed_url.path.split('/')
21
-
22
- width = width.to_i
23
- height = height.to_i
24
-
25
- path_parts.slice(-2).tap do |size|
26
- unless width == 0 && height == 0
27
- size.gsub!(/(max_w-)\d+/) do |match|
28
- width == 0 ? '' : "#{ $1 }#{ width }"
29
- end
30
-
31
- size.gsub!(/(max_h-)\d+/) do |match|
32
- height == 0 ? '' : "#{ $1 }#{ height }"
33
- end
34
-
35
- size.gsub!(/\+/, '') if width == 0 || height == 0
36
- end
37
- end
38
-
39
- parsed_url.path = path_parts.join('/')
40
- parsed_url.to_s
41
- end
12
+ image_url url, width, height if url
42
13
  end
43
14
 
44
15
  def product_image_url(image = nil, size = nil)
45
- width, height = legacy_size_for(size)
46
-
47
- if image.blank?
48
- image_url_hash('http://images.cdn.bigcartel.com/missing/-/missing.png', height, width)
49
- else
50
- image_url_hash(image['url'], height, width)
51
- end
16
+ url = image ? image['url'] : 'http://images.bigcartel.com/missing.png'
17
+ size = legacy_size_for(size)
18
+ image_url url, size, size
52
19
  end
53
20
 
54
21
  def theme_js_url(name)
@@ -85,20 +52,20 @@ module Dugway
85
52
  options
86
53
  end
87
54
 
88
- protected
89
- def image_url_hash(url, max_h = 1000, max_w = 1000)
90
- url = url.gsub(/\/-\//, "/max_h-#{ max_h }+max_w-#{ max_w }/")
91
- url
55
+ def image_url(url, width, height)
56
+ uri = URI.parse(url)
57
+ query_hash = Rack::Utils.parse_nested_query uri.query
58
+ uri.query = query_hash.update('w' => width, 'h' => height).to_query
59
+ uri.to_s
92
60
  end
93
61
 
94
62
  def legacy_size_for(size)
95
- size = size.present? ? size : :original
96
-
97
- Hash.new([ 1000, 1000 ]).merge({
98
- thumb: [ 75, 75 ],
99
- medium: [ 175, 175 ],
100
- large: [ 300, 300 ]
101
- })[size.to_sym]
63
+ case size
64
+ when 'large' then 300
65
+ when 'medium' then 175
66
+ when 'thumb' then 75
67
+ else 1000
68
+ end
102
69
  end
103
70
  end
104
71
  end
@@ -0,0 +1,45 @@
1
+ module Dugway
2
+ class PathInterpreter
3
+ attr_accessor :path
4
+
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def call
10
+ return path unless path.is_a?(String)
11
+ case path
12
+ when category_artist_or_product_path
13
+ %r{^/#{$1}/(?<#{$2}>#{permalink_regex})#{format_regex}$}
14
+ when product_or_cart_path
15
+ %r{^/#{$1}#{format_regex}$}
16
+ when custom_page_path
17
+ %r{^/(?<#{$1}>#{permalink_regex})$}
18
+ else
19
+ %r{^#{path}$}
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def permalink_regex
26
+ %r{[a-z0-9\-_]+}
27
+ end
28
+
29
+ def format_regex
30
+ %r{(\.(?<format>js))?}
31
+ end
32
+
33
+ def category_artist_or_product_path
34
+ %r{^/(\w+)/:(#{permalink_regex})\(\.js\)}
35
+ end
36
+
37
+ def product_or_cart_path
38
+ %r{^/(\w+)\(\.js\)$}
39
+ end
40
+
41
+ def custom_page_path
42
+ %r{^/:(#{permalink_regex})}
43
+ end
44
+ end
45
+ end
data/lib/dugway/store.rb CHANGED
@@ -78,33 +78,33 @@ module Dugway
78
78
  end
79
79
 
80
80
  def product_and_option(option_id)
81
- products.each { |product|
82
- product['options'].each { |option|
81
+ products.each do |product|
82
+ product['options'].each do |option|
83
83
  if option['id'] == option_id
84
84
  return product, option
85
85
  end
86
- }
87
- }
86
+ end
87
+ end
88
88
 
89
89
  nil
90
90
  end
91
91
 
92
92
  def previous_product(permalink)
93
- products.each_with_index { |product, index|
93
+ products.each_with_index do |product, index|
94
94
  if product['permalink'] == permalink && index > 0 && previous_product = products[index - 1]
95
95
  return previous_product
96
96
  end
97
- }
97
+ end
98
98
 
99
99
  nil
100
100
  end
101
101
 
102
102
  def next_product(permalink)
103
- products.each_with_index { |product, index|
103
+ products.each_with_index do |product, index|
104
104
  if product['permalink'] == permalink && (index + 1) < products.size && next_product = products[index + 1]
105
105
  return next_product
106
106
  end
107
- }
107
+ end
108
108
 
109
109
  nil
110
110
  end
data/lib/dugway/theme.rb CHANGED
@@ -36,13 +36,13 @@ module Dugway
36
36
  end
37
37
 
38
38
  def customization
39
- Hash.new.tap { |customization|
40
- %w( fonts colors options images image_sets ).each { |type|
39
+ Hash.new.tap do |customization|
40
+ %w( fonts colors options images image_sets ).each do |type|
41
41
  customization.update(customization_for_type(type))
42
- }
42
+ end
43
43
 
44
44
  customization.update(@overridden_customization)
45
- }
45
+ end
46
46
  end
47
47
 
48
48
  def name
@@ -78,23 +78,23 @@ module Dugway
78
78
  end
79
79
 
80
80
  def image_files
81
- Dir.glob(File.join(source_dir, 'images', '**', '*.{png,jpg,jpeg,gif,ico,svg}')).map { |i|
81
+ Dir.glob(File.join(source_dir, 'images', '**', '*.{png,jpg,jpeg,gif,ico,svg}')).map do |i|
82
82
  i.gsub(source_dir, '')[1..-1]
83
- }
83
+ end
84
84
  end
85
85
 
86
86
  def font_files
87
- Dir.glob(File.join(source_dir, 'fonts', '**', '*.{eot,ttf,otf,woff,svg}')).map { |i|
87
+ Dir.glob(File.join(source_dir, 'fonts', '**', '*.{eot,ttf,otf,woff,svg}')).map do |i|
88
88
  i.gsub(source_dir, '')[1..-1]
89
- }
89
+ end
90
90
  end
91
91
 
92
92
  def valid?
93
93
  @errors = []
94
94
 
95
- REQUIRED_FILES.each { |file|
95
+ REQUIRED_FILES.each do |file|
96
96
  @errors << "Missing source/#{ file }" if read_source_file(file).nil?
97
- }
97
+ end
98
98
 
99
99
  @errors << 'Missing theme name in source/settings.json' if name.blank?
100
100
  @errors << 'Invalid theme version in source/settings.json (ex: 1.0.3)' unless !!(version =~ /\d+\.\d+\.\d+/)
@@ -135,31 +135,31 @@ module Dugway
135
135
  end
136
136
 
137
137
  def customization_for_type(type)
138
- Hash.new.tap { |hash|
138
+ Hash.new.tap do |hash|
139
139
  if settings.has_key?(type)
140
140
  case type
141
141
  when 'images'
142
- settings[type].each { |setting|
142
+ settings[type].each do |setting|
143
143
  if name = setting['default']
144
144
  hash[setting['variable']] = { :url => image_path_from_setting_name(name), :width => 1, :height => 1 }
145
145
  end
146
- }
146
+ end
147
147
  when 'image_sets'
148
- settings[type].each { |setting|
148
+ settings[type].each do |setting|
149
149
  if defaults = setting['default'] || setting['defaults']
150
150
  hash[setting['variable']] ||= []
151
151
  defaults.each do |name|
152
152
  hash[setting['variable']] << { :url => image_path_from_setting_name(name), :width => 1, :height => 1 }
153
153
  end
154
154
  end
155
- }
155
+ end
156
156
  else
157
- settings[type].each { |setting|
157
+ settings[type].each do |setting|
158
158
  hash[setting['variable']] = setting['default']
159
- }
159
+ end
160
160
  end
161
161
  end
162
- }
162
+ end
163
163
  end
164
164
 
165
165
  def image_path_from_setting_name(name)
@@ -1,3 +1,3 @@
1
1
  module Dugway
2
- VERSION = "0.10.3"
2
+ VERSION = "0.10.4"
3
3
  end
@@ -1 +1 @@
1
- [{"price":10.0,"status":"active","created_at":"2013-02-10T19:28:11-07:00","tax":0.0,"position":1,"artists":[{"permalink":"artist-one","name":"Artist One","id":176141,"url":"/artist/artist-one"}],"shipping":[{"amount_with_others":5.0,"country":{"name":"United States","id":43,"code":"US"},"amount_alone":10.0},{"amount_with_others":10.0,"amount_alone":20.0}],"images":[{"width":475,"height":500,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/92599166/-/mens_tee_1.jpg","url":"http://cache1.bigcartel.com/product_images/92599166/-/mens_tee_1.jpg"},{"width":475,"height":475,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/92599178/-/mens_tee_2.jpg","url":"http://cache1.bigcartel.com/product_images/92599178/-/mens_tee_2.jpg"},{"width":475,"height":475,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/92599196/-/mens_tee_3.jpg","url":"http://cache1.bigcartel.com/product_images/92599196/-/mens_tee_3.jpg"},{"width":475,"height":475,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/92599214/-/mens_tee_4.jpg","url":"http://cache0.bigcartel.com/product_images/92599214/-/mens_tee_4.jpg"},{"width":475,"height":475,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/92599226/-/mens_tee_5.jpg","url":"http://cache1.bigcartel.com/product_images/92599226/-/mens_tee_5.jpg"}],"categories":[{"permalink":"tees","name":"Tees","id":4615193,"url":"/category/tees"}],"on_sale":false,"permalink":"my-product","name":"My Product","default_price":10.0,"id":9422939,"description":"This is a description of my product.","options":[{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Small","id":29474321},{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Medium","id":29474324},{"price":10.0,"sold_out":true,"has_custom_price":false,"name":"Large","id":29474327},{"price":15.0,"sold_out":false,"has_custom_price":true,"name":"X-Large","id":29474330}],"url":"/product/my-product"},{"price":10.0,"status":"active","created_at":"2013-03-02T10:05:34-07:00","tax":0.0,"position":2,"artists":[{"permalink":"artist-two","name":"Artist Two","id":176144,"url":"/artist/artist-two"}],"images":[{"width":475,"height":475,"secure_url":"https://s3.amazonaws.com/bigcartel/product_images/95272745/-/mens_tee_8.jpg","url":"http://cache0.bigcartel.com/product_images/95272745/-/mens_tee_8.jpg"}],"categories":[{"permalink":"tees","name":"Tees","id":4615193,"url":"/category/tees"}],"on_sale":false,"permalink":"my-tee","name":"My Tee","default_price":10.0,"id":9696017,"description":"This is my cool tee shirt.","options":[{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Small","id":30344519},{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Medium","id":30344522},{"price":15.0,"sold_out":false,"has_custom_price":true,"name":"Large","id":30344525}],"url":"/product/my-tee"},{"price":20.0,"status":"active","created_at":"2013-03-02T10:06:22-07:00","tax":0.0,"position":3,"artists":[],"categories":[{"permalink":"prints","name":"Prints","id":4615190,"url":"/category/prints"}],"on_sale":true,"permalink":"print","name":"Print","default_price":20.0,"id":9696032,"description":"This is my print.","options":[{"price":20.0,"sold_out":false,"has_custom_price":false,"name":"Default","id":30344567}],"url":"/product/print"}]
1
+ [{"price":10.0,"status":"active","created_at":"2013-02-10T19:28:11-07:00","tax":0.0,"position":1,"artists":[{"permalink":"artist-one","name":"Artist One","id":176141,"url":"/artist/artist-one"}],"shipping":[{"amount_with_others":5.0,"country":{"name":"United States","id":43,"code":"US"},"amount_alone":10.0},{"amount_with_others":10.0,"amount_alone":20.0}],"images":[{"width":475,"height":500,"secure_url":"https://images.bigcartel.com/product_images/92599166/mens_tee_1.jpg","url":"http://images.bigcartel.com/product_images/92599166/mens_tee_1.jpg"},{"width":475,"height":475,"secure_url":"https://images.bigcartel.com/product_images/92599178/mens_tee_2.jpg","url":"http://images.bigcartel.com/product_images/92599178/mens_tee_2.jpg"},{"width":475,"height":475,"secure_url":"https://images.bigcartel.com/product_images/92599196/mens_tee_3.jpg","url":"http://images.bigcartel.com/product_images/92599196/mens_tee_3.jpg"},{"width":475,"height":475,"secure_url":"https://images.bigcartel.com/product_images/92599214/mens_tee_4.jpg","url":"http://images.bigcartel.com/product_images/92599214/mens_tee_4.jpg"},{"width":475,"height":475,"secure_url":"https://images.bigcartel.com/product_images/92599226/mens_tee_5.jpg","url":"http://images.bigcartel.com/product_images/92599226/mens_tee_5.jpg"}],"categories":[{"permalink":"tees","name":"Tees","id":4615193,"url":"/category/tees"}],"on_sale":false,"permalink":"my-product","name":"My Product","default_price":10.0,"id":9422939,"description":"This is a description of my product.","options":[{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Small","id":29474321},{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Medium","id":29474324},{"price":10.0,"sold_out":true,"has_custom_price":false,"name":"Large","id":29474327},{"price":15.0,"sold_out":false,"has_custom_price":true,"name":"X-Large","id":29474330}],"url":"/product/my-product"},{"price":10.0,"status":"active","created_at":"2013-03-02T10:05:34-07:00","tax":0.0,"position":2,"artists":[{"permalink":"artist-two","name":"Artist Two","id":176144,"url":"/artist/artist-two"}],"images":[{"width":475,"height":475,"secure_url":"https://images.bigcartel.com/product_images/95272745/mens_tee_8.jpg","url":"http://images.bigcartel.com/product_images/95272745/mens_tee_8.jpg"}],"categories":[{"permalink":"tees","name":"Tees","id":4615193,"url":"/category/tees"}],"on_sale":false,"permalink":"my-tee","name":"My Tee","default_price":10.0,"id":9696017,"description":"This is my cool tee shirt.","options":[{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Small","id":30344519},{"price":10.0,"sold_out":false,"has_custom_price":false,"name":"Medium","id":30344522},{"price":15.0,"sold_out":false,"has_custom_price":true,"name":"Large","id":30344525}],"url":"/product/my-tee"},{"price":20.0,"status":"active","created_at":"2013-03-02T10:06:22-07:00","tax":0.0,"position":3,"artists":[],"categories":[{"permalink":"prints","name":"Prints","id":4615190,"url":"/category/prints"}],"on_sale":true,"permalink":"print","name":"Print","default_price":20.0,"id":9696032,"description":"This is my print.","options":[{"price":20.0,"sold_out":false,"has_custom_price":false,"name":"Default","id":30344567}],"url":"/product/print"}]
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'dugway/contact_form_validator'
3
+
4
+ describe Dugway::ContactFormValidator do
5
+
6
+ let(:validator) { described_class.new(params) }
7
+
8
+ let(:params) do
9
+ {
10
+ :name => "name",
11
+ :email => "name@example.com",
12
+ :subject => "subject",
13
+ :message => "message",
14
+ :captcha => "rQ9pc",
15
+ }
16
+ end
17
+
18
+ describe "#error_message" do
19
+ it "returns an error for a missing name" do
20
+ validator.params[:name] = " "
21
+ assert_required_fields_error
22
+ end
23
+
24
+ it "returns an error for a missing email" do
25
+ validator.params[:email] = ""
26
+ assert_required_fields_error
27
+ end
28
+
29
+ it "returns an error for a missing subject" do
30
+ validator.params[:subject] = nil
31
+ assert_required_fields_error
32
+ end
33
+
34
+ it "returns an error for a missing message" do
35
+ validator.params[:message] = nil
36
+ assert_required_fields_error
37
+ end
38
+
39
+ it "returns an error for a missing captcha" do
40
+ validator.params[:captcha] = " "
41
+ assert_required_fields_error
42
+ end
43
+
44
+ it "returns an error for invalid email format" do
45
+ validator.params[:email] = "foo-at-foo-dot-net"
46
+ expect(validator.error_message).to eq "Invalid email address"
47
+ end
48
+
49
+ it "returns an error for incorrect captcha" do
50
+ validator.params[:captcha] = "oops"
51
+ expect(validator.error_message).to eq "Spam check was incorrect"
52
+ end
53
+
54
+ def assert_required_fields_error
55
+ expect(validator.error_message).to eql "All fields are required"
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -5,7 +5,7 @@ describe Dugway::Drops::ImageDrop do
5
5
 
6
6
  describe "#url" do
7
7
  it "should return the image's url" do
8
- image.url.should == 'http://cache1.bigcartel.com/product_images/92599166/-/mens_tee_1.jpg'
8
+ image.url.should == 'http://images.bigcartel.com/product_images/92599166/mens_tee_1.jpg'
9
9
  end
10
10
  end
11
11
 
@@ -213,7 +213,7 @@ describe Dugway::Drops::ProductDrop do
213
213
  it "should return the product's first image" do
214
214
  image = product.image
215
215
  image.should be_an_instance_of(Dugway::Drops::ImageDrop)
216
- image.url.should == 'http://cache1.bigcartel.com/product_images/92599166/-/mens_tee_1.jpg'
216
+ image.url.should == 'http://images.bigcartel.com/product_images/92599166/mens_tee_1.jpg'
217
217
  end
218
218
  end
219
219
 
@@ -225,7 +225,7 @@ describe Dugway::Drops::ProductDrop do
225
225
 
226
226
  image = images.first
227
227
  image.should be_an_instance_of(Dugway::Drops::ImageDrop)
228
- image.url.should == 'http://cache1.bigcartel.com/product_images/92599166/-/mens_tee_1.jpg'
228
+ image.url.should == 'http://images.bigcartel.com/product_images/92599166/mens_tee_1.jpg'
229
229
  end
230
230
  end
231
231
 
@@ -10,48 +10,42 @@ describe Dugway::Filters::UrlFilters do
10
10
  describe "when image is not missing" do
11
11
  it "should show image with default size" do
12
12
  template = rendered_template("{{ image | product_image_url }}", 'image' => product_image)
13
- template.should =~ /max_h-1000\+max_w-1000/
14
- template.should =~ /#{Regexp.escape(File.basename(image_url))}/
13
+ template.should include("#{image_url}?h=1000&w=1000")
15
14
  end
16
15
 
17
16
  it "should show a image with custom size" do
18
17
  template = rendered_template("{{ image | product_image_url: 'thumb' }}", 'image' => product_image)
19
- template.should =~ /max_h-75\+max_w-75/
20
- template.should =~ /#{Regexp.escape(File.basename(image_url))}/
18
+ template.should include("#{image_url}?h=75&w=75")
21
19
  end
22
20
 
23
21
  it "should show image with default size when its random crap" do
24
22
  template = rendered_template("{{ image | product_image_url: 'snarble' }}", 'image' => product_image)
25
- template.should =~ /max_h-1000\+max_w-1000/
26
- template.should =~ /#{Regexp.escape(File.basename(image_url))}/
23
+ template.should include("#{image_url}?h=1000&w=1000")
27
24
  end
28
25
  end
29
26
 
30
27
  describe "when image is missing" do
31
28
  it "should show missing image with default 1000x1000" do
32
29
  template = rendered_template("{{ image | product_image_url }}", 'image' => nil)
33
- template.should =~ /max_h-1000\+max_w-1000/
34
- template.should =~ /missing\.png/
30
+ template.should include("http://images.bigcartel.com/missing.png?h=1000&w=1000")
35
31
  end
36
32
 
37
33
  it "should show missing image with custom size" do
38
34
  template = rendered_template("{{ image | product_image_url: 'thumb' }}", 'image' => nil)
39
- template.should =~ /max_h-75\+max_w-75/
40
- template.should =~ /missing\.png/
35
+ template.should include("http://images.bigcartel.com/missing.png?h=75&w=75")
41
36
  end
42
37
 
43
38
  it "should show missing image with default 1000x1000 when its random crap" do
44
39
  template = rendered_template("{{ image | product_image_url: 'snarble' }}", 'image' => nil)
45
- template.should =~ /max_h-1000\+max_w-1000/
46
- template.should =~ /missing\.png/
40
+ template.should include("http://images.bigcartel.com/missing.png?h=1000&w=1000")
47
41
  end
48
42
  end
49
43
  end
50
44
 
51
45
  describe "#constrain" do
52
46
  it 'should constrain the image to the specified size' do
53
- template = rendered_template("{{ image | product_image_url | constrain: '222', '222' }}", 'image' => product_image)
54
- template.should =~ /max_h-222\+max_w-222/
47
+ template = rendered_template("{{ image | product_image_url | constrain: '123', '456' }}", 'image' => product_image)
48
+ template.should include("#{image_url}?h=456&w=123")
55
49
  end
56
50
  end
57
51
  end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'dugway/path_interpreter'
3
+
4
+ describe Dugway::PathInterpreter do
5
+ let(:path) { double 'path' }
6
+ let(:interpreter) { described_class.new(path) }
7
+
8
+ it "initializes with arguements" do
9
+ expect(interpreter.path).to eq path
10
+ end
11
+
12
+ describe "#call" do
13
+ it "handles non-string paths" do
14
+ expect(described_class.new(/regex/).call).to eql /regex/
15
+ end
16
+
17
+ it "handles category, artist, and product type paths" do
18
+ expect(described_class.new("/product/:product(.js)").call).to eq(
19
+ %r{^/product/(?<product>(?-mix:[a-z0-9\-_]+))(?-mix:(\.(?<format>js))?)$}
20
+ )
21
+ end
22
+
23
+ it "handles products and cart type paths" do
24
+ expect(described_class.new("/products(.js)").call).to eq(
25
+ %r{^/products(?-mix:(\.(?<format>js))?)$}
26
+ )
27
+ end
28
+
29
+ it "handles custom pages" do
30
+ expect(described_class.new("/:custom-page").call).to eq(
31
+ %r{^/(?<custom-page>(?-mix:[a-z0-9\-_]+))$}
32
+ )
33
+ end
34
+
35
+ it "handles everything else" do
36
+ expect(described_class.new("/checkout").call).to eq(
37
+ %r{^/checkout$}
38
+ )
39
+ end
40
+ end
41
+ end
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: 0.10.3
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Big Cartel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-22 00:00:00.000000000 Z
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -440,6 +440,7 @@ files:
440
440
  - lib/dugway/cli/templates/source/success.html
441
441
  - lib/dugway/cli/templates/source/theme.css
442
442
  - lib/dugway/cli/templates/source/theme.js
443
+ - lib/dugway/contact_form_validator.rb
443
444
  - lib/dugway/controller.rb
444
445
  - lib/dugway/extensions/time.rb
445
446
  - lib/dugway/liquid/drops/account_drop.rb
@@ -474,6 +475,7 @@ files:
474
475
  - lib/dugway/liquid/tags/paginate.rb
475
476
  - lib/dugway/liquifier.rb
476
477
  - lib/dugway/logger.rb
478
+ - lib/dugway/path_interpreter.rb
477
479
  - lib/dugway/request.rb
478
480
  - lib/dugway/store.rb
479
481
  - lib/dugway/template.rb
@@ -515,6 +517,7 @@ files:
515
517
  - spec/fixtures/theme/theme.js
516
518
  - spec/spec_helper.rb
517
519
  - spec/units/dugway/cart_spec.rb
520
+ - spec/units/dugway/contact_form_validator_spec.rb
518
521
  - spec/units/dugway/liquid/drops/account_drop_spec.rb
519
522
  - spec/units/dugway/liquid/drops/artist_drop_spec.rb
520
523
  - spec/units/dugway/liquid/drops/artists_drop_spec.rb
@@ -537,6 +540,7 @@ files:
537
540
  - spec/units/dugway/liquid/filters/core_filters_spec.rb
538
541
  - spec/units/dugway/liquid/filters/url_filters_spec.rb
539
542
  - spec/units/dugway/liquid/misc/for_loop_spec.rb
543
+ - spec/units/dugway/path_interpreter_spec.rb
540
544
  - spec/units/dugway/request_spec.rb
541
545
  - spec/units/dugway/store_spec.rb
542
546
  - spec/units/dugway/template_spec.rb
@@ -602,6 +606,7 @@ test_files:
602
606
  - spec/fixtures/theme/theme.js
603
607
  - spec/spec_helper.rb
604
608
  - spec/units/dugway/cart_spec.rb
609
+ - spec/units/dugway/contact_form_validator_spec.rb
605
610
  - spec/units/dugway/liquid/drops/account_drop_spec.rb
606
611
  - spec/units/dugway/liquid/drops/artist_drop_spec.rb
607
612
  - spec/units/dugway/liquid/drops/artists_drop_spec.rb
@@ -624,7 +629,9 @@ test_files:
624
629
  - spec/units/dugway/liquid/filters/core_filters_spec.rb
625
630
  - spec/units/dugway/liquid/filters/url_filters_spec.rb
626
631
  - spec/units/dugway/liquid/misc/for_loop_spec.rb
632
+ - spec/units/dugway/path_interpreter_spec.rb
627
633
  - spec/units/dugway/request_spec.rb
628
634
  - spec/units/dugway/store_spec.rb
629
635
  - spec/units/dugway/template_spec.rb
630
636
  - spec/units/dugway/theme_spec.rb
637
+ has_rdoc: