customerio 3.1.0 → 4.2.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
2
  SHA256:
3
- metadata.gz: 48f0d7c8bb61994c6bee0e1b846772f7ab304913182a1d1ac87f52a6e4e9beff
4
- data.tar.gz: e8df14b0db35439d08687a2ff61161d5d6bfc3a9f8ae6df71ba9c1cd7d4c91e9
3
+ metadata.gz: e58bba756887e5c3ae6e7aa75b3e2c5bd08fc5733d45ee513b56895e35b58011
4
+ data.tar.gz: 912374a003fe636fc5837cbf030a64141218f83b63fb9e455efa033375a2a8bb
5
5
  SHA512:
6
- metadata.gz: 7fff0a46a46e90a65f39694abf8713abe1a5e9edd0f388d26fea80d305332ed8425998397822899a9b66f27e77fb98e1051cd332842c73cd20da0a7ad7380a9d
7
- data.tar.gz: 1eab0fb3fe94024954b04f77c34029aa2b9a9b6a089d5d6aa86f9070101e0bf13e7019725e8031fcdd7af0ddf76532e4b2b85b6dfe7e482ecb5f407b339df381
6
+ metadata.gz: 1529f5cc20959ce9cdbe9e4103a29f5b5205594727b8951be18d61a6851520741e52150b20b20603b7d890f62ab56c3d391d9503d6c21e99a31032085da06557
7
+ data.tar.gz: '08adc273fd1d1cf2df0453788ac9c8889b8576aadf865cd9d587f029fe4de4a05b35d61dbcd845da2fdbba81b056bd7d3b92a9d7d2a3ad8800a3ad6b87ecb313'
@@ -1,6 +1,6 @@
1
1
  name: ruby_ci
2
2
 
3
- on: [push]
3
+ on: [push,pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,17 @@
1
+ ## Customerio 4.1.0 - Sep 27, 2021
2
+ ### Added
3
+ - Added support for [merge customers](https://customer.io/docs/api/#operation/merge) API
4
+
5
+ ## Customerio 4.0.1 - July 13, 2021
6
+ ### Changed
7
+ - Update addressable gem dependency to v2.8.0
8
+
9
+ ## Customerio 4.0.0 - July 6, 2021
10
+ ### Removed
11
+ - The `anonymous_track` method.
12
+
13
+ ### Added
14
+ - The `track_anonymous` method replaces `anonymous_track`. This method requires an `anonymous_id` parameter and will no longer trigger campaigns. If you previously used anonymous events to trigger campaigns, you can still do so [directly through the API](https://customer.io/docs/api/#operation/trackAnonymous). We now refer to anonymous events that trigger campaigns as ["invite events"](https://customer.io/docs/anonymous-events/#anonymous-or-invite).
1
15
 
2
16
  ## Customerio 3.1.0 - March 25, 2021
3
17
  ### Added
data/README.md CHANGED
@@ -104,6 +104,21 @@ recreated.
104
104
  $customerio.delete(5)
105
105
  ```
106
106
 
107
+ ### Merge duplicate customer profiles
108
+
109
+ When you merge two people, you pick a primary person and merge a secondary, duplicate person into it. The primary person remains after the merge and the secondary is deleted. This process is permanent: you cannot recover the secondary person.
110
+
111
+ The first and third parameters represent the identifier for the primary and secondary people respectively—one of `id`, `email`, or `cio_id`. The second and fourth parameters are the identifier values for the primary and secondary people respectively.
112
+
113
+ ```ruby
114
+ # $customerio.merge_customers("primaryType", "primaryIdentifier", "secondaryType", "secondaryIdentifier")
115
+ # primaryType / secondaryType are one of "id", "email", or "cio_id"
116
+ # primaryIdentifier / secondaryIdentifier are the identifier value corresponding to the type.
117
+
118
+ # merge customer "cperson@gmail.com" into "cool.person@company.com"
119
+ $customerio.merge_customers("email", "cool.person@company.com", "email", "cperson@gmail.com")
120
+ ```
121
+
107
122
  ### Tracking a custom event
108
123
 
109
124
  Now that you're identifying your customers with [Customer.io](http://customer.io), you can now send events like
@@ -131,10 +146,18 @@ $customerio.track(5, "purchase", :type => "socks", :price => "13.99", :timestamp
131
146
 
132
147
  ### Tracking anonymous events
133
148
 
134
- You can also send anonymous events, for situations where you don't yet have a customer record but still want to trigger a campaign:
149
+ You can also send anonymous events, for situations where you don't yet have a customer record yet. An anonymous event requires an `anonymous_id` representing the unknown person and an event `name`. When you identify a person, you can set their `anonymous_id` attribute. If [event merging](https://customer.io/docs/anonymous-events/#turn-on-merging) is turned on in your workspace, and the attribute matches the `anonymous_id` in one or more events that were logged within the last 30 days, we associate those events with the person.
150
+
151
+ Anonymous events cannot trigger campaigns by themselves. To trigger a campaign, the anonymous event must be associated with a person within 72 hours of the `track_anonymous` request.
135
152
 
136
153
  ```ruby
137
- $customerio.anonymous_track("help_enquiry", :recipient => 'user@example.com')
154
+ # Arguments
155
+ # anonymous_id (required) - the id representing the unknown person.
156
+ # name (required) - the name of the event you want to track.
157
+ # attributes (optional) - any related information you want to attach to the
158
+ # event.
159
+
160
+ $customerio.track_anonymous(anonymous_id, "product_view", :type => "socks" )
138
161
  ```
139
162
 
140
163
  Use the `recipient` attribute to specify the email address to send the messages to. [See our documentation on how to use anonymous events for more details](https://learn.customer.io/recipes/invite-emails.html).
data/customerio.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.version = Customerio::VERSION
18
18
 
19
19
  gem.add_dependency('multi_json', "~> 1.0")
20
- gem.add_dependency('addressable', '~> 2.7.0')
20
+ gem.add_dependency('addressable', '~> 2.8.0')
21
21
 
22
22
  gem.add_development_dependency('rake', '~> 10.5')
23
23
  gem.add_development_dependency('rspec', '3.3.0')
@@ -44,6 +44,8 @@ module Customerio
44
44
 
45
45
  req = request_class(method).new(uri.path)
46
46
 
47
+ headers['User-Agent'] = "Customer.io Ruby Client/" + Customerio::VERSION
48
+
47
49
  if @auth.has_key?(:site_id) && @auth.has_key?(:api_key)
48
50
  req.initialize_http_header(headers)
49
51
  req.basic_auth @auth[:site_id], @auth[:api_key]
@@ -1,7 +1,19 @@
1
1
  require "addressable/uri"
2
2
 
3
3
  module Customerio
4
+ class IdentifierType
5
+ ID = "id"
6
+ EMAIL = "email"
7
+ CIOID = "cio_id"
8
+ end
9
+
4
10
  class Client
11
+ PUSH_OPENED = 'opened'
12
+ PUSH_CONVERTED = 'converted'
13
+ PUSH_DELIVERED = 'delivered'
14
+
15
+ VALID_PUSH_EVENTS = [PUSH_OPENED, PUSH_CONVERTED, PUSH_DELIVERED]
16
+
5
17
  class MissingIdAttributeError < RuntimeError; end
6
18
  class ParamError < RuntimeError; end
7
19
 
@@ -39,9 +51,11 @@ module Customerio
39
51
  create_customer_event(customer_id, event_name, attributes)
40
52
  end
41
53
 
42
- def anonymous_track(event_name, attributes = {})
54
+ def track_anonymous(anonymous_id, event_name, attributes = {})
55
+ raise ParamError.new("anonymous_id must be a non-empty string") if is_empty?(anonymous_id)
43
56
  raise ParamError.new("event_name must be a non-empty string") if is_empty?(event_name)
44
- create_anonymous_event(event_name, attributes)
57
+
58
+ create_anonymous_event(anonymous_id, event_name, attributes)
45
59
  end
46
60
 
47
61
  def add_device(customer_id, device_id, platform, data={})
@@ -70,6 +84,30 @@ module Customerio
70
84
  @client.request_and_verify_response(:delete, device_id_path(customer_id, device_id))
71
85
  end
72
86
 
87
+ def track_push_notification_event(event_name, attributes = {})
88
+ keys = [:delivery_id, :device_id, :timestamp]
89
+ attributes = Hash[attributes.map { |(k,v)| [ k.to_sym, v ] }].
90
+ select { |k, v| keys.include?(k) }
91
+
92
+ raise ParamError.new('event_name must be one of opened, converted, or delivered') unless VALID_PUSH_EVENTS.include?(event_name)
93
+ raise ParamError.new('delivery_id must be a non-empty string') unless attributes[:delivery_id] != "" and !attributes[:delivery_id].nil?
94
+ raise ParamError.new('device_id must be a non-empty string') unless attributes[:device_id] != "" and !attributes[:device_id].nil?
95
+ raise ParamError.new('timestamp must be a valid timestamp') unless valid_timestamp?(attributes[:timestamp])
96
+
97
+ @client.request_and_verify_response(:post, track_push_notification_event_path, attributes.merge(event: event_name))
98
+ end
99
+
100
+ def merge_customers(primary_id_type, primary_id, secondary_id_type, secondary_id)
101
+ raise ParamError.new("invalid primary_id_type") if !is_valid_id_type?(primary_id_type)
102
+ raise ParamError.new("primary_id must be a non-empty string") if is_empty?(primary_id)
103
+ raise ParamError.new("invalid secondary_id_type") if !is_valid_id_type?(secondary_id_type)
104
+ raise ParamError.new("secondary_id must be a non-empty string") if is_empty?(secondary_id)
105
+
106
+ body = { :primary => {primary_id_type => primary_id}, :secondary => {secondary_id_type => secondary_id} }
107
+
108
+ @client.request_and_verify_response(:post, merge_customers_path, body)
109
+ end
110
+
73
111
  private
74
112
 
75
113
  def escape(val)
@@ -97,6 +135,14 @@ module Customerio
97
135
  "/api/v1/customers/#{escape(customer_id)}/unsuppress"
98
136
  end
99
137
 
138
+ def track_push_notification_event_path
139
+ "/push/events"
140
+ end
141
+
142
+ def merge_customers_path
143
+ "/api/v1/merge_customers"
144
+ end
145
+
100
146
  def create_or_update(attributes = {})
101
147
  attributes = Hash[attributes.map { |(k,v)| [ k.to_sym, v ] }]
102
148
  raise MissingIdAttributeError.new("Must provide a customer id") if is_empty?(attributes[:id])
@@ -106,16 +152,27 @@ module Customerio
106
152
  end
107
153
 
108
154
  def create_customer_event(customer_id, event_name, attributes = {})
109
- create_event("#{customer_path(customer_id)}/events", event_name, attributes)
155
+ create_event(
156
+ url: "#{customer_path(customer_id)}/events",
157
+ event_name: event_name,
158
+ attributes: attributes
159
+ )
110
160
  end
111
161
 
112
- def create_anonymous_event(event_name, attributes = {})
113
- create_event("/api/v1/events", event_name, attributes)
162
+ def create_anonymous_event(anonymous_id, event_name, attributes = {})
163
+ create_event(
164
+ url: "/api/v1/events",
165
+ event_name: event_name,
166
+ anonymous_id: anonymous_id,
167
+ attributes: attributes
168
+ )
114
169
  end
115
170
 
116
- def create_event(url, event_name, attributes = {})
171
+ def create_event(url:, event_name:, anonymous_id: nil, attributes: {})
117
172
  body = { :name => event_name, :data => attributes }
118
173
  body[:timestamp] = attributes[:timestamp] if valid_timestamp?(attributes[:timestamp])
174
+ body[:anonymous_id] = anonymous_id unless anonymous_id.nil?
175
+
119
176
  @client.request_and_verify_response(:post, url, body)
120
177
  end
121
178
 
@@ -126,5 +183,9 @@ module Customerio
126
183
  def is_empty?(val)
127
184
  val.nil? || (val.is_a?(String) && val.strip == "")
128
185
  end
186
+
187
+ def is_valid_id_type?(input)
188
+ [IdentifierType::ID, IdentifierType::CIOID, IdentifierType::EMAIL].include? input
189
+ end
129
190
  end
130
191
  end
@@ -1,3 +1,3 @@
1
1
  module Customerio
2
- VERSION = "3.1.0"
2
+ VERSION = "4.2.0"
3
3
  end
@@ -14,7 +14,7 @@ describe Customerio::APIClient do
14
14
  end
15
15
 
16
16
  def request_headers
17
- { 'Authorization': "Bearer #{app_key}", 'Content-Type': 'application/json' }
17
+ { 'Authorization': "Bearer #{app_key}", 'Content-Type': 'application/json', 'User-Agent': 'Customer.io Ruby Client/' + Customerio::VERSION }
18
18
  end
19
19
 
20
20
  def json(data)
@@ -18,11 +18,11 @@ describe Customerio::BaseClient do
18
18
 
19
19
  def track_client_request_headers
20
20
  token = Base64.strict_encode64("#{site_id}:#{api_key}")
21
- { 'Authorization': "Basic #{token}", 'Content-Type': 'application/json' }
21
+ { 'Authorization': "Basic #{token}", 'Content-Type': 'application/json', 'User-Agent': 'Customer.io Ruby Client/' + Customerio::VERSION }
22
22
  end
23
23
 
24
24
  def api_client_request_headers
25
- { 'Authorization': "Bearer #{app_key}", 'Content-Type': 'application/json' }
25
+ { 'Authorization': "Bearer #{app_key}", 'Content-Type': 'application/json', 'User-Agent': 'Customer.io Ruby Client/' + Customerio::VERSION }
26
26
  end
27
27
 
28
28
  describe "with a site ID and API key" do
data/spec/client_spec.rb CHANGED
@@ -150,16 +150,18 @@ describe Customerio::Client do
150
150
  time = Time.now.to_i
151
151
 
152
152
  stub_request(:put, api_uri('/api/v1/customers/5')).with(
153
- body: json({
153
+ body: {
154
154
  id: 5,
155
155
  email: "customer@example.com",
156
156
  created_at: time,
157
157
  first_name: "Bob",
158
- plan: "basic"
159
- })).to_return(status: 200, body: "", headers: {})
158
+ plan: "basic",
159
+ anonymous_id: "anon-id"
160
+ }).to_return(status: 200, body: "", headers: {})
160
161
 
161
162
  client.identify({
162
163
  id: 5,
164
+ anonymous_id: "anon-id",
163
165
  email: "customer@example.com",
164
166
  created_at: time,
165
167
  first_name: "Bob",
@@ -381,31 +383,35 @@ describe Customerio::Client do
381
383
  end
382
384
 
383
385
  context "tracking an anonymous event" do
386
+ let(:anon_id) { "anon-id" }
387
+
384
388
  it "sends a POST request to the customer.io's anonymous event API" do
385
389
  stub_request(:post, api_uri('/api/v1/events')).
386
- with(body: json({ name: "purchase", data: {} })).
390
+ with(body: { anonymous_id: anon_id, name: "purchase", data: {} }).
387
391
  to_return(status: 200, body: "", headers: {})
388
392
 
389
- client.anonymous_track("purchase")
393
+ client.track_anonymous(anon_id, "purchase")
390
394
  end
391
395
 
392
396
  it "sends any optional event attributes" do
393
397
  stub_request(:post, api_uri('/api/v1/events')).
394
- with(body: json({
398
+ with(body: {
399
+ anonymous_id: anon_id,
395
400
  name: "purchase",
396
401
  data: {
397
402
  type: "socks",
398
403
  price: "13.99"
399
404
  }
400
- })).
405
+ }).
401
406
  to_return(status: 200, body: "", headers: {})
402
407
 
403
- client.anonymous_track("purchase", type: "socks", price: "13.99")
408
+ client.track_anonymous(anon_id, "purchase", type: "socks", price: "13.99")
404
409
  end
405
410
 
406
411
  it "allows sending of a timestamp" do
407
412
  stub_request(:post, api_uri('/api/v1/events')).
408
- with(body: json({
413
+ with(body: {
414
+ anonymous_id: anon_id,
409
415
  name: "purchase",
410
416
  data: {
411
417
  type: "socks",
@@ -413,73 +419,34 @@ describe Customerio::Client do
413
419
  timestamp: 1561231234
414
420
  },
415
421
  timestamp: 1561231234
416
- })).
422
+ }).
417
423
  to_return(status: 200, body: "", headers: {})
418
424
 
419
- client.anonymous_track("purchase", type: "socks", price: "13.99", timestamp: 1561231234)
425
+ client.track_anonymous(anon_id, "purchase", type: "socks", price: "13.99", timestamp: 1561231234)
420
426
  end
421
- end
422
- end
423
-
424
- describe "#anonymous_track" do
425
- it "raises an error if POST doesn't return a 2xx response code" do
426
- stub_request(:post, api_uri('/api/v1/events')).
427
- with(body: json(name: "purchase", data: {})).
428
- to_return(status: 500, body: "", headers: {})
429
-
430
- lambda { client.anonymous_track("purchase") }.should raise_error(Customerio::InvalidResponse)
431
- end
432
-
433
- it "throws an error when event_name is missing" do
434
- stub_request(:put, /track.customer.io/)
435
- .to_return(status: 200, body: "", headers: {})
436
-
437
- lambda { client.anonymous_track(" ") }.should raise_error(Customerio::Client::ParamError, "event_name must be a non-empty string")
438
- end
439
-
440
- it "uses the site_id and api key for basic auth and sends the event name" do
441
- stub_request(:post, api_uri('/api/v1/events')).
442
- with(body: json(name: "purchase", data: {})).
443
- to_return(status: 200, body: "", headers: {})
444
-
445
- client.anonymous_track("purchase")
446
- end
447
-
448
- it "sends any optional event attributes" do
449
- stub_request(:post, api_uri('/api/v1/events')).
450
- with(body: {
451
- name: "purchase",
452
- data: {
453
- type: "socks",
454
- price: "27.99"
455
- },
456
- }).
457
427
 
458
- to_return(status: 200, body: "", headers: {})
428
+ it "raises an error if POST doesn't return a 2xx response code" do
429
+ stub_request(:post, api_uri('/api/v1/events')).
430
+ with(body: { anonymous_id: anon_id, name: "purchase", data: {} }).
431
+ to_return(status: 500, body: "", headers: {})
459
432
 
460
- client.anonymous_track("purchase", type: "socks", price: "27.99")
461
- end
433
+ lambda { client.track_anonymous(anon_id, "purchase") }.should raise_error(Customerio::InvalidResponse)
434
+ end
462
435
 
463
- it "allows sending of a timestamp" do
464
- stub_request(:post, api_uri('/api/v1/events')).
465
- with(body: json({
466
- name: "purchase",
467
- data: {
468
- type: "socks",
469
- price: "27.99",
470
- timestamp: 1561235678
471
- },
472
- timestamp: 1561235678
473
- })).
436
+ it "throws an error when anonymous_id is missing" do
437
+ stub_request(:post, api_uri('/api/v1/events')).
438
+ with(body: { anonymous_id: anon_id, name: "purchase", data: {} }).
439
+ to_return(status: 500, body: "", headers: {})
474
440
 
475
- to_return(status: 200, body: "", headers: {})
441
+ lambda { client.track_anonymous("", "some_event") }.should raise_error(Customerio::Client::ParamError)
442
+ end
476
443
 
477
- client.anonymous_track("purchase", type: "socks", price: "27.99", timestamp: 1561235678)
478
- end
444
+ it "throws an error when event_name is missing" do
445
+ stub_request(:post, api_uri('/api/v1/events')).
446
+ with(body: { anonymous_id: anon_id, name: "purchase", data: {} }).
447
+ to_return(status: 500, body: "", headers: {})
479
448
 
480
- context "too many arguments are passed" do
481
- it "throws an error" do
482
- lambda { client.anonymous_track("purchase", "text", type: "socks", price: "27.99") }.should raise_error(ArgumentError)
449
+ lambda { client.track_anonymous(anon_id, "") }.should raise_error(Customerio::Client::ParamError)
483
450
  end
484
451
  end
485
452
  end
@@ -546,4 +513,114 @@ describe Customerio::Client do
546
513
  lambda { client.delete_device(5, nil) }.should raise_error(Customerio::Client::ParamError)
547
514
  end
548
515
  end
516
+
517
+ describe "#track_push_notification_event" do
518
+ attr_accessor :client, :attributes
519
+
520
+ before(:each) do
521
+ @client = Customerio::Client.new("SITE_ID", "API_KEY", :json => true)
522
+ @attributes = {
523
+ :delivery_id => 'foo',
524
+ :device_id => 'bar',
525
+ :timestamp => Time.now.to_i
526
+ }
527
+ end
528
+
529
+ it "sends a POST request to customer.io's /push/events endpoint" do
530
+ stub_request(:post, api_uri('/push/events')).
531
+ with(
532
+ :body => json(attributes.merge({
533
+ :event => 'opened'
534
+ })),
535
+ :headers => {
536
+ 'Content-Type' => 'application/json'
537
+ }).
538
+ to_return(:status => 200, :body => "", :headers => {})
539
+
540
+ client.track_push_notification_event('opened', attributes)
541
+ end
542
+
543
+ it "should raise if event is invalid" do
544
+ stub_request(:post, api_uri('/push/events')).
545
+ to_return(:status => 200, :body => "", :headers => {})
546
+
547
+ expect {
548
+ client.track_push_notification_event('closed', attributes.merge({ :delivery_id => nil }))
549
+ }.to raise_error(Customerio::Client::ParamError, 'event_name must be one of opened, converted, or delivered')
550
+ end
551
+
552
+ it "should raise if delivery_id is invalid" do
553
+ stub_request(:post, api_uri('/push/events')).
554
+ to_return(:status => 200, :body => "", :headers => {})
555
+
556
+ expect {
557
+ client.track_push_notification_event('opened', attributes.merge({ :delivery_id => nil }))
558
+ }.to raise_error(Customerio::Client::ParamError, 'delivery_id must be a non-empty string')
559
+
560
+ expect {
561
+ client.track_push_notification_event('opened', attributes.merge({ :delivery_id => '' }))
562
+ }.to raise_error(Customerio::Client::ParamError, 'delivery_id must be a non-empty string')
563
+ end
564
+
565
+ it "should raise if device_id is invalid" do
566
+ stub_request(:post, api_uri('/push/events')).
567
+ to_return(:status => 200, :body => "", :headers => {})
568
+
569
+ expect {
570
+ client.track_push_notification_event('opened', attributes.merge({ :device_id => nil }))
571
+ }.to raise_error(Customerio::Client::ParamError, 'device_id must be a non-empty string')
572
+
573
+ expect {
574
+ client.track_push_notification_event('opened', attributes.merge({ :device_id => '' }))
575
+ }.to raise_error(Customerio::Client::ParamError, 'device_id must be a non-empty string')
576
+ end
577
+
578
+ it "should raise if timestamp is invalid" do
579
+ stub_request(:post, api_uri('/push/events')).
580
+ to_return(:status => 200, :body => "", :headers => {})
581
+
582
+ expect {
583
+ client.track_push_notification_event('opened', attributes.merge({ :timestamp => nil }))
584
+ }.to raise_error(Customerio::Client::ParamError, 'timestamp must be a valid timestamp')
585
+
586
+ expect {
587
+ client.track_push_notification_event('opened', attributes.merge({ :timestamp => 999999999 }))
588
+ }.to raise_error(Customerio::Client::ParamError, 'timestamp must be a valid timestamp')
589
+
590
+ expect {
591
+ client.track_push_notification_event('opened', attributes.merge({ :timestamp => 100000000000 }))
592
+ }.to raise_error(Customerio::Client::ParamError, 'timestamp must be a valid timestamp')
593
+ end
594
+ end
595
+
596
+ describe "#merge_customers" do
597
+ before(:each) do
598
+ @client = Customerio::Client.new("SITE_ID", "API_KEY", :json => true)
599
+ end
600
+
601
+ it "should raise validation errors on merge params" do
602
+ expect {
603
+ client.merge_customers("", "id1", Customerio::IdentifierType::ID, "id2")
604
+ }.to raise_error(Customerio::Client::ParamError, 'invalid primary_id_type')
605
+
606
+ expect {
607
+ client.merge_customers(Customerio::IdentifierType::EMAIL, "", Customerio::IdentifierType::ID, "id2")
608
+ }.to raise_error(Customerio::Client::ParamError, 'primary_id must be a non-empty string')
609
+
610
+ expect {
611
+ client.merge_customers(Customerio::IdentifierType::CIOID, "id1", "", "id2")
612
+ }.to raise_error(Customerio::Client::ParamError, 'invalid secondary_id_type')
613
+
614
+ expect {
615
+ client.merge_customers(Customerio::IdentifierType::ID, "id1", Customerio::IdentifierType::ID, "")
616
+ }.to raise_error(Customerio::Client::ParamError, 'secondary_id must be a non-empty string')
617
+ end
618
+
619
+ it "requires a valid customer_id when creating" do
620
+ stub_request(:post, api_uri('/api/v1/merge_customers')).
621
+ to_return(status: 200, body: "", headers: {})
622
+
623
+ client.merge_customers(Customerio::IdentifierType::ID, "ID1", Customerio::IdentifierType::EMAIL, "hello@company.com")
624
+ end
625
+ end
549
626
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: customerio
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Allison
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-25 00:00:00.000000000 Z
11
+ date: 2021-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.7.0
33
+ version: 2.8.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.7.0
40
+ version: 2.8.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -101,7 +101,6 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
- - ".circleci/config.yml"
105
104
  - ".github/workflows/main.yml"
106
105
  - ".gitignore"
107
106
  - CHANGELOG.markdown
@@ -126,7 +125,7 @@ homepage: http://customer.io
126
125
  licenses:
127
126
  - MIT
128
127
  metadata: {}
129
- post_install_message:
128
+ post_install_message:
130
129
  rdoc_options: []
131
130
  require_paths:
132
131
  - lib
@@ -141,8 +140,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
140
  - !ruby/object:Gem::Version
142
141
  version: '0'
143
142
  requirements: []
144
- rubygems_version: 3.2.3
145
- signing_key:
143
+ rubygems_version: 3.0.3
144
+ signing_key:
146
145
  specification_version: 4
147
146
  summary: A ruby client for the Customer.io event API.
148
147
  test_files:
data/.circleci/config.yml DELETED
@@ -1,61 +0,0 @@
1
- ---
2
- version: 2
3
-
4
- references:
5
- restore_cache: &restore_cache
6
- type: cache-restore
7
- name: Restore bundle cache
8
- key: customerio-ruby-{{ checksum "customerio.gemspec" }}
9
-
10
- save_cache: &save_cache
11
- type: cache-save
12
- name: Store bundle cache
13
- key: customerio-ruby-{{ checksum "customerio.gemspec" }}
14
- paths:
15
- - vendor/bundle
16
-
17
- jobs:
18
- ruby_27:
19
- working_directory: ~/customerio-ruby
20
- docker:
21
- - image: circleci/ruby:2.7.2
22
- environment:
23
- RAILS_ENV: test
24
- steps:
25
- - checkout
26
- - *restore_cache
27
- - run: bundle install
28
- - *save_cache
29
- - run: bundle exec rspec
30
- ruby_26:
31
- working_directory: ~/customerio-ruby
32
- docker:
33
- - image: circleci/ruby:2.6.6
34
- environment:
35
- RAILS_ENV: test
36
- steps:
37
- - checkout
38
- - *restore_cache
39
- - run: bundle install
40
- - *save_cache
41
- - run: bundle exec rspec
42
- ruby_25:
43
- working_directory: ~/customerio-ruby
44
- docker:
45
- - image: circleci/ruby:2.5.8
46
- environment:
47
- RAILS_ENV: test
48
- steps:
49
- - checkout
50
- - *restore_cache
51
- - run: bundle install
52
- - *save_cache
53
- - run: bundle exec rspec
54
-
55
- workflows:
56
- version: 2
57
- test:
58
- jobs:
59
- - ruby_27
60
- - ruby_26
61
- - ruby_25