mixpanel-ruby 2.2.0 → 2.3.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.
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: []