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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 61012c4117f2e3c9357a2b99e92ad363fb956844
4
- data.tar.gz: 7c565d390d7e8d2b737c6c6a684a14c1f988ff97
2
+ SHA256:
3
+ metadata.gz: 9ebc8de35da4d4e4a5a826ed90de5d35d833d173a705b1972eb273d9d8f7e847
4
+ data.tar.gz: 0fda3e2471d7be6691e06a71718a263dcb488b99f5466aff8735348ff5e85ddd
5
5
  SHA512:
6
- metadata.gz: 0a21006404a04267901a8c607dd9dfd7c154e57f93c07da8d0299c4c26a3292a13393d6bbe60a0471f66e53efa21529f7b1919a9b55b1d463203f88d2cfe594b
7
- data.tar.gz: 30730a58b90f42f5cb20382abeb4affd59275d6ec78be59e511e06249ffb5324b5554d39a5e21c850ba2bc8be5cf747c2bb7e9d271eb32b247ebcae6e7d60ebc
6
+ metadata.gz: 57a08a6323c058c52de8a5c2eb75ad4878b1d6d74558b9032856281ebaeda791f66d34423e10765deb9470c21e0284021eac93aa622202076ddf46d657d7609d
7
+ data.tar.gz: 6dbf0c93e6dccaed5177a3eeac7608ddf06f35af0ad54e0123142346b5a5fb147bbddfb817a0cd9d7c67f951762378e47972ad5f4639c390aaeec35c7dbee298
@@ -1,7 +1,10 @@
1
- language: ruby
2
- rvm:
3
- - 2.4.0
4
- - 2.3.0
5
- - 2.2.0
6
- - 2.1.0
7
- - 2.0.0
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 2.6.0
5
+ - 2.5.0
6
+ - 2.4.0
7
+ - 2.3.0
8
+ before_install:
9
+ - gem update --system
10
+ - gem install bundler
data/README.md CHANGED
@@ -1,53 +1,58 @@
1
- # Exponent Server SDK Ruby
2
- [![Build Status](https://travis-ci.org/expo/exponent-server-sdk-ruby.svg?branch=master)](https://travis-ci.org/expo/exponent-server-sdk-ruby)
3
-
4
- Use to send push notifications to Exponent Experiences from a Ruby server.
5
-
6
- ## Installation
7
-
8
- Add this line to your application's Gemfile:
9
-
10
- ```ruby
11
- gem 'exponent-server-sdk'
12
- ```
13
-
14
- And then execute:
15
-
16
- ```shell
17
- $ bundle
18
- ```
19
-
20
- Or install it yourself as:
21
-
22
- ```shell
23
- $ gem install exponent-server-sdk
24
- ```
25
-
26
- ## Usage
27
-
28
- ### Client
29
-
30
- The push client is the preferred way. This hits the latest version of the api.
31
-
32
- ```ruby
33
- client = Exponent::Push::Client.new
34
-
35
- messages = [{
36
- to: "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
37
- sound: "default",
38
- body: "Hello world!"
39
- }, {
40
- to: "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
41
- badge: 1,
42
- body: "You've got mail"
43
- }]
44
-
45
- client.publish messages
46
- ```
47
-
48
- The complete format of the messages can be found [here.](https://docs.expo.io/versions/latest/index.html#http2-api)
49
-
50
- ## Contributing
51
-
52
- If you have problems with the code in this repository, please file issues & bug reports. We encourage you
53
- to submit a solution or a failing test to reproduce your issue. Thanks!
1
+ # Exponent Server SDK Ruby
2
+ [![Build Status](https://travis-ci.org/expo/exponent-server-sdk-ruby.svg?branch=master)](https://travis-ci.org/expo/exponent-server-sdk-ruby)
3
+ [![Gem Version](https://badge.fury.io/rb/exponent-server-sdk.svg)](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/**/*-test.rb']
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
@@ -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(http_client = Typhoeus,
14
- response_handler = ResponseHandler.new)
15
- @http_client = http_client
16
- @response_handler = response_handler
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
- end
45
- end
46
-
47
- class ResponseHandler
48
- def initialize(error_builder = ErrorBuilder.new)
49
- @error_builder = error_builder
50
- end
51
-
52
- def handle(response)
53
- case response.code.to_s
54
- when /(^4|^5)/
55
- raise build_error_from_failure(parse_json(response))
56
- else
57
- handle_success(parse_json(response))
58
- end
59
- end
60
-
61
- private
62
-
63
- attr_reader :error_builder
64
-
65
- def parse_json(response)
66
- JSON.parse(response.body)
67
- end
68
-
69
- def build_error_from_failure(response)
70
- error_builder.build_from_erroneous(response)
71
- end
72
-
73
- def handle_success(response)
74
- extract_data(response).tap do |data|
75
- validate_status(data.fetch('status'), response)
76
- end
77
- end
78
-
79
- def extract_data(response)
80
- response.fetch('data').first
81
- end
82
-
83
- def validate_status(status, response)
84
- raise build_error_from_success(response) unless status == 'ok'
85
- end
86
-
87
- def build_error_from_success(response)
88
- error_builder.build_from_successful(response)
89
- end
90
- end
91
-
92
- class ErrorBuilder
93
- %i[erroneous successful].each do |selector|
94
- define_method(:"build_from_#{selector}") do |response|
95
- with_error_handling(response) do
96
- send "from_#{selector}_response", response
97
- end
98
- end
99
- end
100
-
101
- private
102
-
103
- def with_error_handling(response)
104
- yield(response)
105
- rescue KeyError
106
- unknown_error_format(response)
107
- end
108
-
109
- def from_erroneous_response(response)
110
- error = response.fetch('errors').first
111
- error_name = error.fetch('code')
112
- message = error.fetch('message')
113
-
114
- get_error_class(error_name).new(message)
115
- end
116
-
117
- def from_successful_response(response)
118
- data = response.fetch('data').first
119
- message = data.fetch('message')
120
-
121
- get_error_class(data.fetch('details').fetch('error')).new(message)
122
- end
123
-
124
- def validate_error_name(condition)
125
- condition ? yield : Exponent::Push::UnknownError
126
- end
127
-
128
- def get_error_class(error_name)
129
- validate_error_name(Exponent::Push.error_names.include?(error_name)) do
130
- Exponent::Push.const_get("#{error_name}Error")
131
- end
132
- end
133
-
134
- def unknown_error_format(response)
135
- Exponent::Push::UnknownError.new("Unknown error format: #{response}")
136
- end
137
- end
138
-
139
- Error = Class.new(StandardError)
140
-
141
- def self.error_names
142
- %w[DeviceNotRegistered MessageTooBig
143
- MessageRateExceeded InvalidCredentials
144
- Unknown]
145
- end
146
-
147
- error_names.each do |error_name|
148
- const_set "#{error_name}Error", Class.new(Error)
149
- end
150
- end
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.5'.freeze
3
- end
1
+ module Exponent
2
+ VERSION = '0.0.6'.freeze
3
+ end
@@ -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
- end
10
-
11
- def test_publish_with_success
12
- @response_mock.expect(:code, 200)
13
- @response_mock.expect(:body, success_body.to_json)
14
-
15
- @mock.expect(:post, @response_mock, client_args)
16
-
17
- @exponent.publish(messages)
18
-
19
- @mock.verify
20
- end
21
-
22
- def test_publish_with_unknown_error
23
- @response_mock.expect(:code, 400)
24
- @response_mock.expect(:body, error_body.to_json)
25
- message = 'An unknown error occurred.'
26
-
27
- @mock.expect(:post, @response_mock, client_args)
28
-
29
- exception = assert_raises Exponent::Push::UnknownError do
30
- @exponent.publish(messages)
31
- end
32
-
33
- assert_equal(message, exception.message)
34
-
35
- @mock.verify
36
- end
37
-
38
- def test_publish_with_device_not_registered_error
39
- @response_mock.expect(:code, 200)
40
- @response_mock.expect(:body, not_registered_device_error_body.to_json)
41
- message = '"ExponentPushToken[42]" is not a registered push notification recipient'
42
-
43
- @mock.expect(:post, @response_mock, client_args)
44
-
45
- exception = assert_raises Exponent::Push::DeviceNotRegisteredError do
46
- @exponent.publish(messages)
47
- end
48
-
49
- assert_equal(message, exception.message)
50
-
51
- @mock.verify
52
- end
53
-
54
- def test_publish_with_message_too_big_error
55
- @response_mock.expect(:code, 200)
56
- @response_mock.expect(:body, message_too_big_error_body.to_json)
57
- message = 'Message too big'
58
-
59
- @mock.expect(:post, @response_mock, client_args)
60
-
61
- exception = assert_raises Exponent::Push::MessageTooBigError do
62
- @exponent.publish(messages)
63
- end
64
-
65
- assert_equal(message, exception.message)
66
-
67
- @mock.verify
68
- end
69
-
70
- def test_publish_with_message_rate_exceeded_error
71
- @response_mock.expect(:code, 200)
72
- @response_mock.expect(:body, message_rate_exceeded_error_body.to_json)
73
- message = 'Message rate exceeded'
74
-
75
- @mock.expect(:post, @response_mock, client_args)
76
-
77
- exception = assert_raises Exponent::Push::MessageRateExceededError do
78
- @exponent.publish(messages)
79
- end
80
-
81
- assert_equal(message, exception.message)
82
-
83
- @mock.verify
84
- end
85
-
86
- def test_publish_with_invalid_credentials_error
87
- @response_mock.expect(:code, 200)
88
- @response_mock.expect(:body, invalid_credentials_error_body.to_json)
89
- message = 'Invalid credentials'
90
-
91
- @mock.expect(:post, @response_mock, client_args)
92
-
93
- exception = assert_raises Exponent::Push::InvalidCredentialsError do
94
- @exponent.publish(messages)
95
- end
96
-
97
- assert_equal(message, exception.message)
98
-
99
- @mock.verify
100
- end
101
-
102
- def test_publish_with_apn_error
103
- @response_mock.expect(:code, 200)
104
- @response_mock.expect(:body, apn_error_body.to_json)
105
-
106
- @mock.expect(:post, @response_mock, client_args)
107
-
108
- exception = assert_raises Exponent::Push::UnknownError do
109
- @exponent.publish(messages)
110
- end
111
-
112
- assert_match(/Unknown error format/, exception.message)
113
-
114
- @mock.verify
115
- end
116
-
117
- private
118
-
119
- def success_body
120
- { 'data' => [{ 'status' => 'ok' }] }
121
- end
122
-
123
- def error_body
124
- {
125
- 'errors' => [{
126
- 'code' => 'INTERNAL_SERVER_ERROR',
127
- 'message' => 'An unknown error occurred.'
128
- }]
129
- }
130
- end
131
-
132
- def message_too_big_error_body
133
- build_error_body('MessageTooBig', 'Message too big')
134
- end
135
-
136
- def not_registered_device_error_body
137
- build_error_body(
138
- 'DeviceNotRegistered',
139
- '"ExponentPushToken[42]" is not a registered push notification recipient'
140
- )
141
- end
142
-
143
- def message_rate_exceeded_error_body
144
- build_error_body('MessageRateExceeded', 'Message rate exceeded')
145
- end
146
-
147
- def invalid_credentials_error_body
148
- build_error_body('InvalidCredentials', 'Invalid credentials')
149
- end
150
-
151
- def apn_error_body
152
- {
153
- 'data' => [{
154
- 'status' => 'error',
155
- 'message' =>
156
- 'Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
157
- }]
158
- }
159
- end
160
-
161
- def client_args
162
- [
163
- 'https://exp.host/--/api/v2/push/send',
164
- {
165
- body: messages.to_json,
166
- headers: {
167
- 'Content-Type' => 'application/json',
168
- 'Accept' => 'application/json'
169
- }
170
- }
171
- ]
172
- end
173
-
174
- def messages
175
- [{
176
- to: 'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]',
177
- sound: 'default',
178
- body: 'Hello world!'
179
- }, {
180
- to: 'ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]',
181
- badge: 1,
182
- body: "You've got mail"
183
- }]
184
- end
185
-
186
- def build_error_body(error_code, message)
187
- {
188
- 'data' => [{
189
- 'status' => 'error',
190
- 'message' => message,
191
- 'details' => { 'error' => error_code }
192
- }]
193
- }
194
- end
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.5
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: 2018-03-01 00:00:00.000000000 Z
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
- - manual-testing.txt
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
- rubyforge_project:
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
@@ -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
-