mixpanel-ruby 0.3.2 → 1.0.0

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.
data/Readme.rdoc CHANGED
@@ -11,12 +11,12 @@ get started sending your first events and updates:
11
11
  == Getting Started
12
12
 
13
13
  require 'mixpanel-ruby'
14
-
14
+
15
15
  tracker = Mixpanel::Tracker.new(YOUR_TOKEN)
16
-
16
+
17
17
  # Track an event on behalf of user "User1"
18
18
  tracker.track('User1', 'A Mixpanel Event')
19
-
19
+
20
20
  # Send an update to User1's profile
21
21
  tracker.people.set('User1', {
22
22
  '$first_name' => 'David',
@@ -34,5 +34,11 @@ For more information please visit:
34
34
 
35
35
  * Our Ruby API Integration page[https://mixpanel.com/help/reference/ruby#introduction]
36
36
  * The usage demo[https://github.com/mixpanel/mixpanel-ruby/tree/master/demo]
37
- * The docuemntation[http://mixpanel.github.io/mixpanel-ruby/]
37
+ * The documentation[http://mixpanel.github.io/mixpanel-ruby/]
38
+
39
+ == Changes
38
40
 
41
+ === 1.0.0 (Proposed)
42
+ * tracker#import added
43
+ * Change to internal tracking message format. Messages written
44
+ by earlier versions of the library will not work with 1.0.0 consumer classes.
@@ -34,7 +34,7 @@ module Mixpanel
34
34
  # the tracker, or just passing a block to Mixpanel::Tracker.new
35
35
  #
36
36
  # tracker = Mixpanel::Tracker.new(MY_TOKEN) do |type, message|
37
- # # type will be one of :event or :profile_update
37
+ # # type will be one of :event, :profile_update or :import
38
38
  # @kestrel.set(ANALYTICS_QUEUE, [ type, message ].to_json)
39
39
  # end
40
40
  #
@@ -56,13 +56,14 @@ module Mixpanel
56
56
  # they will be used instead of the default Mixpanel endpoints.
57
57
  # This can be useful for proxying, debugging, or if you prefer
58
58
  # not to use SSL for your events.
59
- def initialize(events_endpoint=nil, update_endpoint=nil)
59
+ def initialize(events_endpoint=nil, update_endpoint=nil, import_endpoint=nil)
60
60
  @events_endpoint = events_endpoint || 'https://api.mixpanel.com/track'
61
61
  @update_endpoint = update_endpoint || 'https://api.mixpanel.com/engage'
62
+ @import_endpoint = import_endpoint || 'https://api.mixpanel.com/import'
62
63
  end
63
64
 
64
65
  # Send the given string message to Mixpanel. Type should be
65
- # one of :event or :profile_update, which will determine the endpoint.
66
+ # one of :event, :profile_update or :import, which will determine the endpoint.
66
67
  #
67
68
  # Mixpanel::Consumer#send sends messages to Mixpanel immediately on
68
69
  # each call. To reduce the overall bandwidth you use when communicating
@@ -72,16 +73,22 @@ module Mixpanel
72
73
  endpoint = {
73
74
  :event => @events_endpoint,
74
75
  :profile_update => @update_endpoint,
76
+ :import => @import_endpoint
75
77
  }[ type ]
76
- data = Base64.strict_encode64(message)
78
+
79
+ decoded_message = JSON.load(message)
80
+ api_key = decoded_message["api_key"]
81
+ data = Base64.strict_encode64(decoded_message["data"].to_json)
77
82
  uri = URI(endpoint)
78
83
 
79
84
  client = Net::HTTP.new(uri.host, uri.port)
80
85
  client.use_ssl = true
81
86
  Mixpanel.with_http(client)
82
87
 
88
+ form_data = { "data" => data }
89
+ form_data.merge!("api_key" => api_key) if api_key
83
90
  request = Net::HTTP::Post.new(uri.request_uri)
84
- request.set_form_data({"data" => data })
91
+ request.set_form_data(form_data)
85
92
  response = client.request(request)
86
93
 
87
94
  if response.code == '200' and response.body == '1'
@@ -124,9 +131,9 @@ module Mixpanel
124
131
  # consumer automatically sends its buffered events. The Mixpanel
125
132
  # endpoints have a limit of 50 events per HTTP request, but
126
133
  # you can lower the limit if your individual events are very large.
127
- def initialize(events_endpoint=nil, update_endpoint=nil, max_buffer_length=MAX_LENGTH)
134
+ def initialize(events_endpoint=nil, update_endpoint=nil, import_endpoint=nil, max_buffer_length=MAX_LENGTH)
128
135
  @max_length = [ max_buffer_length, MAX_LENGTH ].min
129
- @consumer = Consumer.new(events_endpoint, update_endpoint)
136
+ @consumer = Consumer.new(events_endpoint, update_endpoint, import_endpoint)
130
137
  @buffers = {
131
138
  :event => [],
132
139
  :profile_update => [],
@@ -136,11 +143,18 @@ module Mixpanel
136
143
  # Stores a message for Mixpanel in memory. When the buffer
137
144
  # hits a maximum length, the consumer will flush automatically.
138
145
  # Flushes are synchronous when they occur.
146
+ #
147
+ # Currently, only :event and :profile_update messages are buffered,
148
+ # :import messages will be send immediately on call.
139
149
  def send(type, message)
140
150
  type = type.to_sym
141
- @buffers[type] << message
142
- if @buffers[type].length >= @max_length
143
- flush_type(type)
151
+ if @buffers.has_key? type
152
+ @buffers[type] << message
153
+ if @buffers[type].length >= @max_length
154
+ flush_type(type)
155
+ end
156
+ else
157
+ @consumer.send(type, message)
144
158
  end
145
159
  end
146
160
 
@@ -155,8 +169,8 @@ module Mixpanel
155
169
 
156
170
  def flush_type(type)
157
171
  @buffers[type].each_slice(@max_length) do |chunk|
158
- message = "[ #{chunk.join(',')} ]"
159
- @consumer.send(type, message)
172
+ data = chunk.map {|message| JSON.load(message)['data'] }
173
+ @consumer.send(type, {'data' => data}.to_json)
160
174
  end
161
175
  @buffers[type] = []
162
176
  end
@@ -59,12 +59,58 @@ module Mixpanel
59
59
  properties['ip'] = ip
60
60
  end
61
61
 
62
+ data = {
63
+ 'event' => event,
64
+ 'properties' => properties
65
+ }
66
+
62
67
  message = {
63
- 'event' => event,
64
- 'properties' => properties
68
+ 'data' => data
65
69
  }
66
70
 
67
71
  @sink.call(:event, message.to_json)
68
72
  end
73
+
74
+ # Imports an event that has occurred in the past, along with a distinct_id
75
+ # representing the source of that event (for example, a user id),
76
+ # an event name describing the event and a set of properties
77
+ # describing that event. Properties are provided as a Hash with
78
+ # string keys and strings, numbers or booleans as values.
79
+ #
80
+ # tracker = Mixpanel::Tracker.new
81
+ #
82
+ # # Track that user "12345"'s credit card was declined
83
+ # tracker.import("API_KEY", "12345", "Credit Card Declined")
84
+ #
85
+ # # Properties describe the circumstances of the event,
86
+ # # or aspects of the source or user associated with the event
87
+ # tracker.import("API_KEY", "12345", "Welcome Email Sent", {
88
+ # 'Email Template' => 'Pretty Pink Welcome',
89
+ # 'User Sign-up Cohort' => 'July 2013'
90
+ # })
91
+ def import(api_key, distinct_id, event, properties={}, ip=nil)
92
+ properties = {
93
+ 'distinct_id' => distinct_id,
94
+ 'token' => @token,
95
+ 'time' => Time.now.to_i,
96
+ 'mp_lib' => 'ruby',
97
+ '$lib_version' => Mixpanel::VERSION
98
+ }.merge(properties)
99
+ if ip
100
+ properties['ip'] = ip
101
+ end
102
+
103
+ data = {
104
+ 'event' => event,
105
+ 'properties' => properties
106
+ }
107
+
108
+ message = {
109
+ 'data' => data,
110
+ 'api_key' => api_key
111
+ }
112
+
113
+ @sink.call(:import, message.to_json)
114
+ end
69
115
  end
70
116
  end
@@ -22,6 +22,7 @@ module Mixpanel
22
22
  #
23
23
  def initialize(token, &block)
24
24
  @token = token
25
+
25
26
  if block
26
27
  @sink = block
27
28
  else
@@ -44,12 +45,12 @@ module Mixpanel
44
45
  #
45
46
  # If you provide an ip argument, \Mixpanel will use that
46
47
  # ip address for geolocation (rather than the ip of your server)
47
- def set(distinct_id, properties, ip=nil)
48
+ def set(distinct_id, properties, ip=nil, optional_params={})
48
49
  properties = fix_property_dates(properties)
49
50
  message = {
50
51
  '$distinct_id' => distinct_id,
51
52
  '$set' => properties,
52
- }
53
+ }.merge(optional_params)
53
54
 
54
55
  if ip
55
56
  message['$ip'] = ip
@@ -68,12 +69,12 @@ module Mixpanel
68
69
  # 'First Login Date': DateTime.now
69
70
  # });
70
71
  #
71
- def set_once(distinct_id, properties, ip=nil)
72
+ def set_once(distinct_id, properties, ip=nil, optional_params={})
72
73
  properties = fix_property_dates(properties)
73
74
  message = {
74
75
  '$distinct_id' => distinct_id,
75
76
  '$set_once' => properties,
76
- }
77
+ }.merge(optional_params)
77
78
 
78
79
  if ip
79
80
  message['$ip'] = ip
@@ -94,12 +95,12 @@ module Mixpanel
94
95
  # 'Coins Earned' => -7, # Use a negative number to subtract
95
96
  # });
96
97
  #
97
- def increment(distinct_id, properties, ip=nil)
98
+ def increment(distinct_id, properties, ip=nil, optional_params={})
98
99
  properties = fix_property_dates(properties)
99
100
  message = {
100
101
  '$distinct_id' => distinct_id,
101
102
  '$add' => properties,
102
- }
103
+ }.merge(optional_params)
103
104
 
104
105
  if ip
105
106
  message['$ip'] = ip
@@ -129,12 +130,12 @@ module Mixpanel
129
130
  # 'Alter Ego Names' => 'Ziggy Stardust'
130
131
  # });
131
132
  #
132
- def append(distinct_id, properties, ip=nil)
133
+ def append(distinct_id, properties, ip=nil, optional_params={})
133
134
  properties = fix_property_dates(properties)
134
135
  message = {
135
136
  '$distinct_id' => distinct_id,
136
137
  '$append' => properties,
137
- }
138
+ }.merge(optional_params)
138
139
 
139
140
  if ip
140
141
  message['$ip'] = ip
@@ -143,20 +144,23 @@ module Mixpanel
143
144
  update(message)
144
145
  end
145
146
 
146
- # Appends a value to the end of list-valued properties,
147
- # only if the given value is not already present in the list.
147
+ # Set union on list valued properties.
148
+ # Associates a list containing all elements of a given list,
149
+ # and all elements currently in a list associated with the given
150
+ # property. After a union, every element in the list associated
151
+ # with a property will be unique.
148
152
  #
149
153
  # tracker = Mixpanel::Tracker.new
150
154
  # tracker.people.union("12345", {
151
- # 'Levels Completed' => 'Suffragette City'
155
+ # 'Levels Completed' => ['Suffragette City']
152
156
  # });
153
157
  #
154
- def union(distinct_id, properties, ip=nil)
158
+ def union(distinct_id, properties, ip=nil, optional_params={})
155
159
  properties = fix_property_dates(properties)
156
160
  message = {
157
161
  '$distinct_id' => distinct_id,
158
162
  '$union' => properties,
159
- }
163
+ }.merge(optional_params)
160
164
 
161
165
  if ip
162
166
  message['$ip'] = ip
@@ -190,10 +194,10 @@ module Mixpanel
190
194
  # '$time' => DateTime.parse("Jan 2 2013")
191
195
  # })
192
196
  #
193
- def track_charge(distinct_id, amount, properties={}, ip=nil)
197
+ def track_charge(distinct_id, amount, properties={}, ip=nil, optional_params={})
194
198
  properties = fix_property_dates(properties)
195
199
  charge_properties = properties.merge({ '$amount' => amount })
196
- append(distinct_id, { '$transactions' => charge_properties }, ip)
200
+ append(distinct_id, { '$transactions' => charge_properties }, ip, optional_params)
197
201
  end
198
202
 
199
203
  # Clear all charges from a \Mixpanel people profile
@@ -218,10 +222,15 @@ module Mixpanel
218
222
  # The \Mixpanel HTTP tracking API is documented at
219
223
  # https://mixpanel.com/help/reference/http
220
224
  def update(message)
221
- message = {
222
- '$token' => @token,
223
- '$time' => ((Time.now.to_f) * 1000.0).to_i
225
+ data = {
226
+ '$token' => @token,
227
+ '$time' => ((Time.now.to_f) * 1000.0).to_i
224
228
  }.merge(message)
229
+
230
+ message = {
231
+ 'data' => data
232
+ }
233
+
225
234
  @sink.call(:profile_update, message.to_json)
226
235
  end
227
236
 
@@ -72,6 +72,33 @@ module Mixpanel
72
72
  super
73
73
  end
74
74
 
75
+ # A call to #import is to import an event occurred in the past. #import
76
+ # takes a distinct_id representing the source of that event (for
77
+ # example, a user id), an event name describing the event, and a
78
+ # set of properties describing that event. Properties are provided
79
+ # as a Hash with string keys and strings, numbers or booleans as
80
+ # values.
81
+ #
82
+ # tracker = Mixpanel::Tracker.new
83
+ #
84
+ # # Import event that user "12345"'s credit card was declined
85
+ # tracker.import("12345", "Credit Card Declined", {
86
+ # 'time' => 1310111365
87
+ # })
88
+ #
89
+ # # Properties describe the circumstances of the event,
90
+ # # or aspects of the source or user associated with the event
91
+ # tracker.import("API_KEY", "12345", "Welcome Email Sent", {
92
+ # 'Email Template' => 'Pretty Pink Welcome',
93
+ # 'User Sign-up Cohort' => 'July 2013',
94
+ # 'time' => 1310111365
95
+ # })
96
+ def import(api_key, distinct_id, event, properties={}, ip=nil)
97
+ # This is here strictly to allow rdoc to include the relevant
98
+ # documentation
99
+ super
100
+ end
101
+
75
102
  # Creates a distinct_id alias. \Events and updates with an alias
76
103
  # will be considered by mixpanel to have the same source, and
77
104
  # refer to the same profile.
@@ -84,14 +111,20 @@ module Mixpanel
84
111
  # the \Mixpanel service, regardless of how the tracker is configured.
85
112
  def alias(alias_id, real_id, events_endpoint=nil)
86
113
  consumer = Mixpanel::Consumer.new(events_endpoint)
87
- message = {
114
+ data = {
88
115
  'event' => '$create_alias',
89
116
  'properties' => {
90
117
  'distinct_id' => real_id,
91
- 'token' => @token,
118
+ 'alias' => alias_id,
119
+ 'token' => @token
92
120
  }
93
- }.to_json
94
- consumer.send(:event, message)
121
+ }
122
+
123
+ message = {
124
+ 'data' => data
125
+ }
126
+
127
+ consumer.send(:event, message.to_json)
95
128
  end
96
129
  end
97
130
  end
@@ -1,3 +1,3 @@
1
1
  module Mixpanel
2
- VERSION = '0.3.2'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -11,16 +11,23 @@ describe Mixpanel::Consumer do
11
11
 
12
12
  it 'should send a request to api.mixpanel.com/track on events' do
13
13
  stub_request(:any, 'https://api.mixpanel.com/track').to_return({ :body => "1" })
14
- @consumer.send(:event, 'TEST EVENT MESSAGE')
14
+ @consumer.send(:event, {'data' => 'TEST EVENT MESSAGE'}.to_json)
15
15
  WebMock.should have_requested(:post, 'https://api.mixpanel.com/track').
16
- with(:body => {'data' => 'VEVTVCBFVkVOVCBNRVNTQUdF' })
16
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=' })
17
17
  end
18
18
 
19
19
  it 'should send a request to api.mixpanel.com/people on profile updates' do
20
20
  stub_request(:any, 'https://api.mixpanel.com/engage').to_return({ :body => "1" })
21
- @consumer.send(:profile_update, 'TEST EVENT MESSAGE')
21
+ @consumer.send(:profile_update, {'data' => 'TEST EVENT MESSAGE'}.to_json)
22
22
  WebMock.should have_requested(:post, 'https://api.mixpanel.com/engage').
23
- with(:body => {'data' => 'VEVTVCBFVkVOVCBNRVNTQUdF' })
23
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=' })
24
+ end
25
+
26
+ it 'should send a request to api.mixpanel.com/import on event imports' do
27
+ stub_request(:any, 'https://api.mixpanel.com/import').to_return({ :body => "1" })
28
+ @consumer.send(:import, {'data' => 'TEST EVENT MESSAGE', 'api_key' => 'API_KEY'}.to_json)
29
+ WebMock.should have_requested(:post, 'https://api.mixpanel.com/import').
30
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'api_key' => 'API_KEY' })
24
31
  end
25
32
  end
26
33
 
@@ -28,27 +35,42 @@ describe Mixpanel::BufferedConsumer do
28
35
  before(:each) do
29
36
  WebMock.reset!
30
37
  @max_length = 10
31
- @consumer = Mixpanel::BufferedConsumer.new(nil, nil, @max_length)
38
+ @consumer = Mixpanel::BufferedConsumer.new(nil, nil, nil, @max_length)
32
39
  end
33
40
 
34
41
  it 'should not send a request for a single message until flush is called' do
35
42
  stub_request(:any, 'https://api.mixpanel.com/track').to_return({ :body => "1" })
36
- @consumer.send(:event, 'TEST EVENT 1')
43
+ @consumer.send(:event, {'data' => 'TEST EVENT 1'}.to_json)
37
44
  WebMock.should have_not_requested(:post, 'https://api.mixpanel.com/track')
38
45
 
39
46
  @consumer.flush()
40
47
  WebMock.should have_requested(:post, 'https://api.mixpanel.com/track').
41
- with(:body => {'data' => 'WyBURVNUIEVWRU5UIDEgXQ==' })
48
+ with(:body => {'data' => 'WyJURVNUIEVWRU5UIDEiXQ==' })
42
49
  end
43
50
 
44
51
  it 'should send one message when max_length events are tracked' do
45
52
  stub_request(:any, 'https://api.mixpanel.com/track').to_return({ :body => "1" })
46
53
 
47
54
  @max_length.times do |i|
48
- @consumer.send(:event, "x #{i}")
55
+ @consumer.send(:event, {'data' => "x #{i}"}.to_json)
49
56
  end
50
57
 
51
58
  WebMock.should have_requested(:post, 'https://api.mixpanel.com/track').
52
- with(:body => {'data' => 'WyB4IDAseCAxLHggMix4IDMseCA0LHggNSx4IDYseCA3LHggOCx4IDkgXQ==' })
59
+ with(:body => {'data' => 'WyJ4IDAiLCJ4IDEiLCJ4IDIiLCJ4IDMiLCJ4IDQiLCJ4IDUiLCJ4IDYiLCJ4IDciLCJ4IDgiLCJ4IDkiXQ==' })
60
+ end
61
+
62
+ it 'should send one message per api key on import' do
63
+ stub_request(:any, 'https://api.mixpanel.com/import').to_return({ :body => "1" })
64
+ @consumer.send(:import, {'data' => 'TEST EVENT 1', 'api_key' => 'KEY 1'}.to_json)
65
+ @consumer.send(:import, {'data' => 'TEST EVENT 1', 'api_key' => 'KEY 2'}.to_json)
66
+ @consumer.send(:import, {'data' => 'TEST EVENT 2', 'api_key' => 'KEY 1'}.to_json)
67
+ @consumer.send(:import, {'data' => 'TEST EVENT 2', 'api_key' => 'KEY 2'}.to_json)
68
+ @consumer.flush
69
+
70
+ WebMock.should have_requested(:post, 'https://api.mixpanel.com/import').
71
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgMSI=', 'api_key' => 'KEY 1' })
72
+
73
+ WebMock.should have_requested(:post, 'https://api.mixpanel.com/import').
74
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgMSI=', 'api_key' => 'KEY 2' })
53
75
  end
54
76
  end
@@ -18,7 +18,7 @@ describe Mixpanel::Events do
18
18
  @events.track('TEST ID', 'Test Event', {
19
19
  'Circumstances' => 'During a test'
20
20
  })
21
- @log.should eq([[ :event, {
21
+ @log.should eq([[ :event, 'data' => {
22
22
  'event' => 'Test Event',
23
23
  'properties' => {
24
24
  'Circumstances' => 'During a test',
@@ -26,9 +26,29 @@ describe Mixpanel::Events do
26
26
  'mp_lib' => 'ruby',
27
27
  '$lib_version' => Mixpanel::VERSION,
28
28
  'token' => 'TEST TOKEN',
29
- 'time' => 76695784
29
+ 'time' => @time_now.to_i
30
30
  }
31
31
  }]])
32
32
  end
33
+
34
+ it 'should send a well formed import/ message' do
35
+ @events.import('API_KEY', 'TEST ID', 'Test Event', {
36
+ 'Circumstances' => 'During a test'
37
+ })
38
+ @log.should eq([[ :import, {
39
+ 'api_key' => 'API_KEY',
40
+ 'data' => {
41
+ 'event' => 'Test Event',
42
+ 'properties' => {
43
+ 'Circumstances' => 'During a test',
44
+ 'distinct_id' => 'TEST ID',
45
+ 'mp_lib' => 'ruby',
46
+ '$lib_version' => Mixpanel::VERSION,
47
+ 'token' => 'TEST TOKEN',
48
+ 'time' => @time_now.to_i
49
+ }
50
+ }
51
+ } ]])
52
+ end
33
53
  end
34
54
 
@@ -19,10 +19,10 @@ describe Mixpanel::People do
19
19
  '$firstname' => 'David',
20
20
  '$lastname' => 'Bowie',
21
21
  })
22
- @log.should eq([[ :profile_update, {
22
+ @log.should eq([[ :profile_update, 'data' => {
23
23
  '$token' => 'TEST TOKEN',
24
24
  '$distinct_id' => 'TEST ID',
25
- '$time' => 76695784000,
25
+ '$time' => @time_now.to_i * 1000,
26
26
  '$set' => {
27
27
  '$firstname' => 'David',
28
28
  '$lastname' => 'Bowie'
@@ -35,10 +35,10 @@ describe Mixpanel::People do
35
35
  '$firstname' => 'David',
36
36
  '$lastname' => 'Bowie',
37
37
  })
38
- @log.should eq([[ :profile_update, {
38
+ @log.should eq([[ :profile_update, 'data' => {
39
39
  '$token' => 'TEST TOKEN',
40
40
  '$distinct_id' => 'TEST ID',
41
- '$time' => 76695784000,
41
+ '$time' => @time_now.to_i * 1000,
42
42
  '$set_once' => {
43
43
  '$firstname' => 'David',
44
44
  '$lastname' => 'Bowie'
@@ -48,10 +48,10 @@ describe Mixpanel::People do
48
48
 
49
49
  it 'should send a well formed engage/add message' do
50
50
  @people.increment("TEST ID", { 'Albums Released' => 10 })
51
- @log.should eq([[ :profile_update, {
51
+ @log.should eq([[ :profile_update, 'data' => {
52
52
  '$token' => 'TEST TOKEN',
53
53
  '$distinct_id' => 'TEST ID',
54
- '$time' => 76695784000,
54
+ '$time' => @time_now.to_i * 1000,
55
55
  '$add' => {
56
56
  'Albums Released' => 10
57
57
  }
@@ -60,7 +60,7 @@ describe Mixpanel::People do
60
60
 
61
61
  it 'should send an engage/add message with a value of 1' do
62
62
  @people.plus_one("TEST ID", 'Albums Released')
63
- @log.should eq([[ :profile_update, {
63
+ @log.should eq([[ :profile_update, 'data' => {
64
64
  '$token' => 'TEST TOKEN',
65
65
  '$distinct_id' => 'TEST ID',
66
66
  '$time' => 76695784000,
@@ -72,10 +72,10 @@ describe Mixpanel::People do
72
72
 
73
73
  it 'should send a well formed engage/append message' do
74
74
  @people.append("TEST ID", { 'Albums' => 'Diamond Dogs' })
75
- @log.should eq([[ :profile_update, {
75
+ @log.should eq([[ :profile_update, 'data' => {
76
76
  '$token' => 'TEST TOKEN',
77
77
  '$distinct_id' => 'TEST ID',
78
- '$time' => 76695784000,
78
+ '$time' => @time_now.to_i * 1000,
79
79
  '$append' => {
80
80
  'Albums' => 'Diamond Dogs'
81
81
  }
@@ -83,23 +83,23 @@ describe Mixpanel::People do
83
83
  end
84
84
 
85
85
  it 'should send a well formed engage/union message' do
86
- @people.union("TEST ID", { 'Albums' => 'Diamond Dogs' })
87
- @log.should eq([[ :profile_update, {
86
+ @people.union("TEST ID", { 'Albums' => ['Diamond Dogs'] })
87
+ @log.should eq([[ :profile_update, 'data' => {
88
88
  '$token' => 'TEST TOKEN',
89
89
  '$distinct_id' => 'TEST ID',
90
- '$time' => 76695784000,
90
+ '$time' => @time_now.to_i * 1000,
91
91
  '$union' => {
92
- 'Albums' => 'Diamond Dogs'
92
+ 'Albums' => ['Diamond Dogs']
93
93
  }
94
94
  }]])
95
95
  end
96
96
 
97
97
  it 'should send a well formed unset message' do
98
98
  @people.unset('TEST ID', 'Albums')
99
- @log.should eq([[ :profile_update, {
99
+ @log.should eq([[ :profile_update, 'data' => {
100
100
  '$token' => 'TEST TOKEN',
101
101
  '$distinct_id' => 'TEST ID',
102
- '$time' => 76695784000,
102
+ '$time' => @time_now.to_i * 1000,
103
103
  '$unset' => [ 'Albums' ]
104
104
  }]])
105
105
  end
@@ -109,10 +109,10 @@ describe Mixpanel::People do
109
109
  '$time' => DateTime.new(1999,12,24,14, 02, 53),
110
110
  'SKU' => '1234567'
111
111
  })
112
- @log.should eq([[ :profile_update, {
112
+ @log.should eq([[ :profile_update, 'data' => {
113
113
  '$token' => 'TEST TOKEN',
114
114
  '$distinct_id' => 'TEST ID',
115
- '$time' => 76695784000,
115
+ '$time' => @time_now.to_i * 1000,
116
116
  '$append' => {
117
117
  '$transactions' => {
118
118
  '$time' => '1999-12-24T14:02:53',
@@ -125,20 +125,20 @@ describe Mixpanel::People do
125
125
 
126
126
  it 'should send a well formed engage/unset message for $transaction' do
127
127
  @people.clear_charges("TEST ID")
128
- @log.should eq([[ :profile_update, {
128
+ @log.should eq([[ :profile_update, 'data' => {
129
129
  '$token' => 'TEST TOKEN',
130
130
  '$distinct_id' => 'TEST ID',
131
- '$time' => 76695784000,
131
+ '$time' => @time_now.to_i * 1000,
132
132
  '$unset' => [ '$transactions' ]
133
133
  }]])
134
134
  end
135
135
 
136
136
  it 'should send a well formed engage/delete message' do
137
137
  @people.delete_user("TEST ID")
138
- @log.should eq([[ :profile_update, {
138
+ @log.should eq([[ :profile_update, 'data' => {
139
139
  '$token' => 'TEST TOKEN',
140
140
  '$distinct_id' => 'TEST ID',
141
- '$time' => 76695784000,
141
+ '$time' => @time_now.to_i * 1000,
142
142
  '$delete' => ''
143
143
  }]])
144
144
  end
@@ -16,7 +16,7 @@ describe Mixpanel::Tracker do
16
16
  mixpanel.alias('TEST ALIAS', 'TEST ID')
17
17
 
18
18
  WebMock.should have_requested(:post, 'https://api.mixpanel.com/track').
19
- with(:body => { :data => 'eyJldmVudCI6IiRjcmVhdGVfYWxpYXMiLCJwcm9wZXJ0aWVzIjp7ImRpc3RpbmN0X2lkIjoiVEVTVCBJRCIsInRva2VuIjoiVEVTVCBUT0tFTiJ9fQ==' })
19
+ with(:body => { :data => 'eyJldmVudCI6IiRjcmVhdGVfYWxpYXMiLCJwcm9wZXJ0aWVzIjp7ImRpc3RpbmN0X2lkIjoiVEVTVCBJRCIsImFsaWFzIjoiVEVTVCBBTElBUyIsInRva2VuIjoiVEVTVCBUT0tFTiJ9fQ==' })
20
20
  end
21
21
 
22
22
  it 'should send a request to the track api with the default consumer' do
@@ -42,7 +42,7 @@ describe Mixpanel::Tracker do
42
42
  'mp_lib' => 'ruby',
43
43
  '$lib_version' => Mixpanel::VERSION,
44
44
  'token' => 'TEST TOKEN',
45
- 'time' => 76695784
45
+ 'time' => @time_now.to_i
46
46
  }
47
47
  })
48
48
  end
@@ -53,35 +53,53 @@ describe Mixpanel::Tracker do
53
53
  messages << [ type, JSON.load(message) ]
54
54
  end
55
55
  mixpanel.track('ID', 'Event')
56
+ mixpanel.import('API_KEY', 'ID', 'Import')
56
57
  mixpanel.people.set('ID', { 'k' => 'v' })
57
58
  mixpanel.people.append('ID', { 'k' => 'v' })
58
59
 
59
- messages.should eq([
60
- [ :event,
60
+ expect = [
61
+ [ :event, 'data' =>
61
62
  { 'event' => 'Event',
62
63
  'properties' => {
63
64
  'distinct_id' => 'ID',
64
65
  'mp_lib' => 'ruby',
65
66
  '$lib_version' => Mixpanel::VERSION,
66
67
  'token' => 'TEST TOKEN',
67
- 'time' => 76695784
68
+ 'time' => @time_now.to_i
68
69
  }
69
70
  }
70
71
  ],
71
- [ :profile_update,
72
+ [ :import, {
73
+ 'data' => {
74
+ 'event' => 'Import',
75
+ 'properties' => {
76
+ 'distinct_id' => 'ID',
77
+ 'mp_lib' => 'ruby',
78
+ '$lib_version' => Mixpanel::VERSION,
79
+ 'token' => 'TEST TOKEN',
80
+ 'time' => @time_now.to_i
81
+ }
82
+ },
83
+ 'api_key' => 'API_KEY',
84
+ }
85
+ ],
86
+ [ :profile_update, 'data' =>
72
87
  { '$token' => 'TEST TOKEN',
73
88
  '$distinct_id' => 'ID',
74
- '$time' => 76695784000,
89
+ '$time' => @time_now.to_i * 1000,
75
90
  '$set' => { 'k' => 'v' }
76
91
  }
77
92
  ],
78
- [ :profile_update,
93
+ [ :profile_update, 'data' =>
79
94
  { '$token' => 'TEST TOKEN',
80
95
  '$distinct_id' => 'ID',
81
- '$time' => 76695784000,
96
+ '$time' => @time_now.to_i * 1000,
82
97
  '$append' => { 'k' => 'v' }
83
98
  }
84
99
  ]
85
- ])
100
+ ]
101
+ expect.zip(messages).each do |expect, found|
102
+ expect.should eq(found)
103
+ end
86
104
  end
87
105
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixpanel-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-09 00:00:00.000000000 Z
12
+ date: 2013-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake