radiant-shop-extension 0.11.5 → 0.11.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/Rakefile +2 -1
  2. data/VERSION +1 -1
  3. data/app/controllers/admin/shop/discounts/discountables_controller.rb +44 -0
  4. data/app/controllers/admin/shop/discounts_controller.rb +64 -0
  5. data/app/controllers/admin/shop/orders_controller.rb +19 -3
  6. data/app/controllers/admin/shop/packages_controller.rb +1 -3
  7. data/app/controllers/admin/shop/products_controller.rb +1 -2
  8. data/app/controllers/admin/shop/variants_controller.rb +3 -4
  9. data/app/models/form_address.rb +4 -2
  10. data/app/models/form_discount.rb +39 -0
  11. data/app/models/form_line_item.rb +1 -11
  12. data/app/models/shop_category.rb +3 -0
  13. data/app/models/shop_customer.rb +0 -9
  14. data/app/models/shop_discount.rb +37 -0
  15. data/app/models/shop_discountable.rb +64 -0
  16. data/app/models/shop_line_item.rb +24 -1
  17. data/app/models/shop_order.rb +41 -28
  18. data/app/models/shop_product.rb +11 -0
  19. data/app/models/shop_product_variant.rb +3 -0
  20. data/app/models/shop_variant.rb +1 -3
  21. data/app/views/admin/shop/discounts/edit.html.haml +11 -0
  22. data/app/views/admin/shop/discounts/edit/_foot.html.haml +16 -0
  23. data/app/views/admin/shop/discounts/edit/_form.html.haml +15 -0
  24. data/app/views/admin/shop/discounts/edit/_head.html.haml +4 -0
  25. data/app/views/admin/shop/discounts/edit/_inputs.html.haml +2 -0
  26. data/app/views/admin/shop/discounts/edit/_meta.html.haml +8 -0
  27. data/app/views/admin/shop/discounts/edit/_parts.html.haml +9 -0
  28. data/app/views/admin/shop/discounts/edit/_popups.html.haml +4 -0
  29. data/app/views/admin/shop/discounts/edit/buttons/_browse_categories.html.haml +1 -0
  30. data/app/views/admin/shop/discounts/edit/buttons/_browse_products.html.haml +1 -0
  31. data/app/views/admin/shop/discounts/edit/inputs/_amount.html.haml +3 -0
  32. data/app/views/admin/shop/discounts/edit/inputs/_code.html.haml +3 -0
  33. data/app/views/admin/shop/discounts/edit/inputs/_name.html.haml +3 -0
  34. data/app/views/admin/shop/discounts/edit/meta/_finish.html.haml +5 -0
  35. data/app/views/admin/shop/discounts/edit/meta/_start.html.haml +5 -0
  36. data/app/views/admin/shop/discounts/edit/parts/_categories.html.haml +3 -0
  37. data/app/views/admin/shop/discounts/edit/parts/_products.html.haml +3 -0
  38. data/app/views/admin/shop/discounts/edit/popups/_browse_categories.html.haml +6 -0
  39. data/app/views/admin/shop/discounts/edit/popups/_browse_products.html.haml +6 -0
  40. data/app/views/admin/shop/discounts/edit/shared/_category.html.haml +11 -0
  41. data/app/views/admin/shop/discounts/edit/shared/_product.html.haml +12 -0
  42. data/app/views/admin/shop/discounts/index.html.haml +13 -0
  43. data/app/views/admin/shop/discounts/index/_discount.html.haml +13 -0
  44. data/app/views/admin/shop/discounts/index/_foot.html.haml +5 -0
  45. data/app/views/admin/shop/discounts/index/_head.html.haml +2 -0
  46. data/app/views/admin/shop/discounts/index/buttons/_new_discount.html.haml +1 -0
  47. data/app/views/admin/shop/discounts/new.html.haml +11 -0
  48. data/app/views/admin/shop/discounts/remove.html.haml +12 -0
  49. data/app/views/admin/shop/orders/index.html.haml +1 -1
  50. data/app/views/admin/shop/orders/index/_foot.html.haml +3 -1
  51. data/app/views/admin/shop/orders/index/_head.html.haml +1 -3
  52. data/app/views/admin/shop/packages/index.html.haml +1 -1
  53. data/app/views/admin/shop/packages/index/_foot.html.haml +3 -2
  54. data/app/views/admin/shop/packages/index/_head.html.haml +1 -3
  55. data/app/views/admin/shop/packages/index/buttons/_new_package.html.haml +1 -0
  56. data/app/views/admin/shop/products/index.html.haml +1 -1
  57. data/app/views/admin/shop/products/index/_foot.html.haml +3 -2
  58. data/app/views/admin/shop/products/index/_head.html.haml +1 -3
  59. data/app/views/admin/shop/products/index/buttons/_add_category.html.haml +1 -0
  60. data/app/views/admin/shop/products/index/buttons/_variants.html.haml +1 -1
  61. data/app/views/admin/shop/variants/index.html.haml +1 -1
  62. data/app/views/admin/shop/variants/index/_foot.html.haml +3 -2
  63. data/app/views/admin/shop/variants/index/_head.html.haml +1 -3
  64. data/app/views/admin/shop/variants/index/buttons/_add_variant.html.haml +1 -0
  65. data/app/views/admin/shop/variants/index/buttons/_categories.html.haml +1 -0
  66. data/config/routes.rb +11 -5
  67. data/db/migrate/20101010071143_create_discounts.rb +29 -0
  68. data/db/migrate/20101010072225_modify_categories_remove_variant.rb +9 -0
  69. data/db/migrate/20101010130034_change_discountables_add_observer.rb +15 -0
  70. data/db/migrate/20101011063133_change_orders_set_limits_to_null.rb +11 -0
  71. data/lib/shop/interface/discounts.rb +34 -0
  72. data/lib/shop/interface/orders.rb +2 -2
  73. data/lib/shop/interface/packages.rb +2 -2
  74. data/lib/shop/interface/products.rb +2 -2
  75. data/lib/shop/interface/variants.rb +2 -2
  76. data/lib/shop/models/form_extension.rb +12 -1
  77. data/lib/shop/models/user.rb +18 -0
  78. data/lib/shop/tags/cart.rb +24 -0
  79. data/lib/shop/tags/helpers.rb +1 -1
  80. data/lib/shop/tags/item.rb +26 -11
  81. data/lib/shop/tags/tax.rb +73 -0
  82. data/lib/tasks/shop_extension_tasks.rake +1 -1
  83. data/mockups/discounts/new-edit.bmml +49 -49
  84. data/public/javascripts/admin/extensions/shop/discounts/edit.js +76 -0
  85. data/public/stylesheets/sass/admin/extensions/shop/discounts/edit.sass +125 -0
  86. data/public/stylesheets/sass/admin/extensions/shop/index.sass +14 -40
  87. data/radiant-shop-extension.gemspec +70 -7
  88. data/shop_extension.rb +23 -12
  89. data/spec/controllers/admin/shop/discounts/discountables_controller_spec.rb +73 -0
  90. data/spec/controllers/admin/shop/discounts_controller_spec.rb +81 -0
  91. data/spec/controllers/admin/shop/orders_controller_spec.rb +35 -0
  92. data/spec/datasets/forms.rb +23 -12
  93. data/spec/datasets/shop_discountables.rb +22 -0
  94. data/spec/datasets/shop_discounts.rb +29 -0
  95. data/spec/lib/shop/tags/cart_spec.rb +75 -1
  96. data/spec/lib/shop/tags/item_spec.rb +4 -7
  97. data/spec/lib/shop/tags/tax_spec.rb +201 -0
  98. data/spec/models/form_discount_spec.rb +63 -0
  99. data/spec/models/shop_category_spec.rb +8 -0
  100. data/spec/models/shop_discount_spec.rb +130 -0
  101. data/spec/models/shop_discountable_spec.rb +114 -0
  102. data/spec/models/shop_line_item_spec.rb +9 -1
  103. data/spec/models/shop_order_spec.rb +253 -199
  104. data/spec/models/shop_product_spec.rb +31 -2
  105. data/spec/models/shop_variant_spec.rb +0 -15
  106. metadata +97 -21
  107. data/app/views/admin/shop/products/index/buttons/_discounts.html.haml +0 -1
  108. data/app/views/admin/shop/products/index/buttons/_packages.html.haml +0 -1
@@ -0,0 +1,63 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe FormDiscount do
4
+
5
+ dataset :shop_discounts, :pages, :forms
6
+
7
+ before :each do
8
+ mock_page_with_request_and_data
9
+ end
10
+
11
+ describe '#create' do
12
+ before :each do
13
+ login_as :customer
14
+ @order = shop_orders(:several_items)
15
+ end
16
+ context 'add' do
17
+ before :each do
18
+ mock_valid_form_discount_request
19
+ end
20
+ context 'valid discount' do
21
+ before :each do
22
+ @discount = FormDiscount.new(@form, @page)
23
+ @result = @discount.create
24
+ end
25
+ it 'should add the discount to the order' do
26
+ shop_orders(:several_items).discounts.first(:conditions => { :code => '10pcoff' }).should_not be_nil
27
+ end
28
+ it 'should return true for result[:add]' do
29
+ @result[:add].should be_true
30
+ end
31
+ end
32
+ context 'invalid discount' do
33
+ before :each do
34
+ @data[:discount][:code] = 'invalid'
35
+ end
36
+ it 'should not add the discount to the order' do
37
+ shop_orders(:several_items).discounts.first(:conditions => { :code => 'invalid' }).should be_nil
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'remove' do
43
+ before :each do
44
+ discountable = shop_discounts(:ten_percent).discountables.create(:discounted_id => @order.id, :discounted_type => @order.class.name)
45
+
46
+ mock_valid_form_discount_request
47
+ @form[:extensions][:discount][:process] = 'remove'
48
+ @data[:discountable] = { :id => discountable.id }
49
+
50
+ @discount = FormDiscount.new(@form, @page)
51
+ @result = @discount.create
52
+ end
53
+ it 'should remove the discount from the order' do
54
+ shop_orders(:several_items).discounts.include?(shop_discounts(:ten_percent)).should be_false
55
+ end
56
+ it 'should return true for result[:remove]' do
57
+ @result[:remove].should be_true
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -25,6 +25,14 @@ describe ShopCategory do
25
25
  it 'should have a product_layout Layout' do
26
26
  @category.product_layout.is_a?(Layout).should be_true
27
27
  end
28
+
29
+ it 'should have many discountables' do
30
+ @category.discountables.is_a?(Array).should be_true
31
+ end
32
+
33
+ it 'should have many discounts' do
34
+ @category.discounts.is_a?(Array).should be_true
35
+ end
28
36
  end
29
37
 
30
38
  describe 'validations' do
@@ -0,0 +1,130 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ShopDiscount do
4
+
5
+ dataset :shop_discounts, :shop_products, :shop_orders
6
+
7
+ describe 'scope' do
8
+ before :each do
9
+ @valid = ShopDiscount.all_including_invalid(:conditions => { :code => '10pcoff'}).first
10
+ @invalid = ShopDiscount.all_including_invalid(:conditions => { :code => 'invalid'}).first
11
+ end
12
+ context 'all' do
13
+ it 'should not return invalid by default' do
14
+ ShopDiscount.all.include?(@valid).should be_true
15
+ ShopDiscount.all.include?(@invalid).should be_false
16
+ end
17
+ end
18
+ context 'all_including_invalid' do
19
+ it 'should return all including invalid' do
20
+ ShopDiscount.all_including_invalid.include?(@valid).should be_true
21
+ ShopDiscount.all_including_invalid.include?(@invalid).should be_true
22
+ end
23
+ end
24
+ end
25
+
26
+ describe 'validations' do
27
+ before :each do
28
+ @discount = shop_discounts(:ten_percent)
29
+ end
30
+
31
+ context 'name' do
32
+ it 'should require' do
33
+ @discount.name = nil
34
+ @discount.valid?.should === false
35
+ end
36
+ it 'should be unique' do
37
+ @other = shop_discounts(:five_percent)
38
+ @other.name = @discount.name
39
+ @other.valid?.should === false
40
+ end
41
+ end
42
+
43
+ context 'code' do
44
+ it 'should require' do
45
+ @discount.code = nil
46
+ @discount.valid?.should === false
47
+ end
48
+ it 'should be unique' do
49
+ @other = shop_discounts(:five_percent)
50
+ @other.code = @discount.code
51
+ @other.valid?.should === false
52
+ end
53
+ end
54
+
55
+ context 'amount' do
56
+ it 'should require' do
57
+ @discount.amount = nil
58
+ @discount.valid?.should === false
59
+ end
60
+ it 'should be numerical' do
61
+ @discount.amount = 'failure'
62
+ @discount.valid?.should === false
63
+ end
64
+ end
65
+ end
66
+
67
+ describe 'relationships' do
68
+ before :each do
69
+ @discount = shop_discounts(:five_percent)
70
+ end
71
+ context 'categories' do
72
+ before :each do
73
+ @bread = shop_categories(:bread)
74
+ end
75
+ it 'should have many' do
76
+ @discount.discountables.create(:discounted => @bread)
77
+ @discount.categories.include?(@bread).should === true
78
+ end
79
+ context '#for' do
80
+ before :each do
81
+ @discount.discountables.create(:discounted => shop_categories(:bread))
82
+ @discount.discountables.create(:discounted => shop_categories(:milk))
83
+ @discount.discountables.create(:discounted => shop_products(:crusty_bread))
84
+ @discount.discountables.create(:discounted => shop_products(:full_milk))
85
+ end
86
+ it 'should return result of only that type' do
87
+ discountables = @discount.discountables.for('ShopCategory')
88
+ discountables.each do |d|
89
+ d.discounted.is_a?(ShopCategory).should === true
90
+ end
91
+ end
92
+ it 'should return result of only that type regardless of string format' do
93
+ discountables = @discount.discountables.for('Shop_category')
94
+ discountables.each do |d|
95
+ d.discounted.is_a?(ShopCategory).should === true
96
+ end
97
+
98
+ discountables = @discount.discountables.for('shop_category')
99
+ discountables.each do |d|
100
+ d.discounted.is_a?(ShopCategory).should === true
101
+ end
102
+
103
+ discountables = @discount.discountables.for('ShopProduct')
104
+ discountables.each do |d|
105
+ d.discounted.is_a?(ShopProduct).should === true
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe '#available_categories' do
113
+ before :each do
114
+ @discount = shop_discounts(:ten_percent)
115
+ end
116
+ it 'should return all categories minus its own' do
117
+ @discount.available_categories.should === ShopCategory.all - @discount.categories
118
+ end
119
+ end
120
+
121
+ describe '#available_products' do
122
+ before :each do
123
+ @discount = shop_discounts(:ten_percent)
124
+ end
125
+ it 'should return all products minus its own' do
126
+ @discount.available_products.should === ShopProduct.all - @discount.products
127
+ end
128
+ end
129
+
130
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ShopDiscountable do
4
+
5
+ dataset :shop_discountables, :shop_line_items
6
+
7
+ before(:each) do
8
+ @discount = shop_discounts(:ten_percent)
9
+ end
10
+
11
+ describe 'validations' do
12
+ before :each do
13
+ @discountable = shop_discountables(:ten_percent_bread)
14
+ end
15
+
16
+ context 'discount' do
17
+ it 'should require' do
18
+ @discountable.discount = nil
19
+ @discountable.valid?.should === false
20
+ end
21
+ end
22
+
23
+ context 'discounted' do
24
+ it 'should require' do
25
+ @discountable.discounted = nil
26
+ @discountable.valid?.should === false
27
+ end
28
+ it 'should be unique to the class' do
29
+ @other = ShopDiscountable.new(:discount => @discount, :discounted => @discountable.discounted)
30
+ @other.valid?.should === false
31
+
32
+ @other.discounted = shop_categories(:milk)
33
+ @other.valid?.should === true
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'category and product hooks' do
39
+ describe '#create' do
40
+ before :each do
41
+ @discount = shop_discounts(:one_percent)
42
+ @category = shop_categories(:milk)
43
+
44
+ discountable = @discount.discountables.create(:discounted => @category)
45
+ end
46
+ it 'should assign the category to the discount' do
47
+ @discount.categories.include?(@category).should be_true
48
+ end
49
+ it 'should assign the products to that category' do
50
+ @discount.products.should_not be_empty
51
+ @discount.products.should === @category.products
52
+ end
53
+ end
54
+
55
+ describe '#destroy' do
56
+ before :each do
57
+ @discount = shop_discounts(:one_percent)
58
+ @category = shop_categories(:milk)
59
+
60
+ discountable = @discount.discountables.create(:discounted => @category)
61
+ discountable.destroy
62
+ end
63
+ it 'should remove the category to the discount' do
64
+ @discount.categories.include?(@category).should be_false
65
+ end
66
+ it 'should remove the products of that category' do
67
+ @category.products.each do |p|
68
+ @discount.products.include?(p).should be_false
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ describe 'order and line_item hooks' do
75
+ before :each do
76
+ @discount = shop_discounts(:one_percent)
77
+ @order = shop_orders(:several_items)
78
+ @line_item_one = shop_orders(:several_items).line_items.first
79
+ @line_item_two = shop_orders(:several_items).line_items.last
80
+
81
+ # Creates a discount for the items product
82
+ @discount.discountables.create(:discounted_id => @line_item_one.item.id, :discounted_type => @line_item_one.item.class.name)
83
+ end
84
+ describe '#create' do
85
+ before :each do
86
+ discountable = @discount.discountables.create(:discounted => @order)
87
+ end
88
+ it 'should assign the category to the discount' do
89
+ @discount.orders.include?(@order).should be_true
90
+ end
91
+ it 'should assign only the items with discounted products to that category' do
92
+ @discount.line_items.should_not be_empty
93
+ @discount.line_items.include?(@line_item_one).should be_true
94
+ @discount.line_items.include?(@line_item_two).should be_false
95
+ end
96
+ end
97
+
98
+ describe '#destroy' do
99
+ before :each do
100
+ discountable = @discount.discountables.create(:discounted => @order)
101
+ discountable.destroy
102
+ end
103
+ it 'should remove the category to the discount' do
104
+ @discount.orders.include?(@order).should be_false
105
+ end
106
+ it 'should remove the products of that category' do
107
+ @order.line_items.each do |p|
108
+ @discount.line_items.include?(p).should be_false
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ end
@@ -2,7 +2,7 @@ require 'spec/spec_helper'
2
2
 
3
3
  describe ShopLineItem do
4
4
 
5
- dataset :shop_line_items, :shop_products
5
+ dataset :shop_line_items, :shop_products, :shop_discountables
6
6
 
7
7
  it 'should calculate a weight' do
8
8
  shop_line_items(:one).weight.should === (shop_line_items(:one).item.weight * shop_line_items(:one).quantity).to_f
@@ -14,6 +14,14 @@ describe ShopLineItem do
14
14
  shop_line_items(:two).price.should === (shop_line_items(:two).item.price * shop_line_items(:two).quantity).to_f
15
15
  end
16
16
 
17
+ context 'with discount' do
18
+ it 'should calculate a reduced price' do
19
+ price = shop_line_items(:one).price
20
+ ShopDiscountable.create(:discount => shop_discounts(:ten_percent), :discounted => shop_line_items(:one))
21
+ shop_line_items(:one).price.should === (price-price*0.1)
22
+ end
23
+ end
24
+
17
25
  it 'should have a set of standard parameters' do
18
26
  ShopLineItem.params.should === [
19
27
  :id,
@@ -3,239 +3,293 @@ require 'spec/spec_helper'
3
3
  describe ShopOrder do
4
4
 
5
5
  dataset :shop_orders, :shop_line_items, :shop_products, :shop_packages, :shop_payments
6
+
7
+ describe '#quantity' do
8
+ it 'should return the total items' do
9
+ shop_orders(:empty).quantity.should === shop_orders(:empty).line_items.sum(:quantity)
10
+ shop_orders(:several_items).quantity.should === shop_orders(:several_items).line_items.sum(:quantity)
11
+ end
12
+ end
13
+
14
+ describe '#weight' do
15
+ it 'should calculate a total weight' do
16
+ shop_orders(:empty).weight.should === lambda{ weight = 0; shop_orders(:empty).line_items.map { |l| weight += l.weight }; weight }.call
17
+ shop_orders(:several_items).weight.should === lambda{ weight = 0; shop_orders(:several_items).line_items.map { |l| weight += l.weight }; weight }.call
18
+ end
19
+ end
6
20
 
7
- context 'instance' do
8
- describe 'accessors' do
9
- it 'should return the total items' do
10
- shop_orders(:empty).quantity.should === shop_orders(:empty).line_items.sum(:quantity)
11
- shop_orders(:one_item).quantity.should === shop_orders(:one_item).line_items.sum(:quantity)
12
- shop_orders(:several_items).quantity.should === shop_orders(:several_items).line_items.sum(:quantity)
21
+ describe '#price' do
22
+ context 'inclusive tax' do
23
+ it 'should calculate from the line items alone' do
24
+ Radiant::Config['shop.tax_strategy'] = 'inclusive'
25
+
26
+ shop_orders(:empty).price.should === lambda{ price = 0; shop_orders(:empty).line_items.map { |l| price += l.price }; price }.call
27
+ shop_orders(:several_items).price.should === lambda{ price = 0; shop_orders(:several_items).line_items.map { |l| price += l.price }; price }.call
28
+ end
29
+ end
30
+ context 'exclusive tax' do
31
+ it 'should calculate from the line items and tax' do
32
+ Radiant::Config['shop.tax_strategy'] = 'exclusive'
33
+ Radiant::Config['shop.tax_percentage'] = 10
34
+
35
+ shop_orders(:empty).price.should === lambda{ price = 0; shop_orders(:empty).line_items.map { |l| price += l.price }; price += shop_orders(:empty).tax }.call
36
+ shop_orders(:several_items).price.should === lambda{ price = 0; shop_orders(:several_items).line_items.map { |l| price += l.price }; price += shop_orders(:several_items).tax }.call
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#new?' do
42
+ context 'success' do
43
+ it 'should return true' do
44
+ shop_orders(:one_item).update_attribute(:status, 'new')
45
+ shop_orders(:one_item).new?.should === true
13
46
  end
47
+ end
48
+ context 'failure' do
49
+ it 'should return false' do
50
+ shop_orders(:one_item).update_attribute(:status, 'paid')
51
+ shop_orders(:one_item).new?.should === false
14
52
 
15
- it 'should calculate a total weight' do
16
- shop_orders(:empty).weight.should === lambda{ weight = 0; shop_orders(:empty).line_items.map { |l| weight += l.weight }; weight }.call
17
- shop_orders(:one_item).weight.should === lambda{ weight = 0; shop_orders(:one_item).line_items.map { |l| weight += l.weight }; weight }.call
18
- shop_orders(:several_items).weight.should === lambda{ weight = 0; shop_orders(:several_items).line_items.map { |l| weight += l.weight }; weight }.call
53
+ shop_orders(:one_item).update_attribute(:status, 'shipped')
54
+ shop_orders(:one_item).new?.should === false
19
55
  end
56
+ end
57
+ end
58
+ describe '#shipped?' do
59
+ context 'success' do
60
+ it 'should return true' do
61
+ shop_orders(:one_item).update_attribute(:status, 'shipped')
62
+ shop_orders(:one_item).shipped?.should === true
63
+ end
64
+ end
65
+ context 'failure' do
66
+ it 'should return false' do
67
+ shop_orders(:one_item).update_attribute(:status, 'new')
68
+ shop_orders(:one_item).shipped?.should === false
20
69
 
21
- it 'should calculate the total price' do
22
- shop_orders(:empty).price.should === lambda{ price = 0; shop_orders(:empty).line_items.map { |l| price += l.price }; price }.call
23
- shop_orders(:one_item).price.should === lambda{ price = 0; shop_orders(:one_item).line_items.map { |l| price += l.price }; price }.call
24
- shop_orders(:several_items).price.should === lambda{ price = 0; shop_orders(:several_items).line_items.map { |l| price += l.price }; price }.call
70
+ shop_orders(:one_item).update_attribute(:status, 'paid')
71
+ shop_orders(:one_item).shipped?.should === false
25
72
  end
26
-
27
- describe '#new?' do
28
- context 'success' do
29
- it 'should return true' do
30
- shop_orders(:one_item).update_attribute(:status, 'new')
31
- shop_orders(:one_item).new?.should === true
32
- end
73
+ end
74
+ end
75
+ describe '#paid?' do
76
+ context 'success' do
77
+ it 'should return true' do
78
+ shop_orders(:several_items).update_attribute(:status, 'paid')
79
+
80
+ shop_orders(:several_items).payment.should === shop_payments(:visa)
81
+ shop_orders(:several_items).paid?.should === true
82
+ end
83
+ end
84
+ context 'failure' do
85
+ describe 'status is not paid' do
86
+ it 'should return false' do
87
+ shop_orders(:several_items).update_attribute(:status, 'new')
88
+ shop_orders(:several_items).paid?.should === false
33
89
  end
34
- context 'failure' do
35
- it 'should return false' do
36
- shop_orders(:one_item).update_attribute(:status, 'paid')
37
- shop_orders(:one_item).new?.should === false
38
-
39
- shop_orders(:one_item).update_attribute(:status, 'shipped')
40
- shop_orders(:one_item).new?.should === false
41
- end
90
+ end
91
+ describe 'payment is nil' do
92
+ it 'should return false' do
93
+ shop_orders(:several_items).update_attribute(:status, 'paid')
94
+ shop_orders(:several_items).payment = nil
95
+ shop_orders(:several_items).paid?.should === false
42
96
  end
43
97
  end
44
- describe '#shipped?' do
45
- context 'success' do
46
- it 'should return true' do
47
- shop_orders(:one_item).update_attribute(:status, 'shipped')
48
- shop_orders(:one_item).shipped?.should === true
49
- end
98
+ describe 'payment amount doesnt match' do
99
+ it 'should return false' do
100
+ shop_orders(:several_items).update_attribute(:status, 'paid')
101
+ shop_orders(:several_items).payment.update_attribute(:amount, 11.00)
102
+ shop_orders(:several_items).paid?.should === false
50
103
  end
51
- context 'failure' do
52
- it 'should return false' do
53
- shop_orders(:one_item).update_attribute(:status, 'new')
54
- shop_orders(:one_item).shipped?.should === false
55
-
56
- shop_orders(:one_item).update_attribute(:status, 'paid')
57
- shop_orders(:one_item).shipped?.should === false
58
- end
104
+ end
105
+ end
106
+ end
107
+
108
+ describe '#add!' do
109
+ context 'item not in cart' do
110
+ before :each do
111
+ @order = shop_orders(:empty)
112
+ @product = shop_products(:crusty_bread)
113
+ end
114
+ context 'no quantity or type passed' do
115
+ it 'should assign a default type and default quantity' do
116
+ @order.add!(@product.id)
117
+
118
+ @order.line_items.count.should === 1
119
+ @order.line_items.first.item_type.should === 'ShopProduct'
120
+ @order.line_items.first.quantity.should === 1
121
+ @order.line_items.first.item.should === @product
59
122
  end
60
123
  end
61
- describe '#paid?' do
62
- context 'success' do
63
- it 'should return true' do
64
- shop_orders(:several_items).update_attribute(:status, 'paid')
65
-
66
- shop_orders(:several_items).payment.should === shop_payments(:visa)
67
- shop_orders(:several_items).paid?.should === true
68
- end
124
+ context 'quantity passed' do
125
+ it 'should assign the default type and new quantity' do
126
+ @order.add!(@product.id, 2)
127
+
128
+ @order.line_items.count.should === 1
129
+ @order.line_items.first.item_type.should === 'ShopProduct'
130
+ @order.line_items.first.quantity.should === 2
131
+ @order.line_items.first.item.should === @product
69
132
  end
70
- context 'failure' do
71
- describe 'status is not paid' do
72
- it 'should return false' do
73
- shop_orders(:several_items).update_attribute(:status, 'new')
74
- shop_orders(:several_items).paid?.should === false
75
- end
76
- end
77
- describe 'payment is nil' do
78
- it 'should return false' do
79
- shop_orders(:several_items).update_attribute(:status, 'paid')
80
- shop_orders(:several_items).payment = nil
81
- shop_orders(:several_items).paid?.should === false
82
- end
83
- end
84
- describe 'payment amount doesnt match' do
85
- it 'should return false' do
86
- shop_orders(:several_items).update_attribute(:status, 'paid')
87
- shop_orders(:several_items).payment.update_attribute(:amount, 11.00)
88
- shop_orders(:several_items).paid?.should === false
89
- end
90
- end
133
+ end
134
+ context 'type and quantity passed' do
135
+ it 'should assign the new type and new quantity' do
136
+ @order.add!(shop_packages(:all_bread).id, 2, 'ShopPackage')
137
+
138
+ @order.line_items.count.should === 1
139
+ @order.quantity.should === 2
140
+ @order.line_items.first.item_type.should === 'ShopPackage'
141
+ end
142
+ end
143
+ end
144
+ context 'item in cart' do
145
+ before :each do
146
+ @order = shop_orders(:one_item)
147
+ @line_item = @order.line_items.first
148
+ end
149
+ context 'no quantity or type passed' do
150
+ it 'should assign a default type and default quantity' do
151
+ @order.add!(@line_item.id)
152
+
153
+ @order.line_items.count.should === 1
154
+ @order.quantity.should === 1
155
+ end
156
+ end
157
+ context 'quantity passed' do
158
+ it 'should assign the default type and new quantity' do
159
+ @order.add!(@line_item.id, 2)
160
+
161
+ @order.line_items.count.should === 1
162
+ @order.quantity.should === 3
163
+ end
164
+ end
165
+ end
166
+ end
167
+ describe '#modify!' do
168
+ context 'quantity not set' do
169
+ before :each do
170
+ @order = shop_orders(:one_item)
171
+ @line_item = @order.line_items.first
172
+ end
173
+ it 'should not update the item' do
174
+ @order.modify!(@line_item.id)
175
+
176
+ @order.quantity.should === 1
177
+ end
178
+ end
179
+ context 'quantity set' do
180
+ before :each do
181
+ @order = shop_orders(:one_item)
182
+ @line_item = @order.line_items.first
183
+ end
184
+ context 'quantity > 0' do
185
+ it 'should assign that quantity' do
186
+ @order.modify!(@line_item.id, 1)
187
+ @order.quantity.should === 1
188
+
189
+ @order.modify!(@line_item.id, 2)
190
+ @order.quantity.should === 2
191
+
192
+ @order.modify!(@line_item.id, 100)
193
+ @order.quantity.should === 100
194
+ end
195
+ end
196
+ context 'quantity <= 0' do
197
+ it 'should remove that item for 0' do
198
+ @order.modify!(@line_item.id, 0)
199
+ @order.quantity.should === 0
200
+ end
201
+ it 'should remove that item for -1' do
202
+ @order.modify!(@line_item.id, -1)
203
+ @order.quantity.should === 0
204
+ end
205
+ it 'should remove that item for -100' do
206
+ @order.modify!(@line_item.id, -100)
207
+ @order.quantity.should === 0
91
208
  end
92
209
  end
93
210
  end
211
+ end
212
+ describe '#remove!' do
213
+ it 'should remove the item' do
214
+ @order = shop_orders(:several_items)
215
+ items = @order.line_items.count
216
+
217
+ @order.remove!(@order.line_items.first.id)
218
+ @order.line_items.count.should === items - 1
219
+ end
220
+ end
221
+ describe '#clear!' do
222
+ it 'should remove all items' do
223
+ @order = shop_orders(:several_items)
224
+ @order.clear!
225
+ @order.quantity.should === 0
226
+ end
227
+ end
94
228
 
95
- describe 'mutators' do
96
- describe '#add!' do
97
- context 'item not in cart' do
98
- before :each do
99
- @order = shop_orders(:empty)
100
- @product = shop_products(:crusty_bread)
101
- end
102
- context 'no quantity or type passed' do
103
- it 'should assign a default type and default quantity' do
104
- @order.add!(@product.id)
105
-
106
- @order.line_items.count.should === 1
107
- @order.line_items.first.item_type.should === 'ShopProduct'
108
- @order.line_items.first.quantity.should === 1
109
- @order.line_items.first.item.should === @product
110
- end
111
- end
112
- context 'quantity passed' do
113
- it 'should assign the default type and new quantity' do
114
- @order.add!(@product.id, 2)
115
-
116
- @order.line_items.count.should === 1
117
- @order.line_items.first.item_type.should === 'ShopProduct'
118
- @order.line_items.first.quantity.should === 2
119
- @order.line_items.first.item.should === @product
120
- end
121
- end
122
- context 'type and quantity passed' do
123
- it 'should assign the new type and new quantity' do
124
- @order.add!(shop_packages(:all_bread).id, 2, 'ShopPackage')
125
-
126
- @order.line_items.count.should === 1
127
- @order.quantity.should === 2
128
- @order.line_items.first.item_type.should === 'ShopPackage'
129
- end
229
+ describe '.scope_by_status' do
230
+ context 'no scoping' do
231
+ before :each do
232
+ @orders = ShopOrder.count
233
+ end
234
+ context 'nil' do
235
+ it 'should return all' do
236
+ ShopOrder.scope_by_status(nil) do
237
+ ShopOrder.count.should === @orders
130
238
  end
131
239
  end
132
- context 'item in cart' do
133
- before :each do
134
- @order = shop_orders(:one_item)
135
- @line_item = @order.line_items.first
136
- end
137
- context 'no quantity or type passed' do
138
- it 'should assign a default type and default quantity' do
139
- @order.add!(@line_item.id)
140
-
141
- @order.line_items.count.should === 1
142
- @order.quantity.should === 1
143
- end
144
- end
145
- context 'quantity passed' do
146
- it 'should assign the default type and new quantity' do
147
- @order.add!(@line_item.id, 2)
148
-
149
- @order.line_items.count.should === 1
150
- @order.quantity.should === 3
151
- end
240
+ end
241
+ context 'blank' do
242
+ it 'should return all' do
243
+ ShopOrder.scope_by_status('') do
244
+ ShopOrder.count.should === @orders
152
245
  end
153
246
  end
154
247
  end
155
- describe '#modify!' do
156
- context 'quantity not set' do
157
- before :each do
158
- @order = shop_orders(:one_item)
159
- @line_item = @order.line_items.first
160
- end
161
- it 'should not update the item' do
162
- @order.modify!(@line_item.id)
163
-
164
- @order.quantity.should === 1
248
+ context 'missing' do
249
+ it 'should return all' do
250
+ ShopOrder.scope_by_status('this_status_shall_never_be_real') do
251
+ ShopOrder.count.should === @orders
165
252
  end
166
253
  end
167
- context 'quantity set' do
168
- before :each do
169
- @order = shop_orders(:one_item)
170
- @line_item = @order.line_items.first
171
- end
172
- context 'quantity > 0' do
173
- it 'should assign that quantity' do
174
- @order.modify!(@line_item.id, 1)
175
- @order.quantity.should === 1
176
-
177
- @order.modify!(@line_item.id, 2)
178
- @order.quantity.should === 2
179
-
180
- @order.modify!(@line_item.id, 100)
181
- @order.quantity.should === 100
182
- end
183
- end
184
- context 'quantity <= 0' do
185
- it 'should remove that item for 0' do
186
- @order.modify!(@line_item.id, 0)
187
- @order.quantity.should === 0
188
- end
189
- it 'should remove that item for -1' do
190
- @order.modify!(@line_item.id, -1)
191
- @order.quantity.should === 0
192
- end
193
- it 'should remove that item for -100' do
194
- @order.modify!(@line_item.id, -100)
195
- @order.quantity.should === 0
196
- end
254
+ end
255
+ end
256
+ context 'scoping' do
257
+ before :each do
258
+ ShopOrder.create(:status => 'new')
259
+ ShopOrder.create(:status => 'shipped')
260
+ ShopOrder.create(:status => 'paid')
261
+ end
262
+ context 'new' do
263
+ it 'should return matching count' do
264
+ @orders = ShopOrder.all(:conditions => { :status => 'new' }).count
265
+ ShopOrder.scope_by_status('new') do
266
+ ShopOrder.count.should === @orders
197
267
  end
198
268
  end
199
269
  end
200
- describe '#remove!' do
201
- it 'should remove the item' do
202
- @order = shop_orders(:several_items)
203
- items = @order.line_items.count
204
-
205
- @order.remove!(@order.line_items.first.id)
206
- @order.line_items.count.should === items - 1
270
+ context 'shipped' do
271
+ it 'should return matching count' do
272
+ @orders = ShopOrder.all(:conditions => { :status => 'shipped' }).count
273
+ ShopOrder.scope_by_status('shipped') do
274
+ ShopOrder.count.should === @orders
275
+ end
207
276
  end
208
277
  end
209
- describe '#clear!' do
210
- it 'should remove all items' do
211
- @order = shop_orders(:several_items)
212
- @order.clear!
213
- @order.quantity.should === 0
278
+ context 'paid' do
279
+ it 'should return matching count' do
280
+ @orders = ShopOrder.all(:conditions => { :status => 'paid' }).count
281
+ ShopOrder.scope_by_status('paid') do
282
+ ShopOrder.count.should === @orders
283
+ end
214
284
  end
215
285
  end
216
286
  end
217
287
  end
218
288
 
219
- context 'class methods' do
220
- describe '#search' do
221
- context 'status' do
222
- it 'should return valid subsets' do
223
- count = ShopOrder.count
224
-
225
- old = ShopOrder.first
226
- old.update_attribute(:status, 'paid')
227
-
228
- results = ShopOrder.search('new')
229
- results.count.should === count - 1
230
- end
231
- end
232
- end
233
-
234
- describe '#params' do
235
- it 'should have a set of standard parameters' do
236
- ShopOrder.params.should === [ :id, :notes, :status ]
237
- end
289
+ describe '.params' do
290
+ it 'should have a set of standard parameters' do
291
+ ShopOrder.params.should === [ :id, :notes, :status ]
238
292
  end
239
293
  end
240
-
294
+
241
295
  end