mixpal 0.1.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +1 -0
- data/.travis.yml +5 -3
- data/Dockerfile +6 -0
- data/README.md +45 -1
- data/Rakefile +3 -1
- data/docker-compose.yml +14 -0
- data/lib/mixpal.rb +20 -0
- data/lib/mixpal/integration.rb +6 -2
- data/lib/mixpal/revenue.rb +32 -0
- data/lib/mixpal/tracker.rb +18 -4
- data/lib/mixpal/version.rb +1 -1
- data/mixpanel_assistant.gemspec +8 -8
- data/spec/lib/mixpal/event_spec.rb +1 -1
- data/spec/lib/mixpal/revenue_spec.rb +60 -0
- data/spec/lib/mixpal/tracker_spec.rb +66 -16
- data/spec/lib/mixpal/user_spec.rb +1 -1
- data/spec/lib/mixpal_spec.rb +11 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/support/custom_events_module.rb +5 -0
- data/test_app/.gitignore +2 -0
- metadata +53 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b8c9c74b1185daabd7b04ce5ac8865084eeaa8ca222c342c12ace6e4d1c444cd
|
4
|
+
data.tar.gz: 82a07a359fe377bd2dbf60e95f9eb20d79afb764a4c50219846e529c981e271a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9dcceef2cf2269fc79e6c45675702ecc7e568c7340dedc62d45d358d15ff52c87a2c15d257d986bae53004d7c78a305706912f590448877d29622fc0a0f1df36
|
7
|
+
data.tar.gz: a989eb95e2e2ac576379e4bcc63d161f1d8815774f8ee1a079e735a42da24ed3e7e6dbc42547a285263c4bc5c5642a660de2f5dac8881249d5b5d33bae93baa5
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/Dockerfile
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Mixpal [![Build Status](https://travis-ci.org/
|
1
|
+
# Mixpal [![Build Status](https://travis-ci.org/philosophie/mixpal.svg?branch=master)](https://travis-ci.org/philosophie/mixpal)
|
2
2
|
|
3
3
|
As the JavaScript library is Mixpanel's preferred method of usage,
|
4
4
|
Mixpal aims to make it easier to work with from your Rails backend.
|
@@ -78,6 +78,38 @@ mixpanel.update_user email: "mynewemail@example.com"
|
|
78
78
|
|
79
79
|
As with `register_user`, this method will also identify "special properties".
|
80
80
|
|
81
|
+
### Custom Events
|
82
|
+
|
83
|
+
Mixpal allows you to define custom mixpal methods to use in your controllers/views
|
84
|
+
|
85
|
+
1. create a custom module and define your mixpal events
|
86
|
+
```ruby
|
87
|
+
module YourCustomEventsModule
|
88
|
+
def sign_up(user)
|
89
|
+
register_user user.attributes.slice('name', 'email')
|
90
|
+
track 'User signed up'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
2. create a mixpal.rb initializer and configure mixpal to use your module
|
96
|
+
```ruby
|
97
|
+
Mixpal.configure do |config|
|
98
|
+
config.helper_module = YourCustomEventsModule
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
3. use in controllers/views
|
103
|
+
```ruby
|
104
|
+
class UserController < ActionController::Base
|
105
|
+
def create
|
106
|
+
# ... do cool stuff ...
|
107
|
+
mixpal.sign_up(user)
|
108
|
+
redirect_to root_path
|
109
|
+
end
|
110
|
+
end
|
111
|
+
```
|
112
|
+
|
81
113
|
### Persistance Across Redirects
|
82
114
|
|
83
115
|
Mixpal stores any tracked events or user data in the session when
|
@@ -120,3 +152,15 @@ If you anticipate tracking many events or large data sets to Mixpal,
|
|
120
152
|
1. Commit your changes (`git commit -am 'Add some feature'`)
|
121
153
|
1. Push to the branch (`git push origin feature/my-new-feature`)
|
122
154
|
1. Create new Pull Request
|
155
|
+
|
156
|
+
## Releasing
|
157
|
+
|
158
|
+
Bump `lib/mixpal/version.rb` then build + release with docker-compose. If you
|
159
|
+
prefer local development, inspect the Dockerfile to get your local env built.
|
160
|
+
|
161
|
+
```
|
162
|
+
docker-compose build \
|
163
|
+
--build-arg USER_ID=$(id -u) \
|
164
|
+
--build-arg GROUP_ID=$(id -g)
|
165
|
+
docker-compose run rake release
|
166
|
+
```
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
require 'rspec/core/rake_task'
|
3
5
|
require 'rubocop/rake_task'
|
@@ -5,4 +7,4 @@ require 'rubocop/rake_task'
|
|
5
7
|
RSpec::Core::RakeTask.new(:spec)
|
6
8
|
RuboCop::RakeTask.new
|
7
9
|
|
8
|
-
task default: [
|
10
|
+
task default: %i[spec rubocop]
|
data/docker-compose.yml
ADDED
data/lib/mixpal.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mixpal/version'
|
2
|
+
require 'active_support'
|
2
3
|
require 'active_support/core_ext'
|
3
4
|
|
4
5
|
module Mixpal
|
@@ -6,5 +7,24 @@ module Mixpal
|
|
6
7
|
autoload :Tracker, 'mixpal/tracker'
|
7
8
|
autoload :Event, 'mixpal/event'
|
8
9
|
autoload :User, 'mixpal/user'
|
10
|
+
autoload :Revenue, 'mixpal/revenue'
|
9
11
|
autoload :Integration, 'mixpal/integration'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def configuration
|
15
|
+
@configuration ||= Configuration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield(configuration)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Configuration
|
24
|
+
attr_writer :helper_module
|
25
|
+
|
26
|
+
def helper_module
|
27
|
+
@helper_module ||= Module.new
|
28
|
+
end
|
29
|
+
end
|
10
30
|
end
|
data/lib/mixpal/integration.rb
CHANGED
@@ -4,7 +4,11 @@ module Mixpal
|
|
4
4
|
|
5
5
|
included do
|
6
6
|
helper_method :mixpanel
|
7
|
-
|
7
|
+
if Rails::VERSION::MAJOR >= 4
|
8
|
+
after_action :store_mixpanel_if_redirecting
|
9
|
+
else
|
10
|
+
after_filter :store_mixpanel_if_redirecting
|
11
|
+
end
|
8
12
|
|
9
13
|
class_attribute :mixpanel_identity_data
|
10
14
|
def self.mixpanel_identity(object_method, attribute_method)
|
@@ -28,7 +32,7 @@ module Mixpal
|
|
28
32
|
private
|
29
33
|
|
30
34
|
def store_mixpanel_if_redirecting
|
31
|
-
mixpanel.store!(session) if status
|
35
|
+
mixpanel.store!(session) if (300..399).cover?(status)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Mixpal
|
2
|
+
class Revenue
|
3
|
+
attr_reader :amount, :properties
|
4
|
+
|
5
|
+
def initialize(amount, properties)
|
6
|
+
@amount = amount
|
7
|
+
@properties = properties
|
8
|
+
end
|
9
|
+
|
10
|
+
def render
|
11
|
+
args = "#{amount}, #{properties_as_js_object_for_mixpanel}"
|
12
|
+
"mixpanel.people.track_charge(#{args});".html_safe
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_store
|
16
|
+
{
|
17
|
+
'amount' => amount,
|
18
|
+
'properties' => properties
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.from_store(data)
|
23
|
+
new(data['amount'], data['properties'])
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def properties_as_js_object_for_mixpanel
|
29
|
+
Mixpal::Util.hash_to_js_object_string(properties)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/mixpal/tracker.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
module Mixpal
|
2
2
|
class Tracker
|
3
|
-
attr_reader :events, :user_updates, :identity, :alias_user
|
3
|
+
attr_reader :events, :user_updates, :revenue_updates, :identity, :alias_user
|
4
4
|
|
5
5
|
STORAGE_KEY = 'mixpal'
|
6
6
|
|
7
7
|
def initialize(args = {})
|
8
|
+
extend Mixpal.configuration.helper_module
|
9
|
+
|
8
10
|
@events = []
|
9
11
|
@user_updates = []
|
12
|
+
@revenue_updates = []
|
10
13
|
|
11
14
|
@identity = args[:identity]
|
12
15
|
end
|
@@ -24,6 +27,10 @@ module Mixpal
|
|
24
27
|
events << Mixpal::Event.new(name, properties)
|
25
28
|
end
|
26
29
|
|
30
|
+
def track_charge(amount, properties = {})
|
31
|
+
revenue_updates << Mixpal::Revenue.new(amount, properties)
|
32
|
+
end
|
33
|
+
|
27
34
|
def render
|
28
35
|
''.tap do |html|
|
29
36
|
html << '<script type="text/javascript">'
|
@@ -31,6 +38,7 @@ module Mixpal
|
|
31
38
|
html << "mixpanel.identify(\"#{identity}\");" if identity
|
32
39
|
html << events.map(&:render).join('')
|
33
40
|
html << user_updates.map(&:render).join('')
|
41
|
+
html << revenue_updates.map(&:render).join('')
|
34
42
|
html << '</script>'
|
35
43
|
end.html_safe
|
36
44
|
end
|
@@ -50,8 +58,13 @@ module Mixpal
|
|
50
58
|
end
|
51
59
|
|
52
60
|
if data['user_updates']
|
53
|
-
@user_updates =
|
54
|
-
.map { |u| Mixpal::User.from_store(u) }
|
61
|
+
@user_updates =
|
62
|
+
data['user_updates'].map { |u| Mixpal::User.from_store(u) }
|
63
|
+
end
|
64
|
+
|
65
|
+
if data['revenue_updates']
|
66
|
+
@revenue_updates =
|
67
|
+
data['revenue_updates'].map { |u| Mixpal::Revenue.from_store(u) }
|
55
68
|
end
|
56
69
|
|
57
70
|
session.delete(STORAGE_KEY)
|
@@ -64,7 +77,8 @@ module Mixpal
|
|
64
77
|
'alias_user' => alias_user,
|
65
78
|
'identity' => identity,
|
66
79
|
'events' => events.map(&:to_store),
|
67
|
-
'user_updates' => user_updates.map(&:to_store)
|
80
|
+
'user_updates' => user_updates.map(&:to_store),
|
81
|
+
'revenue_updates' => revenue_updates.map(&:to_store)
|
68
82
|
}
|
69
83
|
end
|
70
84
|
end
|
data/lib/mixpal/version.rb
CHANGED
data/mixpanel_assistant.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'mixpal/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "mixpal"
|
8
8
|
spec.version = Mixpal::VERSION
|
9
|
-
spec.authors = ["patbenatar"]
|
9
|
+
spec.authors = ["patbenatar", "mikehmorrissey"]
|
10
10
|
spec.email = ["nick@gophilosophie.com"]
|
11
11
|
spec.description = "Use Mixpanel's JavaScript library from your backend with ease"
|
12
12
|
spec.summary = "As the JavaScript library is Mixpanel's preferred method of usage, Mixpal aims to make it easier to work with from your Rails backend. Most notably it persists tracking data across redirects, perfect for handling events like user sign ups or form submissions."
|
@@ -18,15 +18,15 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~>
|
21
|
+
spec.add_development_dependency "bundler", "~> 2"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "pry"
|
24
|
-
spec.add_development_dependency "rubocop", "~> 0.
|
25
|
-
spec.add_development_dependency "rspec", "~>
|
26
|
-
spec.add_development_dependency "guard-rspec", "~>
|
27
|
-
spec.add_development_dependency "rb-fsevent", "~> 0.
|
28
|
-
spec.add_development_dependency "awesome_print", "~> 1.
|
29
|
-
spec.add_development_dependency "nokogiri", "~> 1
|
24
|
+
spec.add_development_dependency "rubocop", "~> 0.91.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.9.0"
|
26
|
+
spec.add_development_dependency "guard-rspec", "~> 4.7.3"
|
27
|
+
spec.add_development_dependency "rb-fsevent", "~> 0.10.4"
|
28
|
+
spec.add_development_dependency "awesome_print", "~> 1.8.0"
|
29
|
+
spec.add_development_dependency "nokogiri", "~> 1"
|
30
30
|
|
31
31
|
spec.add_development_dependency "actionpack", ">= 3.0"
|
32
32
|
|
@@ -7,7 +7,7 @@ describe Mixpal::Event do
|
|
7
7
|
|
8
8
|
describe '#render' do
|
9
9
|
it 'delegates to Util for js_object composition' do
|
10
|
-
Mixpal::Util.
|
10
|
+
expect(Mixpal::Util).to receive(:hash_to_js_object_string).with(properties)
|
11
11
|
subject.render
|
12
12
|
end
|
13
13
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mixpal::Revenue do
|
4
|
+
let(:properties) do
|
5
|
+
{
|
6
|
+
sku: 'SKU-1010'
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:amount) { 50 }
|
11
|
+
|
12
|
+
let(:subject) { described_class.new(amount, properties) }
|
13
|
+
|
14
|
+
describe '#render' do
|
15
|
+
it 'delegates to Util for js_object composition' do
|
16
|
+
expect(Mixpal::Util).to receive(:hash_to_js_object_string).with(properties)
|
17
|
+
subject.render
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'outputs a call to people.track_charge' do
|
21
|
+
js_object = Mixpal::Util.hash_to_js_object_string(properties)
|
22
|
+
expect(subject.render)
|
23
|
+
.to eq "mixpanel.people.track_charge(#{amount}, #{js_object});"
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'outputs an html safe string' do
|
27
|
+
expect(subject.render).to be_html_safe
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#to_store' do
|
32
|
+
it 'returns a hash with its data' do
|
33
|
+
expect(subject.to_store).to eq(
|
34
|
+
'amount' => amount,
|
35
|
+
'properties' => properties
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#from_store' do
|
41
|
+
let(:result) do
|
42
|
+
described_class.from_store(
|
43
|
+
'amount' => amount,
|
44
|
+
'properties' => properties
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'instantiates a new instance' do
|
49
|
+
expect(result).to be_an_instance_of(described_class)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'sets its amount from the data' do
|
53
|
+
expect(result.amount).to eq amount
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'sets its properties from the data' do
|
57
|
+
expect(result.properties).to eq properties
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -5,6 +5,18 @@ describe Mixpal::Tracker do
|
|
5
5
|
let(:identity) { 'nick' }
|
6
6
|
let(:subject_with_identity) { Mixpal::Tracker.new(identity: identity) }
|
7
7
|
|
8
|
+
context 'with configured helper module' do
|
9
|
+
before do
|
10
|
+
Mixpal.configure do |config|
|
11
|
+
config.helper_module = CustomEventsModule
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'exposes helper module methods on tracker instance' do
|
16
|
+
expect(subject.custom_event).to eq true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
8
20
|
describe '#initialize' do
|
9
21
|
it 'creates an empty set of events' do
|
10
22
|
expect(subject.events).to eq []
|
@@ -14,6 +26,10 @@ describe Mixpal::Tracker do
|
|
14
26
|
expect(subject.user_updates).to eq []
|
15
27
|
end
|
16
28
|
|
29
|
+
it 'creates an empty set of revenue_updates' do
|
30
|
+
expect(subject.revenue_updates).to eq []
|
31
|
+
end
|
32
|
+
|
17
33
|
context 'with an :identity arg' do
|
18
34
|
subject { subject_with_identity }
|
19
35
|
|
@@ -26,12 +42,12 @@ describe Mixpal::Tracker do
|
|
26
42
|
describe '#register_user' do
|
27
43
|
it 'sets the alias_user flag so we render the alias call' do
|
28
44
|
subject.register_user(name: 'Nick')
|
29
|
-
expect(subject.alias_user).to
|
45
|
+
expect(subject.alias_user).to be true
|
30
46
|
end
|
31
47
|
|
32
48
|
it 'delegates to #update_user for tracking user properties' do
|
33
49
|
properties = { name: 'Nick' }
|
34
|
-
subject.
|
50
|
+
expect(subject).to receive(:update_user).with(properties)
|
35
51
|
subject.register_user(properties)
|
36
52
|
end
|
37
53
|
end
|
@@ -39,7 +55,7 @@ describe Mixpal::Tracker do
|
|
39
55
|
describe '#update_user' do
|
40
56
|
it 'instantiates a new User object with properties' do
|
41
57
|
properties = { name: 'Nick' }
|
42
|
-
Mixpal::User.
|
58
|
+
expect(Mixpal::User).to receive(:new).with(properties)
|
43
59
|
subject.update_user(properties)
|
44
60
|
end
|
45
61
|
|
@@ -48,7 +64,7 @@ describe Mixpal::Tracker do
|
|
48
64
|
subject.update_user(name: 'Nick')
|
49
65
|
end.to change(subject.user_updates, :size).by(1)
|
50
66
|
|
51
|
-
subject.user_updates.first.
|
67
|
+
expect(subject.user_updates.first).to be_an_instance_of(Mixpal::User)
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
@@ -57,7 +73,7 @@ describe Mixpal::Tracker do
|
|
57
73
|
name = 'Clicked Button'
|
58
74
|
properties = { color: 'Green' }
|
59
75
|
|
60
|
-
Mixpal::Event.
|
76
|
+
expect(Mixpal::Event).to receive(:new).with(name, properties)
|
61
77
|
subject.track(name, properties)
|
62
78
|
end
|
63
79
|
|
@@ -66,7 +82,23 @@ describe Mixpal::Tracker do
|
|
66
82
|
subject.track('Clicked Button', color: 'Green')
|
67
83
|
end.to change(subject.events, :size).by(1)
|
68
84
|
|
69
|
-
subject.events.first.
|
85
|
+
expect(subject.events.first).to be_an_instance_of(Mixpal::Event)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#track_charge' do
|
90
|
+
it 'instantiates a new Revenue object with properties' do
|
91
|
+
properties = { sku: 'SKU-1010' }
|
92
|
+
expect(Mixpal::Revenue).to receive(:new).with(50, properties)
|
93
|
+
subject.track_charge(50, properties)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'adds the Revenue to revenue_updates for rendering later' do
|
97
|
+
expect do
|
98
|
+
subject.track_charge(50, sku: 'SKU-1010')
|
99
|
+
end.to change(subject.revenue_updates, :size).by(1)
|
100
|
+
|
101
|
+
expect(subject.revenue_updates.first).to be_an_instance_of(Mixpal::Revenue)
|
70
102
|
end
|
71
103
|
end
|
72
104
|
|
@@ -114,7 +146,7 @@ describe Mixpal::Tracker do
|
|
114
146
|
end
|
115
147
|
|
116
148
|
it 'delegates render to the events' do
|
117
|
-
subject.events.each { |event| event.
|
149
|
+
subject.events.each { |event| expect(event).to receive :render }
|
118
150
|
subject.render
|
119
151
|
end
|
120
152
|
|
@@ -131,7 +163,7 @@ describe Mixpal::Tracker do
|
|
131
163
|
end
|
132
164
|
|
133
165
|
it 'delegates render to the users' do
|
134
|
-
subject.user_updates.each { |user| user.
|
166
|
+
subject.user_updates.each { |user| expect(user).to receive :render }
|
135
167
|
subject.render
|
136
168
|
end
|
137
169
|
|
@@ -140,24 +172,42 @@ describe Mixpal::Tracker do
|
|
140
172
|
expect(subject.render).to include joined
|
141
173
|
end
|
142
174
|
end
|
175
|
+
|
176
|
+
context 'with revenue' do
|
177
|
+
before do
|
178
|
+
subject.track_charge(50)
|
179
|
+
subject.track_charge(100, sku: 'SKU-1010')
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'delegates render to the revenues' do
|
183
|
+
subject.revenue_updates.each { |r| expect(r).to receive :render }
|
184
|
+
subject.render
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'joins each rendered revenue' do
|
188
|
+
joined =
|
189
|
+
subject.revenue_updates[0].render + subject.revenue_updates[1].render
|
190
|
+
expect(subject.render).to include joined
|
191
|
+
end
|
192
|
+
end
|
143
193
|
end
|
144
194
|
|
145
195
|
describe '#store!' do
|
146
196
|
let(:session) { {} }
|
147
197
|
|
148
|
-
def
|
198
|
+
def expect_storage_to_include(hash_fragment)
|
149
199
|
expect(session[described_class::STORAGE_KEY]).to include hash_fragment
|
150
200
|
end
|
151
201
|
|
152
202
|
it 'stores the alias_user property' do
|
153
203
|
subject.register_user({})
|
154
204
|
subject.store!(session)
|
155
|
-
|
205
|
+
expect_storage_to_include('alias_user' => true)
|
156
206
|
end
|
157
207
|
|
158
208
|
it 'stores the identity' do
|
159
209
|
subject_with_identity.store!(session)
|
160
|
-
|
210
|
+
expect_storage_to_include('identity' => identity)
|
161
211
|
end
|
162
212
|
|
163
213
|
context 'when events have been tracked' do
|
@@ -167,13 +217,13 @@ describe Mixpal::Tracker do
|
|
167
217
|
end
|
168
218
|
|
169
219
|
it 'delegates composition to the events' do
|
170
|
-
subject.events.each { |event| event.
|
220
|
+
subject.events.each { |event| expect(event).to receive :to_store }
|
171
221
|
subject.store!(session)
|
172
222
|
end
|
173
223
|
|
174
224
|
it 'stores the events composed hashes in an array' do
|
175
225
|
subject.store!(session)
|
176
|
-
|
226
|
+
expect_storage_to_include(
|
177
227
|
'events' => [subject.events[0].to_store, subject.events[1].to_store]
|
178
228
|
)
|
179
229
|
end
|
@@ -186,14 +236,14 @@ describe Mixpal::Tracker do
|
|
186
236
|
end
|
187
237
|
|
188
238
|
it 'delegates composition to the users' do
|
189
|
-
subject.user_updates.each { |user| user.
|
239
|
+
subject.user_updates.each { |user| expect(user).to receive :to_store }
|
190
240
|
subject.store!(session)
|
191
241
|
end
|
192
242
|
|
193
243
|
it 'stores the users composed hashes in an array' do
|
194
244
|
subject.store!(session)
|
195
245
|
|
196
|
-
|
246
|
+
expect_storage_to_include(
|
197
247
|
'user_updates' => [
|
198
248
|
subject.user_updates[0].to_store,
|
199
249
|
subject.user_updates[1].to_store
|
@@ -224,7 +274,7 @@ describe Mixpal::Tracker do
|
|
224
274
|
end
|
225
275
|
|
226
276
|
it 'delegates event restoration to the Event class' do
|
227
|
-
Mixpal::Event.
|
277
|
+
expect(Mixpal::Event).to receive(:from_store)
|
228
278
|
.with(old_tracker.events.first.to_store)
|
229
279
|
|
230
280
|
subject.restore!(session)
|
@@ -12,7 +12,7 @@ describe Mixpal::User do
|
|
12
12
|
|
13
13
|
describe '#render' do
|
14
14
|
it 'delegates to Util for js_object composition' do
|
15
|
-
Mixpal::Util.
|
15
|
+
expect(Mixpal::Util).to receive(:hash_to_js_object_string).with(properties)
|
16
16
|
subject.render
|
17
17
|
end
|
18
18
|
|
data/spec/lib/mixpal_spec.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mixpal do
|
4
|
+
describe '#configure' do
|
5
|
+
before do
|
6
|
+
Mixpal.configure do |config|
|
7
|
+
config.helper_module = CustomEventsModule
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'allows a helper module to be set on Mixpal.configuration' do
|
12
|
+
expect(Mixpal.configuration.helper_module).to be(CustomEventsModule)
|
13
|
+
end
|
14
|
+
end
|
4
15
|
end
|
data/spec/spec_helper.rb
CHANGED
data/test_app/.gitignore
CHANGED
metadata
CHANGED
@@ -1,167 +1,168 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixpal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- patbenatar
|
8
|
+
- mikehmorrissey
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-05-03 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - ~>
|
18
|
+
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '2'
|
20
21
|
type: :development
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - ~>
|
25
|
+
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
+
version: '2'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: rake
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- -
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '0'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- -
|
39
|
+
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '0'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
43
|
name: pry
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
|
-
- -
|
46
|
+
- - ">="
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '0'
|
48
49
|
type: :development
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
|
-
- -
|
53
|
+
- - ">="
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: '0'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: rubocop
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- - ~>
|
60
|
+
- - "~>"
|
60
61
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
62
|
+
version: 0.91.0
|
62
63
|
type: :development
|
63
64
|
prerelease: false
|
64
65
|
version_requirements: !ruby/object:Gem::Requirement
|
65
66
|
requirements:
|
66
|
-
- - ~>
|
67
|
+
- - "~>"
|
67
68
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
69
|
+
version: 0.91.0
|
69
70
|
- !ruby/object:Gem::Dependency
|
70
71
|
name: rspec
|
71
72
|
requirement: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
|
-
- - ~>
|
74
|
+
- - "~>"
|
74
75
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
76
|
+
version: 3.9.0
|
76
77
|
type: :development
|
77
78
|
prerelease: false
|
78
79
|
version_requirements: !ruby/object:Gem::Requirement
|
79
80
|
requirements:
|
80
|
-
- - ~>
|
81
|
+
- - "~>"
|
81
82
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
+
version: 3.9.0
|
83
84
|
- !ruby/object:Gem::Dependency
|
84
85
|
name: guard-rspec
|
85
86
|
requirement: !ruby/object:Gem::Requirement
|
86
87
|
requirements:
|
87
|
-
- - ~>
|
88
|
+
- - "~>"
|
88
89
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
90
|
+
version: 4.7.3
|
90
91
|
type: :development
|
91
92
|
prerelease: false
|
92
93
|
version_requirements: !ruby/object:Gem::Requirement
|
93
94
|
requirements:
|
94
|
-
- - ~>
|
95
|
+
- - "~>"
|
95
96
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
97
|
+
version: 4.7.3
|
97
98
|
- !ruby/object:Gem::Dependency
|
98
99
|
name: rb-fsevent
|
99
100
|
requirement: !ruby/object:Gem::Requirement
|
100
101
|
requirements:
|
101
|
-
- - ~>
|
102
|
+
- - "~>"
|
102
103
|
- !ruby/object:Gem::Version
|
103
|
-
version: 0.
|
104
|
+
version: 0.10.4
|
104
105
|
type: :development
|
105
106
|
prerelease: false
|
106
107
|
version_requirements: !ruby/object:Gem::Requirement
|
107
108
|
requirements:
|
108
|
-
- - ~>
|
109
|
+
- - "~>"
|
109
110
|
- !ruby/object:Gem::Version
|
110
|
-
version: 0.
|
111
|
+
version: 0.10.4
|
111
112
|
- !ruby/object:Gem::Dependency
|
112
113
|
name: awesome_print
|
113
114
|
requirement: !ruby/object:Gem::Requirement
|
114
115
|
requirements:
|
115
|
-
- - ~>
|
116
|
+
- - "~>"
|
116
117
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.
|
118
|
+
version: 1.8.0
|
118
119
|
type: :development
|
119
120
|
prerelease: false
|
120
121
|
version_requirements: !ruby/object:Gem::Requirement
|
121
122
|
requirements:
|
122
|
-
- - ~>
|
123
|
+
- - "~>"
|
123
124
|
- !ruby/object:Gem::Version
|
124
|
-
version: 1.
|
125
|
+
version: 1.8.0
|
125
126
|
- !ruby/object:Gem::Dependency
|
126
127
|
name: nokogiri
|
127
128
|
requirement: !ruby/object:Gem::Requirement
|
128
129
|
requirements:
|
129
|
-
- - ~>
|
130
|
+
- - "~>"
|
130
131
|
- !ruby/object:Gem::Version
|
131
|
-
version: 1
|
132
|
+
version: '1'
|
132
133
|
type: :development
|
133
134
|
prerelease: false
|
134
135
|
version_requirements: !ruby/object:Gem::Requirement
|
135
136
|
requirements:
|
136
|
-
- - ~>
|
137
|
+
- - "~>"
|
137
138
|
- !ruby/object:Gem::Version
|
138
|
-
version: 1
|
139
|
+
version: '1'
|
139
140
|
- !ruby/object:Gem::Dependency
|
140
141
|
name: actionpack
|
141
142
|
requirement: !ruby/object:Gem::Requirement
|
142
143
|
requirements:
|
143
|
-
- -
|
144
|
+
- - ">="
|
144
145
|
- !ruby/object:Gem::Version
|
145
146
|
version: '3.0'
|
146
147
|
type: :development
|
147
148
|
prerelease: false
|
148
149
|
version_requirements: !ruby/object:Gem::Requirement
|
149
150
|
requirements:
|
150
|
-
- -
|
151
|
+
- - ">="
|
151
152
|
- !ruby/object:Gem::Version
|
152
153
|
version: '3.0'
|
153
154
|
- !ruby/object:Gem::Dependency
|
154
155
|
name: activesupport
|
155
156
|
requirement: !ruby/object:Gem::Requirement
|
156
157
|
requirements:
|
157
|
-
- -
|
158
|
+
- - ">="
|
158
159
|
- !ruby/object:Gem::Version
|
159
160
|
version: '3.0'
|
160
161
|
type: :runtime
|
161
162
|
prerelease: false
|
162
163
|
version_requirements: !ruby/object:Gem::Requirement
|
163
164
|
requirements:
|
164
|
-
- -
|
165
|
+
- - ">="
|
165
166
|
- !ruby/object:Gem::Version
|
166
167
|
version: '3.0'
|
167
168
|
description: Use Mixpanel's JavaScript library from your backend with ease
|
@@ -171,29 +172,34 @@ executables: []
|
|
171
172
|
extensions: []
|
172
173
|
extra_rdoc_files: []
|
173
174
|
files:
|
174
|
-
- .gitignore
|
175
|
-
- .rspec
|
176
|
-
- .rubocop.yml
|
177
|
-
- .travis.yml
|
175
|
+
- ".gitignore"
|
176
|
+
- ".rspec"
|
177
|
+
- ".rubocop.yml"
|
178
|
+
- ".travis.yml"
|
179
|
+
- Dockerfile
|
178
180
|
- Gemfile
|
179
181
|
- Guardfile
|
180
182
|
- LICENSE.txt
|
181
183
|
- README.md
|
182
184
|
- Rakefile
|
185
|
+
- docker-compose.yml
|
183
186
|
- lib/mixpal.rb
|
184
187
|
- lib/mixpal/event.rb
|
185
188
|
- lib/mixpal/integration.rb
|
189
|
+
- lib/mixpal/revenue.rb
|
186
190
|
- lib/mixpal/tracker.rb
|
187
191
|
- lib/mixpal/user.rb
|
188
192
|
- lib/mixpal/util.rb
|
189
193
|
- lib/mixpal/version.rb
|
190
194
|
- mixpanel_assistant.gemspec
|
191
195
|
- spec/lib/mixpal/event_spec.rb
|
196
|
+
- spec/lib/mixpal/revenue_spec.rb
|
192
197
|
- spec/lib/mixpal/tracker_spec.rb
|
193
198
|
- spec/lib/mixpal/user_spec.rb
|
194
199
|
- spec/lib/mixpal/util_spec.rb
|
195
200
|
- spec/lib/mixpal_spec.rb
|
196
201
|
- spec/spec_helper.rb
|
202
|
+
- spec/support/custom_events_module.rb
|
197
203
|
- spec/support/matchers/element_matchers.rb
|
198
204
|
- test_app/.gitignore
|
199
205
|
- test_app/Gemfile
|
@@ -254,17 +260,16 @@ require_paths:
|
|
254
260
|
- lib
|
255
261
|
required_ruby_version: !ruby/object:Gem::Requirement
|
256
262
|
requirements:
|
257
|
-
- -
|
263
|
+
- - ">="
|
258
264
|
- !ruby/object:Gem::Version
|
259
265
|
version: '0'
|
260
266
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
261
267
|
requirements:
|
262
|
-
- -
|
268
|
+
- - ">="
|
263
269
|
- !ruby/object:Gem::Version
|
264
270
|
version: '0'
|
265
271
|
requirements: []
|
266
|
-
|
267
|
-
rubygems_version: 2.0.3
|
272
|
+
rubygems_version: 3.1.2
|
268
273
|
signing_key:
|
269
274
|
specification_version: 4
|
270
275
|
summary: As the JavaScript library is Mixpanel's preferred method of usage, Mixpal
|
@@ -273,9 +278,11 @@ summary: As the JavaScript library is Mixpanel's preferred method of usage, Mixp
|
|
273
278
|
form submissions.
|
274
279
|
test_files:
|
275
280
|
- spec/lib/mixpal/event_spec.rb
|
281
|
+
- spec/lib/mixpal/revenue_spec.rb
|
276
282
|
- spec/lib/mixpal/tracker_spec.rb
|
277
283
|
- spec/lib/mixpal/user_spec.rb
|
278
284
|
- spec/lib/mixpal/util_spec.rb
|
279
285
|
- spec/lib/mixpal_spec.rb
|
280
286
|
- spec/spec_helper.rb
|
287
|
+
- spec/support/custom_events_module.rb
|
281
288
|
- spec/support/matchers/element_matchers.rb
|