expo-push 1.0.2
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 +7 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +3923 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +19 -0
- data/examples/getting_started.rb +47 -0
- data/expo-push.gemspec +26 -0
- data/lib/expo-push/too_many_messages_error.rb +2 -0
- data/lib/expo-push/version.rb +3 -0
- data/lib/expo-push.rb +269 -0
- data/test/expo-push-test.rb +550 -0
- metadata +131 -0
@@ -0,0 +1,550 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'expo-push'
|
5
|
+
require 'expo-push/too_many_messages_error'
|
6
|
+
|
7
|
+
class ExponentServerSdkTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@mock = MiniTest::Mock.new
|
10
|
+
@response_mock = MiniTest::Mock.new
|
11
|
+
@client = Exponent::Push::Client.new(http_client: @mock)
|
12
|
+
@client_gzip = Exponent::Push::Client.new(http_client: @mock, gzip: true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_send_messages_with_success
|
16
|
+
@response_mock.expect(:code, 200)
|
17
|
+
@response_mock.expect(:body, success_body.to_json)
|
18
|
+
|
19
|
+
@mock.expect(:post, @response_mock, client_args)
|
20
|
+
|
21
|
+
response = @client.send_messages(messages)
|
22
|
+
assert_equal(response.errors?, false)
|
23
|
+
|
24
|
+
@mock.verify
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_send_messages_alternate_message_format_with_success
|
28
|
+
@response_mock.expect(:code, 200)
|
29
|
+
@response_mock.expect(:body, success_body.to_json)
|
30
|
+
|
31
|
+
alternate_messages = alternate_format_messages
|
32
|
+
@mock.expect(:post, @response_mock, alternative_client_args(alternate_messages))
|
33
|
+
|
34
|
+
response = @client.send_messages(alternate_messages)
|
35
|
+
assert_equal(response.errors?, false)
|
36
|
+
|
37
|
+
@mock.verify
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_send_messages_with_gzip_success
|
41
|
+
@response_mock.expect(:code, 200)
|
42
|
+
@response_mock.expect(:body, success_body.to_json)
|
43
|
+
|
44
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
45
|
+
|
46
|
+
response = @client_gzip.send_messages(messages)
|
47
|
+
assert_equal(response.errors?, false)
|
48
|
+
|
49
|
+
@mock.verify
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_send_messages_with_empty_string_response_body
|
53
|
+
@response_mock.expect(:code, 400)
|
54
|
+
@response_mock.expect(:body, '')
|
55
|
+
|
56
|
+
@mock.expect(:post, @response_mock, client_args)
|
57
|
+
|
58
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
59
|
+
handler = @client.send_messages(messages)
|
60
|
+
# this first assertion is just stating that errors will be false when
|
61
|
+
# an exception is thrown on the request, not the content of the request
|
62
|
+
# 400/500 level errors are not delivery errors, they are functionality errors
|
63
|
+
assert_equal(handler.response.errors?, false)
|
64
|
+
assert_equal(handler.response.body, {})
|
65
|
+
assert_equal(handler.response.code, 400)
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_match(/Unknown error format/, exception.message)
|
69
|
+
|
70
|
+
@mock.verify
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_send_messages_with_nil_response_body
|
74
|
+
@response_mock.expect(:code, 400)
|
75
|
+
@response_mock.expect(:body, nil)
|
76
|
+
|
77
|
+
@mock.expect(:post, @response_mock, client_args)
|
78
|
+
|
79
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
80
|
+
handler = @client.send_messages(messages)
|
81
|
+
# this first assertion is just stating that errors will be false when
|
82
|
+
# an exception is thrown on the request, not the content of the request
|
83
|
+
# 400/500 level errors are not delivery errors, they are functionality errors
|
84
|
+
assert_equal(handler.response.errors?, false)
|
85
|
+
assert_equal(handler.response.body, {})
|
86
|
+
assert_equal(handler.response.code, 400)
|
87
|
+
end
|
88
|
+
|
89
|
+
assert_match(/Unknown error format/, exception.message)
|
90
|
+
|
91
|
+
@mock.verify
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_send_messages_with_gzip_empty_string_response
|
95
|
+
@response_mock.expect(:code, 400)
|
96
|
+
@response_mock.expect(:body, '')
|
97
|
+
|
98
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
99
|
+
|
100
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
101
|
+
handler = @client_gzip.send_messages(messages)
|
102
|
+
# this first assertion is just stating that errors will be false when
|
103
|
+
# an exception is thrown on the request, not the content of the request
|
104
|
+
# 400/500 level errors are not delivery errors, they are functionality errors
|
105
|
+
assert_equal(handler.response.errors?, false)
|
106
|
+
assert_equal(handler.response.body, {})
|
107
|
+
assert_equal(handler.response.code, 400)
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_match(/Unknown error format/, exception.message)
|
111
|
+
|
112
|
+
@mock.verify
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_send_messages_with_gzip_nil_response_body
|
116
|
+
@response_mock.expect(:code, 400)
|
117
|
+
@response_mock.expect(:body, nil)
|
118
|
+
|
119
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
120
|
+
|
121
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
122
|
+
handler = @client_gzip.send_messages(messages)
|
123
|
+
# this first assertion is just stating that errors will be false when
|
124
|
+
# an exception is thrown on the request, not the content of the request
|
125
|
+
# 400/500 level errors are not delivery errors, they are functionality errors
|
126
|
+
assert_equal(handler.response.errors?, false)
|
127
|
+
assert_equal(handler.response.body, {})
|
128
|
+
assert_equal(handler.response.code, 400)
|
129
|
+
end
|
130
|
+
|
131
|
+
assert_match(/Unknown error format/, exception.message)
|
132
|
+
|
133
|
+
@mock.verify
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_send_messages_with_unknown_error
|
137
|
+
@response_mock.expect(:code, 400)
|
138
|
+
@response_mock.expect(:body, error_body.to_json)
|
139
|
+
|
140
|
+
@mock.expect(:post, @response_mock, client_args)
|
141
|
+
|
142
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
143
|
+
@client.send_messages(messages)
|
144
|
+
end
|
145
|
+
|
146
|
+
assert_equal("Unknown error format: #{error_body.to_json}", exception.message)
|
147
|
+
|
148
|
+
@mock.verify
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_send_messages_with_gzip_unknown_error
|
152
|
+
@response_mock.expect(:code, 400)
|
153
|
+
@response_mock.expect(:body, error_body.to_json)
|
154
|
+
|
155
|
+
@mock.expect(:post, @response_mock, gzip_client_args)
|
156
|
+
|
157
|
+
exception = assert_raises Exponent::Push::UnknownError do
|
158
|
+
@client_gzip.send_messages(messages)
|
159
|
+
end
|
160
|
+
|
161
|
+
assert_match(/Unknown error format/, exception.message)
|
162
|
+
|
163
|
+
@mock.verify
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_send_messages_with_device_not_registered_error
|
167
|
+
@response_mock.expect(:code, 200)
|
168
|
+
@response_mock.expect(:body, not_registered_device_error_body.to_json)
|
169
|
+
token = 'ExponentPushToken[42]'
|
170
|
+
message = "\"#{token}\" is not a registered push notification recipient"
|
171
|
+
|
172
|
+
@mock.expect(:post, @response_mock, client_args)
|
173
|
+
|
174
|
+
response_handler = @client.send_messages(messages)
|
175
|
+
assert_equal(message, response_handler.errors.first.message)
|
176
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::DeviceNotRegisteredError))
|
177
|
+
assert(response_handler.invalid_push_tokens.include?(token))
|
178
|
+
assert(response_handler.errors?)
|
179
|
+
|
180
|
+
@mock.verify
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_send_messages_too_many_messages
|
184
|
+
message = 'Only 100 message objects at a time allowed.'
|
185
|
+
|
186
|
+
e = assert_raises TooManyMessagesError do
|
187
|
+
@client.send_messages(too_many_messages)
|
188
|
+
end
|
189
|
+
|
190
|
+
assert_equal(e.message, message)
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_send_messages_with_message_too_big_error
|
194
|
+
@response_mock.expect(:code, 200)
|
195
|
+
@response_mock.expect(:body, message_too_big_error_body.to_json)
|
196
|
+
message = 'Message too big'
|
197
|
+
|
198
|
+
@mock.expect(:post, @response_mock, client_args)
|
199
|
+
|
200
|
+
response_handler = @client.send_messages(messages)
|
201
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::MessageTooBigError))
|
202
|
+
assert_equal(message, response_handler.errors.first.message)
|
203
|
+
assert(response_handler.errors?)
|
204
|
+
|
205
|
+
@mock.verify
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_send_messages_with_message_rate_exceeded_error
|
209
|
+
@response_mock.expect(:code, 200)
|
210
|
+
@response_mock.expect(:body, message_rate_exceeded_error_body.to_json)
|
211
|
+
message = 'Message rate exceeded'
|
212
|
+
|
213
|
+
@mock.expect(:post, @response_mock, client_args)
|
214
|
+
|
215
|
+
response_handler = @client.send_messages(messages)
|
216
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::MessageRateExceededError))
|
217
|
+
assert_equal(message, response_handler.errors.first.message)
|
218
|
+
|
219
|
+
@mock.verify
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_send_messages_with_invalid_credentials_error
|
223
|
+
@response_mock.expect(:code, 200)
|
224
|
+
@response_mock.expect(:body, invalid_credentials_error_body.to_json)
|
225
|
+
message = 'Invalid credentials'
|
226
|
+
|
227
|
+
@mock.expect(:post, @response_mock, client_args)
|
228
|
+
|
229
|
+
response_handler = @client.send_messages(messages)
|
230
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::InvalidCredentialsError))
|
231
|
+
assert_equal(message, response_handler.errors.first.message)
|
232
|
+
|
233
|
+
@mock.verify
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_send_messages_with_apn_error
|
237
|
+
@response_mock.expect(:code, 200)
|
238
|
+
@response_mock.expect(:body, apn_error_body.to_json)
|
239
|
+
|
240
|
+
@mock.expect(:post, @response_mock, client_args)
|
241
|
+
|
242
|
+
response_handler = @client.send_messages(messages)
|
243
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::UnknownError))
|
244
|
+
assert_match(/Unknown error format/, response_handler.errors.first.message)
|
245
|
+
|
246
|
+
@mock.verify
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_get_receipts_with_success_receipt
|
250
|
+
@response_mock.expect(:code, 200)
|
251
|
+
@response_mock.expect(:body, receipt_success_body.to_json)
|
252
|
+
receipt_ids = [success_receipt]
|
253
|
+
|
254
|
+
@mock.expect(:post, @response_mock, receipt_client_args(receipt_ids))
|
255
|
+
|
256
|
+
response_handler = @client.verify_deliveries(receipt_ids)
|
257
|
+
assert_match(success_receipt, response_handler.receipt_ids.first)
|
258
|
+
|
259
|
+
@mock.verify
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_get_receipts_with_error_receipt
|
263
|
+
@response_mock.expect(:code, 200)
|
264
|
+
@response_mock.expect(:body, receipt_error_body.to_json)
|
265
|
+
receipt_ids = [error_receipt]
|
266
|
+
|
267
|
+
@mock.expect(:post, @response_mock, receipt_client_args(receipt_ids))
|
268
|
+
|
269
|
+
response_handler = @client.verify_deliveries(receipt_ids)
|
270
|
+
assert_match(error_receipt, response_handler.receipt_ids.first)
|
271
|
+
assert_equal(true, response_handler.errors?)
|
272
|
+
assert_equal(1, response_handler.errors.count)
|
273
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::DeviceNotRegisteredError))
|
274
|
+
|
275
|
+
@mock.verify
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_get_receipts_with_variable_success_receipts
|
279
|
+
@response_mock.expect(:code, 200)
|
280
|
+
@response_mock.expect(:body, multiple_receipts.to_json)
|
281
|
+
receipt_ids = [error_receipt, success_receipt]
|
282
|
+
|
283
|
+
@mock.expect(:post, @response_mock, receipt_client_args(receipt_ids))
|
284
|
+
|
285
|
+
response_handler = @client.verify_deliveries(receipt_ids)
|
286
|
+
assert_match(error_receipt, response_handler.receipt_ids.first)
|
287
|
+
assert_match(success_receipt, response_handler.receipt_ids.last)
|
288
|
+
assert_equal(true, response_handler.errors?)
|
289
|
+
assert_equal(1, response_handler.errors.count)
|
290
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::DeviceNotRegisteredError))
|
291
|
+
|
292
|
+
@mock.verify
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_get_receipts_with_gzip_success_receipt
|
296
|
+
@response_mock.expect(:code, 200)
|
297
|
+
@response_mock.expect(:body, receipt_success_body.to_json)
|
298
|
+
receipt_ids = [success_receipt]
|
299
|
+
|
300
|
+
@mock.expect(:post, @response_mock, gzip_receipt_client_args(receipt_ids))
|
301
|
+
|
302
|
+
response_handler = @client_gzip.verify_deliveries(receipt_ids)
|
303
|
+
assert_match(success_receipt, response_handler.receipt_ids.first)
|
304
|
+
|
305
|
+
@mock.verify
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_get_receipts_with_gzip_error_receipt
|
309
|
+
@response_mock.expect(:code, 200)
|
310
|
+
@response_mock.expect(:body, receipt_error_body.to_json)
|
311
|
+
receipt_ids = [error_receipt]
|
312
|
+
|
313
|
+
@mock.expect(:post, @response_mock, gzip_receipt_client_args(receipt_ids))
|
314
|
+
|
315
|
+
response_handler = @client_gzip.verify_deliveries(receipt_ids)
|
316
|
+
assert_match(error_receipt, response_handler.receipt_ids.first)
|
317
|
+
assert_equal(true, response_handler.errors?)
|
318
|
+
assert_equal(1, response_handler.errors.count)
|
319
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::DeviceNotRegisteredError))
|
320
|
+
|
321
|
+
@mock.verify
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_get_receipts_with_gzip_variable_success_receipts
|
325
|
+
@response_mock.expect(:code, 200)
|
326
|
+
@response_mock.expect(:body, multiple_receipts.to_json)
|
327
|
+
receipt_ids = [error_receipt, success_receipt]
|
328
|
+
|
329
|
+
@mock.expect(:post, @response_mock, gzip_receipt_client_args(receipt_ids))
|
330
|
+
|
331
|
+
response_handler = @client_gzip.verify_deliveries(receipt_ids)
|
332
|
+
assert_match(error_receipt, response_handler.receipt_ids.first)
|
333
|
+
assert_match(success_receipt, response_handler.receipt_ids.last)
|
334
|
+
assert_equal(true, response_handler.errors?)
|
335
|
+
assert_equal(1, response_handler.errors.count)
|
336
|
+
assert(response_handler.errors.first.instance_of?(Exponent::Push::DeviceNotRegisteredError))
|
337
|
+
|
338
|
+
@mock.verify
|
339
|
+
end
|
340
|
+
|
341
|
+
private
|
342
|
+
|
343
|
+
def success_body
|
344
|
+
{ 'data' => [{ 'status' => 'ok' }] }
|
345
|
+
end
|
346
|
+
|
347
|
+
def success_receipt
|
348
|
+
'YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY'
|
349
|
+
end
|
350
|
+
|
351
|
+
def error_receipt
|
352
|
+
'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
353
|
+
end
|
354
|
+
|
355
|
+
def receipt_success_body
|
356
|
+
{
|
357
|
+
'data' => {
|
358
|
+
'YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY' => {
|
359
|
+
'status' => 'ok'
|
360
|
+
}
|
361
|
+
}
|
362
|
+
}
|
363
|
+
end
|
364
|
+
|
365
|
+
def receipt_error_body
|
366
|
+
{
|
367
|
+
'data' => {
|
368
|
+
'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' => {
|
369
|
+
'status' => 'error',
|
370
|
+
'message' => 'The Apple Push Notification service failed to send the notification',
|
371
|
+
'details' => {
|
372
|
+
'error' => 'DeviceNotRegistered'
|
373
|
+
}
|
374
|
+
}
|
375
|
+
}
|
376
|
+
}
|
377
|
+
end
|
378
|
+
|
379
|
+
def multiple_receipts
|
380
|
+
{
|
381
|
+
'data' => {
|
382
|
+
'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' => {
|
383
|
+
'status' => 'error',
|
384
|
+
'message' => 'The Apple Push Notification service failed to send the notification',
|
385
|
+
'details' => {
|
386
|
+
'error' => 'DeviceNotRegistered'
|
387
|
+
}
|
388
|
+
},
|
389
|
+
'YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY' => {
|
390
|
+
'status' => 'ok'
|
391
|
+
}
|
392
|
+
}
|
393
|
+
}
|
394
|
+
end
|
395
|
+
|
396
|
+
def error_body
|
397
|
+
{
|
398
|
+
'errors' => [{
|
399
|
+
'code' => 'INTERNAL_SERVER_ERROR',
|
400
|
+
'message' => 'An unknown error occurred.'
|
401
|
+
}]
|
402
|
+
}
|
403
|
+
end
|
404
|
+
|
405
|
+
def message_too_big_error_body
|
406
|
+
build_error_body('MessageTooBig', 'Message too big')
|
407
|
+
end
|
408
|
+
|
409
|
+
def not_registered_device_error_body
|
410
|
+
build_error_body(
|
411
|
+
'DeviceNotRegistered',
|
412
|
+
'"ExponentPushToken[42]" is not a registered push notification recipient'
|
413
|
+
)
|
414
|
+
end
|
415
|
+
|
416
|
+
def message_rate_exceeded_error_body
|
417
|
+
build_error_body('MessageRateExceeded', 'Message rate exceeded')
|
418
|
+
end
|
419
|
+
|
420
|
+
def invalid_credentials_error_body
|
421
|
+
build_error_body('InvalidCredentials', 'Invalid credentials')
|
422
|
+
end
|
423
|
+
|
424
|
+
def apn_error_body
|
425
|
+
{
|
426
|
+
'data' => [{
|
427
|
+
'status' => 'error',
|
428
|
+
'message' =>
|
429
|
+
'Could not find APNs credentials for you (your_app). Check whether you are trying to send a notification to a detached app.'
|
430
|
+
}]
|
431
|
+
}
|
432
|
+
end
|
433
|
+
|
434
|
+
def client_args
|
435
|
+
[
|
436
|
+
'https://exp.host/--/api/v2/push/send',
|
437
|
+
{
|
438
|
+
body: messages.to_json,
|
439
|
+
headers: {
|
440
|
+
'Content-Type' => 'application/json',
|
441
|
+
'Accept' => 'application/json'
|
442
|
+
},
|
443
|
+
accept_encoding: false
|
444
|
+
}
|
445
|
+
]
|
446
|
+
end
|
447
|
+
|
448
|
+
def alternative_client_args(messages)
|
449
|
+
[
|
450
|
+
'https://exp.host/--/api/v2/push/send',
|
451
|
+
{
|
452
|
+
body: messages.to_json,
|
453
|
+
headers: {
|
454
|
+
'Content-Type' => 'application/json',
|
455
|
+
'Accept' => 'application/json'
|
456
|
+
},
|
457
|
+
accept_encoding: false
|
458
|
+
}
|
459
|
+
]
|
460
|
+
end
|
461
|
+
|
462
|
+
def gzip_client_args
|
463
|
+
[
|
464
|
+
'https://exp.host/--/api/v2/push/send',
|
465
|
+
{
|
466
|
+
body: messages.to_json,
|
467
|
+
headers: {
|
468
|
+
'Content-Type' => 'application/json',
|
469
|
+
'Accept' => 'application/json'
|
470
|
+
},
|
471
|
+
accept_encoding: true
|
472
|
+
}
|
473
|
+
]
|
474
|
+
end
|
475
|
+
|
476
|
+
def receipt_client_args(receipt_ids)
|
477
|
+
[
|
478
|
+
'https://exp.host/--/api/v2/push/getReceipts',
|
479
|
+
{
|
480
|
+
body: { ids: receipt_ids }.to_json,
|
481
|
+
headers: {
|
482
|
+
'Content-Type' => 'application/json',
|
483
|
+
'Accept' => 'application/json'
|
484
|
+
},
|
485
|
+
accept_encoding: false
|
486
|
+
}
|
487
|
+
]
|
488
|
+
end
|
489
|
+
|
490
|
+
def gzip_receipt_client_args(receipt_ids)
|
491
|
+
[
|
492
|
+
'https://exp.host/--/api/v2/push/getReceipts',
|
493
|
+
{
|
494
|
+
body: { ids: receipt_ids }.to_json,
|
495
|
+
headers: {
|
496
|
+
'Content-Type' => 'application/json',
|
497
|
+
'Accept' => 'application/json'
|
498
|
+
},
|
499
|
+
accept_encoding: true
|
500
|
+
}
|
501
|
+
]
|
502
|
+
end
|
503
|
+
|
504
|
+
def alternate_format_messages
|
505
|
+
[{
|
506
|
+
to: [
|
507
|
+
'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]',
|
508
|
+
'ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]'
|
509
|
+
],
|
510
|
+
badge: 1,
|
511
|
+
sound: 'default',
|
512
|
+
body: 'You got a completely unique message from us! /s'
|
513
|
+
}]
|
514
|
+
end
|
515
|
+
|
516
|
+
def messages
|
517
|
+
[{
|
518
|
+
to: 'ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]',
|
519
|
+
sound: 'default',
|
520
|
+
body: 'Hello world!'
|
521
|
+
}, {
|
522
|
+
to: 'ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]',
|
523
|
+
badge: 1,
|
524
|
+
body: "You've got mail"
|
525
|
+
}]
|
526
|
+
end
|
527
|
+
|
528
|
+
def too_many_messages
|
529
|
+
(0..101).map { create_message }
|
530
|
+
end
|
531
|
+
|
532
|
+
def create_message
|
533
|
+
id = (0...22).map { ('a'..'z').to_a[rand(26)] }.join
|
534
|
+
{
|
535
|
+
to: "ExponentPushToken[#{id}]",
|
536
|
+
sound: 'default',
|
537
|
+
body: 'Hello world!'
|
538
|
+
}
|
539
|
+
end
|
540
|
+
|
541
|
+
def build_error_body(error_code, message)
|
542
|
+
{
|
543
|
+
'data' => [{
|
544
|
+
'status' => 'error',
|
545
|
+
'message' => message,
|
546
|
+
'details' => { 'error' => error_code }
|
547
|
+
}]
|
548
|
+
}
|
549
|
+
end
|
550
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: expo-push
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jesse Ruder
|
8
|
+
- Pablo Gomez
|
9
|
+
- Mike Taylor
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2022-11-01 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: typhoeus
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.4'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.4'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: bundler
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :development
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: minitest
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :development
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: rake
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rubocop
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
description: A ruby gem to communicate with the Expo Push service.
|
86
|
+
email:
|
87
|
+
- jesse@sixfivezero.net
|
88
|
+
- pablonahuelgomez@gmail.com
|
89
|
+
- mike.taylor@growmaple.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- ".gitignore"
|
95
|
+
- ".rubocop.yml"
|
96
|
+
- ".travis.yml"
|
97
|
+
- Gemfile
|
98
|
+
- LICENSE.txt
|
99
|
+
- README.md
|
100
|
+
- Rakefile
|
101
|
+
- examples/getting_started.rb
|
102
|
+
- expo-push.gemspec
|
103
|
+
- lib/expo-push.rb
|
104
|
+
- lib/expo-push/too_many_messages_error.rb
|
105
|
+
- lib/expo-push/version.rb
|
106
|
+
- test/expo-push-test.rb
|
107
|
+
homepage: https://github.com/growmaple/expo-push
|
108
|
+
licenses:
|
109
|
+
- MIT
|
110
|
+
metadata: {}
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubygems_version: 3.1.6
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Expo Push
|
130
|
+
test_files:
|
131
|
+
- test/expo-push-test.rb
|