mixpanel-ruby 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ffb9a7cb934ae663374cf0850ba2049e77ad6844
4
- data.tar.gz: 577cf98aaeb43e608a7d50e0b37d49b2437dd298
2
+ SHA256:
3
+ metadata.gz: 0a4bc0206903c9c7d7e61253d7cfe248e17f698a754dac067e3d6997ee44688a
4
+ data.tar.gz: eda4910784b73583c7ff29fcbeaae86b1259e407d8cddf5c5c9ccb7ad9004661
5
5
  SHA512:
6
- metadata.gz: 3e768a749828219fd77e9d3b4c29810d2f92a47b6ec8d4f6e0ab92f977d6f540b1c57bba0881f73d18fb59073a1e97da8688fe0a3cc8d4d10aefe6825aa36870
7
- data.tar.gz: c19c92bcbb59663e617ba24eb6df74662e67e08605cbb535040185d5d66c28206c70d5f34268d1e98a0e98558707772dc338f57c61f1bc6cfcd0a127bc7bd9a4
6
+ metadata.gz: ba267b81907f663ef400b694973569c2e2e00c323e8e199bea82516d3552c73f2ffcc6c864c0fca2123f53a3e246218e60c64e58b51aab5ac96792dae8f76a13
7
+ data.tar.gz: 541c0b8b4da498f37a749d76542fad417c776c83f4d583c8ae5bbbfbba9979103cfb634bb4a3d8ae6748b6b302ca546524edc80258423eb2e862d279328d07f1
data/.travis.yml CHANGED
@@ -1,12 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.6.0
4
+ - 2.5.0
5
+ - 2.3.0
3
6
  - 2.2.0
4
7
  - 2.1.0
5
8
  - 2.0.0
6
- - 1.9.3
7
- - jruby-19mode
8
- - rbx-2
9
-
10
- matrix:
11
- allow_failures:
12
- - rvm: "rbx-2"
data/Readme.rdoc CHANGED
@@ -49,6 +49,12 @@ In particular, for Rails apps, the following projects are currently actively mai
49
49
 
50
50
  == Changes
51
51
 
52
+ == 2.2.2
53
+ * Add Group Analytics support with Mixpanel::Groups
54
+
55
+ == 2.2.1
56
+ * Fix buffer clearing on partially successful writes in BufferedConsumer.
57
+
52
58
  == 2.2.0
53
59
  * Add Mixpanel::ErrorHandler to simplify custom error handling.
54
60
  * Modify Mixpanel::People#fix_property_dates to handle ActiveSupport::TimeWithZone.
@@ -58,9 +58,13 @@ module Mixpanel
58
58
  # they will be used instead of the default Mixpanel endpoints.
59
59
  # This can be useful for proxying, debugging, or if you prefer
60
60
  # not to use SSL for your events.
61
- def initialize(events_endpoint=nil, update_endpoint=nil, import_endpoint=nil)
61
+ def initialize(events_endpoint=nil,
62
+ update_endpoint=nil,
63
+ groups_endpoint=nil,
64
+ import_endpoint=nil)
62
65
  @events_endpoint = events_endpoint || 'https://api.mixpanel.com/track'
63
66
  @update_endpoint = update_endpoint || 'https://api.mixpanel.com/engage'
67
+ @groups_endpoint = groups_endpoint || 'https://api.mixpanel.com/groups'
64
68
  @import_endpoint = import_endpoint || 'https://api.mixpanel.com/import'
65
69
  end
66
70
 
@@ -75,6 +79,7 @@ module Mixpanel
75
79
  endpoint = {
76
80
  :event => @events_endpoint,
77
81
  :profile_update => @update_endpoint,
82
+ :group_update => @groups_endpoint,
78
83
  :import => @import_endpoint,
79
84
  }[type]
80
85
 
@@ -225,9 +230,16 @@ module Mixpanel
225
230
  private
226
231
 
227
232
  def flush_type(type)
228
- @buffers[type].each_slice(@max_length) do |chunk|
229
- data = chunk.map {|message| JSON.load(message)['data'] }
230
- @sink.call(type, {'data' => data}.to_json)
233
+ sent_messages = 0
234
+ begin
235
+ @buffers[type].each_slice(@max_length) do |chunk|
236
+ data = chunk.map {|message| JSON.load(message)['data'] }
237
+ @sink.call(type, {'data' => data}.to_json)
238
+ sent_messages += chunk.length
239
+ end
240
+ rescue
241
+ @buffers[type].slice!(0, sent_messages)
242
+ raise
231
243
  end
232
244
  @buffers[type] = []
233
245
  end
@@ -55,7 +55,7 @@ module Mixpanel
55
55
  properties = {
56
56
  'distinct_id' => distinct_id,
57
57
  'token' => @token,
58
- 'time' => Time.now.to_i,
58
+ 'time' => Time.now.to_f,
59
59
  'mp_lib' => 'ruby',
60
60
  '$lib_version' => Mixpanel::VERSION,
61
61
  }.merge(properties)
@@ -103,7 +103,7 @@ module Mixpanel
103
103
  properties = {
104
104
  'distinct_id' => distinct_id,
105
105
  'token' => @token,
106
- 'time' => Time.now.to_i,
106
+ 'time' => Time.now.to_f,
107
107
  'mp_lib' => 'ruby',
108
108
  '$lib_version' => Mixpanel::VERSION,
109
109
  }.merge(properties)
@@ -0,0 +1,201 @@
1
+ require 'date'
2
+ require 'json'
3
+ require 'time'
4
+
5
+ require 'mixpanel-ruby/consumer'
6
+ require 'mixpanel-ruby/error'
7
+
8
+ module Mixpanel
9
+
10
+ # Handles formatting Mixpanel group updates and
11
+ # sending them to the consumer. You will rarely need
12
+ # to instantiate this class directly- to send
13
+ # group updates, use Mixpanel::Tracker#groups
14
+ #
15
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
16
+ # tracker.groups.set(...) or .set_once(..), or .delete(...) etc.
17
+ class Groups
18
+
19
+ # You likely won't need to instantiate instances of Mixpanel::Groups
20
+ # directly. The best way to get an instance of Mixpanel::Groups is
21
+ #
22
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
23
+ # tracker.groups # An instance of Mixpanel::Groups
24
+ #
25
+ def initialize(token, error_handler=nil, &block)
26
+ @token = token
27
+ @error_handler = error_handler || ErrorHandler.new
28
+
29
+ if block
30
+ @sink = block
31
+ else
32
+ consumer = Consumer.new
33
+ @sink = consumer.method(:send!)
34
+ end
35
+ end
36
+
37
+ # Sets properties on a group record. Takes a Hash with string
38
+ # keys, and values that are strings, numbers, booleans, or
39
+ # DateTimes
40
+ #
41
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
42
+ # # Sets properties on group with id "1234"
43
+ # tracker.groups.set("GROUP KEY", "1234", {
44
+ # 'company' => 'Acme',
45
+ # 'plan' => 'Premium',
46
+ # 'Sign-Up Date' => DateTime.now
47
+ # });
48
+ #
49
+ # If you provide an ip argument, \Mixpanel will use that
50
+ # ip address for geolocation (rather than the ip of your server)
51
+ def set(group_key, group_id, properties, ip=nil, optional_params={})
52
+ properties = fix_property_dates(properties)
53
+ message = {
54
+ '$group_key' => group_key,
55
+ '$group_id' => group_id,
56
+ '$set' => properties,
57
+ }.merge(optional_params)
58
+ message['$ip'] = ip if ip
59
+
60
+ update(message)
61
+ end
62
+
63
+ # set_once works just like #set, but will only change the
64
+ # value of properties if they are not already present
65
+ # in the group. That means you can call set_once many times
66
+ # without changing an original value.
67
+ #
68
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
69
+ # tracker.groups.set_once("GROUP KEY", "1234", {
70
+ # 'First Login Date': DateTime.now
71
+ # });
72
+ #
73
+ def set_once(group_key, group_id, properties, ip=nil, optional_params={})
74
+ properties = fix_property_dates(properties)
75
+ message = {
76
+ '$group_key' => group_key,
77
+ '$group_id' => group_id,
78
+ '$set_once' => properties,
79
+ }.merge(optional_params)
80
+ message['$ip'] = ip if ip
81
+
82
+ update(message)
83
+ end
84
+
85
+ # Removes a specific value in a list property
86
+ #
87
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
88
+ #
89
+ # # removes "socks" from the "Items purchased" list property
90
+ # # for the specified group
91
+ # tracker.groups.remove("GROUP KEY", "1234", { 'Items purchased' => 'socks' })
92
+ #
93
+ def remove(group_key, group_id, properties, ip=nil, optional_params={})
94
+ properties = fix_property_dates(properties)
95
+ message = {
96
+ '$group_key' => group_key,
97
+ '$group_id' => group_id,
98
+ '$remove' => properties,
99
+ }.merge(optional_params)
100
+ message['$ip'] = ip if ip
101
+
102
+ update(message)
103
+ end
104
+
105
+ # Set union on list valued properties.
106
+ # Associates a list containing all elements of a given list,
107
+ # and all elements currently in a list associated with the given
108
+ # property. After a union, every element in the list associated
109
+ # with a property will be unique.
110
+ #
111
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
112
+ # tracker.groups.union("GROUP KEY", "1234", {
113
+ # 'Levels Completed' => ['Suffragette City']
114
+ # });
115
+ #
116
+ def union(group_key, group_id, properties, ip=nil, optional_params={})
117
+ properties = fix_property_dates(properties)
118
+ message = {
119
+ '$group_key' => group_key,
120
+ '$group_id' => group_id,
121
+ '$union' => properties,
122
+ }.merge(optional_params)
123
+ message['$ip'] = ip if ip
124
+
125
+ update(message)
126
+ end
127
+
128
+ # Removes properties and their values from a group.
129
+ #
130
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
131
+ #
132
+ # # removes a single property and its value from a group
133
+ # tracker.groups.unset("GROUP KEY", "1234", "Overdue Since")
134
+ #
135
+ # # removes multiple properties and their values from a group
136
+ # tracker.groups.unset("GROUP KEY",
137
+ # "1234",
138
+ # ["Overdue Since", "Paid Date"])
139
+ #
140
+ def unset(group_key, group_id, properties, ip=nil, optional_params={})
141
+ properties = [properties] unless properties.is_a?(Array)
142
+ message = {
143
+ '$group_key' => group_key,
144
+ '$group_id' => group_id,
145
+ '$unset' => properties,
146
+ }.merge(optional_params)
147
+ message['$ip'] = ip if ip
148
+
149
+ update(message)
150
+ end
151
+
152
+ # Permanently delete a group from \Mixpanel groups analytics (all group
153
+ # properties on events stay)
154
+ def delete_group(group_key, group_id, optional_params={})
155
+ update({
156
+ '$group_key' => group_key,
157
+ '$group_id' => group_id,
158
+ '$delete' => '',
159
+ }.merge(optional_params))
160
+ end
161
+
162
+ # Send a generic update to \Mixpanel groups analytics.
163
+ # Caller is responsible for formatting the update message, as
164
+ # documented in the \Mixpanel HTTP specification, and passing
165
+ # the message as a dict to #update. This
166
+ # method might be useful if you want to use very new
167
+ # or experimental features of groups analytics from Ruby
168
+ # The \Mixpanel HTTP tracking API is documented at
169
+ # https://mixpanel.com/help/reference/http
170
+ def update(message)
171
+ data = {
172
+ '$token' => @token,
173
+ '$time' => Time.now.to_f,
174
+ }.merge(message)
175
+
176
+ message = {'data' => data}
177
+
178
+ ret = true
179
+ begin
180
+ @sink.call(:group_update, message.to_json)
181
+ rescue MixpanelError => e
182
+ @error_handler.handle(e)
183
+ ret = false
184
+ end
185
+
186
+ ret
187
+ end
188
+
189
+ private
190
+
191
+ def fix_property_dates(properties)
192
+ properties.inject({}) do |ret, (key, value)|
193
+ value = value.respond_to?(:new_offset) ? value.new_offset('0') : value
194
+ value = value.respond_to?(:utc) ? value.utc : value # Handle ActiveSupport::TimeWithZone
195
+
196
+ ret[key] = value.respond_to?(:strftime) ? value.strftime('%Y-%m-%dT%H:%M:%S') : value
197
+ ret
198
+ end
199
+ end
200
+ end
201
+ end
@@ -223,7 +223,7 @@ module Mixpanel
223
223
  def update(message)
224
224
  data = {
225
225
  '$token' => @token,
226
- '$time' => ((Time.now.to_f) * 1000.0).to_i,
226
+ '$time' => Time.now.to_f,
227
227
  }.merge(message)
228
228
 
229
229
  message = {'data' => data}
@@ -1,5 +1,6 @@
1
1
  require 'mixpanel-ruby/events.rb'
2
2
  require 'mixpanel-ruby/people.rb'
3
+ require 'mixpanel-ruby/groups.rb'
3
4
 
4
5
  module Mixpanel
5
6
  # Use Mixpanel::Tracker to track events and profile updates in your application.
@@ -13,16 +14,25 @@ module Mixpanel
13
14
  # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
14
15
  # tracker.people.set(a_distinct_id, {properties})
15
16
  #
17
+ # To send groups updates, call
18
+ #
19
+ # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
20
+ # tracker.groups.set(group_key, group_id, {properties})
21
+ #
16
22
  # You can find your project token in the settings dialog for your
17
23
  # project, inside of the Mixpanel web application.
18
24
  #
19
25
  # Mixpanel::Tracker is a subclass of Mixpanel::Events, and exposes
20
26
  # an instance of Mixpanel::People as Tracker#people
27
+ # and an instance of Mixpanel::Groups as Tracker#groups
21
28
  class Tracker < Events
22
29
  # An instance of Mixpanel::People. Use this to
23
30
  # send profile updates
24
31
  attr_reader :people
25
32
 
33
+ # An instance of Mixpanel::Groups. Use this to send groups updates
34
+ attr_reader :groups
35
+
26
36
  # Takes your Mixpanel project token, as a string.
27
37
  #
28
38
  # tracker = Mixpanel::Tracker.new(YOUR_MIXPANEL_TOKEN)
@@ -46,6 +56,7 @@ module Mixpanel
46
56
  super(token, error_handler, &block)
47
57
  @token = token
48
58
  @people = People.new(token, error_handler, &block)
59
+ @groups = Groups.new(token, error_handler, &block)
49
60
  end
50
61
 
51
62
  # A call to #track is a report that an event has occurred. #track
@@ -154,7 +165,7 @@ module Mixpanel
154
165
  properties = {
155
166
  'distinct_id' => distinct_id,
156
167
  'token' => @token,
157
- 'time' => Time.now.to_i,
168
+ 'time' => Time.now.to_f,
158
169
  'mp_lib' => 'ruby',
159
170
  '$lib_version' => Mixpanel::VERSION,
160
171
  }.merge(properties)
@@ -1,3 +1,3 @@
1
1
  module Mixpanel
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -22,6 +22,13 @@ describe Mixpanel::Consumer do
22
22
  with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
23
23
  end
24
24
 
25
+ it 'should send a request to api.mixpanel.com/groups on groups updates' do
26
+ stub_request(:any, 'https://api.mixpanel.com/groups').to_return({:body => '{"status": 1, "error": null}'})
27
+ subject.send!(:group_update, {'data' => 'TEST EVENT MESSAGE'}.to_json)
28
+ expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/groups').
29
+ with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
30
+ end
31
+
25
32
  it 'should send a request to api.mixpanel.com/import on event imports' do
26
33
  stub_request(:any, 'https://api.mixpanel.com/import').to_return({:body => '{"status": 1, "error": null}'})
27
34
  subject.send!(:import, {'data' => 'TEST EVENT MESSAGE', 'api_key' => 'API_KEY','verbose' => '1' }.to_json)
@@ -55,7 +62,7 @@ describe Mixpanel::Consumer do
55
62
  with(:body => {'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=', 'verbose' => '1' })
56
63
  end
57
64
 
58
- it 'should raise server error when verbose is disabled' do
65
+ it 'should raise server error when verbose is disabled', :skip => true do
59
66
  stub_request(:any, 'https://api.mixpanel.com/track').to_return({:body => '0'})
60
67
  expect { subject.send!(:event, {'data' => 'TEST EVENT MESSAGE'}.to_json) }.to raise_exception(Mixpanel::ServerError, /Could not interpret Mixpanel server response: '0'/)
61
68
  expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/track').
@@ -160,4 +167,42 @@ describe Mixpanel::BufferedConsumer do
160
167
 
161
168
  end
162
169
 
170
+ context 'with failing requests' do
171
+ let(:sent_messages) { [] }
172
+ let(:submission_queue) { [] }
173
+ subject do
174
+ Mixpanel::BufferedConsumer.new(nil, nil, nil, 2) do |type, message|
175
+ raise Mixpanel::ServerError if submission_queue.shift == :fail
176
+ sent_messages << [type, message]
177
+ end
178
+ end
179
+
180
+ it 'clears any slices that complete on flush' do
181
+ # construct a consumer that is backed up and has a multi-slice buffer
182
+ 3.times { submission_queue << :fail }
183
+ 4.times do |i|
184
+ begin
185
+ subject.send!(:event, {'data' => i}.to_json)
186
+ rescue Mixpanel::ServerError
187
+ end
188
+ end
189
+ expect(sent_messages).to match_array([])
190
+
191
+ submission_queue << :pass
192
+ submission_queue << :fail
193
+
194
+ expect { subject.flush }.to raise_error Mixpanel::ServerError
195
+ expect(sent_messages).to match_array([
196
+ [:event, '{"data":[0,1]}']
197
+ ])
198
+
199
+ submission_queue << :pass
200
+ subject.flush
201
+ expect(sent_messages).to match_array([
202
+ [:event, '{"data":[0,1]}'],
203
+ [:event, '{"data":[2,3]}'],
204
+ ])
205
+ end
206
+ end
207
+
163
208
  end
@@ -0,0 +1,159 @@
1
+ require 'spec_helper'
2
+ require 'active_support/time'
3
+
4
+ require 'mixpanel-ruby/groups'
5
+
6
+ describe Mixpanel::Groups do
7
+ before(:each) do
8
+ @time_now = Time.parse('Jun 6 1972, 16:23:04')
9
+ allow(Time).to receive(:now).and_return(@time_now)
10
+
11
+ @log = []
12
+ @groups = Mixpanel::Groups.new('TEST TOKEN') do |type, message|
13
+ @log << [type, JSON.load(message)]
14
+ end
15
+ end
16
+
17
+ it 'should send a well formed groups/set message' do
18
+ @groups.set("TEST GROUP KEY", "TEST GROUP ID", {
19
+ '$groupname' => 'Mixpanel',
20
+ '$grouprevenue' => 200
21
+ })
22
+ expect(@log).to eq([[:group_update, 'data' => {
23
+ '$token' => 'TEST TOKEN',
24
+ '$group_key' => 'TEST GROUP KEY',
25
+ '$group_id' => 'TEST GROUP ID',
26
+ '$time' => @time_now.to_i * 1000,
27
+ '$set' => {
28
+ '$groupname' => 'Mixpanel',
29
+ '$grouprevenue' => 200
30
+ }
31
+ }]])
32
+ end
33
+
34
+ it 'should properly cast dates' do
35
+ @groups.set("TEST GROUP KEY", "TEST GROUP ID", {
36
+ 'created_at' => DateTime.new(2013, 1, 2, 3, 4, 5)
37
+ })
38
+ expect(@log).to eq([[:group_update, 'data' => {
39
+ '$token' => 'TEST TOKEN',
40
+ '$group_key' => 'TEST GROUP KEY',
41
+ '$group_id' => 'TEST GROUP ID',
42
+ '$time' => @time_now.to_i * 1000,
43
+ '$set' => {
44
+ 'created_at' => '2013-01-02T03:04:05'
45
+ }
46
+ }]])
47
+ end
48
+
49
+ it 'should convert offset datetimes to UTC' do
50
+ @groups.set("TEST GROUP KEY", "TEST GROUP ID", {
51
+ 'created_at' => DateTime.new(2013, 1, 1, 18, 4, 5, '-8')
52
+ })
53
+ expect(@log).to eq([[:group_update, 'data' => {
54
+ '$token' => 'TEST TOKEN',
55
+ '$group_key' => 'TEST GROUP KEY',
56
+ '$group_id' => 'TEST GROUP ID',
57
+ '$time' => @time_now.to_i * 1000,
58
+ '$set' => {
59
+ 'created_at' => '2013-01-02T02:04:05'
60
+ }
61
+ }]])
62
+ end
63
+
64
+ it 'should convert offset ActiveSupport::TimeWithZone objects to UTC' do
65
+ Time.zone = 'Pacific Time (US & Canada)'
66
+ @groups.set("TEST GROUP KEY", "TEST GROUP ID", {
67
+ 'created_at' => Time.zone.local(2013, 1, 1, 18, 4, 5)
68
+ })
69
+ expect(@log).to eq([[:group_update, 'data' => {
70
+ '$token' => 'TEST TOKEN',
71
+ '$group_key' => 'TEST GROUP KEY',
72
+ '$group_id' => 'TEST GROUP ID',
73
+ '$time' => @time_now.to_i * 1000,
74
+ '$set' => {
75
+ 'created_at' => '2013-01-02T02:04:05'
76
+ }
77
+ }]])
78
+ end
79
+
80
+ it 'should send a well formed groups/set_once message' do
81
+ @groups.set_once("TEST GROUP KEY", "TEST GROUP ID", {
82
+ '$groupname' => 'Mixpanel',
83
+ '$grouprevenue' => 200
84
+ })
85
+ expect(@log).to eq([[:group_update, 'data' => {
86
+ '$token' => 'TEST TOKEN',
87
+ '$group_key' => 'TEST GROUP KEY',
88
+ '$group_id' => 'TEST GROUP ID',
89
+ '$time' => @time_now.to_i * 1000,
90
+ '$set_once' => {
91
+ '$groupname' => 'Mixpanel',
92
+ '$grouprevenue' => 200
93
+ }
94
+ }]])
95
+ end
96
+
97
+ it 'should send a well formed groups/remove message' do
98
+ @groups.remove("TEST GROUP KEY", "TEST GROUP ID", {
99
+ 'Albums' => 'Diamond Dogs'
100
+ })
101
+ expect(@log).to eq([[:group_update, 'data' => {
102
+ '$token' => 'TEST TOKEN',
103
+ '$group_key' => 'TEST GROUP KEY',
104
+ '$group_id' => 'TEST GROUP ID',
105
+ '$time' => @time_now.to_i * 1000,
106
+ '$remove' => {
107
+ 'Albums' => 'Diamond Dogs'
108
+ }
109
+ }]])
110
+ end
111
+
112
+ it 'should send a well formed groups/union message' do
113
+ @groups.union("TEST GROUP KEY", "TEST GROUP ID", {
114
+ 'Albums' => ['Diamond Dogs']
115
+ })
116
+ expect(@log).to eq([[:group_update, 'data' => {
117
+ '$token' => 'TEST TOKEN',
118
+ '$group_key' => 'TEST GROUP KEY',
119
+ '$group_id' => 'TEST GROUP ID',
120
+ '$time' => @time_now.to_i * 1000,
121
+ '$union' => {
122
+ 'Albums' => ['Diamond Dogs']
123
+ }
124
+ }]])
125
+ end
126
+
127
+ it 'should send a well formed unset message' do
128
+ @groups.unset("TEST GROUP KEY", "TEST GROUP ID", 'Albums')
129
+ expect(@log).to eq([[:group_update, 'data' => {
130
+ '$token' => 'TEST TOKEN',
131
+ '$group_key' => 'TEST GROUP KEY',
132
+ '$group_id' => 'TEST GROUP ID',
133
+ '$time' => @time_now.to_i * 1000,
134
+ '$unset' => ['Albums']
135
+ }]])
136
+ end
137
+
138
+ it 'should send a well formed unset message with multiple properties' do
139
+ @groups.unset("TEST GROUP KEY", "TEST GROUP ID", ['Albums', 'Vinyls'])
140
+ expect(@log).to eq([[:group_update, 'data' => {
141
+ '$token' => 'TEST TOKEN',
142
+ '$group_key' => 'TEST GROUP KEY',
143
+ '$group_id' => 'TEST GROUP ID',
144
+ '$time' => @time_now.to_i * 1000,
145
+ '$unset' => ['Albums', 'Vinyls']
146
+ }]])
147
+ end
148
+
149
+ it 'should send a well formed groups/delete message' do
150
+ @groups.delete_group("TEST GROUP KEY", "TEST GROUP ID")
151
+ expect(@log).to eq([[:group_update, 'data' => {
152
+ '$token' => 'TEST TOKEN',
153
+ '$group_key' => 'TEST GROUP KEY',
154
+ '$group_id' => 'TEST GROUP ID',
155
+ '$time' => @time_now.to_i * 1000,
156
+ '$delete' => ''
157
+ }]])
158
+ end
159
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixpanel-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mixpanel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2022-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -86,6 +86,7 @@ files:
86
86
  - lib/mixpanel-ruby/consumer.rb
87
87
  - lib/mixpanel-ruby/error.rb
88
88
  - lib/mixpanel-ruby/events.rb
89
+ - lib/mixpanel-ruby/groups.rb
89
90
  - lib/mixpanel-ruby/people.rb
90
91
  - lib/mixpanel-ruby/tracker.rb
91
92
  - lib/mixpanel-ruby/version.rb
@@ -93,6 +94,7 @@ files:
93
94
  - spec/mixpanel-ruby/consumer_spec.rb
94
95
  - spec/mixpanel-ruby/error_spec.rb
95
96
  - spec/mixpanel-ruby/events_spec.rb
97
+ - spec/mixpanel-ruby/groups_spec.rb
96
98
  - spec/mixpanel-ruby/people_spec.rb
97
99
  - spec/mixpanel-ruby/tracker_spec.rb
98
100
  - spec/spec_helper.rb
@@ -100,7 +102,7 @@ homepage: https://mixpanel.com/help/reference/ruby
100
102
  licenses:
101
103
  - Apache License 2.0
102
104
  metadata: {}
103
- post_install_message:
105
+ post_install_message:
104
106
  rdoc_options: []
105
107
  require_paths:
106
108
  - lib
@@ -115,9 +117,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
117
  - !ruby/object:Gem::Version
116
118
  version: '0'
117
119
  requirements: []
118
- rubyforge_project:
119
- rubygems_version: 2.2.0
120
- signing_key:
120
+ rubygems_version: 3.3.7
121
+ signing_key:
121
122
  specification_version: 4
122
123
  summary: Official Mixpanel tracking library for ruby
123
124
  test_files: []