solidus_events_tracker 2.1.0 → 2.1.1

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.
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