mixpanel-ruby 3.1.0 → 3.2.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 +4 -4
- data/.github/dependabot.yml +14 -0
- data/.github/modules.json +18 -0
- data/.github/scripts/generate-changelog.sh +87 -0
- data/.github/workflows/pr-title-check.yml +51 -0
- data/.github/workflows/prepare-release.yml +189 -0
- data/.github/workflows/release-rubygems.yml +217 -0
- data/CHANGELOG.md +30 -0
- data/Readme.rdoc +65 -0
- data/lib/mixpanel-ruby/consumer.rb +54 -6
- data/lib/mixpanel-ruby/credentials.rb +26 -0
- data/lib/mixpanel-ruby/events.rb +69 -11
- data/lib/mixpanel-ruby/flags/flags_provider.rb +16 -2
- data/lib/mixpanel-ruby/flags/local_flags_provider.rb +85 -18
- data/lib/mixpanel-ruby/flags/remote_flags_provider.rb +4 -2
- data/lib/mixpanel-ruby/tracker.rb +39 -9
- data/lib/mixpanel-ruby/version.rb +1 -1
- data/lib/mixpanel-ruby.rb +1 -0
- data/openfeature-provider/CHANGELOG.md +5 -0
- data/openfeature-provider/README.md +2 -0
- data/openfeature-provider/lib/mixpanel/openfeature/version.rb +7 -0
- data/openfeature-provider/lib/mixpanel/openfeature.rb +1 -0
- data/openfeature-provider/mixpanel-ruby-openfeature.gemspec +3 -1
- data/spec/mixpanel-ruby/consumer_spec.rb +81 -0
- data/spec/mixpanel-ruby/credentials_security_spec.rb +108 -0
- data/spec/mixpanel-ruby/credentials_spec.rb +54 -0
- data/spec/mixpanel-ruby/events_spec.rb +152 -0
- data/spec/mixpanel-ruby/flags/local_flags_spec.rb +209 -2
- data/spec/mixpanel-ruby/flags/remote_flags_spec.rb +36 -0
- data/spec/mixpanel-ruby/tracker_spec.rb +18 -0
- metadata +14 -2
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require File.join(File.dirname(__FILE__), 'lib/mixpanel/openfeature/version.rb')
|
|
4
|
+
|
|
3
5
|
Gem::Specification.new do |spec|
|
|
4
6
|
spec.name = 'mixpanel-ruby-openfeature'
|
|
5
|
-
spec.version =
|
|
7
|
+
spec.version = Mixpanel::OpenFeature::VERSION
|
|
6
8
|
spec.authors = ['Mixpanel']
|
|
7
9
|
spec.email = 'support@mixpanel.com'
|
|
8
10
|
spec.summary = 'OpenFeature provider for Mixpanel feature flags'
|
|
@@ -3,6 +3,7 @@ require 'spec_helper'
|
|
|
3
3
|
require 'webmock'
|
|
4
4
|
|
|
5
5
|
require 'mixpanel-ruby/consumer'
|
|
6
|
+
require 'mixpanel-ruby/credentials'
|
|
6
7
|
|
|
7
8
|
describe Mixpanel::Consumer do
|
|
8
9
|
before { WebMock.reset! }
|
|
@@ -95,6 +96,56 @@ describe Mixpanel::Consumer do
|
|
|
95
96
|
it_behaves_like 'consumer'
|
|
96
97
|
end
|
|
97
98
|
|
|
99
|
+
context 'service account credentials' do
|
|
100
|
+
it 'should send a request to api.mixpanel.com/import with service account credentials' do
|
|
101
|
+
stub_request(:any, 'https://api.mixpanel.com/import?project_id=test-project-123').to_return({:body => '{"status": 1, "error": null}'})
|
|
102
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project-123')
|
|
103
|
+
consumer = Mixpanel::Consumer.new(nil, nil, nil, nil, credentials: credentials)
|
|
104
|
+
|
|
105
|
+
consumer.send!(:import, {'data' => 'TEST EVENT MESSAGE'}.to_json)
|
|
106
|
+
|
|
107
|
+
# Should use Basic Auth header with username:secret
|
|
108
|
+
# Should add project_id as query parameter
|
|
109
|
+
# Should NOT include credentials in POST body or message
|
|
110
|
+
expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/import?project_id=test-project-123').
|
|
111
|
+
with(
|
|
112
|
+
:body => {
|
|
113
|
+
'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=',
|
|
114
|
+
'verbose' => '1'
|
|
115
|
+
},
|
|
116
|
+
:headers => {
|
|
117
|
+
'Authorization' => 'Basic ' + Base64.strict_encode64('test-user:test-secret')
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'should raise ArgumentError when credentials is not ServiceAccountCredentials' do
|
|
123
|
+
consumer = Mixpanel::Consumer.new
|
|
124
|
+
|
|
125
|
+
expect {
|
|
126
|
+
consumer.request('https://api.mixpanel.com/import', {'data' => 'test', 'verbose' => '1'}, credentials: 'invalid', type: :import)
|
|
127
|
+
}.to raise_error(ArgumentError, /credentials must be ServiceAccountCredentials, got String/)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'should not include api_key when credentials are present' do
|
|
131
|
+
stub_request(:any, 'https://api.mixpanel.com/import?project_id=test-project').to_return({:body => '{"status": 1, "error": null}'})
|
|
132
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'test-project')
|
|
133
|
+
consumer = Mixpanel::Consumer.new(nil, nil, nil, nil, credentials: credentials)
|
|
134
|
+
|
|
135
|
+
# Message includes api_key but it should be ignored when credentials are present
|
|
136
|
+
consumer.send!(:import, {'data' => 'TEST EVENT MESSAGE', 'api_key' => 'SHOULD_BE_IGNORED'}.to_json)
|
|
137
|
+
|
|
138
|
+
# api_key should NOT be in the request body (only data and verbose)
|
|
139
|
+
expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/import?project_id=test-project').
|
|
140
|
+
with(
|
|
141
|
+
:body => {
|
|
142
|
+
'data' => 'IlRFU1QgRVZFTlQgTUVTU0FHRSI=',
|
|
143
|
+
'verbose' => '1'
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
98
149
|
end
|
|
99
150
|
|
|
100
151
|
describe Mixpanel::BufferedConsumer do
|
|
@@ -205,4 +256,34 @@ describe Mixpanel::BufferedConsumer do
|
|
|
205
256
|
end
|
|
206
257
|
end
|
|
207
258
|
|
|
259
|
+
context 'with service account credentials' do
|
|
260
|
+
it 'should pass credentials to consumer when using BufferedConsumer' do
|
|
261
|
+
stub_request(:any, 'https://api.mixpanel.com/import?project_id=buffered-project').to_return({:body => '{"status": 1, "error": null}'})
|
|
262
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('buffered-user', 'buffered-secret', 'buffered-project')
|
|
263
|
+
consumer = Mixpanel::BufferedConsumer.new(nil, nil, nil, 2, credentials: credentials)
|
|
264
|
+
|
|
265
|
+
# Import messages are not buffered - they're sent immediately
|
|
266
|
+
consumer.send!(:import, {'data' => 'EVENT 1'}.to_json)
|
|
267
|
+
|
|
268
|
+
# Verify credentials were used in the request
|
|
269
|
+
expect(WebMock).to have_requested(:post, 'https://api.mixpanel.com/import?project_id=buffered-project').
|
|
270
|
+
with(
|
|
271
|
+
:headers => {
|
|
272
|
+
'Authorization' => 'Basic ' + Base64.strict_encode64('buffered-user:buffered-secret')
|
|
273
|
+
}
|
|
274
|
+
).once
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe 'Connection error handling' do
|
|
281
|
+
it 'should raise ConnectionError when network error occurs' do
|
|
282
|
+
stub_request(:any, 'https://api.mixpanel.com/track').to_raise(StandardError.new('Network timeout'))
|
|
283
|
+
consumer = Mixpanel::Consumer.new
|
|
284
|
+
|
|
285
|
+
expect {
|
|
286
|
+
consumer.send!(:event, {'data' => 'TEST EVENT MESSAGE'}.to_json)
|
|
287
|
+
}.to raise_error(Mixpanel::ConnectionError, /Could not connect to Mixpanel, with error "Network timeout"/)
|
|
288
|
+
end
|
|
208
289
|
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require 'mixpanel-ruby'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
describe 'Credentials Security' do
|
|
5
|
+
describe 'import with constructor credentials (recommended)' do
|
|
6
|
+
it 'should NOT include credentials in message payload' do
|
|
7
|
+
messages = []
|
|
8
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project')
|
|
9
|
+
|
|
10
|
+
# Create tracker with credentials in constructor
|
|
11
|
+
tracker = Mixpanel::Tracker.new('TOKEN', nil, credentials: credentials) do |type, message|
|
|
12
|
+
messages << [type, message]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Call import with nil api_key (recommended pattern)
|
|
16
|
+
tracker.import(nil, 'user123', 'Test Event', {'prop' => 'value'})
|
|
17
|
+
|
|
18
|
+
# Verify message was sent
|
|
19
|
+
expect(messages.length).to eq(1)
|
|
20
|
+
type, message_json = messages[0]
|
|
21
|
+
expect(type).to eq(:import)
|
|
22
|
+
|
|
23
|
+
# Parse the message
|
|
24
|
+
message = JSON.parse(message_json)
|
|
25
|
+
|
|
26
|
+
# CRITICAL: Credentials should NOT be in the message
|
|
27
|
+
expect(message).not_to have_key('credentials')
|
|
28
|
+
expect(message_json).not_to include('test-secret')
|
|
29
|
+
expect(message_json).not_to include('test-user')
|
|
30
|
+
|
|
31
|
+
# Message should only contain data
|
|
32
|
+
expect(message).to have_key('data')
|
|
33
|
+
expect(message['data']).to have_key('event')
|
|
34
|
+
expect(message['data']['event']).to eq('Test Event')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should NOT include credentials in buffered messages' do
|
|
38
|
+
messages = []
|
|
39
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project')
|
|
40
|
+
|
|
41
|
+
# Create buffered consumer with credentials
|
|
42
|
+
consumer = Mixpanel::BufferedConsumer.new(nil, nil, nil, 5, credentials: credentials) do |type, message|
|
|
43
|
+
messages << [type, message]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Send multiple event messages (events are buffered, imports are not)
|
|
47
|
+
5.times do |i|
|
|
48
|
+
consumer.send!(:event, {'data' => {'event' => "Event #{i}"}}.to_json)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Verify batched message was sent (auto-flushed when buffer reaches max_length)
|
|
52
|
+
expect(messages.length).to eq(1)
|
|
53
|
+
type, message_json = messages[0]
|
|
54
|
+
|
|
55
|
+
# CRITICAL: Credentials should NOT be in the batched message
|
|
56
|
+
expect(message_json).not_to include('credentials')
|
|
57
|
+
expect(message_json).not_to include('test-secret')
|
|
58
|
+
expect(message_json).not_to include('test-user')
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe 'tracking events' do
|
|
63
|
+
it 'should never include credentials in event messages' do
|
|
64
|
+
messages = []
|
|
65
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project')
|
|
66
|
+
|
|
67
|
+
tracker = Mixpanel::Tracker.new('TOKEN', nil, credentials: credentials) do |type, message|
|
|
68
|
+
messages << [type, message]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Track a regular event
|
|
72
|
+
tracker.track('user123', 'Test Event', {'prop' => 'value'})
|
|
73
|
+
|
|
74
|
+
# Verify message
|
|
75
|
+
expect(messages.length).to eq(1)
|
|
76
|
+
type, message_json = messages[0]
|
|
77
|
+
expect(type).to eq(:event)
|
|
78
|
+
|
|
79
|
+
# Credentials should NEVER be in event messages
|
|
80
|
+
expect(message_json).not_to include('credentials')
|
|
81
|
+
expect(message_json).not_to include('test-secret')
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe 'legacy API key pattern' do
|
|
86
|
+
it 'should include api_key in message but not credentials' do
|
|
87
|
+
messages = []
|
|
88
|
+
tracker = Mixpanel::Tracker.new('TOKEN') do |type, message|
|
|
89
|
+
messages << [type, message]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Use legacy API key pattern
|
|
93
|
+
tracker.import('MY_API_KEY', 'user123', 'Test Event', {'prop' => 'value'})
|
|
94
|
+
|
|
95
|
+
# Verify message
|
|
96
|
+
expect(messages.length).to eq(1)
|
|
97
|
+
type, message_json = messages[0]
|
|
98
|
+
message = JSON.parse(message_json)
|
|
99
|
+
|
|
100
|
+
# API key should be in message (legacy pattern)
|
|
101
|
+
expect(message).to have_key('api_key')
|
|
102
|
+
expect(message['api_key']).to eq('MY_API_KEY')
|
|
103
|
+
|
|
104
|
+
# But credentials should NOT be
|
|
105
|
+
expect(message).not_to have_key('credentials')
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'mixpanel-ruby'
|
|
2
|
+
|
|
3
|
+
describe Mixpanel::ServiceAccountCredentials do
|
|
4
|
+
describe '#initialize' do
|
|
5
|
+
it 'creates credentials with valid parameters' do
|
|
6
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'project123')
|
|
7
|
+
expect(credentials.username).to eq('user')
|
|
8
|
+
expect(credentials.secret).to eq('secret')
|
|
9
|
+
expect(credentials.project_id).to eq('project123')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'raises ArgumentError when username is nil' do
|
|
13
|
+
expect {
|
|
14
|
+
Mixpanel::ServiceAccountCredentials.new(nil, 'secret', 'project123')
|
|
15
|
+
}.to raise_error(ArgumentError, 'username is required')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'raises ArgumentError when username is empty' do
|
|
19
|
+
expect {
|
|
20
|
+
Mixpanel::ServiceAccountCredentials.new('', 'secret', 'project123')
|
|
21
|
+
}.to raise_error(ArgumentError, 'username is required')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'raises ArgumentError when secret is nil' do
|
|
25
|
+
expect {
|
|
26
|
+
Mixpanel::ServiceAccountCredentials.new('user', nil, 'project123')
|
|
27
|
+
}.to raise_error(ArgumentError, 'secret is required')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'raises ArgumentError when secret is empty' do
|
|
31
|
+
expect {
|
|
32
|
+
Mixpanel::ServiceAccountCredentials.new('user', '', 'project123')
|
|
33
|
+
}.to raise_error(ArgumentError, 'secret is required')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'raises ArgumentError when project_id is nil' do
|
|
37
|
+
expect {
|
|
38
|
+
Mixpanel::ServiceAccountCredentials.new('user', 'secret', nil)
|
|
39
|
+
}.to raise_error(ArgumentError, 'project_id is required')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'raises ArgumentError when project_id is empty' do
|
|
43
|
+
expect {
|
|
44
|
+
Mixpanel::ServiceAccountCredentials.new('user', 'secret', '')
|
|
45
|
+
}.to raise_error(ArgumentError, 'project_id is required')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'accepts integer project_id and converts to string' do
|
|
49
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 12345)
|
|
50
|
+
expect(credentials.project_id).to eq('12345')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
@@ -3,6 +3,7 @@ require 'time'
|
|
|
3
3
|
|
|
4
4
|
require 'mixpanel-ruby/events.rb'
|
|
5
5
|
require 'mixpanel-ruby/version.rb'
|
|
6
|
+
require 'mixpanel-ruby/credentials.rb'
|
|
6
7
|
|
|
7
8
|
describe Mixpanel::Events do
|
|
8
9
|
before(:each) do
|
|
@@ -73,4 +74,155 @@ describe Mixpanel::Events do
|
|
|
73
74
|
}
|
|
74
75
|
} ]])
|
|
75
76
|
end
|
|
77
|
+
|
|
78
|
+
it 'should send a well formed import/ message with service account credentials' do
|
|
79
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project-123')
|
|
80
|
+
|
|
81
|
+
# Create new Events instance with credentials in constructor
|
|
82
|
+
events_with_creds = Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials) do |type, message|
|
|
83
|
+
@log << [type, JSON.load(message)]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# New API: pass nil for api_key, credentials come from instance
|
|
87
|
+
events_with_creds.import(nil, 'TEST ID', 'Test Event', {
|
|
88
|
+
'Circumstances' => 'During a test'
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
expect(@log.length).to eq(1)
|
|
92
|
+
expect(@log[0][0]).to eq(:import)
|
|
93
|
+
|
|
94
|
+
message = @log[0][1]
|
|
95
|
+
# Credentials should NOT be in message (secure API)
|
|
96
|
+
expect(message).not_to have_key('credentials')
|
|
97
|
+
expect(message).not_to have_key('api_key')
|
|
98
|
+
expect(message['data']).to eq({
|
|
99
|
+
'event' => 'Test Event',
|
|
100
|
+
'properties' => {
|
|
101
|
+
'Circumstances' => 'During a test',
|
|
102
|
+
'distinct_id' => 'TEST ID',
|
|
103
|
+
'mp_lib' => 'ruby',
|
|
104
|
+
'$lib_version' => Mixpanel::VERSION,
|
|
105
|
+
'token' => 'TEST TOKEN',
|
|
106
|
+
'time' => @time_now.to_i * 1000
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'should raise ArgumentError when import is called without authentication' do
|
|
112
|
+
# Create Events without credentials
|
|
113
|
+
events = Mixpanel::Events.new('TEST TOKEN') do |type, message|
|
|
114
|
+
@log << [type, JSON.load(message)]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Try to import with nil api_key and no credentials
|
|
118
|
+
expect {
|
|
119
|
+
events.import(nil, 'TEST ID', 'Test Event', {})
|
|
120
|
+
}.to raise_error(ArgumentError, /import requires authentication/)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe 'import_events' do
|
|
124
|
+
it 'should send a well formed import/ message with constructor credentials' do
|
|
125
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('test-user', 'test-secret', 'test-project-123')
|
|
126
|
+
|
|
127
|
+
events_with_creds = Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials) do |type, message|
|
|
128
|
+
@log << [type, JSON.load(message)]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Clean API - no nil!
|
|
132
|
+
events_with_creds.import_events('TEST ID', 'Test Event', {
|
|
133
|
+
'Circumstances' => 'During a test'
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(@log.length).to eq(1)
|
|
137
|
+
expect(@log[0][0]).to eq(:import)
|
|
138
|
+
|
|
139
|
+
message = @log[0][1]
|
|
140
|
+
# Credentials should NOT be in message
|
|
141
|
+
expect(message).not_to have_key('credentials')
|
|
142
|
+
expect(message).not_to have_key('api_key')
|
|
143
|
+
expect(message['data']).to eq({
|
|
144
|
+
'event' => 'Test Event',
|
|
145
|
+
'properties' => {
|
|
146
|
+
'Circumstances' => 'During a test',
|
|
147
|
+
'distinct_id' => 'TEST ID',
|
|
148
|
+
'mp_lib' => 'ruby',
|
|
149
|
+
'$lib_version' => Mixpanel::VERSION,
|
|
150
|
+
'token' => 'TEST TOKEN',
|
|
151
|
+
'time' => @time_now.to_i * 1000
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it 'should raise ArgumentError when called without constructor credentials' do
|
|
157
|
+
events = Mixpanel::Events.new('TEST TOKEN') do |type, message|
|
|
158
|
+
@log << [type, JSON.load(message)]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
expect {
|
|
162
|
+
events.import_events('TEST ID', 'Test Event', {})
|
|
163
|
+
}.to raise_error(ArgumentError, /import_events requires credentials in constructor/)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
describe 'warnings' do
|
|
168
|
+
it 'should warn when credentials are passed with a custom block' do
|
|
169
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'project')
|
|
170
|
+
|
|
171
|
+
expect {
|
|
172
|
+
Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials) do |type, message|
|
|
173
|
+
# Custom block
|
|
174
|
+
end
|
|
175
|
+
}.to output(/credentials passed to Events\/Tracker are ignored/).to_stderr
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'should not warn when credentials are passed without a block' do
|
|
179
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'project')
|
|
180
|
+
|
|
181
|
+
expect {
|
|
182
|
+
Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials)
|
|
183
|
+
}.not_to output.to_stderr
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it 'should warn when using deprecated api_key in import' do
|
|
187
|
+
events = Mixpanel::Events.new('TEST TOKEN') do |type, message|
|
|
188
|
+
@log << [type, JSON.load(message)]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
expect {
|
|
192
|
+
events.import('API_KEY', 'TEST ID', 'Test Event', {})
|
|
193
|
+
}.to output(/DEPRECATION.*api_key to import\(\) is deprecated/).to_stderr
|
|
194
|
+
|
|
195
|
+
# Second call should also warn
|
|
196
|
+
expect {
|
|
197
|
+
events.import('API_KEY', 'TEST ID', 'Test Event 2', {})
|
|
198
|
+
}.to output(/DEPRECATION.*api_key to import\(\) is deprecated/).to_stderr
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should warn when using import(nil, ...) with credentials' do
|
|
202
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'project')
|
|
203
|
+
events = Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials) do |type, message|
|
|
204
|
+
@log << [type, JSON.load(message)]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
expect {
|
|
208
|
+
events.import(nil, 'TEST ID', 'Test Event', {})
|
|
209
|
+
}.to output(/DEPRECATION.*import\(nil, \.\.\.\) is deprecated.*import_events/).to_stderr
|
|
210
|
+
|
|
211
|
+
# Second call should also warn
|
|
212
|
+
expect {
|
|
213
|
+
events.import(nil, 'TEST ID', 'Test Event 2', {})
|
|
214
|
+
}.to output(/DEPRECATION.*import\(nil, \.\.\.\) is deprecated.*import_events/).to_stderr
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'should not warn when using import_events' do
|
|
218
|
+
credentials = Mixpanel::ServiceAccountCredentials.new('user', 'secret', 'project')
|
|
219
|
+
events = Mixpanel::Events.new('TEST TOKEN', nil, credentials: credentials) do |type, message|
|
|
220
|
+
@log << [type, JSON.load(message)]
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
expect {
|
|
224
|
+
events.import_events('TEST ID', 'Test Event', {})
|
|
225
|
+
}.not_to output(/DEPRECATION/).to_stderr
|
|
226
|
+
end
|
|
227
|
+
end
|
|
76
228
|
end
|