radiant-shop_packages-extension 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +2 -0
  2. data/README +3 -0
  3. data/Rakefile +138 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/.DS_Store +0 -0
  6. data/app/controllers/admin/shop/packages/packings_controller.rb +90 -0
  7. data/app/controllers/admin/shop/packages_controller.rb +63 -0
  8. data/app/datasets/shop_packages.rb +25 -0
  9. data/app/models/shop_package.rb +79 -0
  10. data/app/models/shop_packing.rb +22 -0
  11. data/app/views/admin/shop/packages/edit.html.haml +11 -0
  12. data/app/views/admin/shop/packages/edit/_foot.html.haml +17 -0
  13. data/app/views/admin/shop/packages/edit/_form.html.haml +15 -0
  14. data/app/views/admin/shop/packages/edit/_head.html.haml +4 -0
  15. data/app/views/admin/shop/packages/edit/_inputs.html.haml +2 -0
  16. data/app/views/admin/shop/packages/edit/_meta.html.haml +8 -0
  17. data/app/views/admin/shop/packages/edit/_parts.html.haml +9 -0
  18. data/app/views/admin/shop/packages/edit/_popups.html.haml +4 -0
  19. data/app/views/admin/shop/packages/edit/buttons/_browse_products.html.haml +1 -0
  20. data/app/views/admin/shop/packages/edit/inputs/_name.html.haml +3 -0
  21. data/app/views/admin/shop/packages/edit/inputs/_price.html.haml +3 -0
  22. data/app/views/admin/shop/packages/edit/meta/_sku.html.haml +5 -0
  23. data/app/views/admin/shop/packages/edit/parts/_description.html.haml +1 -0
  24. data/app/views/admin/shop/packages/edit/parts/_products.html.haml +3 -0
  25. data/app/views/admin/shop/packages/edit/popups/_browse_products.html.haml +7 -0
  26. data/app/views/admin/shop/packages/edit/shared/_product.html.haml +8 -0
  27. data/app/views/admin/shop/packages/index.html.haml +13 -0
  28. data/app/views/admin/shop/packages/index/_foot.html.haml +8 -0
  29. data/app/views/admin/shop/packages/index/_head.html.haml +2 -0
  30. data/app/views/admin/shop/packages/index/_package.html.haml +9 -0
  31. data/app/views/admin/shop/packages/index/buttons/_new_package.html.haml +1 -0
  32. data/app/views/admin/shop/packages/new.html.haml +11 -0
  33. data/app/views/admin/shop/packages/remove.html.haml +12 -0
  34. data/config/locales/en.yml +11 -0
  35. data/config/routes.rb +13 -0
  36. data/cucumber.yml +1 -0
  37. data/db/migrate/20101015161749_setup_shop_packages.rb +27 -0
  38. data/lib/shop_packages/interface/packages.rb +34 -0
  39. data/lib/shop_packages/models/shop_packageable.rb +15 -0
  40. data/lib/shop_packages/tags/helpers.rb +41 -0
  41. data/lib/shop_packages/tags/package.rb +94 -0
  42. data/lib/tasks/shop_packages_extension_tasks.rake +55 -0
  43. data/public/javascripts/admin/extensions/shop/packages/edit.js +109 -0
  44. data/public/stylesheets/sass/admin/extensions/shop/packages/edit.sass +162 -0
  45. data/radiant-shop_packages-extension.gemspec +104 -0
  46. data/shop_packages_extension.rb +37 -0
  47. data/spec/controllers/admin/shop/packages/packings_controller_spec.rb +188 -0
  48. data/spec/controllers/admin/shop/packages_controller_spec.rb +32 -0
  49. data/spec/datasets/shop_packages.rb +23 -0
  50. data/spec/lib/shop_packages/tags/package_spec.rb +348 -0
  51. data/spec/models/shop_package_spec.rb +117 -0
  52. data/spec/models/shop_packing_spec.rb +67 -0
  53. data/spec/models/shop_product_spec.rb +25 -0
  54. data/spec/spec.opts +4 -0
  55. data/spec/spec_helper.rb +23 -0
  56. metadata +141 -0
@@ -0,0 +1,188 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Admin::Shop::Packages::PackingsController do
4
+
5
+ dataset :users
6
+
7
+ before(:each) do
8
+ login_as :admin
9
+
10
+ @shop_package = ShopPackage.new
11
+ @shop_packages = [ @shop_package ]
12
+
13
+ @shop_product = ShopProduct.new
14
+ @shop_products = [ @shop_product ]
15
+
16
+ @shop_packing = ShopPacking.new
17
+ @shop_packings = [ @shop_packing ]
18
+
19
+ stub(@shop_package).id { 1 }
20
+ stub(@shop_package).packings { @shop_packings }
21
+ end
22
+
23
+ describe '#sort' do
24
+ before :each do
25
+ @packings = [
26
+ 'package_products[]=2',
27
+ 'package_products[]=1'
28
+ ].join('&')
29
+ end
30
+
31
+ context 'packings are not passed' do
32
+ context 'js' do
33
+ it 'should return an error string and failure status' do
34
+ put :sort, :package_id => 1, :format => 'js'
35
+
36
+ response.should_not be_success
37
+ response.body.should === "Could not sort products."
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'categories are passed' do
43
+ context 'could not sort' do
44
+ before :each do
45
+ mock(ShopPacking).find('2').stub!.update_attributes!({:position,1}) { raise ActiveRecord::RecordNotSaved }
46
+ end
47
+
48
+ context 'js' do
49
+ it 'should return an error string and failure status' do
50
+ put :sort, :package_id => 1, :packings => @packings, :format => 'js'
51
+
52
+ response.should_not be_success
53
+ response.body.should === 'Could not sort products.'
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'successfully sorted' do
59
+ before :each do
60
+ mock(ShopPacking).find('2').stub!.update_attributes!({:position,1}) { true }
61
+ mock(ShopPacking).find('1').stub!.update_attributes!({:position,2}) { true }
62
+ end
63
+
64
+ context 'js' do
65
+ it 'should return success string and success status' do
66
+ put :sort, :package_id => 1, :packings => @packings, :format => 'js'
67
+
68
+ response.should be_success
69
+ response.body.should === 'Products successfully sorted.'
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ describe '#create' do
77
+ before :each do
78
+ mock(ShopPackage).find('1') { @shop_package }
79
+ mock(ShopProduct).find('1') { @shop_product }
80
+ mock(ShopPacking).new { @shop_packing }
81
+ end
82
+ context 'packing could not be created' do
83
+ before :each do
84
+ mock(@shop_packing).save! { raise ActiveRecord::RecordNotSaved }
85
+ end
86
+
87
+ context 'js' do
88
+ it 'should return error notice and failure status' do
89
+ post :create, :package_id => 1, :product_id => 1, :format => 'js'
90
+
91
+ response.body.should === 'Could not attach product.'
92
+ response.should_not be_success
93
+ end
94
+ end
95
+ end
96
+
97
+ context 'packing successfully created' do
98
+ before :each do
99
+ mock(@shop_packing).save! { true }
100
+ end
101
+
102
+ context 'js' do
103
+ it 'should render the collection partial and success status' do
104
+ post :create, :package_id => 1, :product_id => 1, :format => 'js'
105
+
106
+ response.should be_success
107
+ assigns(:shop_packing).should === @shop_packing
108
+ response.should render_template('admin/shop/packages/edit/shared/_product')
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#update' do
115
+ before :each do
116
+ mock(ShopPacking).find('1') { @shop_packing }
117
+ end
118
+ context 'packing could not be created' do
119
+ before :each do
120
+ mock(@shop_packing).update_attributes!({ :quantity => '1' }) { raise ActiveRecord::RecordNotSaved }
121
+ end
122
+
123
+ context 'js' do
124
+ it 'should return error notice and failure status' do
125
+ put :update, :package_id => 1, :id => 1, :quantity => 1, :format => 'js'
126
+
127
+ response.should_not be_success
128
+ response.body.should === 'Could not update Product Quantity.'
129
+ end
130
+ end
131
+ end
132
+
133
+ context 'packing successfully created' do
134
+ before :each do
135
+ mock(@shop_packing).update_attributes!({ :quantity => '1' }) { true }
136
+ end
137
+
138
+ context 'js' do
139
+ it 'should render the collection partial and success status' do
140
+ put :update, :package_id => 1, :id => 1, :quantity => 1, :format => 'js'
141
+
142
+ response.should be_success
143
+ response.body.should === 'Product Quantity successfully updated.'
144
+
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '#destroy' do
151
+ before :each do
152
+ mock(ShopPacking).find('1') { @shop_packing }
153
+ stub(@shop_packing).product { nil }
154
+ stub(@shop_packing).package { nil }
155
+ end
156
+
157
+ context 'product not destroyed' do
158
+ before :each do
159
+ stub(@shop_packing).destroy { raise ActiveRecord::RecordNotFound }
160
+ end
161
+
162
+ context 'js' do
163
+ it 'should render an error and failure status' do
164
+ delete :destroy, :package_id => 1, :id => 1, :format => 'js'
165
+
166
+ response.should_not be_success
167
+ response.body.should === 'Could not remove product.'
168
+ end
169
+ end
170
+ end
171
+
172
+ context 'product successfully destroyed' do
173
+ before :each do
174
+ stub(@shop_packing).destroy { true }
175
+ end
176
+
177
+ context 'js' do
178
+ it 'should render success message and success status' do
179
+ delete :destroy, :package_id => 1, :id => 1, :format => 'js'
180
+
181
+ response.should be_success
182
+ response.should render_template('admin/shop/packages/edit/shared/_product')
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe Admin::Shop::PackagesController do
4
+
5
+ dataset :users, :shop_packages
6
+
7
+ before(:each) do
8
+ login_as :admin
9
+ @package = shop_packages(:all_bread)
10
+ end
11
+
12
+ describe '#new' do
13
+ it 'should assign global instance variables' do
14
+ get :new
15
+
16
+ assigns(:meta).should === ['sku']
17
+ assigns(:buttons).should === []
18
+ assigns(:parts).should === ['description']
19
+ end
20
+ end
21
+
22
+ describe '#edit' do
23
+ it 'should assign global instance variables' do
24
+ get :edit, :id => @package.id
25
+
26
+ assigns(:meta).should === ['sku']
27
+ assigns(:buttons).should === ['browse_products']
28
+ assigns(:parts).should === ['description','products']
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,23 @@
1
+ class ShopPackagesDataset < Dataset::Base
2
+ uses :shop_products
3
+
4
+ def load
5
+ packages = {
6
+ :bread => [ :soft, :crusty, :warm ]
7
+ }
8
+ packages.each do |package, products|
9
+ create_record :shop_package, "all_#{package.to_s}".to_sym,
10
+ :name => "all #{package.to_s}",
11
+ :sku => "all_#{package.to_s}",
12
+ :price => 1 * 10
13
+
14
+ products.each_with_index do |product, i|
15
+ create_record :shop_packing, "#{product.to_s}_bread".to_s.to_sym,
16
+ :quantity => 1,
17
+ :position => 1,
18
+ :package => shop_packages("all_#{package.to_s}".to_sym),
19
+ :product => shop_products("#{product.to_s}_bread".to_sym)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,348 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ShopPackages::Tags::Package do
4
+
5
+ dataset :pages, :shop_packages
6
+
7
+ it 'should describe these tags' do
8
+ ShopPackages::Tags::Package.tags.sort.should == [
9
+ 'shop:packages',
10
+ 'shop:packages:if_packages',
11
+ 'shop:packages:unless_packages',
12
+ 'shop:packages:each',
13
+ 'shop:package',
14
+ 'shop:package:id',
15
+ 'shop:package:name',
16
+ 'shop:package:sku',
17
+ 'shop:package:description',
18
+ 'shop:package:price',
19
+ 'shop:package:value',
20
+ 'shop:package:if_products',
21
+ 'shop:package:unless_products',
22
+ 'shop:package:products',
23
+ 'shop:package:products:each',
24
+ 'shop:package:product:quantity'].sort
25
+ end
26
+
27
+ before :all do
28
+ @page = pages(:home)
29
+ end
30
+
31
+ before :each do
32
+ @package = shop_packages(:all_bread)
33
+ end
34
+
35
+ context 'outside a package' do
36
+ describe '<r:shop:packages>' do
37
+ context 'packages' do
38
+ it 'should render' do
39
+ tag = %{<r:shop:packages>success</r:shop:packages>}
40
+ exp = %{success}
41
+
42
+ @page.should render(tag).as(exp)
43
+ end
44
+ end
45
+ context 'no packages' do
46
+ it 'should render' do
47
+ tag = %{<r:shop:packages>success</r:shop:packages>}
48
+ exp = %{success}
49
+
50
+ @page.should render(tag).as(exp)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '<r:shop:packages:if_packages>' do
56
+ context 'success' do
57
+ it 'should render' do
58
+ tag = %{<r:shop:packages:if_packages>success</r:shop:packages:if_packages>}
59
+ exp = %{success}
60
+
61
+ @page.should render(tag).as(exp)
62
+ end
63
+ end
64
+ context 'failure' do
65
+ it 'should render' do
66
+ mock(ShopPackages::Tags::Helpers).current_packages(anything) { [] }
67
+ tag = %{<r:shop:packages:if_packages>failure</r:shop:packages:if_packages>}
68
+ exp = %{}
69
+
70
+ @page.should render(tag).as(exp)
71
+ end
72
+ end
73
+ end
74
+
75
+ describe '<r:shop:packages:unless_packages>' do
76
+ context 'success' do
77
+ it 'should not render' do
78
+ mock(ShopPackages::Tags::Helpers).current_packages(anything) { [] }
79
+
80
+ tag = %{<r:shop:packages:unless_packages>success</r:shop:packages:unless_packages>}
81
+ exp = %{success}
82
+
83
+ @page.should render(tag).as(exp)
84
+ end
85
+ end
86
+ context 'failure' do
87
+ it 'should render' do
88
+ mock(ShopPackages::Tags::Helpers).current_packages(anything) { ShopPackage.all }
89
+
90
+ tag = %{<r:shop:packages:unless_packages>failure</r:shop:packages:unless_packages>}
91
+ exp = %{}
92
+
93
+ @page.should render(tag).as(exp)
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '<r:shop:packages:each>' do
99
+ context 'success' do
100
+ it 'should render' do
101
+ mock(ShopPackages::Tags::Helpers).current_packages(anything) { ShopPackage.all }
102
+
103
+ tag = %{<r:shop:packages:each>.a.</r:shop:packages:each>}
104
+ exp = ShopPackage.all.map{ '.a.' }.join('')
105
+
106
+ @page.should render(tag).as(exp)
107
+ end
108
+ end
109
+
110
+ context 'failure' do
111
+ it 'should not render' do
112
+ mock(ShopPackages::Tags::Helpers).current_packages(anything) { [] }
113
+
114
+ tag = %{<r:shop:packages:each>failure</r:shop:packages:each>}
115
+ exp = %{}
116
+
117
+ @page.should render(tag).as(exp)
118
+ end
119
+ end
120
+ end
121
+
122
+ describe '<r:shop:package>' do
123
+ context 'success' do
124
+ it 'should render' do
125
+ mock(ShopPackages::Tags::Helpers).current_package(anything) { @package }
126
+
127
+ tag = %{<r:shop:package>success</r:shop:package>}
128
+ exp = %{success}
129
+
130
+ @page.should render(tag).as(exp)
131
+ end
132
+ end
133
+
134
+ context 'failure' do
135
+ it 'should not render' do
136
+ mock(ShopPackages::Tags::Helpers).current_package(anything) { nil }
137
+
138
+ tag = %{<r:shop:package>failure</r:shop:package>}
139
+ exp = %{}
140
+
141
+ @page.should render(tag).as(exp)
142
+ end
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ context 'within a package' do
149
+
150
+ before :each do
151
+ mock(ShopPackages::Tags::Helpers).current_package(anything) { @package }
152
+ end
153
+
154
+ context 'simple attributes' do
155
+ describe '<r:shop:package:id />' do
156
+ it 'should render the id' do
157
+ tag = %{<r:shop:package:id />}
158
+ exp = @package.id.to_s
159
+
160
+ @page.should render(tag).as(exp)
161
+ end
162
+ end
163
+
164
+ describe '<r:shop:package:name />' do
165
+ it 'should render the name' do
166
+ tag = %{<r:shop:package:name />}
167
+ exp = @package.name.to_s
168
+
169
+ @page.should render(tag).as(exp)
170
+ end
171
+ end
172
+
173
+ describe '<r:shop:package:sku />' do
174
+ it 'should render the sku' do
175
+ tag = %{<r:shop:package:sku />}
176
+ exp = @package.sku.to_s
177
+
178
+ @page.should render(tag).as(exp)
179
+ end
180
+ end
181
+ end
182
+
183
+ describe '<r:package:description />' do
184
+ it 'should render a textile filtered result' do
185
+ @package.description = '*bold*'
186
+
187
+ tag = %{<r:shop:package:description />}
188
+ exp = %{<p><strong>bold</strong></p>}
189
+
190
+ @page.should render(tag).as(exp)
191
+ end
192
+ end
193
+
194
+ context 'currency attributes' do
195
+ before :each do
196
+ Radiant::Config['shop.price_unit'] = '$'
197
+ Radiant::Config['shop.price_precision'] = 2
198
+ Radiant::Config['shop.price_separator'] = '.'
199
+ Radiant::Config['shop.price_delimiter'] = ','
200
+ end
201
+ describe '<r:shop:package:price />' do
202
+ before :each do
203
+ @package.price = 1234.34567890
204
+ end
205
+
206
+ it 'should render a standard price' do
207
+ tag = %{<r:shop:package:price />}
208
+ exp = %{$1,234.35}
209
+ @page.should render(tag).as(exp)
210
+ end
211
+
212
+ it 'should render a high precision price' do
213
+ tag = %{<r:shop:package:price precision="8"/>}
214
+ exp = %{$1,234.34567890}
215
+
216
+ @page.should render(tag).as(exp)
217
+ end
218
+
219
+ it 'should render a custom format' do
220
+ tag = %{<r:shop:package:price unit="%" separator="-" delimiter="+" />}
221
+ exp = %{%1+234-35}
222
+
223
+ @page.should render(tag).as(exp)
224
+ end
225
+ end
226
+
227
+ describe '<r:shop:package:value />' do
228
+ before :each do
229
+ stub(@package).value { 1234.34567890 }
230
+ end
231
+
232
+ it 'should render a standard price' do
233
+ tag = %{<r:shop:package:value />}
234
+ exp = %{$1,234.35}
235
+
236
+ @page.should render(tag).as(exp)
237
+ end
238
+
239
+ it 'should render a high precision price' do
240
+ tag = %{<r:shop:package:value precision="8"/>}
241
+ exp = %{$1,234.34567890}
242
+
243
+ @page.should render(tag).as(exp)
244
+ end
245
+
246
+ it 'should render a custom format' do
247
+ tag = %{<r:shop:package:value unit="%" separator="-" delimiter="+" />}
248
+ exp = %{%1+234-35}
249
+
250
+ @page.should render(tag).as(exp)
251
+ end
252
+ end
253
+ end
254
+
255
+ end
256
+
257
+ context 'products in a package' do
258
+
259
+ before :each do
260
+ mock(ShopPackages::Tags::Helpers).current_package(anything) { @package }
261
+ end
262
+
263
+ describe '<r:shop:package:if_products>' do
264
+ context 'success' do
265
+ it 'should render' do
266
+ tag = %{<r:shop:package:if_products>success</r:shop:package:if_products>}
267
+ exp = %{success}
268
+
269
+ @page.should render(tag).as(exp)
270
+ end
271
+ end
272
+
273
+ context 'failure' do
274
+ it 'should not render' do
275
+ stub(@package).products { [] }
276
+
277
+ tag = %{<r:shop:package:if_products>failure</r:shop:package:if_products>}
278
+ exp = %{}
279
+
280
+ @page.should render(tag).as(exp)
281
+ end
282
+ end
283
+ end
284
+
285
+ describe '<r:shop:package:unless_products>' do
286
+ context 'success' do
287
+ it 'should render' do
288
+ stub(@package).products { [] }
289
+ tag = %{<r:shop:package:unless_products>success</r:shop:package:unless_products>}
290
+ exp = %{success}
291
+
292
+ @page.should render(tag).as(exp)
293
+ end
294
+ end
295
+
296
+ context 'failure' do
297
+ it 'should not render' do
298
+ tag = %{<r:shop:package:unless_products>failure</r:shop:package:unless_products>}
299
+ exp = %{}
300
+
301
+ @page.should render(tag).as(exp)
302
+ end
303
+ end
304
+ end
305
+
306
+ describe '<r:shop:package:products>' do
307
+ it 'should render' do
308
+ tag = %{<r:shop:package:products>success</r:shop:package:products>}
309
+ exp = %{success}
310
+
311
+ @page.should render(tag).as(exp)
312
+ end
313
+ end
314
+
315
+ describe '<r:shop:package:products:each>' do
316
+ context 'success' do
317
+ it 'should render' do
318
+ tag = %{<r:shop:package:products:each>.a.</r:shop:package:products:each>}
319
+ exp = @package.products.map{'.a.'}.join('')
320
+
321
+ @page.should render(tag).as(exp)
322
+ end
323
+ end
324
+
325
+ context 'failure' do
326
+ it 'should not render' do
327
+ stub(@package).packings { [] }
328
+
329
+ tag = %{<r:shop:package:products:each>failure</r:shop:package:products:each>}
330
+ exp = %{}
331
+
332
+ @page.should render(tag).as(exp)
333
+ end
334
+ end
335
+ end
336
+
337
+ describe '<r:shop:package:product:quantity>' do
338
+ it 'should render the quantity of the current packing' do
339
+ tag = %{<r:shop:package:products:each:product:quantity />}
340
+ exp = @package.packings.map{|p| p.quantity}.join('')
341
+
342
+ @page.should render(tag).as(exp)
343
+ end
344
+ end
345
+
346
+ end
347
+
348
+ end