shrew 0.0.3 → 0.0.4

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +67 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +114 -0
  5. data/README.md +38 -0
  6. data/Rakefile +15 -0
  7. data/app/assets/javascripts/shrew.js +69 -0
  8. data/app/controllers/shrew/application_controller.rb +4 -0
  9. data/app/controllers/shrew/page_views_controller.rb +22 -0
  10. data/app/models/shrew/page_view.rb +19 -0
  11. data/app/views/shrew/_automatically_track_page_views.html.erb +11 -0
  12. data/config/routes.rb +9 -0
  13. data/db/migrate/1_add_shrew_page_view_table.rb +17 -0
  14. data/lib/generators/shrew/install_generator.rb +31 -0
  15. data/lib/generators/templates/page_view_migration.rb +17 -0
  16. data/lib/generators/templates/shrew.rb +4 -0
  17. data/lib/shrew/engine.rb +14 -0
  18. data/lib/shrew/tracks_page_views.rb +21 -0
  19. data/lib/shrew/version.rb +3 -0
  20. data/shrew.gemspec +26 -0
  21. data/spec/controllers/page_views_controller_spec.rb +56 -0
  22. data/spec/controllers/tracks_page_views_spec.rb +34 -0
  23. data/spec/rails_helper.rb +50 -0
  24. data/spec/shrew_spec.rb +6 -0
  25. data/spec/spec_helper.rb +52 -0
  26. data/test/dummy/README.rdoc +28 -0
  27. data/test/dummy/Rakefile +6 -0
  28. data/test/dummy/app/assets/images/.keep +0 -0
  29. data/test/dummy/app/assets/javascripts/application.js +13 -0
  30. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  31. data/test/dummy/app/controllers/application_controller.rb +5 -0
  32. data/test/dummy/app/controllers/concerns/.keep +0 -0
  33. data/test/dummy/app/helpers/application_helper.rb +2 -0
  34. data/test/dummy/app/mailers/.keep +0 -0
  35. data/test/dummy/app/models/.keep +0 -0
  36. data/test/dummy/app/models/concerns/.keep +0 -0
  37. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  38. data/test/dummy/bin/bundle +3 -0
  39. data/test/dummy/bin/rails +4 -0
  40. data/test/dummy/bin/rake +4 -0
  41. data/test/dummy/config/application.rb +23 -0
  42. data/test/dummy/config/boot.rb +5 -0
  43. data/test/dummy/config/database.yml +25 -0
  44. data/test/dummy/config/environment.rb +5 -0
  45. data/test/dummy/config/environments/development.rb +37 -0
  46. data/test/dummy/config/environments/production.rb +82 -0
  47. data/test/dummy/config/environments/test.rb +39 -0
  48. data/test/dummy/config/initializers/assets.rb +8 -0
  49. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  51. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  52. data/test/dummy/config/initializers/inflections.rb +16 -0
  53. data/test/dummy/config/initializers/mime_types.rb +4 -0
  54. data/test/dummy/config/initializers/session_store.rb +3 -0
  55. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  56. data/test/dummy/config/locales/en.yml +23 -0
  57. data/test/dummy/config/routes.rb +4 -0
  58. data/test/dummy/config/secrets.yml +22 -0
  59. data/test/dummy/config.ru +4 -0
  60. data/test/dummy/db/development.sqlite3 +0 -0
  61. data/test/dummy/db/schema.rb +30 -0
  62. data/test/dummy/db/test.sqlite3 +0 -0
  63. data/test/dummy/lib/assets/.keep +0 -0
  64. data/test/dummy/log/.keep +0 -0
  65. data/test/dummy/log/development.log +81 -0
  66. data/test/dummy/log/test.log +1689 -0
  67. data/test/dummy/public/404.html +67 -0
  68. data/test/dummy/public/422.html +67 -0
  69. data/test/dummy/public/500.html +66 -0
  70. data/test/dummy/public/favicon.ico +0 -0
  71. data/test/test_helper.rb +15 -0
  72. metadata +77 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f547aa76f469d4d753a91e5d52bba25ae8bbf5fe
4
- data.tar.gz: 604784d086e871a6f3fec1682ae210597ca67c33
3
+ metadata.gz: 08a92b898b271df0893a9cae07e5da9a9339438f
4
+ data.tar.gz: b2cb9fafe62a8abd0820a0f67448f6cadfa98914
5
5
  SHA512:
6
- metadata.gz: cda8105d1e2110e48a8abc07cc2d895c872dfac3e845951bd70bcb91f72fc0648d8a86989001cbd1b60b870f5b3aa22d6c4511393bcaeb894cdb9f31f7eb3887
7
- data.tar.gz: 0a5bc8e4efd71f465c55e3e6b3ad05afd223feac8e68a1e1c6ab44315a25b67e0e6ab6238890360a43fac3bd05be2556a0e1d3166a398da22caada5b897190d5
6
+ metadata.gz: 66dbce425c0109ec66c1a709ae0fe394b42d459cc64cea9a2636a5d7e2fd7da4e85a1fa5b4d7ed558aafcb2b7f56f70178acdc46c91a4657526261984b6823e2
7
+ data.tar.gz: 3856eaf445d5c010d64eaf7f0f171f86daf13acfce1666c1e008a3a63fe5514d6e003b671f36be5d7f07ce33eeab2702abf25ab08c28633e781056f66faea7e6
data/.gitignore ADDED
@@ -0,0 +1,67 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*.log
16
+ /tmp
17
+
18
+ #https://github.com/github/gitignore/blob/master/Rails.gitignore
19
+ *.rbc
20
+ capybara-*.html
21
+ .rspec
22
+ /log
23
+ /tmp
24
+ /db/*.sqlite3
25
+ /public/system
26
+ /public/uploads
27
+ /coverage/
28
+ /spec/tmp
29
+ **.orig
30
+ rerun.txt
31
+ pickle-email-*.html
32
+
33
+ # Comment out this rules if you are OK with secrets been uploaded to the repo
34
+ config/initializers/secret_token.rb
35
+ #config/secrets.yml
36
+
37
+ ## Environment normalisation:
38
+ /.bundle
39
+ /vendor/bundle
40
+
41
+ # these should all be checked in to normalise the environment:
42
+ # Gemfile.lock, .ruby-version, .ruby-gemset
43
+
44
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
45
+ .rvmrc
46
+
47
+ #ignore idea
48
+ /.idea
49
+
50
+ #mac
51
+ .DS_Store
52
+
53
+ #precompiled assets
54
+ public/assets/
55
+
56
+ solr/**/data
57
+ solr/pids/
58
+
59
+ #uploaded files
60
+ public/file/
61
+
62
+
63
+ #javascript code coverage
64
+ spec/javascripts_coverage/
65
+
66
+ #node modules
67
+ node_modules
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rails', '~> 4.1'
data/Gemfile.lock ADDED
@@ -0,0 +1,114 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ shrew (0.0.2)
5
+ activerecord (>= 4.0.0)
6
+ activesupport (>= 4.0.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionmailer (4.1.7)
12
+ actionpack (= 4.1.7)
13
+ actionview (= 4.1.7)
14
+ mail (~> 2.5, >= 2.5.4)
15
+ actionpack (4.1.7)
16
+ actionview (= 4.1.7)
17
+ activesupport (= 4.1.7)
18
+ rack (~> 1.5.2)
19
+ rack-test (~> 0.6.2)
20
+ actionview (4.1.7)
21
+ activesupport (= 4.1.7)
22
+ builder (~> 3.1)
23
+ erubis (~> 2.7.0)
24
+ activemodel (4.1.7)
25
+ activesupport (= 4.1.7)
26
+ builder (~> 3.1)
27
+ activerecord (4.1.7)
28
+ activemodel (= 4.1.7)
29
+ activesupport (= 4.1.7)
30
+ arel (~> 5.0.0)
31
+ activesupport (4.1.7)
32
+ i18n (~> 0.6, >= 0.6.9)
33
+ json (~> 1.7, >= 1.7.7)
34
+ minitest (~> 5.1)
35
+ thread_safe (~> 0.1)
36
+ tzinfo (~> 1.1)
37
+ arel (5.0.1.20140414130214)
38
+ builder (3.2.2)
39
+ database_cleaner (1.3.0)
40
+ diff-lcs (1.2.5)
41
+ erubis (2.7.0)
42
+ hike (1.2.3)
43
+ i18n (0.6.11)
44
+ json (1.8.1)
45
+ mail (2.6.3)
46
+ mime-types (>= 1.16, < 3)
47
+ mime-types (2.4.3)
48
+ minitest (5.4.2)
49
+ multi_json (1.10.1)
50
+ rack (1.5.2)
51
+ rack-test (0.6.2)
52
+ rack (>= 1.0)
53
+ rails (4.1.7)
54
+ actionmailer (= 4.1.7)
55
+ actionpack (= 4.1.7)
56
+ actionview (= 4.1.7)
57
+ activemodel (= 4.1.7)
58
+ activerecord (= 4.1.7)
59
+ activesupport (= 4.1.7)
60
+ bundler (>= 1.3.0, < 2.0)
61
+ railties (= 4.1.7)
62
+ sprockets-rails (~> 2.0)
63
+ railties (4.1.7)
64
+ actionpack (= 4.1.7)
65
+ activesupport (= 4.1.7)
66
+ rake (>= 0.8.7)
67
+ thor (>= 0.18.1, < 2.0)
68
+ rake (10.3.2)
69
+ rspec (3.1.0)
70
+ rspec-core (~> 3.1.0)
71
+ rspec-expectations (~> 3.1.0)
72
+ rspec-mocks (~> 3.1.0)
73
+ rspec-core (3.1.7)
74
+ rspec-support (~> 3.1.0)
75
+ rspec-expectations (3.1.2)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.1.0)
78
+ rspec-mocks (3.1.3)
79
+ rspec-support (~> 3.1.0)
80
+ rspec-rails (3.1.0)
81
+ actionpack (>= 3.0)
82
+ activesupport (>= 3.0)
83
+ railties (>= 3.0)
84
+ rspec-core (~> 3.1.0)
85
+ rspec-expectations (~> 3.1.0)
86
+ rspec-mocks (~> 3.1.0)
87
+ rspec-support (~> 3.1.0)
88
+ rspec-support (3.1.2)
89
+ sprockets (2.12.3)
90
+ hike (~> 1.2)
91
+ multi_json (~> 1.0)
92
+ rack (~> 1.0)
93
+ tilt (~> 1.1, != 1.3.0)
94
+ sprockets-rails (2.2.0)
95
+ actionpack (>= 3.0)
96
+ activesupport (>= 3.0)
97
+ sprockets (>= 2.8, < 4.0)
98
+ sqlite3 (1.3.10)
99
+ thor (0.19.1)
100
+ thread_safe (0.3.4)
101
+ tilt (1.4.1)
102
+ tzinfo (1.2.2)
103
+ thread_safe (~> 0.1)
104
+
105
+ PLATFORMS
106
+ ruby
107
+
108
+ DEPENDENCIES
109
+ database_cleaner
110
+ rails (~> 4.1)
111
+ rspec (~> 3.1.0)
112
+ rspec-rails (~> 3.1.0)
113
+ shrew!
114
+ sqlite3
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Shrew
2
+
3
+
4
+ Simple analytics engine for rails
5
+
6
+ ### Installation
7
+
8
+ Run the generator to install the migration and routes.
9
+
10
+ ```
11
+ rails g analytics:install
12
+ rake db:migrate
13
+ ```
14
+
15
+ Add page tracking to your application controller (or any other controller)
16
+
17
+ ```
18
+ class ApplicationController < ActionController::Base
19
+ include Analytics::TracksPageViews
20
+ end
21
+ ```
22
+
23
+ *For tracking javascript run time*
24
+
25
+ Include analytics.js in your application.js
26
+
27
+ ```
28
+ //= require analytics
29
+ ```
30
+
31
+ Include the partial at the end of your layout to automatically track javascript run time
32
+
33
+ ```
34
+ ...
35
+ <%= render "analytics/automatically_track_page_views" %>
36
+ </body>
37
+ </html>
38
+ ```
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ desc 'Default: run specs'
5
+ task default: :spec
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
11
+
12
+ Bundler::GemHelper.install_tasks
13
+
14
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
15
+ load 'rails/tasks/engine.rake'
@@ -0,0 +1,69 @@
1
+ /* jshint: asi:false */
2
+ (function(config) {
3
+ var _validConfig = function(){
4
+ if(typeof config.pageViewUrl !== 'string'){
5
+ return false
6
+ }
7
+ if(typeof config.jTI !== 'string'){
8
+ return false
9
+ }
10
+ return true
11
+ }
12
+
13
+ /* http://stackoverflow.com/questions/8790099/detect-if-any-javascript-function-is-running */
14
+ var automaticallyTrackPageView = function() {
15
+ if (window.addEventListener) {
16
+ window.addEventListener("load", loadHandler, false)
17
+ }
18
+ else if (window.attachEvent) {
19
+ window.attachEvent("onload", loadHandler)
20
+ }
21
+ else {
22
+ window.onload = loadHandler
23
+ }
24
+
25
+ function loadHandler() {
26
+ setTimeout(trackPageView, 0)
27
+ }
28
+ }
29
+
30
+ var trackPageView = function() {
31
+ if(!_validConfig()){
32
+ if(typeof console !== 'undefined' && typeof console.error !== 'undefined'){
33
+ console.error('invalid shrew configuration')
34
+ }
35
+ return false
36
+ }
37
+ var xmlhttp = new XMLHttpRequest()
38
+ var params = 'url=' + encodeURIComponent(window.location.href) +
39
+ '&title=' + encodeURIComponent(document.title) +
40
+ '&jTI=' + encodeURIComponent(config.jTI) +
41
+ '&jRT=' + encodeURIComponent(new Date().getTime())
42
+ params.replace(/%20/g, '+')
43
+ xmlhttp.open('POST', config.pageViewUrl, true)
44
+ xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
45
+ xmlhttp.send(params)
46
+ }
47
+
48
+ var setJTI = function(jTI){
49
+ config.jTI = jTI
50
+ }
51
+
52
+ var publicAccess = {
53
+ automaticallyTrackPageView: automaticallyTrackPageView,
54
+ trackPageView: trackPageView,
55
+ setJTI: setJTI,
56
+ config: config
57
+ }
58
+
59
+ if ( typeof define === "function" && define.amd ) {
60
+ define([], function(){
61
+ return publicAccess
62
+ })
63
+ } else {
64
+ window.shrew = publicAccess
65
+ }
66
+ })(typeof shrewConfig !== 'undefined' ? shrewConfig : {
67
+ pageViewUrl: '/shrew/page_views',
68
+ jTI: null
69
+ })
@@ -0,0 +1,4 @@
1
+ module Shrew
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,22 @@
1
+ module Shrew
2
+ class PageViewsController < ApplicationController
3
+ def create
4
+ empty_response && return unless params[:jTI].present? && params[:jRT].present?
5
+
6
+ page_view = Shrew::PageView.find_by js_tracking_id: params[:jTI]
7
+ empty_response && return unless page_view
8
+
9
+ page_view.js_return_time = params[:jRT]
10
+ page_view.time_between_sent_and_return = page_view.js_return_time - page_view.sent_time if page_view.js_return_time && page_view.sent_time
11
+ page_view.save
12
+
13
+ empty_response
14
+ end
15
+
16
+ private
17
+
18
+ def empty_response
19
+ render json: []
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module Shrew
2
+ class PageView < ActiveRecord::Base
3
+ self.table_name = 'shrew_page_views'
4
+ belongs_to :user, class_name: Shrew.user_class
5
+
6
+ def self.create_from_payload(payload)
7
+ attributes = payload.slice(:user_id, :controller, :status, :view_runtime,
8
+ :db_runtime, :sent_time, :js_return_time,
9
+ :js_tracking_id)
10
+ .merge(sent_time: milliseconds_since_epoch)
11
+ create(attributes)
12
+ end
13
+
14
+ private
15
+ def self.milliseconds_since_epoch
16
+ (Time.now.to_f * 1000).to_i
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ <script defer async>
2
+ if (typeof define === "function" && define.amd) {
3
+ require(['shrew'], function(shrew){
4
+ shrew.setJTI('<%= @_js_tracking_id %>')
5
+ shrew.automaticallyTrackPageView()
6
+ })
7
+ } else {
8
+ shrew.setJTI('<%= @_js_tracking_id %>')
9
+ shrew.automaticallyTrackPageView()
10
+ }
11
+ </script>
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Rails.application.routes.draw do
2
+ # mount Shrew::Engine => Rails.configuration.shrew[:route_scope]
3
+ # end
4
+
5
+ Shrew::Engine.routes.draw do
6
+ scope module: Shrew.route_scope do
7
+ resources :page_views, only: [:create], defaults: { format: :json }
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ class AddShrewPageViewTable < ActiveRecord::Migration
2
+ def change
3
+ create_table :shrew_page_views do |t|
4
+ t.integer :user_id
5
+ t.string :controller
6
+ t.integer :status
7
+ t.float :view_runtime
8
+ t.float :db_runtime
9
+ t.integer :sent_time
10
+ t.integer :js_return_time
11
+ t.integer :time_between_sent_and_return
12
+ t.binary :js_tracking_id, limit: 16
13
+ end
14
+
15
+ add_index :shrew_page_views, :user_id
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ module Shrew
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+ source_root File.expand_path('../../templates', __FILE__)
6
+
7
+ desc 'Create a shrew initializer'
8
+
9
+ def copy_initializer
10
+ template 'shrew.rb', 'config/initializers/shrew.rb'
11
+ end
12
+
13
+ def copy_migration
14
+ migration_template 'page_view_migration.rb', 'db/migrate/add_shrew_page_view_table.rb'
15
+ end
16
+
17
+ def add_routes
18
+ route "mount Shrew::Engine => '/shrew', as: 'shrew'"
19
+ end
20
+
21
+ def self.next_migration_number(path)
22
+ unless @prev_migration_nr
23
+ @prev_migration_nr = Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
24
+ else
25
+ @prev_migration_nr += 1
26
+ end
27
+ @prev_migration_nr.to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ class AddShrewPageViewTable < ActiveRecord::Migration
2
+ def change
3
+ create_table :shrew_page_views do |t|
4
+ t.integer :user_id
5
+ t.string :controller
6
+ t.integer :status
7
+ t.float :view_runtime
8
+ t.float :db_runtime
9
+ t.integer :sent_time
10
+ t.integer :js_return_time
11
+ t.integer :time_between_sent_and_return
12
+ t.binary :js_tracking_id, limit: 16
13
+ end
14
+
15
+ add_index :shrew_page_views, :user_id
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ Shrew.setup do |config|
2
+ # config.route_scope = 'shrew'
3
+ # config.user_class = 'User'
4
+ end
@@ -0,0 +1,14 @@
1
+ module Shrew
2
+ class Engine < Rails::Engine
3
+ initializer 'shrew.configure_rails_initialization' do |_|
4
+ ActiveSupport::Notifications.subscribe 'process_action.action_controller' do
5
+ |_, start, finish, _, payload|
6
+
7
+ duration = (finish - start) * 1000
8
+ payload[:duration] = duration
9
+ next if payload[:controller] == 'Shrew::PageViewsController'
10
+ Shrew::PageView.create_from_payload(payload)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ module Shrew
2
+ module TracksPageViews
3
+ extend ActiveSupport::Concern
4
+
5
+ def append_info_to_payload(payload)
6
+ super
7
+ return unless @_tracking_page_views
8
+ payload[:user_id] = try(:current_user).try(:id)
9
+ payload[:js_tracking_id] = @_js_tracking_id
10
+ end
11
+
12
+ included do
13
+ before_action :tracks_page_views
14
+ end
15
+
16
+ def tracks_page_views
17
+ @_tracking_page_views = true
18
+ @_js_tracking_id = SecureRandom.uuid
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Shrew
2
+ VERSION = '0.0.4'
3
+ end
data/shrew.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'shrew/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'shrew'
8
+ s.version = Shrew::VERSION
9
+ s.date = '2014-11-05'
10
+ s.summary = 'Shrew'
11
+ s.description = 'A simple shrew gem'
12
+ s.authors = ['Adam Gross']
13
+ s.email = 'agross@synergydatasystems.com'
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- spec/*`.split("\n")
16
+ s.require_paths = ['lib']
17
+ s.license = 'MIT'
18
+
19
+ s.add_dependency 'activesupport', '>=4.0.0'
20
+ s.add_dependency 'activerecord', '>=4.0.0'
21
+
22
+ s.add_development_dependency 'rspec', '~>3.1.0'
23
+ s.add_development_dependency 'rspec-rails', '~>3.1.0'
24
+ s.add_development_dependency 'sqlite3'
25
+ s.add_development_dependency 'database_cleaner'
26
+ end
@@ -0,0 +1,56 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe Shrew::PageViewsController, type: :controller do
4
+ routes { Shrew::Engine.routes }
5
+
6
+ required_params = { jTI: '1', jRT: '100' }
7
+
8
+ context 'when missing parameter' do
9
+ required_params.each do |required_param|
10
+ it "#{required_param} does not attempt to find a page view" do
11
+ expect(Shrew::PageView).not_to receive(:find_by)
12
+
13
+ post :create, required_params.slice(required_param)
14
+ end
15
+
16
+ it 'returns a 200 empty response anyways' do
17
+ post :create, required_params.slice(required_param)
18
+
19
+ expect(response.status).to eq 200
20
+ expect(response.body).to eq '[]'
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'when the javascript tracking id matches no existing page view' do
26
+ it 'returns a 200 empty response anyways' do
27
+ expect(Shrew::PageView).to receive(:find_by).and_return(nil)
28
+
29
+ post :create, required_params
30
+
31
+ expect(response.status).to eq 200
32
+ expect(response.body).to eq '[]'
33
+ end
34
+ end
35
+
36
+ context 'when successful' do
37
+ let(:page_view) { Shrew::PageView.new }
38
+ before(:each) do
39
+ expect(Shrew::PageView).to receive(:find_by).and_return(page_view)
40
+ expect(page_view).to receive(:save).and_return(true)
41
+ end
42
+
43
+ it 'updates the page view with the js return time' do
44
+ post :create, required_params
45
+
46
+ expect(page_view.js_return_time).to eq 100
47
+ end
48
+
49
+ it 'returns a 200 empty response' do
50
+ post :create, required_params
51
+
52
+ expect(response.status).to eq 200
53
+ expect(response.body).to eq '[]'
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,34 @@
1
+ require 'rails_helper'
2
+
3
+ class ApplicationController < ActionController::Base
4
+ include Shrew::TracksPageViews
5
+ end
6
+
7
+ RSpec.describe ApplicationController do
8
+ controller do
9
+ def current_user
10
+ {}
11
+ end
12
+ def index
13
+ render json: 'ok'
14
+ end
15
+ end
16
+
17
+ describe Shrew::TracksPageViews do
18
+ it 'adds the js tracking id to be used in the layout' do
19
+ get :index
20
+ expect(assigns(:_js_tracking_id)).not_to eq nil
21
+ end
22
+
23
+ it 'sets that we are going to track page views to append to payload' do
24
+ get :index
25
+ expect(assigns(:_tracking_page_views)).to eq true
26
+ end
27
+
28
+ it 'creates the initial page view' do
29
+ expect {
30
+ get :index
31
+ }.to change{Shrew::PageView.count}.by(1)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require 'spec_helper'
4
+ require File.expand_path("../../test/dummy/config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+ # Add additional requires below this line. Rails is not loaded until this point!
7
+
8
+ # Requires supporting ruby files with custom matchers and macros, etc, in
9
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
10
+ # run as spec files by default. This means that files in spec/support that end
11
+ # in _spec.rb will both be required and run as specs, causing the specs to be
12
+ # run twice. It is recommended that you do not name files matching this glob to
13
+ # end with _spec.rb. You can configure this pattern with the --pattern
14
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
15
+ #
16
+ # The following line is provided for convenience purposes. It has the downside
17
+ # of increasing the boot-up time by auto-requiring all files in the support
18
+ # directory. Alternatively, in the individual `*_spec.rb` files, manually
19
+ # require only the support files necessary.
20
+ #
21
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
22
+
23
+ # Checks for pending migrations before tests are run.
24
+ # If you are not using ActiveRecord, you can remove this line.
25
+ ActiveRecord::Migration.maintain_test_schema!
26
+
27
+ RSpec.configure do |config|
28
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
29
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
30
+
31
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
32
+ # examples within a transaction, remove the following line or assign false
33
+ # instead of true.
34
+ config.use_transactional_fixtures = false
35
+
36
+ # RSpec Rails can automatically mix in different behaviours to your tests
37
+ # based on their file location, for example enabling you to call `get` and
38
+ # `post` in specs under `spec/controllers`.
39
+ #
40
+ # You can disable this behaviour by removing the line below, and instead
41
+ # explicitly tag your specs with their type, e.g.:
42
+ #
43
+ # RSpec.describe UsersController, :type => :controller do
44
+ # # ...
45
+ # end
46
+ #
47
+ # The different available types are documented in the features, such as in
48
+ # https://relishapp.com/rspec/rspec-rails/docs
49
+ config.infer_spec_type_from_file_location!
50
+ end