carter 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+
4
+
5
+
6
+ describe Carter::ActiveRecord::Cartable do
7
+
8
+ describe "configuration" do
9
+ it "should add the thing class to the Carter config" do
10
+ Thing.acts_as_cartable
11
+ Carter.settings.cartables.should include(Thing.name)
12
+ end
13
+ end
14
+
15
+ let(:cartable){Factory(:product)}
16
+ it "should load the schema for testing" do
17
+ Product.all.should be_a Array
18
+ end
19
+
20
+ it "should add acts_as_cartable method to product" do
21
+ Product.should respond_to(:acts_as_cartable)
22
+ end
23
+
24
+ describe "Product.acts_as_cartable" do
25
+ context "default settings" do
26
+ before(){ Product.acts_as_cartable }
27
+
28
+ it "should add the product class to the Carter config" do
29
+ Carter.settings.cartables.should include(Product.name)
30
+ end
31
+
32
+ it {cartable.should have_many(:cart_items)}
33
+ it {cartable.should have_many(:carts) }
34
+ it "should set the default name column" do
35
+ Product.cartable_configuration[:name].should == "name"
36
+ end
37
+
38
+ it "should set the default price column" do
39
+ Product.cartable_configuration[:price].should == "price"
40
+ end
41
+
42
+ it "should return the price" do
43
+ cartable.price.should == cartable.cartable_price
44
+ end
45
+ it "should return the name" do
46
+ cartable.name.should == cartable.cartable_name
47
+ end
48
+ end
49
+
50
+ context "finding carts on a cartable" do
51
+ let(:cart){ Factory(:cart) }
52
+ let(:thing){ Factory(:thing) }
53
+ before do
54
+ cart.add_item(cartable, 2)
55
+ cart.add_item(thing)
56
+ end
57
+
58
+ it 'should find the cart from the cartable' do
59
+ cartable.carts.should be_include(cart)
60
+ thing.carts.should be_include(cart)
61
+ end
62
+
63
+ it "a cartable should be in cart" do
64
+ cartable.in_cart?(cart).should be_true
65
+ end
66
+ end
67
+
68
+ context "custom settings" do
69
+ before(){ Product.acts_as_cartable(:name => "ping", :price => "pong") }
70
+
71
+ it "should set the name column" do
72
+ Product.cartable_configuration[:name].should == "ping"
73
+ end
74
+
75
+ it "should set the price column" do
76
+ Product.cartable_configuration[:price].should == "pong"
77
+ end
78
+ end
79
+
80
+ describe "unique cart_items" do
81
+ let(:cart){ Factory(:cart) }
82
+ let(:product){ Factory(:product) }
83
+ let(:thing){ Factory(:thing) }
84
+ let(:owner) { Factory(:user) }
85
+
86
+ before() do
87
+ Product.acts_as_cartable(:unique => true)
88
+ Thing.acts_as_cartable(:unique => true)
89
+ end
90
+
91
+ it "should not allow multiple cart_items in the cart of this cartable" do
92
+ cartable.allow_multiples?.should be_false
93
+ end
94
+
95
+ it "should raise an error if an item of the same type is added to the cart" do
96
+ cart.add_item(product)
97
+ cart.cart_items.size.should == 1
98
+ lambda{ cart.add_item(product) }.should raise_error(Carter::MultipleCartItemsNotAllowed, /is already in your basket/)
99
+ end
100
+
101
+ it "should not raise an error if an item of same type is added to the cart but with a different owner" do
102
+ cart.add_item(product)
103
+ cart.cart_items.size.should == 1
104
+ lambda{ cart.add_item(product, 1, owner) }.should_not raise_error(Carter::MultipleCartItemsNotAllowed, /is already in your basket/)
105
+ cart.cart_items.size.should == 2
106
+ end
107
+
108
+ it "should not raise an error if an item of different type is added to the cart" do
109
+ cart.add_item(product)
110
+ cart.cart_items.size.should == 1
111
+ lambda{ cart.add_item(thing) }.should_not raise_error(Carter::MultipleCartItemsNotAllowed, /is already in your basket/)
112
+ cart.cart_items.size.should == 2
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ #
3
+ # describe CartItemsController do
4
+ #
5
+ # describe "adding to the cart" do
6
+ #
7
+ # before do
8
+ #
9
+ # end
10
+ #
11
+ # it "should be successful" do
12
+ # Product.should_receive(:find_by_id).with("1").and_return(mock_model(Product))
13
+ # post :create, :cartable_type => "product", :cartable_id => "1"
14
+ # response.should be_success
15
+ # end
16
+ #
17
+ #
18
+ # end
19
+ # end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Carter" do
4
+
5
+ end
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app'))
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ require 'rubygems'
5
+ require 'rspec'
6
+ require 'shoulda'
7
+ require 'carter'
8
+ require 'factory_girl'
9
+ require 'action_pack'
10
+ require 'state_machine'
11
+ require 'money'
12
+
13
+ Carter::Initializer.setup
14
+ # Requires supporting files with custom matchers and macros, etc,
15
+ # in ./support/ and its subdirectories.
16
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
17
+
18
+
19
+ RSpec.configure do |config|
20
+
21
+ end
22
+
23
+
24
+ load_schema
@@ -0,0 +1,100 @@
1
+ describe Carter::StateMachine::Cart do
2
+
3
+ let(:cart){Factory(:cart) }
4
+ let(:product){ Factory(:product) }
5
+
6
+ describe "the states" do
7
+ [:active, :processing, :failure, :success, :expired].each do |state|
8
+ it "should have the state #{state}" do
9
+ cart.should respond_to("#{state}?")
10
+ end
11
+ end
12
+ end
13
+
14
+ describe "the transitions" do
15
+ [:checkout, :succeeded, :failed, :expire].each do |transition|
16
+ it "should have the transition event #{transition}" do
17
+ cart.should respond_to("#{transition}")
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "the lifecycle" do
23
+ it "should have an initial state of active" do
24
+ cart.active?.should be_true
25
+ end
26
+
27
+ describe "without a on_checkout proc defined" do
28
+ it "should transition to processing on checkout" do
29
+ expect { cart.checkout }.to change(cart, :state).from("active").to("processing")
30
+ end
31
+ end
32
+
33
+ describe "with a on_checkout proc defined" do
34
+ before(:each) do
35
+ @gateway = mock()
36
+ Carter.settings.on_checkout = Proc.new() do |record|
37
+ if @gateway.status == :success
38
+ record.succeeded
39
+ else
40
+ record.failed
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "a successful payment" do
46
+ before(:each) do
47
+ Product.acts_as_cartable :after_purchase_method => :yippee_shiny_product_is_mine
48
+ @gateway.should_receive(:status).and_return(:success)
49
+ end
50
+
51
+ it "should transition to paid on success " do
52
+ expect { cart.checkout}.to change(cart, :state).from("active").to("success")
53
+ end
54
+
55
+ it "should trigger the on success method" do
56
+ cart.should_receive(:on_success)
57
+ cart.checkout
58
+ end
59
+
60
+ context "with cart_items" do
61
+ before(:each) do
62
+ product.stub!(:yippee_shiny_product_is_mine)
63
+ end
64
+
65
+ it "should trigger the add_to_owner method for each cart_item" do
66
+ cart.add_item(product)
67
+ cart.cart_items.each{|cart_item|
68
+ cart_item.should_receive(:add_to_owner)
69
+ }
70
+ cart.checkout
71
+ end
72
+
73
+ it "should call the on purchase method for the cartable product" do
74
+ cart.add_item(product)
75
+ cart.cart_items.each{|cart_item|
76
+ cart_item.stub!(:cartable).and_return(product)
77
+ }
78
+ product.should_receive(:yippee_shiny_product_is_mine)
79
+ cart.checkout
80
+ end
81
+ end
82
+ end
83
+ describe "a failed payment" do
84
+ before(:each) do
85
+ Product.acts_as_cartable :after_purchase_method => :yippee_shiny_product_is_mine
86
+ @gateway.should_receive(:status).and_return(:failed)
87
+ end
88
+
89
+ it "should transition to failure on success " do
90
+ expect { cart.checkout}.to change(cart, :state).from("active").to("failure")
91
+ end
92
+
93
+ it "should trigger the on_failure method" do
94
+ cart.should_receive(:on_failed)
95
+ cart.checkout
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,79 @@
1
+
2
+ require 'active_record'
3
+ ActiveRecord::Base.extend Carter::ActiveRecord::Cartable if defined?(ActiveRecord)
4
+
5
+ Dir["app/models/*.rb"].each {|f| require f}
6
+
7
+ class User < ActiveRecord::Base
8
+ end
9
+
10
+ class Product < ActiveRecord::Base
11
+
12
+ end
13
+ class Thing < ActiveRecord::Base
14
+
15
+ end
16
+ def load_schema
17
+
18
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
19
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
20
+
21
+ db_adapter = ENV['DB']
22
+
23
+ # no db passed, try one of these fine config-free DBs before bombing.
24
+ db_adapter ||=
25
+ begin
26
+ require 'sqlite'
27
+ 'sqlite'
28
+ rescue MissingSourceFile
29
+ begin
30
+ require 'sqlite3'
31
+ 'sqlite3'
32
+ rescue MissingSourceFile
33
+ end
34
+ end
35
+
36
+ if db_adapter.nil?
37
+ raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
38
+ end
39
+
40
+
41
+ ActiveRecord::Base.establish_connection(config[db_adapter])
42
+ ActiveRecord::Schema.define(:version => 0) do
43
+ create_table "users", :force => true do |t|
44
+ t.string :name
45
+ t.timestamps
46
+ end
47
+ create_table "things", :force => true do |t|
48
+ t.string :name
49
+ t.float :price
50
+ t.timestamps
51
+ end
52
+ create_table "products", :force => true do |t|
53
+ t.string :name
54
+ t.float :price
55
+ t.timestamps
56
+ end
57
+
58
+ create_table "cart_items", :force => true do |t|
59
+ t.string :name
60
+ t.string :state
61
+ t.belongs_to :owner, :polymorphic => true
62
+ t.belongs_to :cartable, :polymorphic => true
63
+ t.belongs_to :cart
64
+ t.column :price, :float
65
+ t.column :quantity, :integer
66
+ t.timestamps
67
+ end
68
+
69
+ create_table "carts", :force => true do |t|
70
+ t.string :session_id
71
+ t.string :state
72
+ t.belongs_to :shopper, :polymorphic => true
73
+ t.timestamps
74
+ end
75
+ end
76
+ require 'rails/init'
77
+
78
+ end
79
+
@@ -0,0 +1,25 @@
1
+ Factory.sequence :name do |n|
2
+ "name_#{n}"
3
+ end
4
+
5
+ Factory.define :product do |f|
6
+ f.sequence(:name) {|n| "name#{n}" }
7
+ f.price 2.00
8
+ end
9
+
10
+ Factory.define :thing do |f|
11
+ f.sequence(:name) {|n| "name#{n}" }
12
+ f.price 4.00
13
+ end
14
+
15
+ Factory.define :user do |f|
16
+ f.sequence(:name) {|n| "name#{n}" }
17
+ end
18
+
19
+ Factory.define :cart do |f|
20
+ f.shopper {|a| a.association(:user) }
21
+ end
22
+
23
+ Factory.define :cart_item do |f|
24
+ f.cart {|a| a.association(:cart) }
25
+ end
metadata ADDED
@@ -0,0 +1,265 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 1
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 5
10
+ version: 0.5.5
11
+ platform: ruby
12
+ authors:
13
+ - Louis Gillies
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-10 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :development
24
+ name: rspec
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 2
33
+ - 3
34
+ - 0
35
+ version: 2.3.0
36
+ requirement: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ type: :development
40
+ name: yard
41
+ version_requirements: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ hash: 7
47
+ segments:
48
+ - 0
49
+ - 6
50
+ - 0
51
+ version: 0.6.0
52
+ requirement: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ type: :development
56
+ name: cucumber
57
+ version_requirements: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirement: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ prerelease: false
69
+ type: :development
70
+ name: bundler
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 23
77
+ segments:
78
+ - 1
79
+ - 0
80
+ - 0
81
+ version: 1.0.0
82
+ requirement: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ prerelease: false
85
+ type: :development
86
+ name: jeweler
87
+ version_requirements: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ~>
91
+ - !ruby/object:Gem::Version
92
+ hash: 7
93
+ segments:
94
+ - 1
95
+ - 5
96
+ - 2
97
+ version: 1.5.2
98
+ requirement: *id005
99
+ - !ruby/object:Gem::Dependency
100
+ prerelease: false
101
+ type: :development
102
+ name: rcov
103
+ version_requirements: &id006 !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ requirement: *id006
113
+ - !ruby/object:Gem::Dependency
114
+ prerelease: false
115
+ type: :development
116
+ name: state_machine
117
+ version_requirements: &id007 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - "="
121
+ - !ruby/object:Gem::Version
122
+ hash: 51
123
+ segments:
124
+ - 0
125
+ - 9
126
+ - 4
127
+ version: 0.9.4
128
+ requirement: *id007
129
+ - !ruby/object:Gem::Dependency
130
+ prerelease: false
131
+ type: :development
132
+ name: money
133
+ version_requirements: &id008 !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - "="
137
+ - !ruby/object:Gem::Version
138
+ hash: 9
139
+ segments:
140
+ - 3
141
+ - 1
142
+ - 5
143
+ version: 3.1.5
144
+ requirement: *id008
145
+ - !ruby/object:Gem::Dependency
146
+ prerelease: false
147
+ type: :runtime
148
+ name: state_machine
149
+ version_requirements: &id009 !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - "="
153
+ - !ruby/object:Gem::Version
154
+ hash: 51
155
+ segments:
156
+ - 0
157
+ - 9
158
+ - 4
159
+ version: 0.9.4
160
+ requirement: *id009
161
+ - !ruby/object:Gem::Dependency
162
+ prerelease: false
163
+ type: :development
164
+ name: money
165
+ version_requirements: &id010 !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ">"
169
+ - !ruby/object:Gem::Version
170
+ hash: 9
171
+ segments:
172
+ - 3
173
+ - 1
174
+ - 5
175
+ version: 3.1.5
176
+ requirement: *id010
177
+ description: A really simple shopping cart implementation for rails.
178
+ email: louisgillies@yahoo.co.uk
179
+ executables: []
180
+
181
+ extensions: []
182
+
183
+ extra_rdoc_files:
184
+ - LICENSE.txt
185
+ - README.md
186
+ files:
187
+ - app/controllers/cart_items_controller.rb
188
+ - app/controllers/carts_controller.rb
189
+ - app/models/cart.rb
190
+ - app/models/cart_item.rb
191
+ - app/views/carts/show.html.erb
192
+ - generators/carter_generator.rb
193
+ - generators/carter_install_generator.rb
194
+ - generators/templates/migration.rb
195
+ - init.rb
196
+ - lib/carter.rb
197
+ - lib/carter/active_record/extensions.rb
198
+ - lib/carter/cart.rb
199
+ - lib/carter/cartable.rb
200
+ - lib/carter/controller_additions.rb
201
+ - lib/carter/controller_resource.rb
202
+ - lib/carter/engine.rb
203
+ - lib/carter/errors.rb
204
+ - lib/carter/errors/multiple_cart_items_not_allowed.rb
205
+ - lib/carter/errors/setup_error.rb
206
+ - lib/carter/initializer.rb
207
+ - lib/carter/routing.rb
208
+ - lib/carter/state_machine.rb
209
+ - lib/tasks/carter.rake
210
+ - rails/init.rb
211
+ - LICENSE.txt
212
+ - README.md
213
+ - spec/active_record/cart_item_spec.rb
214
+ - spec/active_record/cart_spec.rb
215
+ - spec/active_record/cartable_spec.rb
216
+ - spec/app/controllers/cart_items_controller_spec.rb
217
+ - spec/carter_spec.rb
218
+ - spec/spec_helper.rb
219
+ - spec/state_machine_spec.rb
220
+ - spec/support/active_record_helper.rb
221
+ - spec/support/factories.rb
222
+ has_rdoc: true
223
+ homepage: http://github.com/playgood/carter
224
+ licenses:
225
+ - MIT
226
+ post_install_message:
227
+ rdoc_options: []
228
+
229
+ require_paths:
230
+ - lib
231
+ required_ruby_version: !ruby/object:Gem::Requirement
232
+ none: false
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ hash: 3
237
+ segments:
238
+ - 0
239
+ version: "0"
240
+ required_rubygems_version: !ruby/object:Gem::Requirement
241
+ none: false
242
+ requirements:
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ hash: 3
246
+ segments:
247
+ - 0
248
+ version: "0"
249
+ requirements: []
250
+
251
+ rubyforge_project:
252
+ rubygems_version: 1.3.7
253
+ signing_key:
254
+ specification_version: 3
255
+ summary: A really simple shopping cart implementation for rails.
256
+ test_files:
257
+ - spec/active_record/cart_item_spec.rb
258
+ - spec/active_record/cart_spec.rb
259
+ - spec/active_record/cartable_spec.rb
260
+ - spec/app/controllers/cart_items_controller_spec.rb
261
+ - spec/carter_spec.rb
262
+ - spec/spec_helper.rb
263
+ - spec/state_machine_spec.rb
264
+ - spec/support/active_record_helper.rb
265
+ - spec/support/factories.rb