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 +4 -4
- data/.travis.yml +2 -3
- data/CHANGELOG.md +25 -1
- data/README.md +98 -2
- data/lib/delighted.rb +5 -0
- data/lib/delighted/client.rb +16 -3
- data/lib/delighted/errors.rb +4 -0
- data/lib/delighted/http_response.rb +22 -0
- data/lib/delighted/list_resource.rb +45 -0
- data/lib/delighted/operations/list.rb +15 -0
- data/lib/delighted/resources/autopilot_configuration.rb +7 -0
- data/lib/delighted/resources/autopilot_membership.rb +28 -0
- data/lib/delighted/resources/person.rb +1 -0
- data/lib/delighted/version.rb +1 -1
- data/test/delighted_test.rb +331 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65db888686e9187504e0327b3c9e4398fc9fe22070caf2554a6095f9a6a23a77
|
4
|
+
data.tar.gz: cb7b9a981561519bd04ab15ce8bd626f52c4766261a8a56aa1f55f170b467783
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83cb181d09e2f31eb37966b96c359fc2b5483b0cb239d8b808443bbce6cb3c194da52846d2ea9afa860e2dd3ca80208a6f6242161c71b3a172ea3d95ab456a35
|
7
|
+
data.tar.gz: 3dc2423403ee8ad2a4c9bb66a3c7b840929e467e299ed36af2143aacde4522f945e7ed36e47e62ebc73f1ef802e834e60e7f1e19e2480280f33ab548a85c29b9
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,28 @@
|
|
1
|
-
## 1.
|
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'
|
data/lib/delighted/client.rb
CHANGED
@@ -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
|
-
|
14
|
+
request_get(path, {params: params})[:json]
|
15
|
+
end
|
14
16
|
|
15
|
-
|
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
|
data/lib/delighted/errors.rb
CHANGED
@@ -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,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
|
data/lib/delighted/version.rb
CHANGED
data/test/delighted_test.rb
CHANGED
@@ -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.
|
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:
|
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:
|
129
|
+
version: '0'
|
126
130
|
requirements: []
|
127
|
-
|
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
|