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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5207d6b6f9bdac0e62f5dd4d215fda33e732ca77
4
- data.tar.gz: bb4db818202615ad96a2f28c16bd4ab315f5676f
3
+ metadata.gz: fc9d932b29081cbbb4a1b13d092b2016a85a7211
4
+ data.tar.gz: 6b6aede72f41dbcc4fb0a399e362e42582fbed1c
5
5
  SHA512:
6
- metadata.gz: fbcd05b501b6f197f50e6b7aa631345101e0e9c41b6cc7530e99af5fa80099ff26e9c2ea2071b424900da9e6e12d0f00bbd46b2d892ce2941dd2034a7a5b78db
7
- data.tar.gz: 38ece47268bddae954490d74d3e86a0fd634a7dc6f87d43c55c377482cb39211d45705aa5ec933865d0d5584acdb53a74dd9b0db5d170248ac806e3e481b071a
6
+ metadata.gz: 62f76b683cbd06af0b23504b33b7373864907d33c2cc664d5784464d865fc0feed7855885ad72aaedad5817b3fb6cab2687819b4a510f61696207f019a43b0cb
7
+ data.tar.gz: 5ddefadfa935923d548ab35b044c62f518711de9a82098625ae9cc811c239c1b1e8ff39fa4d41e9cf4871cb87f17cb315dbf7b284a90d185b5dd4d0eaa0fcc8a
@@ -0,0 +1,73 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ *.sassc
5
+ *.DS_Store
6
+ .sass-cache
7
+ coverage
8
+ Gemfile.lock
9
+ .idea
10
+ .project
11
+ nbproject
12
+ .ruby-gemset
13
+ pkg
14
+ *.swp
15
+ spec/dummy
16
+
17
+ *.rbc
18
+ capybara-*.html
19
+ .rspec
20
+ /log
21
+ /tmp
22
+ /db/*.sqlite3
23
+ /db/*.sqlite3-journal
24
+ /public/system
25
+ /coverage/
26
+ /spec/tmp
27
+ **.orig
28
+ rerun.txt
29
+ pickle-email-*.html
30
+
31
+ # TODO Comment out these rules if you are OK with secrets being uploaded to the repo
32
+ config/initializers/secret_token.rb
33
+ config/secrets.yml
34
+
35
+ ## Environment normalization:
36
+ /.bundle/
37
+ /vendor/bundle
38
+ /lib/bundler/man/
39
+
40
+ # these should all be checked in to normalize the environment:
41
+ # Gemfile.lock, .ruby-version, .ruby-gemset
42
+
43
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
44
+ .rvmrc
45
+ .ruby-version
46
+ /test
47
+ /config/*.yml
48
+ *.log
49
+ /public/test_files
50
+ /public/system/*
51
+ /public/*.json
52
+ .byebug_history
53
+
54
+ # if using bower-rails ignore default bower_components path bower.json files
55
+ /vendor/assets/bower_components
56
+ *.bowerrc
57
+ bower.json
58
+
59
+ # Ignore pow environment settings
60
+ .powenv
61
+
62
+ *.gem
63
+ /.config
64
+ /InstalledFiles
65
+ /spec/examples.txt
66
+ /test/tmp/
67
+ /test/version_tmp/
68
+ /tmp/*
69
+
70
+ ## Specific to RubyMotion:
71
+ .dat*
72
+ .repl_history
73
+ build/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'solidus', '~> 2.1'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2017 [Vinsol & community]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,52 @@
1
+ Solidus Events Tracker
2
+ ==================
3
+
4
+ Solidus Port for Spree Events Tracker.
5
+
6
+ Tracks user activity and events on the server side. Use Solidus Admin Insights to build reports of user activity.
7
+
8
+
9
+ ## Installation
10
+
11
+ 1. Add this extension to your Gemfile with this line:
12
+ ```ruby
13
+ gem 'solidus_events_tracker'
14
+ ```
15
+
16
+ 2. Install the gem using Bundler:
17
+ ```ruby
18
+ bundle install
19
+ ```
20
+
21
+ 3. Copy & run migrations
22
+ ```ruby
23
+ bundle exec rails g solidus_events_tracker:install
24
+ ```
25
+
26
+ 4. Restart your server
27
+
28
+ If your server was running, restart it so that it can find the assets properly.
29
+
30
+ ## Testing
31
+
32
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `rake test_app`.
33
+
34
+ ```shell
35
+ bundle
36
+ bundle exec rake
37
+ ```
38
+
39
+ When testing your applications integration with this extension you may use it's factories.
40
+ Simply add this require statement to your spec_helper:
41
+
42
+ ```ruby
43
+ require 'solidus_events_tracker/factories'
44
+ ```
45
+
46
+
47
+ Credits
48
+ -------
49
+
50
+ [![vinsol.com: Ruby on Rails, iOS and Android developers](http://vinsol.com/vin_logo.png "Ruby on Rails, iOS and Android developers")](http://vinsol.com)
51
+
52
+ Copyright (c) 2017 [vinsol.com](http://vinsol.com "Ruby on Rails, iOS and Android developers"), released under the New MIT License
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/extension_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default do
10
+ if Dir["spec/dummy"].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir("../../")
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc 'Generates a dummy app for testing'
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'solidus_events_tracker'
20
+ Rake::Task['extension:test_app'].invoke
21
+ end
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
@@ -0,0 +1,2 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
@@ -0,0 +1,28 @@
1
+ module Spree
2
+ module CheckoutEventTracker
3
+ extend ActiveSupport::Concern
4
+
5
+ def track_activity(attributes)
6
+ default_attributes = {
7
+ referrer: request.referrer,
8
+ actor: spree_current_user,
9
+ target: @order,
10
+ session_id: session.id
11
+ }
12
+ Spree::Checkout::Event::Tracker.new(default_attributes.merge(attributes)).track
13
+ end
14
+
15
+ def next_state
16
+ @next_state ||= checkout_state(request.url)
17
+ end
18
+
19
+ def previous_state
20
+ referrer = request.referrer
21
+ @previous_state ||= (referrer ? checkout_state(referrer) : nil)
22
+ end
23
+
24
+ def checkout_state(request_path)
25
+ request_path.split('/').last.split('?').first
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,55 @@
1
+ module Spree
2
+ module PageTracker
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def track_actions(actions = [])
7
+ after_action :track_event, only: actions
8
+ end
9
+ end
10
+
11
+ def track_event
12
+ if event_trackable?
13
+ Spree::Page::Event::Tracker.new(
14
+ session_id: session.id,
15
+ referrer: request.referrer,
16
+ actor: current_spree_user,
17
+ target: instance_variable_get("@#{ controller_name.singularize }"),
18
+ activity: get_activity,
19
+ search_keywords: get_keywords,
20
+ query_string: request.query_string
21
+ ).track
22
+ end
23
+ end
24
+
25
+ def get_activity
26
+ if index_action?
27
+ if @searcher && (@searcher.keywords || @searcher.search)
28
+ Spree::Page::Event::Tracker::EVENTS[:search]
29
+ else
30
+ Spree::Page::Event::Tracker::EVENTS[:index]
31
+ end
32
+ elsif show_action?
33
+ if @searcher && @searcher.search
34
+ Spree::Page::Event::Tracker::EVENTS[:filter]
35
+ else
36
+ Spree::Page::Event::Tracker::EVENTS[:show]
37
+ end
38
+ end
39
+ end
40
+
41
+ def get_keywords
42
+ @searcher && (@searcher.search.to_s + @searcher.keywords.to_s)
43
+ end
44
+
45
+ def event_trackable?
46
+ show_action? || index_action?
47
+ end
48
+
49
+ %w(index show).each do |_action_|
50
+ define_method("#{ _action_ }_action?") do
51
+ action_name == _action_
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,22 @@
1
+ Spree::CheckoutController.class_eval do
2
+
3
+ include Spree::CheckoutEventTracker
4
+
5
+ after_action :track_order_state_change, only: :edit
6
+ after_action :track_order_completion, only: :update, if: :confirm?
7
+
8
+ private
9
+ def confirm?
10
+ previous_state == 'confirm'
11
+ end
12
+
13
+ def track_order_completion
14
+ track_activity(activity: :complete_order, previous_state: previous_state, next_state: 'complete')
15
+ end
16
+
17
+ def track_order_state_change
18
+ unless previous_state == next_state
19
+ track_activity(activity: :change_order_state, previous_state: previous_state, next_state: next_state)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ Spree::HomeController.class_eval do
2
+ include Spree::PageTracker
3
+ track_actions [:index]
4
+ end
@@ -0,0 +1,32 @@
1
+ Spree::OrdersController.class_eval do
2
+
3
+ include Spree::CheckoutEventTracker
4
+
5
+ after_action :track_return_to_cart, only: :edit, if: :current_order
6
+ after_action :track_empty_cart_activity, only: :empty
7
+
8
+ private
9
+ def track_empty_cart_activity
10
+ track_activity(activity: :empty_cart, previous_state: previous_state, next_state: nil)
11
+ end
12
+
13
+ def track_return_to_cart
14
+ preceeding_state = referred_from_any_checkout_step? ? previous_state : nil
15
+ unless preceeding_state == next_state
16
+ track_activity(activity: activity, previous_state: preceeding_state, next_state: next_state)
17
+ end
18
+ end
19
+
20
+ def activity
21
+ !(referred_from_any_checkout_step?) ? :initialize_order : :return_to_cart
22
+ end
23
+
24
+ def current_order_includes_previous_state?
25
+ current_order.checkout_steps.include?(previous_state)
26
+ end
27
+
28
+ def referred_from_any_checkout_step?
29
+ current_order_includes_previous_state? || previous_state.eql?('cart')
30
+ end
31
+
32
+ end
@@ -0,0 +1,4 @@
1
+ Spree::ProductsController.class_eval do
2
+ include Spree::PageTracker
3
+ track_actions [:show, :index]
4
+ end
@@ -0,0 +1,4 @@
1
+ Spree::TaxonsController.class_eval do
2
+ include Spree::PageTracker
3
+ track_actions [:show]
4
+ end
@@ -0,0 +1,38 @@
1
+ module Spree
2
+ module OrderContentsWithTracker
3
+
4
+ # Override: since order's line_items were overridden
5
+ def update_cart(params)
6
+ if order.update_attributes(params)
7
+ order.line_items.select(&:quantity_previously_changed?).each do |line_item|
8
+ Spree::Cart::Event::Tracker.new(
9
+ actor: order, target: line_item, total: order.total, variant_id: line_item.variant_id
10
+ ).track
11
+ end
12
+ # line_items which have 0 quantity will be lost and couldn't be tracked
13
+ # so tracking is done before the execution of next statement
14
+ order.line_items = order.line_items.select { |li| li.quantity > 0 }
15
+ reload_totals
16
+ PromotionHandler::Cart.new(order).activate
17
+ order.ensure_updated_shipments
18
+ reload_totals
19
+ true
20
+ else
21
+ false
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ # Override: Add tracking entry after a line_item is added or removed
28
+ def after_add_or_remove(line_item, options = {})
29
+ line_item = super
30
+ Spree::Cart::Event::Tracker.new(
31
+ actor: order, target: line_item, total: order.total, variant_id: line_item.variant_id
32
+ ).track
33
+ line_item
34
+ end
35
+ end
36
+ end
37
+
38
+ Spree::OrderContents.send(:prepend, Spree::OrderContentsWithTracker)
@@ -0,0 +1,20 @@
1
+ module Spree
2
+ class CartEvent < Spree::Base
3
+
4
+ belongs_to :actor, polymorphic: true
5
+ belongs_to :target, polymorphic: true
6
+ belongs_to :variant
7
+ has_one :product, through: :variant
8
+
9
+ validates :activity,
10
+ :actor,
11
+ :quantity,
12
+ :target,
13
+ :total,
14
+ :variant, presence: true
15
+
16
+ scope :added, -> { where(activity: 'add') }
17
+ scope :removed, -> { where(activity: 'remove') }
18
+ scope :updated, -> { where(activity: 'update') }
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ class CheckoutEvent < Spree::Base
3
+
4
+ belongs_to :actor, polymorphic: true
5
+ belongs_to :target, polymorphic: true
6
+
7
+ validates :activity,
8
+ :session_id,
9
+ :target, presence: true
10
+ end
11
+ end