shrew 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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