delighted 1.8.0rc1 → 2.1.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: 92ff2bf5264a02443144522c7aa937d879d285414b2f27d5da9a149d8523b851
4
- data.tar.gz: 0671a5ab613fdf6824dd86527d9fd0592eee37d0f53052a5e1e2b24b55ba3eae
3
+ metadata.gz: 65db888686e9187504e0327b3c9e4398fc9fe22070caf2554a6095f9a6a23a77
4
+ data.tar.gz: cb7b9a981561519bd04ab15ce8bd626f52c4766261a8a56aa1f55f170b467783
5
5
  SHA512:
6
- metadata.gz: 8ec727249f7682b0c3bf66fb0bfd921f456a013e775d4f206d98e61fb35807312c6329e105acb9f5ef8c7276839a47c67829e7e7b2626bd0e9a4e3d91d6d8d6d
7
- data.tar.gz: 9914a4c08a10787c4da9a94d6a7208bc5345cf513535a36945442596a6d0967372a2c1a216b0028e88ee888b06e286c72325fa54c162d9ca7ca4389e486bc861
6
+ metadata.gz: 83cb181d09e2f31eb37966b96c359fc2b5483b0cb239d8b808443bbce6cb3c194da52846d2ea9afa860e2dd3ca80208a6f6242161c71b3a172ea3d95ab456a35
7
+ data.tar.gz: 3dc2423403ee8ad2a4c9bb66a3c7b840929e467e299ed36af2143aacde4522f945e7ed36e47e62ebc73f1ef802e834e60e7f1e19e2480280f33ab548a85c29b9
data/.travis.yml CHANGED
@@ -1,12 +1,11 @@
1
1
  language: ruby
2
2
  before_install: gem update bundler
3
3
  rvm:
4
+ - ruby-head
5
+ - 2.5
4
6
  - 2.2
5
7
  - 2.1
6
8
  - 2.0
7
9
  - 1.9.3
8
- - 1.9.2
9
- - 1.8.7
10
10
  - jruby-18mode
11
11
  - jruby-19mode
12
- - ree
data/CHANGELOG.md CHANGED
@@ -1,4 +1,28 @@
1
- ## 1.8.0rc1 (2018-05-22)
1
+ ## 2.1.0 (2021-05-12)
2
+
3
+ Features:
4
+
5
+ - Add `Delighted::AutopilotConfiguration.retrieve`
6
+ - Add `Delighted::AutopilotMembership.list`
7
+ - Add `Delighted::AutopilotMembership.create`
8
+ - Add `Delighted::AutopilotMembership.delete`
9
+
10
+ Compatibility changes:
11
+
12
+ - Replace deprecated `URI::regexp` with `URI::DEFAULT_PARSER.make_regexp`
13
+
14
+ ## 2.0.0 (2020-03-18)
15
+
16
+ Features:
17
+
18
+ - Add `Delighted::Person.list`
19
+
20
+ Compatibility changes:
21
+
22
+ - Add support for Ruby 2.7
23
+ - Drop support for Ruby 1.8.7, 1.9.2, and ree
24
+
25
+ ## 1.8.0 (2018-05-22)
2
26
 
3
27
  Features:
4
28
 
data/README.md CHANGED
@@ -49,6 +49,28 @@ updated_person1 = Delighted::Person.create(:email => "foo+test1@delighted.com",
49
49
  :name => "James Scott", :send => false)
50
50
  ```
51
51
 
52
+ Listing all people:
53
+
54
+ ```ruby
55
+ # List all people, auto pagination
56
+ # Note: Make sure to handle the possible rate limits error
57
+ people = Delighted::Person.list
58
+ begin
59
+ people.auto_paging_each do |person|
60
+ # Do something with person
61
+ end
62
+ rescue Delighted::RateLimitError => e
63
+ # Indicates how long to wait before making this request again
64
+ e.retry_after
65
+ retry
66
+ end
67
+
68
+ # For convenience, this method can use a sleep to automatically handle rate limits
69
+ people.auto_paging_each({ auto_handle_rate_limits: true }) do |person|
70
+ # Do something with person
71
+ end
72
+ ```
73
+
52
74
  Unsubscribing people:
53
75
 
54
76
  ```ruby
@@ -56,7 +78,7 @@ Unsubscribing people:
56
78
  Delighted::Unsubscribe.create(:person_email => "foo+test1@delighted.com")
57
79
  ```
58
80
 
59
- Listing people who have unsubscribed:
81
+ Listing people who have unsubscribed (auto pagination not supported):
60
82
 
61
83
  ```ruby
62
84
  # List all people who have unsubscribed, 20 per page, first 2 pages
@@ -64,7 +86,7 @@ survey_responses_page1 = Delighted::Unsubscribe.all
64
86
  survey_responses_page2 = Delighted::Unsubscribe.all(:page => 2)
65
87
  ```
66
88
 
67
- Listing people whose emails have bounced:
89
+ Listing people whose emails have bounced (auto pagination not supported):
68
90
 
69
91
  ```ruby
70
92
  # List all people whose emails have bounced, 20 per page, first 2 pages
@@ -149,6 +171,80 @@ filtered_survey_responses = Delighted::SurveyResponse.all(:page => 5,
149
171
  :until => Time.utc(2013, 11, 01))
150
172
  ```
151
173
 
174
+ Getting Autopilot state:
175
+
176
+ ```ruby
177
+ email_autopilot_state = Delighted::AutopilotConfiguration.retrieve("email")
178
+ sms_autopilot_state = Delighted::AutopilotConfiguration.retrieve("sms")
179
+ ```
180
+
181
+ Listing Autopilot members:
182
+
183
+ ```ruby
184
+ email_autopilot_members = Delighted::AutopilotMembership::Email.list
185
+ begin
186
+ email_autopilot_members.auto_paging_each do |membership|
187
+ # Do something with membership
188
+ end
189
+ rescue Delighted::RateLimitError => e
190
+ # Indicates how long to wait before making this request again
191
+ e.retry_after
192
+ retry
193
+ end
194
+
195
+ # For convenience, this method can use a sleep to automatically handle rate limits
196
+ email_autopilot_members.auto_paging_each({ auto_handle_rate_limits: true }) do |membership|
197
+ # Do something with membership
198
+ end
199
+ ```
200
+
201
+ Look up specific Autopilot member:
202
+
203
+ ```ruby
204
+ Delighted::AutopilotMembership::Email
205
+ .list(person_email: "foo+test1@delighted.com") # or person_id or person_phone_number
206
+ .auto_paging_each({ auto_handle_rate_limits: true }) do |membership|
207
+ # Do something with membership. If no membership for this person exists,
208
+ # this block will never be called.
209
+ end
210
+ ```
211
+
212
+ Add a person to Autopilot:
213
+
214
+ ```ruby
215
+ props = {
216
+ "Shoe Type" => "Sneaker",
217
+ "Handedness" => "Left"
218
+ }
219
+ result = Delighted::AutopilotMembership::Email.create(
220
+ person_email: "foo+test1@delighted.com",
221
+ properties: props
222
+ )
223
+ ```
224
+
225
+ Update a person in Autopilot:
226
+
227
+ ```ruby
228
+ props = {
229
+ "Shoe Type" => "Sandal",
230
+ "Handedness" => "Left"
231
+ }
232
+ result = Delighted::AutopilotMembership::Email.create(
233
+ person_email: "foo+test1@delighted.com",
234
+ properties: props
235
+ )
236
+ ```
237
+
238
+ Remove a person from Autopilot:
239
+
240
+ ```ruby
241
+ result = Delighted::AutopilotMembership::Sms.delete(
242
+ person_phone_number: "+15555551212"
243
+ )
244
+
245
+ result = Delighted::AutopilotMembership::Sms.delete(person_id: "433523")
246
+ ```
247
+
152
248
  Retrieving metrics:
153
249
 
154
250
  ```ruby
data/lib/delighted.rb CHANGED
@@ -9,9 +9,11 @@ require 'delighted/version'
9
9
  require 'delighted/utils'
10
10
  require 'delighted/json'
11
11
 
12
+ require 'delighted/list_resource'
12
13
  require 'delighted/enumerable_resource_collection'
13
14
  require 'delighted/resource'
14
15
  require 'delighted/operations/all'
16
+ require 'delighted/operations/list'
15
17
  require 'delighted/operations/create'
16
18
  require 'delighted/operations/retrieve'
17
19
  require 'delighted/operations/update'
@@ -24,6 +26,9 @@ require 'delighted/resources/survey_request'
24
26
  require 'delighted/resources/survey_response'
25
27
  require 'delighted/resources/unsubscribe'
26
28
 
29
+ require 'delighted/resources/autopilot_configuration'
30
+ require 'delighted/resources/autopilot_membership'
31
+
27
32
  require 'delighted/errors'
28
33
  require 'delighted/http_response'
29
34
  require 'delighted/http_adapter'
@@ -2,6 +2,7 @@ module Delighted
2
2
  class Client
3
3
  DEFAULT_API_BASE_URL = "https://api.delightedapp.com/v1"
4
4
  DEFAULT_HTTP_ADAPTER = HTTPAdapter.new
5
+ DEFAULT_ACCEPT_HEADER = "application/json"
5
6
 
6
7
  def initialize(opts = {})
7
8
  @api_key = opts[:api_key] or raise ArgumentError, "You must provide an API key by setting Delighted.api_key = '123abc' or passing { :api_key => '123abc' } when instantiating Delighted::Client.new"
@@ -10,13 +11,21 @@ module Delighted
10
11
  end
11
12
 
12
13
  def get_json(path, params = {})
13
- headers = default_headers.dup.merge('Accept' => 'application/json')
14
+ request_get(path, {params: params})[:json]
15
+ end
14
16
 
15
- uri = URI.parse(File.join(@api_base_url, path))
17
+ def request_get(path, opts = {})
18
+ accept_header = opts.fetch(:accept_header, DEFAULT_ACCEPT_HEADER)
19
+ params = opts.fetch(:params, {})
20
+
21
+ headers = default_headers.dup.merge('Accept' => accept_header)
22
+
23
+ path = File.join(@api_base_url, path) unless is_full_url(path)
24
+ uri = URI.parse(path)
16
25
  uri.query = Utils.to_query(params) unless params.empty?
17
26
 
18
27
  response = @http_adapter.request(:get, uri, headers)
19
- handle_json_response(response)
28
+ { json: handle_json_response(response), response: response }
20
29
  end
21
30
 
22
31
  def post_json(path, params = {})
@@ -76,5 +85,9 @@ module Delighted
76
85
  'User-Agent' => "Delighted RubyGem #{Delighted::VERSION}"
77
86
  }.freeze
78
87
  end
88
+
89
+ def is_full_url(url)
90
+ !!(URI::DEFAULT_PARSER.make_regexp(%w(http https)) =~ url)
91
+ end
79
92
  end
80
93
  end
@@ -38,4 +38,8 @@ module Delighted
38
38
  class ServiceUnavailableError < Error
39
39
  # 503, maintenance or overloaded
40
40
  end
41
+
42
+ class PaginationError < StandardError
43
+ # e.g. pagination completed
44
+ end
41
45
  end
@@ -12,6 +12,11 @@ module Delighted
12
12
  get_header_value("content-type")
13
13
  end
14
14
 
15
+ def next_link
16
+ link_header = get_header_value("link")
17
+ parse_link_header(link_header)[:next]
18
+ end
19
+
15
20
  def retry_after
16
21
  if value = get_header_value("retry-after")
17
22
  value.to_i
@@ -37,5 +42,22 @@ module Delighted
37
42
  end
38
43
  end
39
44
  end
45
+
46
+ def parse_link_header(header_value)
47
+ links = {}
48
+ parts = Array(header_value)
49
+ .map { |v| v.split(",") }
50
+ .flatten
51
+ .map(&:strip)
52
+ # Parse each part into a named link
53
+ parts.each do |part|
54
+ section = part.split(';')
55
+ next if section.length < 2
56
+ url = section[0][/<(.*)>/,1]
57
+ name = section[1][/rel="?([^"]*)"?/,1].to_sym
58
+ links[name] = url
59
+ end
60
+ links
61
+ end
40
62
  end
41
63
  end
@@ -0,0 +1,45 @@
1
+ module Delighted
2
+ class ListResource
3
+ def initialize(klass, path, opts, client)
4
+ @class = klass
5
+ @path = path
6
+ @opts = opts
7
+ @client = client
8
+ @iteration_count = 0
9
+ @done = false
10
+ end
11
+
12
+ def auto_paging_each(opts = {})
13
+ raise PaginationError, "pagination completed" if @done
14
+
15
+ auto_handle_rate_limits = opts.fetch(:auto_handle_rate_limits, false)
16
+ loop do
17
+ begin
18
+ # Get next (or first) page
19
+ if @iteration_count == 0
20
+ data = @client.request_get(@path, { params: @opts })
21
+ else
22
+ data = @client.request_get(@next_link)
23
+ end
24
+ rescue Delighted::RateLimitedError => e
25
+ if auto_handle_rate_limits
26
+ sleep e.retry_after
27
+ retry
28
+ else
29
+ raise
30
+ end
31
+ end
32
+
33
+ @iteration_count += 1
34
+ @next_link = data[:response].next_link
35
+
36
+ data[:json].map do |attributes|
37
+ yield @class.new(attributes)
38
+ end
39
+
40
+ break if @next_link.nil?
41
+ end
42
+ @done = true
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ module Delighted
2
+ module Operations
3
+ module List
4
+ def self.included(klass)
5
+ klass.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def list(opts = {}, client = Delighted.shared_client)
10
+ ListResource.new(self, path, Utils.serialize_values(opts), client)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Delighted
2
+ class AutopilotConfiguration < Resource
3
+ self.path = "/autopilot"
4
+
5
+ include Operations::Retrieve
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ module Delighted
2
+ class AutopilotMembership < Resource
3
+ # This is a class purely so that Sms and Email share a common semantic base class
4
+
5
+ class << self
6
+ def delete(person_id_hash, client = Delighted.shared_client)
7
+ json = client.delete_json(path, person_id_hash)
8
+ json.merge(:person => Person.new(json[:person]))
9
+ end
10
+ end
11
+
12
+ class Sms < AutopilotMembership
13
+ self.path = "/autopilot/sms/memberships"
14
+ self.expandable_attributes = { :person => Person, :next_survey_request => SurveyRequest }
15
+
16
+ include Operations::List
17
+ include Operations::Create
18
+ end
19
+
20
+ class Email < AutopilotMembership
21
+ self.path = "/autopilot/email/memberships"
22
+ self.expandable_attributes = { :person => Person, :next_survey_request => SurveyRequest }
23
+
24
+ include Operations::List
25
+ include Operations::Create
26
+ end
27
+ end
28
+ end
@@ -4,5 +4,6 @@ module Delighted
4
4
 
5
5
  include Operations::Create
6
6
  include Operations::Delete
7
+ include Operations::List
7
8
  end
8
9
  end
@@ -1,3 +1,3 @@
1
1
  module Delighted
2
- VERSION = "1.8.0rc1"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -38,6 +38,129 @@ class Delighted::MetricsTest < Delighted::TestCase
38
38
  end
39
39
 
40
40
  class Delighted::PeopleTest < Delighted::TestCase
41
+ def test_listing_people_auto_paginate
42
+ uri = URI.parse("https://api.delightedapp.com/v1/people")
43
+ uri_next = URI.parse("https://api.delightedapp.com/v1/people.json?page_info=123456789")
44
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
45
+
46
+ # First request mock
47
+ example_person1 = {:person_id => "4945", :email => "foo@example.com", :name => "Gold"}
48
+ example_person2 = {:person_id => "4946", :email => "foo+2@example.com", :name => "Silver"}
49
+ response = Delighted::HTTPResponse.new(200, {"Link" => "<#{uri_next}>; rel=\"next\""}, Delighted::JSON.dump([example_person1,example_person2]))
50
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
51
+
52
+ # Next request mock
53
+ example_person_next = {:person_id => "4947", :email => "foo+3@example.com", :name => "Bronze"}
54
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump([example_person_next]))
55
+ mock_http_adapter.expects(:request).with(:get, uri_next, headers).once.returns(response)
56
+
57
+ persons_all = []
58
+ Delighted::Person.list.auto_paging_each do |p|
59
+ persons_all << p
60
+ end
61
+
62
+ assert_equal 3, persons_all.size
63
+
64
+ first_person = persons_all[0]
65
+ assert_kind_of Delighted::Person, first_person
66
+ assert_equal "Gold", first_person.name
67
+ assert_equal example_person1, first_person.to_hash
68
+ second_person = persons_all[1]
69
+ assert_kind_of Delighted::Person, second_person
70
+ assert_equal "Silver", second_person.name
71
+ assert_equal example_person2, second_person.to_hash
72
+ third_person = persons_all[2]
73
+ assert_kind_of Delighted::Person, third_person
74
+ assert_equal "Bronze", third_person.name
75
+ assert_equal example_person_next, third_person.to_hash
76
+ end
77
+
78
+ def test_listing_people_rate_limited
79
+ uri = URI.parse("https://api.delightedapp.com/v1/people")
80
+ uri_next = URI.parse("https://api.delightedapp.com/v1/people.json?page_info=123456789")
81
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
82
+
83
+ # First request mock
84
+ example_person1 = {:person_id => "4945", :email => "foo@example.com", :name => "Gold"}
85
+ response = Delighted::HTTPResponse.new(200, {"Link" => "<#{uri_next}>; rel=\"next\""}, Delighted::JSON.dump([example_person1]))
86
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
87
+
88
+ # Next rate limited request mock
89
+ response = Delighted::HTTPResponse.new(429, { "Retry-After" => "10" }, {})
90
+ mock_http_adapter.expects(:request).with(:get, uri_next, headers).once.returns(response)
91
+
92
+ persons_all = []
93
+ exception = assert_raises Delighted::RateLimitedError do
94
+ Delighted::Person.list.auto_paging_each({ :auto_handle_rate_limits => false }) do |p|
95
+ persons_all << p
96
+ end
97
+ end
98
+
99
+ assert_equal 10, exception.retry_after
100
+
101
+ assert_equal 1, persons_all.size
102
+ first_person = persons_all[0]
103
+ assert_kind_of Delighted::Person, first_person
104
+ assert_equal "Gold", first_person.name
105
+ assert_equal example_person1, first_person.to_hash
106
+ end
107
+
108
+ def test_listing_people_auto_handle_rate_limits
109
+ uri = URI.parse("https://api.delightedapp.com/v1/people")
110
+ uri_next = URI.parse("https://api.delightedapp.com/v1/people.json?page_info=123456789")
111
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
112
+
113
+ # First request mock
114
+ example_person1 = {:person_id => "4945", :email => "foo@example.com", :name => "Gold"}
115
+ response = Delighted::HTTPResponse.new(200, {"Link" => "<#{uri_next}>; rel=\"next\""}, Delighted::JSON.dump([example_person1]))
116
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
117
+
118
+ # Next rate limited request mock, then accepted request
119
+ response_rate_limited = Delighted::HTTPResponse.new(429, { "Retry-After" => "3" }, {})
120
+ example_person_next = {:person_id => "4947", :email => "foo+next@example.com", :name => "Silver"}
121
+ response_ok = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump([example_person_next]))
122
+ mock_http_adapter.expects(:request).with(:get, uri_next, headers).twice.returns(response_rate_limited, response_ok)
123
+
124
+ persons_all = []
125
+ people = Delighted::Person.list
126
+ people.expects(:sleep).with(3)
127
+ people.auto_paging_each({ :auto_handle_rate_limits => true }) do |p|
128
+ persons_all << p
129
+ end
130
+
131
+ assert_equal 2, persons_all.size
132
+ first_person = persons_all[0]
133
+ assert_kind_of Delighted::Person, first_person
134
+ assert_equal "Gold", first_person.name
135
+ assert_equal example_person1, first_person.to_hash
136
+ next_person = persons_all[1]
137
+ assert_kind_of Delighted::Person, next_person
138
+ assert_equal "Silver", next_person.name
139
+ assert_equal example_person_next, next_person.to_hash
140
+ end
141
+
142
+ def test_listing_people_auto_paginate_second_call
143
+ uri = URI.parse("https://api.delightedapp.com/v1/people")
144
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
145
+
146
+ # First request mock
147
+ example_person1 = {:person_id => "4945", :email => "foo@example.com", :name => "Gold"}
148
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump([example_person1]))
149
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
150
+
151
+ persons_all = []
152
+ people = Delighted::Person.list
153
+ people.auto_paging_each do |p|
154
+ persons_all << p
155
+ end
156
+
157
+ assert_equal 1, persons_all.size
158
+
159
+ assert_raises Delighted::PaginationError do
160
+ people.auto_paging_each
161
+ end
162
+ end
163
+
41
164
  def test_creating_or_updating_a_person
42
165
  uri = URI.parse("https://api.delightedapp.com/v1/people")
43
166
  headers = { 'Authorization' => @auth_header, "Accept" => "application/json", 'Content-Type' => 'application/json', 'User-Agent' => "Delighted RubyGem #{Delighted::VERSION}" }
@@ -264,3 +387,211 @@ class Delighted::BouncesTest < Delighted::TestCase
264
387
  end
265
388
  end
266
389
 
390
+ class Delighted::AutopilotConfigurationsTest < Delighted::TestCase
391
+ def test_getting_sms_autopilot_configuration
392
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/sms")
393
+ headers = { 'Authorization' => @auth_header, "Accept" => "application/json", 'User-Agent' => "Delighted RubyGem #{Delighted::VERSION}" }
394
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump({ :platform_id => 'sms', :active => true, :frequency => 7776000, :created_at => 1611253998, :updated_at => 1618421598 }))
395
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
396
+
397
+ configuration = Delighted::AutopilotConfiguration.retrieve('sms')
398
+ assert_kind_of Delighted::AutopilotConfiguration, configuration
399
+ assert_equal({ :platform_id => 'sms', :active => true, :frequency => 7776000, :created_at => 1611253998, :updated_at => 1618421598 }, configuration.to_hash)
400
+ assert_equal 'sms', configuration.platform_id
401
+ assert_equal true, configuration.active
402
+ assert_equal 7776000, configuration.frequency
403
+ assert_equal 1611253998, configuration.created_at
404
+ assert_equal 1618421598, configuration.updated_at
405
+ end
406
+ end
407
+
408
+ class Delighted::AutopilotMembershipsTest < Delighted::TestCase
409
+ def test_listing_autopilot_memberships
410
+ first_membership = {
411
+ :created_at => 1611253998,
412
+ :updated_at => 1618421598,
413
+ :person => {
414
+ :id => "34",
415
+ :name => "Leslie",
416
+ :email => "leslie@example.com",
417
+ :created_at => 1611365037,
418
+ :phone_number => "+1555555112",
419
+ :last_sent_at => nil
420
+ },
421
+ :next_survey_request => {
422
+ :id => "42",
423
+ :created_at => 1614043237,
424
+ :survey_scheduled_at => 1620087437,
425
+ :properties => { :"Purchase Experience" => "Web", :"State" => "OR" }
426
+ }
427
+ }
428
+ second_membership = {
429
+ :created_at => 1611243998,
430
+ :updated_at => 1618420598,
431
+ :person => {
432
+ :id => "42",
433
+ :name => "Taylor",
434
+ :email => "taylor@example.com",
435
+ :created_at => 1611242998,
436
+ :phone_number => "+1555551212",
437
+ :last_sent_at => 1611242998
438
+ },
439
+ :next_survey_request => {
440
+ :id => "3445",
441
+ :created_at => 1614043437,
442
+ :survey_scheduled_at => 1620087837,
443
+ :properties => { :"Purchase Experience" => "Mobile", :"State" => "CA" }
444
+ }
445
+ }
446
+ third_membership = {
447
+ :created_at => 1611143998,
448
+ :updated_at => 1618320598,
449
+ :person => {
450
+ :id => "47",
451
+ :name => "Casey",
452
+ :email => "casey@example.com",
453
+ :created_at => 1610242998,
454
+ :phone_number => "+1555551234",
455
+ :last_sent_at => 1610242998
456
+ },
457
+ :next_survey_request => {
458
+ :id => "3449",
459
+ :created_at => 1614063437,
460
+ :survey_scheduled_at => 1620097837,
461
+ :properties => { :"Purchase Experience" => "Store", :"State" => "WA" }
462
+ }
463
+ }
464
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/sms/memberships")
465
+ uri_next = URI.parse("https://api.delightedapp.com/v1/autopilot/sms/memberships?page_info=123456789")
466
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
467
+
468
+ # First request mock
469
+ response = Delighted::HTTPResponse.new(200, {"Link" => "<#{uri_next}>; rel=\"next\""}, Delighted::JSON.dump([first_membership, second_membership]))
470
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
471
+
472
+ # Next request mock
473
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump([third_membership]))
474
+ mock_http_adapter.expects(:request).with(:get, uri_next, headers).once.returns(response)
475
+
476
+ memberships = []
477
+ Delighted::AutopilotMembership::Sms.list.auto_paging_each do |membership|
478
+ memberships << membership
479
+ end
480
+
481
+ assert_equal 3, memberships.size
482
+ assert_kind_of Delighted::AutopilotMembership::Sms, memberships[0]
483
+ assert_kind_of Delighted::Person, memberships[0].person
484
+ assert_kind_of Delighted::SurveyRequest, memberships[0].next_survey_request
485
+ assert_equal 1611253998, memberships[0].created_at
486
+ assert_equal "34", memberships[0].person.id
487
+ assert_nil memberships[0].person.last_sent_at
488
+ assert_equal first_membership[:person].reject { |k,_| k == :id }, memberships[0].person.to_hash
489
+ assert_equal "+1555555112", memberships[0].person.phone_number
490
+ assert_equal 1620087437, memberships[0].next_survey_request.survey_scheduled_at
491
+ assert_equal first_membership[:next_survey_request][:properties], memberships[0].next_survey_request.properties
492
+ assert_kind_of Delighted::AutopilotMembership, memberships[1]
493
+ assert_equal 1611242998, memberships[1].person.last_sent_at
494
+ end
495
+
496
+ def test_listing_specific_autopilot_memberships
497
+ specific_membership = {
498
+ :created_at => 1611253998,
499
+ :updated_at => 1618421598,
500
+ :person => {
501
+ :id => "34",
502
+ :name => "Leslie",
503
+ :email => "leslie@example.com",
504
+ :created_at => 1611365037,
505
+ :phone_number => "+1555555112",
506
+ :last_sent_at => nil
507
+ },
508
+ :next_survey_request => {
509
+ :id => "42",
510
+ :created_at => 1614043237,
511
+ :survey_scheduled_at => 1620087437,
512
+ :properties => {
513
+ :"Purchase Experience" => "Web",
514
+ :"State" => "OR"
515
+ }
516
+ }
517
+ }
518
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/sms/memberships?person_id=34")
519
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
520
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump([specific_membership]))
521
+ mock_http_adapter.expects(:request).with(:get, uri, headers).once.returns(response)
522
+
523
+ memberships = []
524
+ Delighted::AutopilotMembership::Sms.list(person_id: 34).auto_paging_each do |membership|
525
+ memberships << membership
526
+ end
527
+
528
+ assert_equal 1, memberships.size
529
+ assert_kind_of Delighted::AutopilotMembership::Sms, memberships[0]
530
+ assert_kind_of Delighted::Person, memberships[0].person
531
+ assert_kind_of Delighted::SurveyRequest, memberships[0].next_survey_request
532
+ assert_equal 1, memberships.size
533
+ end
534
+
535
+ def test_adding_autopilot_membership
536
+ params = {
537
+ person_email: "leslie@example.com",
538
+ person_name: "Leslie",
539
+ properties: {
540
+ :"Purchase Experience" => "Web",
541
+ :"State" => "OR"
542
+ }
543
+ }
544
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/email/memberships")
545
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", 'Content-Type' => 'application/json', "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
546
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump({ person: { id: "333", name: params[:person_name], email: params[:person_email] }, properties: params[:properties] }))
547
+ mock_http_adapter.expects(:request).with(:post, uri, headers, Delighted::JSON.dump(params)).once.returns(response)
548
+
549
+ result = Delighted::AutopilotMembership::Email.create(params)
550
+
551
+ assert_kind_of Delighted::AutopilotMembership::Email, result
552
+ assert_kind_of Delighted::Person, result.person
553
+ assert_equal params[:properties], result.properties
554
+ assert_equal params[:person_email], result.person.email
555
+ assert_equal params[:person_name], result.person.name
556
+ assert result.person.id
557
+ assert_equal params[:properties], result.properties
558
+ end
559
+
560
+ def test_updating_autopilot_membership
561
+ params = {
562
+ person_id: "333",
563
+ properties: {
564
+ :"Purchase Experience" => "Web",
565
+ :"State" => "OR"
566
+ }
567
+ }
568
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/sms/memberships")
569
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", 'Content-Type' => 'application/json', "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
570
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump({ person: { id: "333", name: "Leslie", email: "leslie@example.com", phone_numer: "+15555551212" }, properties: params[:properties] }))
571
+ mock_http_adapter.expects(:request).with(:post, uri, headers, Delighted::JSON.dump(params)).once.returns(response)
572
+
573
+ result = Delighted::AutopilotMembership::Sms.create(params)
574
+
575
+ assert_kind_of Delighted::AutopilotMembership::Sms, result
576
+ assert_kind_of Delighted::Person, result.person
577
+ assert_equal params[:properties], result.properties
578
+ assert_equal "leslie@example.com", result.person.email
579
+ assert_equal "Leslie", result.person.name
580
+ assert_equal "333", result.person.id
581
+ assert_equal params[:properties], result.properties
582
+ end
583
+
584
+ def test_removing_autopilot_membership
585
+ uri = URI.parse("https://api.delightedapp.com/v1/autopilot/sms/memberships")
586
+ headers = { "Authorization" => @auth_header, "Accept" => "application/json", 'Content-Type' => 'application/json', "User-Agent" => "Delighted RubyGem #{Delighted::VERSION}" }
587
+ response = Delighted::HTTPResponse.new(200, {}, Delighted::JSON.dump({ person: { id: "333", name: "Leslie", email: "leslie@example.com"} }))
588
+ mock_http_adapter.expects(:request).with(:delete, uri, headers, Delighted::JSON.dump({person_id: "455"})).once.returns(response)
589
+
590
+ result = Delighted::AutopilotMembership::Sms.delete(:person_id => "455")
591
+
592
+ assert_kind_of Hash, result
593
+ assert_equal "leslie@example.com", result[:person].email
594
+ assert_equal "Leslie", result[:person].name
595
+ assert_equal "333", result[:person].id
596
+ end
597
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delighted
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0rc1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Dodwell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-22 00:00:00.000000000 Z
11
+ date: 2021-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_json
@@ -88,12 +88,16 @@ files:
88
88
  - lib/delighted/http_adapter.rb
89
89
  - lib/delighted/http_response.rb
90
90
  - lib/delighted/json.rb
91
+ - lib/delighted/list_resource.rb
91
92
  - lib/delighted/operations/all.rb
92
93
  - lib/delighted/operations/create.rb
93
94
  - lib/delighted/operations/delete.rb
95
+ - lib/delighted/operations/list.rb
94
96
  - lib/delighted/operations/retrieve.rb
95
97
  - lib/delighted/operations/update.rb
96
98
  - lib/delighted/resource.rb
99
+ - lib/delighted/resources/autopilot_configuration.rb
100
+ - lib/delighted/resources/autopilot_membership.rb
97
101
  - lib/delighted/resources/bounce.rb
98
102
  - lib/delighted/resources/metrics.rb
99
103
  - lib/delighted/resources/person.rb
@@ -120,12 +124,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
124
  version: '0'
121
125
  required_rubygems_version: !ruby/object:Gem::Requirement
122
126
  requirements:
123
- - - ">"
127
+ - - ">="
124
128
  - !ruby/object:Gem::Version
125
- version: 1.3.1
129
+ version: '0'
126
130
  requirements: []
127
- rubyforge_project:
128
- rubygems_version: 2.7.6
131
+ rubygems_version: 3.2.17
129
132
  signing_key:
130
133
  specification_version: 4
131
134
  summary: Delighted is the fastest and easiest way to gather actionable feedback from