exponent-server-sdk 0.0.5 → 0.0.6
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 +5 -5
- data/.travis.yml +10 -7
- data/README.md +58 -53
- data/Rakefile +10 -10
- data/lib/exponent-server-sdk.rb +153 -151
- data/lib/exponent-server-sdk/version.rb +3 -3
- data/manual_test.rb +19 -0
- data/test/exponent-server-sdk-test.rb +232 -195
- metadata +4 -5
- data/manual-testing.txt +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ebc8de35da4d4e4a5a826ed90de5d35d833d173a705b1972eb273d9d8f7e847
|
4
|
+
data.tar.gz: 0fda3e2471d7be6691e06a71718a263dcb488b99f5466aff8735348ff5e85ddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57a08a6323c058c52de8a5c2eb75ad4878b1d6d74558b9032856281ebaeda791f66d34423e10765deb9470c21e0284021eac93aa622202076ddf46d657d7609d
|
7
|
+
data.tar.gz: 6dbf0c93e6dccaed5177a3eeac7608ddf06f35af0ad54e0123142346b5a5fb147bbddfb817a0cd9d7c67f951762378e47972ad5f4639c390aaeec35c7dbee298
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,53 +1,58 @@
|
|
1
|
-
# Exponent Server SDK Ruby
|
2
|
-
[](https://travis-ci.org/expo/exponent-server-sdk-ruby)
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
1
|
+
# Exponent Server SDK Ruby
|
2
|
+
[](https://travis-ci.org/expo/exponent-server-sdk-ruby)
|
3
|
+
[](https://badge.fury.io/rb/exponent-server-sdk)
|
4
|
+
|
5
|
+
Use to send push notifications to Exponent Experiences from a Ruby server.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'exponent-server-sdk'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```shell
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
```shell
|
24
|
+
$ gem install exponent-server-sdk
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Client
|
30
|
+
|
31
|
+
The push client is the preferred way. This hits the latest version of the api.
|
32
|
+
|
33
|
+
Optional arguments: `gzip: true`
|
34
|
+
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
client = Exponent::Push::Client.new
|
38
|
+
# client = Exponent::Push::Client.new(gzip: true) # for compressed, faster requests
|
39
|
+
|
40
|
+
messages = [{
|
41
|
+
to: "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
|
42
|
+
sound: "default",
|
43
|
+
body: "Hello world!"
|
44
|
+
}, {
|
45
|
+
to: "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
|
46
|
+
badge: 1,
|
47
|
+
body: "You've got mail"
|
48
|
+
}]
|
49
|
+
|
50
|
+
client.publish messages
|
51
|
+
```
|
52
|
+
|
53
|
+
The complete format of the messages can be found [here.](https://docs.expo.io/versions/latest/guides/push-notifications#message-format)
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
If you have problems with the code in this repository, please file issues & bug reports. We encourage you
|
58
|
+
to submit a pull request with a solution or a failing test to reproduce your issue. Thanks!
|
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rake/testtask"
|
3
|
-
|
4
|
-
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs << "test"
|
6
|
-
t.libs << "lib"
|
7
|
-
t.test_files = FileList['test/**/*-
|
8
|
-
end
|
9
|
-
|
10
|
-
task :default => :test
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList['test/**/*-manual_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :test
|
data/lib/exponent-server-sdk.rb
CHANGED
@@ -1,151 +1,153 @@
|
|
1
|
-
require 'exponent-server-sdk/version'
|
2
|
-
require 'typhoeus'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module Exponent
|
6
|
-
def self.is_exponent_push_token?(token)
|
7
|
-
token.start_with?('ExponentPushToken')
|
8
|
-
end
|
9
|
-
|
10
|
-
module Push
|
11
|
-
|
12
|
-
class Client
|
13
|
-
def initialize(
|
14
|
-
|
15
|
-
@
|
16
|
-
@
|
17
|
-
end
|
18
|
-
|
19
|
-
def publish(messages)
|
20
|
-
response_handler.handle(push_notifications(messages))
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
attr_reader :http_client, :response_handler
|
26
|
-
|
27
|
-
def push_notifications(messages)
|
28
|
-
http_client.post(
|
29
|
-
push_url,
|
30
|
-
body: messages.to_json,
|
31
|
-
headers: headers
|
32
|
-
)
|
33
|
-
end
|
34
|
-
|
35
|
-
def push_url
|
36
|
-
'https://exp.host/--/api/v2/push/send'
|
37
|
-
end
|
38
|
-
|
39
|
-
def headers
|
40
|
-
{
|
41
|
-
'Content-Type' => 'application/json',
|
42
|
-
'Accept' => 'application/json'
|
43
|
-
}
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
1
|
+
require 'exponent-server-sdk/version'
|
2
|
+
require 'typhoeus'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Exponent
|
6
|
+
def self.is_exponent_push_token?(token)
|
7
|
+
token.start_with?('ExponentPushToken')
|
8
|
+
end
|
9
|
+
|
10
|
+
module Push
|
11
|
+
|
12
|
+
class Client
|
13
|
+
def initialize(**args)
|
14
|
+
@http_client = args[:http_client] || Typhoeus
|
15
|
+
@response_handler = args[:response_handler] || ResponseHandler.new
|
16
|
+
@gzip = args[:gzip] == true
|
17
|
+
end
|
18
|
+
|
19
|
+
def publish(messages)
|
20
|
+
response_handler.handle(push_notifications(messages))
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :http_client, :response_handler
|
26
|
+
|
27
|
+
def push_notifications(messages)
|
28
|
+
http_client.post(
|
29
|
+
push_url,
|
30
|
+
body: messages.to_json,
|
31
|
+
headers: headers
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def push_url
|
36
|
+
'https://exp.host/--/api/v2/push/send'
|
37
|
+
end
|
38
|
+
|
39
|
+
def headers
|
40
|
+
headers = {
|
41
|
+
'Content-Type' => 'application/json',
|
42
|
+
'Accept' => 'application/json'
|
43
|
+
}
|
44
|
+
headers['Accept-Encoding'] = 'gzip, deflate' if @gzip
|
45
|
+
headers
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class ResponseHandler
|
50
|
+
def initialize(error_builder = ErrorBuilder.new)
|
51
|
+
@error_builder = error_builder
|
52
|
+
end
|
53
|
+
|
54
|
+
def handle(response)
|
55
|
+
case response.code.to_s
|
56
|
+
when /(^4|^5)/
|
57
|
+
raise build_error_from_failure(parse_json(response))
|
58
|
+
else
|
59
|
+
handle_success(parse_json(response))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
attr_reader :error_builder
|
66
|
+
|
67
|
+
def parse_json(response)
|
68
|
+
JSON.parse(response.body)
|
69
|
+
end
|
70
|
+
|
71
|
+
def build_error_from_failure(response)
|
72
|
+
error_builder.build_from_erroneous(response)
|
73
|
+
end
|
74
|
+
|
75
|
+
def handle_success(response)
|
76
|
+
extract_data(response).tap do |data|
|
77
|
+
validate_status(data.fetch('status'), response)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def extract_data(response)
|
82
|
+
response.fetch('data').first
|
83
|
+
end
|
84
|
+
|
85
|
+
def validate_status(status, response)
|
86
|
+
raise build_error_from_success(response) unless status == 'ok'
|
87
|
+
end
|
88
|
+
|
89
|
+
def build_error_from_success(response)
|
90
|
+
error_builder.build_from_successful(response)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class ErrorBuilder
|
95
|
+
%i[erroneous successful].each do |selector|
|
96
|
+
define_method(:"build_from_#{selector}") do |response|
|
97
|
+
with_error_handling(response) do
|
98
|
+
send "from_#{selector}_response", response
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def with_error_handling(response)
|
106
|
+
yield(response)
|
107
|
+
rescue KeyError
|
108
|
+
unknown_error_format(response)
|
109
|
+
end
|
110
|
+
|
111
|
+
def from_erroneous_response(response)
|
112
|
+
error = response.fetch('errors').first
|
113
|
+
error_name = error.fetch('code')
|
114
|
+
message = error.fetch('message')
|
115
|
+
|
116
|
+
get_error_class(error_name).new(message)
|
117
|
+
end
|
118
|
+
|
119
|
+
def from_successful_response(response)
|
120
|
+
data = response.fetch('data').first
|
121
|
+
message = data.fetch('message')
|
122
|
+
|
123
|
+
get_error_class(data.fetch('details').fetch('error')).new(message)
|
124
|
+
end
|
125
|
+
|
126
|
+
def validate_error_name(condition)
|
127
|
+
condition ? yield : Exponent::Push::UnknownError
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_error_class(error_name)
|
131
|
+
validate_error_name(Exponent::Push.error_names.include?(error_name)) do
|
132
|
+
Exponent::Push.const_get("#{error_name}Error")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def unknown_error_format(response)
|
137
|
+
Exponent::Push::UnknownError.new("Unknown error format: #{response}")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
Error = Class.new(StandardError)
|
142
|
+
|
143
|
+
def self.error_names
|
144
|
+
%w[DeviceNotRegistered MessageTooBig
|
145
|
+
MessageRateExceeded InvalidCredentials
|
146
|
+
Unknown]
|
147
|
+
end
|
148
|
+
|
149
|
+
error_names.each do |error_name|
|
150
|
+
const_set "#{error_name}Error", Class.new(Error)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module Exponent
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
1
|
+
module Exponent
|
2
|
+
VERSION = '0.0.6'.freeze
|
3
|
+
end
|
data/manual_test.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'lib/exponent-server-sdk'
|
2
|
+
|
3
|
+
client = Exponent::Push::Client.new
|
4
|
+
|
5
|
+
# OR use GZIP to be AWESOME
|
6
|
+
# client = Exponent::Push::Client.new(gzip: true)
|
7
|
+
|
8
|
+
messages = [{
|
9
|
+
to: 'ExponentPushToken[HbuLbNFwb5_ENuljvAePLs]',
|
10
|
+
sound: "default",
|
11
|
+
title: "You're Winning!",
|
12
|
+
body: "You just won EVERTHING!",
|
13
|
+
data: {
|
14
|
+
type: 'WINNINGS',
|
15
|
+
message: "You just won EVERTHING!"
|
16
|
+
|
17
|
+
}.to_json
|
18
|
+
}]
|
19
|
+
client.publish messages
|
@@ -1,195 +1,232 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'exponent-server-sdk'
|
3
|
-
|
4
|
-
class ExponentServerSdkTest < Minitest::Test
|
5
|
-
def setup
|
6
|
-
@mock = MiniTest::Mock.new
|
7
|
-
@response_mock = MiniTest::Mock.new
|
8
|
-
@exponent = Exponent::Push::Client.new(@mock)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@response_mock.expect(:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@response_mock.expect(:
|
25
|
-
|
26
|
-
|
27
|
-
@mock.expect(:post, @response_mock,
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@mock.
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
@mock.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
def
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
end
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'exponent-server-sdk'
|
3
|
+
|
4
|
+
class ExponentServerSdkTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
@mock = MiniTest::Mock.new
|
7
|
+
@response_mock = MiniTest::Mock.new
|
8
|
+
@exponent = Exponent::Push::Client.new(http_client: @mock)
|
9
|
+
@exponent_gzip = Exponent::Push::Client.new(http_client: @mock, gzip: true)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_publish_with_success
|
13
|
+
@response_mock.expect(:code, 200)
|
14
|
+
@response_mock.expect(:body, success_body.to_json)
|
15
|
+
|
16
|
+
@mock.expect(:post, @response_mock, client_args)
|
17
|
+
|
18
|
+
@exponent.publish(messages)
|
19
|
+
|
20
|
+
@mock.verify
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_publish_with_gzip_success
|
24
|
+
@response_mock.expect(:code, 200)
|
25
|
+
@response_mock.expect(:body, success_body.to_json)
|
26
|
+
|
27
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
28
|
+
|
29
|
+
@exponent_gzip.publish(messages)
|
30
|
+
|
31
|
+
@mock.verify
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_publish_with_gzip
|
35
|
+
@response_mock.expect(:code, 200)
|
36
|
+
@response_mock.expect(:body, success_body.to_json)
|
37
|
+
|
38
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
39
|
+
|
40
|
+
@exponent_gzip.publish(messages)
|
41
|
+
|
42
|
+
@mock.verify
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_publish_with_unknown_error
|
46
|
+
@response_mock.expect(:code, 400)
|
47
|
+
@response_mock.expect(:body, error_body.to_json)
|
48
|
+
message = 'An unknown error occurred.'
|
49
|
+
|
50
|
+
@mock.expect(:post, @response_mock, client_args)
|
51
|
+
|
52
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
53
|
+
@exponent.publish(messages)
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal(message, exception.message)
|
57
|
+
|
58
|
+
@mock.verify
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_publish_with_device_not_registered_error
|
62
|
+
@response_mock.expect(:code, 200)
|
63
|
+
@response_mock.expect(:body, not_registered_device_error_body.to_json)
|
64
|
+
message = '"ExponentPushToken[42]" is not a registered push notification recipient'
|
65
|
+
|
66
|
+
@mock.expect(:post, @response_mock, client_args)
|
67
|
+
|
68
|
+
exception = assert_raises Exponent::Push::DeviceNotRegisteredError do
|
69
|
+
@exponent.publish(messages)
|
70
|
+
end
|
71
|
+
|
72
|
+
assert_equal(message, exception.message)
|
73
|
+
|
74
|
+
@mock.verify
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_publish_with_message_too_big_error
|
78
|
+
@response_mock.expect(:code, 200)
|
79
|
+
@response_mock.expect(:body, message_too_big_error_body.to_json)
|
80
|
+
message = 'Message too big'
|
81
|
+
|
82
|
+
@mock.expect(:post, @response_mock, client_args)
|
83
|
+
|
84
|
+
exception = assert_raises Exponent::Push::MessageTooBigError do
|
85
|
+
@exponent.publish(messages)
|
86
|
+
end
|
87
|
+
|
88
|
+
assert_equal(message, exception.message)
|
89
|
+
|
90
|
+
@mock.verify
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_publish_with_message_rate_exceeded_error
|
94
|
+
@response_mock.expect(:code, 200)
|
95
|
+
@response_mock.expect(:body, message_rate_exceeded_error_body.to_json)
|
96
|
+
message = 'Message rate exceeded'
|
97
|
+
|
98
|
+
@mock.expect(:post, @response_mock, client_args)
|
99
|
+
|
100
|
+
exception = assert_raises Exponent::Push::MessageRateExceededError do
|
101
|
+
@exponent.publish(messages)
|
102
|
+
end
|
103
|
+
|
104
|
+
assert_equal(message, exception.message)
|
105
|
+
|
106
|
+
@mock.verify
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_publish_with_invalid_credentials_error
|
110
|
+
@response_mock.expect(:code, 200)
|
111
|
+
@response_mock.expect(:body, invalid_credentials_error_body.to_json)
|
112
|
+
message = 'Invalid credentials'
|
113
|
+
|
114
|
+
@mock.expect(:post, @response_mock, client_args)
|
115
|
+
|
116
|
+
exception = assert_raises Exponent::Push::InvalidCredentialsError do
|
117
|
+
@exponent.publish(messages)
|
118
|
+
end
|
119
|
+
|
120
|
+
assert_equal(message, exception.message)
|
121
|
+
|
122
|
+
@mock.verify
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_publish_with_apn_error
|
126
|
+
@response_mock.expect(:code, 200)
|
127
|
+
@response_mock.expect(:body, apn_error_body.to_json)
|
128
|
+
|
129
|
+
@mock.expect(:post, @response_mock, client_args)
|
130
|
+
|
131
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
132
|
+
@exponent.publish(messages)
|
133
|
+
end
|
134
|
+
|
135
|
+
assert_match(/Unknown error format/, exception.message)
|
136
|
+
|
137
|
+
@mock.verify
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def success_body
|
143
|
+
{ 'data' => [{ 'status' => 'ok' }] }
|
144
|
+
end
|
145
|
+
|
146
|
+
def error_body
|
147
|
+
{
|
148
|
+
'errors' => [{
|
149
|
+
'code' => 'INTERNAL_SERVER_ERROR',
|
150
|
+
'message' => 'An unknown error occurred.'
|
151
|
+
}]
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
def message_too_big_error_body
|
156
|
+
build_error_body('MessageTooBig', 'Message too big')
|
157
|
+
end
|
158
|
+
|
159
|
+
def not_registered_device_error_body
|
160
|
+
build_error_body(
|
161
|
+
'DeviceNotRegistered',
|
162
|
+
'"ExponentPushToken[42]" is not a registered push notification recipient'
|
163
|
+
)
|
164
|
+
end
|
165
|
+
|
166
|
+
def message_rate_exceeded_error_body
|
167
|
+
build_error_body('MessageRateExceeded', 'Message rate exceeded')
|
168
|
+
end
|
169
|
+
|
170
|
+
def invalid_credentials_error_body
|
171
|
+
build_error_body('InvalidCredentials', 'Invalid credentials')
|
172
|
+
end
|
173
|
+
|
174
|
+
def apn_error_body
|
175
|
+
{
|
176
|
+
'data' => [{
|
177
|
+
'status' => 'error',
|
178
|
+
'message' =>
|
179
|
+
'Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
|
180
|
+
}]
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
def client_args
|
185
|
+
[
|
186
|
+
'https://exp.host/--/api/v2/push/send',
|
187
|
+
{
|
188
|
+
body: messages.to_json,
|
189
|
+
headers: {
|
190
|
+
'Content-Type' => 'application/json',
|
191
|
+
'Accept' => 'application/json'
|
192
|
+
}
|
193
|
+
}
|
194
|
+
]
|
195
|
+
end
|
196
|
+
|
197
|
+
def gzip_client_args
|
198
|
+
[
|
199
|
+
'https://exp.host/--/api/v2/push/send',
|
200
|
+
{
|
201
|
+
body: messages.to_json,
|
202
|
+
headers: {
|
203
|
+
'Content-Type' => 'application/json',
|
204
|
+
'Accept' => 'application/json',
|
205
|
+
'Accept-Encoding' => 'gzip, deflate'
|
206
|
+
}
|
207
|
+
}
|
208
|
+
]
|
209
|
+
end
|
210
|
+
|
211
|
+
def messages
|
212
|
+
[{
|
213
|
+
to: 'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]',
|
214
|
+
sound: 'default',
|
215
|
+
body: 'Hello world!'
|
216
|
+
}, {
|
217
|
+
to: 'ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]',
|
218
|
+
badge: 1,
|
219
|
+
body: "You've got mail"
|
220
|
+
}]
|
221
|
+
end
|
222
|
+
|
223
|
+
def build_error_body(error_code, message)
|
224
|
+
{
|
225
|
+
'data' => [{
|
226
|
+
'status' => 'error',
|
227
|
+
'message' => message,
|
228
|
+
'details' => { 'error' => error_code }
|
229
|
+
}]
|
230
|
+
}
|
231
|
+
end
|
232
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exponent-server-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesse Ruder
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-01-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: typhoeus
|
@@ -84,7 +84,7 @@ files:
|
|
84
84
|
- exponent-server-sdk.gemspec
|
85
85
|
- lib/exponent-server-sdk.rb
|
86
86
|
- lib/exponent-server-sdk/version.rb
|
87
|
-
-
|
87
|
+
- manual_test.rb
|
88
88
|
- test/exponent-server-sdk-test.rb
|
89
89
|
homepage: ''
|
90
90
|
licenses:
|
@@ -105,8 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
105
|
- !ruby/object:Gem::Version
|
106
106
|
version: '0'
|
107
107
|
requirements: []
|
108
|
-
|
109
|
-
rubygems_version: 2.6.11
|
108
|
+
rubygems_version: 3.0.2
|
110
109
|
signing_key:
|
111
110
|
specification_version: 4
|
112
111
|
summary: Exponent Server SDK
|
data/manual-testing.txt
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
irb -r exponent-server-sdk -I ./lib
|
2
|
-
|
3
|
-
exponent = Exponent::Push::Client.new
|
4
|
-
|
5
|
-
exponent.publish(
|
6
|
-
exponentPushToken: 'ExponentPushToken[HbuLbNFwb5_ENuljvAePLs]',
|
7
|
-
#message: 'Hello Charlie. It is ' + Time::now.to_s,
|
8
|
-
message: 'Hello Charlie from Ruby',
|
9
|
-
data: {a: "b"},
|
10
|
-
)
|
11
|
-
|
12
|
-
|
13
|
-
ipython
|
14
|
-
|
15
|
-
import exponent_server_sdk
|
16
|
-
import datetime
|
17
|
-
|
18
|
-
exponent = exponent_server_sdk.Client()
|
19
|
-
|
20
|
-
exponent.publish('ExponentPushToken[HbuLbNFwb5_ENuljvAePLs]', "Hello Charlie from Python. It is " + datetime.datetime.now().time().isoformat(), {"a": "p"})
|
21
|
-
|
22
|
-
|
23
|
-
|