solidus_events_tracker 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +73 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE +26 -0
  5. data/README.md +52 -0
  6. data/Rakefile +21 -0
  7. data/app/assets/javascripts/spree/backend/solidus_events_tracker.js +2 -0
  8. data/app/assets/javascripts/spree/frontend/solidus_events_tracker.js +2 -0
  9. data/app/assets/stylesheets/spree/backend/solidus_events_tracker.css +4 -0
  10. data/app/assets/stylesheets/spree/frontend/solidus_events_tracker.css +4 -0
  11. data/app/controllers/concerns/spree/checkout_event_tracker.rb +28 -0
  12. data/app/controllers/concerns/spree/page_tracker.rb +55 -0
  13. data/app/controllers/spree/checkout_controller_decorator.rb +22 -0
  14. data/app/controllers/spree/home_controller_decorator.rb +4 -0
  15. data/app/controllers/spree/orders_controller_decorator.rb +32 -0
  16. data/app/controllers/spree/products_controller_decorator.rb +4 -0
  17. data/app/controllers/spree/taxons_controller_decorator.rb +4 -0
  18. data/app/models/concerns/spree/order_contents_decorator.rb +38 -0
  19. data/app/models/spree/cart_event.rb +20 -0
  20. data/app/models/spree/checkout_event.rb +11 -0
  21. data/app/models/spree/page_event.rb +14 -0
  22. data/app/trackers/spree/cart/event/tracker.rb +44 -0
  23. data/app/trackers/spree/checkout/event/tracker.rb +18 -0
  24. data/app/trackers/spree/event/tracker.rb +17 -0
  25. data/app/trackers/spree/page/event/tracker.rb +17 -0
  26. data/bin/rails +7 -0
  27. data/config/locales/en.yml +4 -0
  28. data/config/routes.rb +3 -0
  29. data/db/migrate/20160313145434_create_spree_cart_events.rb +15 -0
  30. data/db/migrate/20160314080710_create_spree_page_events.rb +14 -0
  31. data/db/migrate/20160314080822_create_spree_checkout_events.rb +14 -0
  32. data/lib/generators/solidus_events_tracker/install/install_generator.rb +31 -0
  33. data/lib/solidus_events_tracker.rb +2 -0
  34. data/lib/solidus_events_tracker/engine.rb +20 -0
  35. data/lib/solidus_events_tracker/factories.rb +6 -0
  36. data/solidus_events_tracker.gemspec +37 -0
  37. data/spec/controllers/spree/checkout_controller_decorator_spec.rb +132 -0
  38. data/spec/controllers/spree/orders_controller_decorator_spec.rb +136 -0
  39. data/spec/models/spree/cart_event_spec.rb +18 -0
  40. data/spec/models/spree/checkout_event_spec.rb +16 -0
  41. data/spec/models/spree/page_event_spec.rb +15 -0
  42. data/spec/spec_helper.rb +97 -0
  43. data/spec/trackers/spree/cart/event/tracker_spec.rb +67 -0
  44. data/spec/trackers/spree/checkout/event/tracker_spec.rb +33 -0
  45. data/spec/trackers/spree/event/tracker_spec.rb +29 -0
  46. data/spec/trackers/spree/page/event/tracker_spec.rb +32 -0
  47. metadata +47 -2
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ class PageEvent < Spree::Base
3
+ ACTIVITIES = { view: :view, search: :search, filter: :filter, index: :index }
4
+
5
+ belongs_to :actor, polymorphic: true
6
+ belongs_to :target, polymorphic: true
7
+
8
+ validates :activity,
9
+ :session_id, presence: true
10
+
11
+ scope :viewed, -> { where(activity: :view) }
12
+ scope :product, -> { where(target_type: 'Spree::Product') }
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ module Spree
2
+ module Cart
3
+ module Event
4
+ class Tracker < Spree::Event::Tracker
5
+ attr_reader :target
6
+ attr_accessor :activity, :quantity
7
+
8
+ def initialize(arguments = {})
9
+ super(arguments)
10
+ @quantity = arguments[:quantity]
11
+ @total = arguments[:total]
12
+ @variant_id = arguments[:variant_id]
13
+ end
14
+
15
+ def track
16
+ changed_quantity = changed_quantity(target.previous_changes[:quantity].map(&:to_i))
17
+ self.activity = activity(changed_quantity, target)
18
+ self.quantity = changed_quantity
19
+ CartEvent.create(instance_values)
20
+ end
21
+
22
+ private
23
+ # 1. ADD EVENT: When a new product is added to cart
24
+ # so the changed quantity will be equal to line_item.quantity
25
+ # 2. REMOVE EVENT: When a product is removed from cart,
26
+ # change in quantity will be negative and line_items quantity will be zero
27
+ # 3. UPDATE EVENT: When product's quantity is changed from the cart and it shouldn't be removed
28
+ def activity(changed_quantity, line_item)
29
+ if (changed_quantity > 0 && changed_quantity == line_item.quantity)
30
+ :add
31
+ elsif (changed_quantity < 0 && line_item.quantity == 0)
32
+ :remove
33
+ elsif changed_quantity
34
+ :update
35
+ end
36
+ end
37
+
38
+ def changed_quantity(previous_quantity_changes)
39
+ previous_quantity_changes.last - previous_quantity_changes.first
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module Checkout
3
+ module Event
4
+ class Tracker < Spree::Event::Tracker
5
+
6
+ def initialize(arguments = {})
7
+ super(arguments)
8
+ @previous_state = arguments[:previous_state]
9
+ @next_state = arguments[:next_state]
10
+ end
11
+
12
+ def track
13
+ CheckoutEvent.create(instance_values)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Event
3
+ class Tracker
4
+ def initialize(arguments = {})
5
+ @activity = arguments[:activity]
6
+ @actor = arguments[:actor]
7
+ @target = arguments[:target]
8
+ @referrer = arguments[:referrer]
9
+ @session_id = arguments[:session_id]
10
+ end
11
+
12
+ def track
13
+ raise '#track should be implemented in a sub-class of Event::Tracker'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Page::Event
3
+ class Tracker < Spree::Event::Tracker
4
+ EVENTS = { show: :view, search: :search, filter: :filter, index: :index }
5
+
6
+ def initialize(arguments = {})
7
+ super(arguments)
8
+ @search_keywords = arguments[:search_keywords]
9
+ @query_string = arguments[:query_string]
10
+ end
11
+
12
+ def track
13
+ PageEvent.create(instance_values)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/solidus_events_tracker/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,4 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
@@ -0,0 +1,3 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ # Add your extension routes here
3
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSpreeCartEvents < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_cart_events do |t|
4
+ t.belongs_to :actor, polymorphic: true, index: true
5
+ t.belongs_to :target, polymorphic: true, index: true
6
+ t.string :activity
7
+ t.string :referrer
8
+ t.integer :quantity
9
+ t.decimal :total, precision: 16, scale: 4
10
+ t.string :session_id
11
+ t.belongs_to :variant, index: true
12
+ t.timestamps null: false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSpreePageEvents < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_page_events do |t|
4
+ t.belongs_to :actor, polymorphic: true, index: true
5
+ t.belongs_to :target, polymorphic: true, index: true
6
+ t.string :activity
7
+ t.string :referrer
8
+ t.string :search_keywords
9
+ t.string :session_id
10
+ t.string :query_string
11
+ t.timestamps null: false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ class CreateSpreeCheckoutEvents < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_checkout_events do |t|
4
+ t.belongs_to :actor, polymorphic: true, index: true
5
+ t.belongs_to :target, polymorphic: true, index: true
6
+ t.string :activity
7
+ t.string :referrer
8
+ t.string :previous_state
9
+ t.string :next_state
10
+ t.string :session_id
11
+ t.timestamps null: false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ module SolidusEventsTracker
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ class_option :auto_run_migrations, :type => :boolean, :default => false
6
+
7
+ def add_javascripts
8
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_events_tracker\n"
9
+ append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_events_tracker\n"
10
+ end
11
+
12
+ def add_stylesheets
13
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_events_tracker\n", :before => /\*\//, :verbose => true
14
+ inject_into_file 'vendor/assets/stylesheets/spree/backend/all.css', " *= require spree/backend/solidus_events_tracker\n", :before => /\*\//, :verbose => true
15
+ end
16
+
17
+ def add_migrations
18
+ run 'bundle exec rake railties:install:migrations FROM=solidus_events_tracker'
19
+ end
20
+
21
+ def run_migrations
22
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
23
+ if run_migrations
24
+ run 'bundle exec rake db:migrate'
25
+ else
26
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,2 @@
1
+ require 'solidus_core'
2
+ require 'solidus_events_tracker/engine'
@@ -0,0 +1,20 @@
1
+ module SolidusEventsTracker
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'solidus_events_tracker'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ def self.activate
13
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
14
+ Rails.configuration.cache_classes ? require(c) : load(c)
15
+ end
16
+ end
17
+
18
+ config.to_prepare &method(:activate).to_proc
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
+ #
4
+ # Example adding this to your spec_helper will load these Factories for use:
5
+ # require 'spree_events_tracker/factories'
6
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: UTF-8
2
+ Gem::Specification.new do |s|
3
+ s.platform = Gem::Platform::RUBY
4
+ s.name = 'solidus_events_tracker'
5
+ s.version = '2.1.1'
6
+ s.summary = 'Tracks user activity for reporting.'
7
+ s.description = 'Tracks user activity and events on the server side. Use Solidus Admin Insights to build reports of user activity.'
8
+ s.required_ruby_version = '>= 2.1.0'
9
+
10
+ s.author = ["Nimish Mehta", "Tanmay Sinha", "+ Vinsol Team"]
11
+ s.email = 'info@vinsol.com'
12
+ s.homepage = 'http://vinsol.com'
13
+ s.license = 'BSD-3'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ # s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.require_path = 'lib'
18
+ s.requirements << 'none'
19
+
20
+ solidus_version = '~> 2.1'
21
+
22
+ s.add_dependency 'solidus_core', solidus_version
23
+
24
+ s.add_development_dependency 'shoulda-matchers', '~> 2.6.2'
25
+ s.add_development_dependency 'rspec-activemodel-mocks'
26
+
27
+ s.add_development_dependency 'capybara', '~> 2.5'
28
+ s.add_development_dependency 'coffee-rails'
29
+ s.add_development_dependency 'database_cleaner'
30
+ s.add_development_dependency 'factory_girl', '~> 4.5'
31
+ s.add_development_dependency 'ffaker', '~> 2.2.0'
32
+ s.add_development_dependency 'rspec-rails', '~> 3.4'
33
+ s.add_development_dependency 'sass-rails', '~> 5.0.0'
34
+ s.add_development_dependency 'selenium-webdriver'
35
+ s.add_development_dependency 'simplecov'
36
+ s.add_development_dependency 'sqlite3'
37
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::CheckoutController do
4
+
5
+ let(:order) { mock_model(Spree::Order, remaining_total: 1000, state: 'cart') }
6
+ let(:user) { mock_model(Spree.user_class, store_credits_total: 500) }
7
+ let(:checkout_event) { mock_model(Spree::CheckoutEvent) }
8
+
9
+ before do
10
+ allow(user).to receive(:orders).and_return(Spree::Order.all)
11
+ allow(controller).to receive(:track_activity).and_return(checkout_event)
12
+ allow(controller).to receive(:ensure_order_not_completed).and_return(true)
13
+ allow(controller).to receive(:ensure_checkout_allowed).and_return(true)
14
+ allow(controller).to receive(:ensure_sufficient_stock_lines).and_return(true)
15
+ allow(controller).to receive(:ensure_valid_state).and_return(true)
16
+ allow(controller).to receive(:associate_user).and_return(true)
17
+ allow(controller).to receive(:check_authorization).and_return(true)
18
+ allow(controller).to receive(:current_order).and_return(order)
19
+ allow(controller).to receive(:setup_for_current_state).and_return(true)
20
+ allow(controller).to receive(:spree_current_user).and_return(user)
21
+ allow(order).to receive(:can_go_to_state?).and_return(false)
22
+ end
23
+
24
+ describe '#edit' do
25
+
26
+ def send_request(state)
27
+ get :edit, state: state
28
+ end
29
+
30
+ before do
31
+ allow(order).to receive(:state=).and_return("address")
32
+ end
33
+
34
+ context 'when previous state is different than next state' do
35
+
36
+ describe 'expects to receive' do
37
+ it { expect(user).to receive(:orders).and_return(Spree::Order.all) }
38
+ it { expect(controller).to receive(:track_activity).and_return(checkout_event) }
39
+ it { expect(controller).to receive(:ensure_order_not_completed).and_return(true) }
40
+ it { expect(controller).to receive(:ensure_checkout_allowed).and_return(true) }
41
+ it { expect(controller).to receive(:ensure_sufficient_stock_lines).and_return(true) }
42
+ it { expect(controller).to receive(:ensure_valid_state).and_return(true) }
43
+ it { expect(controller).to receive(:associate_user).and_return(true) }
44
+ it { expect(controller).to receive(:check_authorization).and_return(true) }
45
+ it { expect(controller).to receive(:current_order).and_return(order) }
46
+ it { expect(controller).to receive(:setup_for_current_state).and_return(true) }
47
+ it { expect(controller).to receive(:spree_current_user).and_return(user) }
48
+ it { expect(order).to receive(:can_go_to_state?).and_return(false) }
49
+ it { expect(order).to receive(:state=).and_return("address") }
50
+
51
+ after { send_request('address') }
52
+ end
53
+
54
+ describe 'response' do
55
+ before { send_request('address') }
56
+ it { expect(response).to have_http_status(200) }
57
+ end
58
+
59
+ describe 'assigns' do
60
+ before { send_request('address') }
61
+ it { expect(controller.track_activity).to be_instance_of(Spree::CheckoutEvent) }
62
+ end
63
+
64
+ end
65
+
66
+ context 'when previous state is same as next state' do
67
+ before { request.env['HTTP_REFERER'] = 'test/cart' }
68
+
69
+ describe 'response' do
70
+ before { send_request('cart') }
71
+ it { expect(response).to have_http_status(200) }
72
+ end
73
+
74
+ describe 'expect not to receive' do
75
+ it { expect(controller).not_to receive(:track_activity) }
76
+ after { send_request('cart') }
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ describe '#update' do
83
+
84
+ def send_request
85
+ patch :update, state: order.state
86
+ end
87
+
88
+ before do
89
+ allow(order).to receive(:assign_attributes).and_return(order)
90
+ allow(order).to receive(:save).and_return(true)
91
+ allow(order).to receive(:temporary_address=).and_return(true)
92
+ allow(order).to receive(:state=).and_return("complete")
93
+ allow(order).to receive(:next).and_return(true)
94
+ allow(order).to receive(:completed?).and_return(true)
95
+ allow(order).to receive(:shipments).and_return([])
96
+ request.env['HTTP_REFERER'] = 'test/confirm'
97
+ end
98
+
99
+ describe 'expects to receive' do
100
+ it { expect(user).to receive(:orders).and_return(Spree::Order.all) }
101
+ it { expect(controller).to receive(:track_activity).and_return(checkout_event) }
102
+ it { expect(controller).to receive(:ensure_order_not_completed).and_return(true) }
103
+ it { expect(controller).to receive(:ensure_checkout_allowed).and_return(true) }
104
+ it { expect(controller).to receive(:ensure_sufficient_stock_lines).and_return(true) }
105
+ it { expect(controller).to receive(:ensure_valid_state).and_return(true) }
106
+ it { expect(controller).to receive(:associate_user).and_return(true) }
107
+ it { expect(controller).to receive(:check_authorization).and_return(true) }
108
+ it { expect(controller).to receive(:current_order).and_return(order) }
109
+ it { expect(controller).to receive(:setup_for_current_state).and_return(true) }
110
+ it { expect(controller).to receive(:spree_current_user).and_return(user) }
111
+ it { expect(order).to receive(:can_go_to_state?).and_return(false) }
112
+ it { expect(order).to receive(:temporary_address=).and_return(true) }
113
+ it { expect(order).to receive(:state=).and_return("complete") }
114
+ it { expect(order).to receive(:next).and_return(true) }
115
+ it { expect(order).to receive(:completed?).and_return(true) }
116
+
117
+ after { send_request }
118
+ end
119
+
120
+ describe 'assigns' do
121
+ before { send_request }
122
+ it { expect(controller.track_activity).to be_instance_of(Spree::CheckoutEvent) }
123
+ end
124
+
125
+ describe 'response' do
126
+ before { send_request }
127
+ it { expect(response).to have_http_status(302) }
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::OrdersController do
4
+
5
+ let(:order) { mock_model(Spree::Order, remaining_total: 1000, state: 'cart') }
6
+ let(:user) { mock_model(Spree.user_class, store_credits_total: 500) }
7
+ let(:checkout_event) { mock_model(Spree::CheckoutEvent) }
8
+
9
+ before do
10
+ allow(user).to receive(:orders).and_return(Spree::Order.all)
11
+ allow(controller).to receive(:track_activity).and_return(checkout_event)
12
+ allow(controller).to receive(:check_authorization).and_return(true)
13
+ allow(controller).to receive(:current_order).and_return(order)
14
+ allow(controller).to receive(:associate_user).and_return(true)
15
+ allow(controller).to receive(:spree_current_user).and_return(user)
16
+ allow(controller).to receive(:current_order).and_return(order)
17
+ end
18
+
19
+ describe '#edit' do
20
+
21
+ def send_request
22
+ get :edit, id: order.number
23
+ end
24
+
25
+ describe 'when return to cart' do
26
+
27
+ context 'when return from a checkout step' do
28
+ before do
29
+ @checkout_steps = double('checkout_steps')
30
+ allow(order).to receive(:checkout_steps).and_return(@checkout_steps)
31
+ allow(@checkout_steps).to receive(:include?).and_return(true)
32
+ request.env['HTTP_REFERER'] = 'test/address'
33
+ end
34
+
35
+ describe 'expects to receive' do
36
+ it { expect(user).to receive(:orders).and_return(Spree::Order.all) }
37
+ it { expect(controller).to receive(:track_activity).and_return(checkout_event) }
38
+ it { expect(controller).to receive(:check_authorization).and_return(true) }
39
+ it { expect(controller).to receive(:current_order).and_return(order) }
40
+ it { expect(controller).to receive(:spree_current_user).and_return(user) }
41
+ it { expect(controller).to receive(:current_order).and_return(order) }
42
+ it { expect(controller).to receive(:associate_user).and_return(true) }
43
+ it { expect(order).to receive(:checkout_steps).and_return(@checkout_steps) }
44
+ it { expect(@checkout_steps).to receive(:include?).and_return(true) }
45
+
46
+ after { send_request }
47
+ end
48
+
49
+ describe 'response' do
50
+ before { send_request }
51
+ it { expect(response).to have_http_status(200) }
52
+ end
53
+
54
+ describe 'assigns' do
55
+ before { send_request }
56
+ it { expect(controller.track_activity).to be_instance_of(Spree::CheckoutEvent) }
57
+ end
58
+
59
+ end
60
+
61
+ context 'when a product is added' do
62
+ before do
63
+ checkout_steps = double('checkout_steps')
64
+ allow(order).to receive(:checkout_steps).and_return(checkout_steps)
65
+ allow(checkout_steps).to receive(:include?).and_return(false)
66
+ request.env['HTTP_REFERER'] = 'test/my_test_product'
67
+ end
68
+
69
+ describe 'response' do
70
+ before { send_request }
71
+ it { expect(response).to have_http_status(200) }
72
+ end
73
+
74
+ describe 'assigns' do
75
+ before { send_request }
76
+ it { expect(controller.track_activity).to be_instance_of(Spree::CheckoutEvent) }
77
+ end
78
+ end
79
+
80
+ context 'when return to cart from cart itself' do
81
+ before do
82
+ checkout_steps = double('checkout_steps')
83
+ allow(order).to receive(:checkout_steps).and_return(checkout_steps)
84
+ allow(checkout_steps).to receive(:include?).and_return(true)
85
+ request.env['HTTP_REFERER'] = 'test/cart'
86
+ end
87
+
88
+ describe 'response' do
89
+ before { send_request }
90
+ it { expect(response).to have_http_status(200) }
91
+ end
92
+
93
+ describe 'expect to not receive' do
94
+ it { expect(controller).not_to receive(:track_activity) }
95
+ after { send_request }
96
+ end
97
+ end
98
+
99
+ end
100
+ end
101
+
102
+ describe '#empty' do
103
+ def send_request
104
+ put :empty
105
+ end
106
+
107
+ before do
108
+ allow(order).to receive(:empty!)
109
+ request.env['HTTP_REFERER'] = 'test/cart'
110
+ end
111
+
112
+ describe 'expects to receive' do
113
+ it { expect(user).to receive(:orders).and_return(Spree::Order.all) }
114
+ it { expect(controller).to receive(:track_activity).and_return(checkout_event) }
115
+ it { expect(controller).to receive(:check_authorization).and_return(true) }
116
+ it { expect(controller).to receive(:current_order).and_return(order) }
117
+ it { expect(controller).to receive(:spree_current_user).and_return(user) }
118
+ it { expect(controller).to receive(:current_order).and_return(order) }
119
+ it { expect(order).to receive(:empty!) }
120
+
121
+ after { send_request }
122
+ end
123
+
124
+
125
+ describe 'assigns' do
126
+ before { send_request }
127
+ it { expect(controller.track_activity).to be_instance_of(Spree::CheckoutEvent) }
128
+ end
129
+
130
+ describe 'response' do
131
+ before { send_request }
132
+ it { expect(response).to have_http_status(302) }
133
+ end
134
+ end
135
+
136
+ end