twinpush 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4e5f75a1774fcdbbf792c1e4d982e07cf13d324e0ef3ee113efea24c0c9ae417
4
+ data.tar.gz: 0776ed72759003f8108506bcd4d9e1645ef12e27a6575d681fc5030a30f4e7f0
5
+ SHA512:
6
+ metadata.gz: 8246fe87adbae38faed5bc5d7d8de5bf1b022ec284ef73363bd88de647a2ec4e292074e9742283740928c52c27fa010266c6a83b1dc2b340a5c77a14e8263c65
7
+ data.tar.gz: b1d5e69a2c9137a795cb107fba7e8e59143bd0a73689c43b7e3f5fc9d699face3514682ffb4a6f46c4c42e468a5af054a40a1c7d6c5c0ce0723a20cedd7d0afe
data/lib/twinpush.rb ADDED
@@ -0,0 +1,159 @@
1
+ require 'faraday'
2
+ require 'cgi'
3
+ require 'json'
4
+
5
+ class TWINPUSH
6
+ DEFAULT_TIMEOUT = 30
7
+ FORMAT = :json
8
+ BASE_URI = 'https://subdomain.twinpush.com'
9
+ API_URL = '/api/v2/apps'
10
+
11
+ attr_accessor :uri, :app_id, :api_token, :api_token_creator
12
+
13
+ # @param [Hash] authentication_keys
14
+ # @param [Hash] client_options
15
+ # @param [Integer] timeout
16
+ def initialize(authentication_keys, client_options = {}, timeout = nil)
17
+ validate_keys(authentication_keys)
18
+ authentication_keys.each_pair do |key, value|
19
+ instance_variable_set("@#{key}", value)
20
+ self.class.instance_eval { attr_accessor key.to_sym }
21
+ end
22
+ @uri = BASE_URI.sub! 'subdomain', @subdomain
23
+ @client_options = client_options
24
+ @timeout = timeout | DEFAULT_TIMEOUT
25
+ end
26
+
27
+ #obtains details from a previously created notification
28
+ def show_notification(notification_id, device_id = nil)
29
+ path = "#{API_URL}/#{app_id}#{"/devices/#{device_id}" if device_id }/notifications/#{notification_id}"
30
+ for_uri(uri) do |connection|
31
+ response = connection.get(path)
32
+ build_response(response)
33
+ end
34
+ end
35
+
36
+ alias show show_notification
37
+
38
+ #creates a new notification to be delivered from the platform
39
+ def create_notification(notification_params)
40
+ path = "#{API_URL}/#{app_id}/notifications"
41
+ for_uri(uri) do |connection|
42
+ response = connection.post(path, notification_params.to_json)
43
+ build_response(response)
44
+ end
45
+ end
46
+
47
+ alias create create_notification
48
+
49
+ # obtains delivery statistics for a given notification
50
+ def report_notification(notification_id)
51
+ path = "#{API_URL}/#{app_id}/notifications/#{notification_id}/report"
52
+ for_uri(uri) do |connection|
53
+ response = connection.get(path)
54
+ build_response(response)
55
+ end
56
+ end
57
+
58
+ alias report report_notification
59
+
60
+ #Obtains paginated list of all the deliveries for a given notification.
61
+ #This is useful to obtain exactly who has been the recipient of the notification and also who has opened it
62
+ def deliveries_notification(notification_id)
63
+ path = "#{API_URL}/#{app_id}/notifications/#{notification_id}/deliveries"
64
+ for_uri(uri) do |connection|
65
+ response = connection.get(path)
66
+ build_response(response)
67
+ end
68
+ end
69
+
70
+ alias deliveries deliveries_notification
71
+
72
+ # Makes a paginated search of the notifications sent to an user through the device alias. It allows filtering by notification tags
73
+ def inbox(device_id)
74
+ path = "#{API_URL}/#{app_id}/devices/#{device_id}/inbox"
75
+ for_uri(uri) do |connection|
76
+ response = connection.get(path)
77
+ build_response(response)
78
+ end
79
+ end
80
+
81
+ #Obtains a fast summary of the notification inbox associated to the current device alias
82
+ #It offers the total notification count and the unopened notification count
83
+ def inbox_summary(device_id)
84
+ path = "#{API_URL}/#{app_id}/devices/#{device_id}/inbox_summary"
85
+ for_uri(uri) do |connection|
86
+ response = connection.get(path)
87
+ build_response(response)
88
+ end
89
+ end
90
+
91
+ #Removes the selected notification from the inbox of the user (or alias) associated to the device
92
+ def delete_inbox(device_id, notification_id)
93
+ path = "#{API_URL}/#{app_id}/devices/#{device_id}/notifications/#{notification_id}"
94
+ for_uri(uri) do |connection|
95
+ response = connection.delete(path)
96
+ build_response(response)
97
+ end
98
+ end
99
+
100
+ # assigns value for a device custom property
101
+ def set_custom_property(device_id, properties)
102
+ path = "#{API_URL}/#{app_id}/devices/#{device_id}/set_custom_property"
103
+ for_uri(uri) do |connection|
104
+ response = connection.post(path, properties.to_json)
105
+ build_response(response)
106
+ end
107
+ end
108
+
109
+ #Makes a paginated search of the notifications received by a device. It allows filtering by notification tags
110
+ def search_device_notifications(device_id, params)
111
+ path = "#{API_URL}/#{app_id}/devices/#{device_id}/search_notifications"
112
+ for_uri(uri) do |connection|
113
+ response = connection.post(path, params.to_json)
114
+ build_response(response)
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ def validate_keys(authentication_keys)
121
+ required_params = [:app_id, :subdomain, :api_token, :api_token_creator]
122
+ (required_params - authentication_keys.keys).each do |params|
123
+ raise ArgumentError, "Required authentication_key #{params} missing"
124
+ end
125
+ end
126
+
127
+ def for_uri(uri, extra_headers = {})
128
+ connection = ::Faraday.new(:url => uri) do |faraday|
129
+ faraday.adapter Faraday.default_adapter
130
+ faraday.headers["Content-Type"] = "application/json"
131
+ faraday.headers["X-TwinPush-REST-API-Key-Creator"] = api_token_creator
132
+ faraday.headers["X-TwinPush-REST-API-Token"] = api_token
133
+ extra_headers.each do |key, value|
134
+ faraday.headers[key] = value
135
+ end
136
+ end
137
+ yield connection
138
+ end
139
+
140
+ def build_response(response)
141
+ body = response.body || {}
142
+ response_hash = { body: body, headers: response.headers, status_code: response.status }
143
+ case response.status
144
+ when 200
145
+ response_hash[:response] = 'success'
146
+ when 403
147
+ response_hash[:response] = 'API Key Token or Creator API Key Token are not valid or does not match with App ID'
148
+ when 404
149
+ response_hash[:response] = 'Application not found for given application_id, device not found for given device_id or delivery not found for given notification and device'
150
+ when 422
151
+ response_hash[:response] = 'Some of the parameters given is not valid when trying to create a notification, create a device property or register or update a device'
152
+ when 500..599
153
+ response_hash[:response] = 'There was an internal error in the Twinpush server while trying to process the request.'
154
+ end
155
+ response_hash
156
+ end
157
+
158
+
159
+ end
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'webmock/rspec'
4
+
5
+ require 'twinpush'
6
+
7
+ RSpec.configure do |config|
8
+ config.run_all_when_everything_filtered = true
9
+ config.expect_with :rspec do |c|
10
+ c.syntax = [:should, :expect]
11
+ end
12
+ end
@@ -0,0 +1,475 @@
1
+ require 'spec_helper'
2
+
3
+ describe TWINPUSH do
4
+ let(:app_id) { '1a2b3c4d5f' }
5
+ let(:subdomain) { 'test' }
6
+ let(:api_token) { '1c5cabc4055e03c64f123d9dbfb4d0e9' }
7
+ let(:api_token_creator) { '232ddfd56b6a3af1ba89b93c5ffd836d' }
8
+ let(:authentication_keys) {{app_id: app_id, subdomain: subdomain, api_token: api_token, api_token_creator: api_token_creator}}
9
+
10
+ it 'should replace subdomian in uri' do
11
+ twinpush = TWINPUSH.new(authentication_keys)
12
+ expect(twinpush.uri).to eq "https://test.googleapis.com/api/v2"
13
+ end
14
+
15
+ it 'should raise an error if authentication_keys is not provided' do
16
+ expect { TWINPUSH.new }.to raise_error(ArgumentError)
17
+ expect { TWINPUSH.new(app_id: app_id )}.to raise_error(ArgumentError, 'Required authentication_key subdomain missing')
18
+ expect { TWINPUSH.new(app_id: app_id, subdomain: subdomain )}.to raise_error(ArgumentError, 'Required authentication_key api_token missing')
19
+ expect { TWINPUSH.new(app_id: app_id, subdomain: subdomain, api_token: api_token)}.to raise_error(ArgumentError, 'Required authentication_key api_token_creator missing')
20
+ expect { TWINPUSH.new(authentication_keys)}.not_to raise_error(ArgumentError)
21
+ end
22
+
23
+ # describe 'sending notification' do
24
+ # let(:valid_request_body) do
25
+ # { registration_ids: registration_ids }
26
+ # end
27
+ # let(:valid_request_body_with_string) do
28
+ # { registration_ids: registration_id }
29
+ # end
30
+ # let(:valid_request_headers) do
31
+ # {
32
+ # 'Content-Type' => 'application/json',
33
+ # 'Authorization' => "key=#{api_key}"
34
+ # }
35
+ # end
36
+ #
37
+ # let(:stub_fcm_send_request) do
38
+ # stub_request(:post, send_url).with(
39
+ # body: valid_request_body.to_json,
40
+ # headers: valid_request_headers
41
+ # ).to_return(
42
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
43
+ # body: '{}',
44
+ # headers: {},
45
+ # status: 200
46
+ # )
47
+ # end
48
+ #
49
+ # let(:stub_fcm_send_request_with_string) do
50
+ # stub_request(:post, send_url).with(
51
+ # body: valid_request_body_with_string.to_json,
52
+ # headers: valid_request_headers
53
+ # ).to_return(
54
+ # body: '{}',
55
+ # headers: {},
56
+ # status: 200
57
+ # )
58
+ # end
59
+ #
60
+ # let(:stub_fcm_send_request_with_basic_auth) do
61
+ # uri = URI.parse(send_url)
62
+ # uri.user = 'a'
63
+ # uri.password = 'b'
64
+ # stub_request(:post, uri.to_s).to_return(body: '{}', headers: {}, status: 200)
65
+ # end
66
+ #
67
+ # before(:each) do
68
+ # stub_fcm_send_request
69
+ # stub_fcm_send_request_with_string
70
+ # stub_fcm_send_request_with_basic_auth
71
+ # end
72
+ #
73
+ # it 'should send notification using POST to FCM server' do
74
+ # fcm = FCM.new(api_key)
75
+ # fcm.send(registration_ids).should eq(response: 'success', body: '{}', headers: {}, status_code: 200, canonical_ids: [], not_registered_ids: [])
76
+ # stub_fcm_send_request.should have_been_made.times(1)
77
+ # end
78
+ #
79
+ # it 'should send notification using POST to FCM if id provided as string' do
80
+ # fcm = FCM.new(api_key)
81
+ # fcm.send(registration_id).should eq(response: 'success', body: '{}', headers: {}, status_code: 200, canonical_ids: [], not_registered_ids: [])
82
+ # stub_fcm_send_request.should have_been_made.times(1)
83
+ # end
84
+ #
85
+ # context 'send notification with data' do
86
+ # let!(:stub_with_data) do
87
+ # stub_request(:post, send_url)
88
+ # .with(body: '{"registration_ids":["42"],"data":{"score":"5x1","time":"15:10"}}',
89
+ # headers: valid_request_headers)
90
+ # .to_return(status: 200, body: '', headers: {})
91
+ # end
92
+ # before do
93
+ # end
94
+ # it 'should send the data in a post request to fcm' do
95
+ # fcm = FCM.new(api_key)
96
+ # fcm.send(registration_ids, data: { score: '5x1', time: '15:10' })
97
+ # stub_with_data.should have_been_requested
98
+ # end
99
+ # end
100
+ #
101
+ # context "sending notification to a topic" do
102
+ # let!(:stub_with_valid_topic) do
103
+ # stub_request(:post, send_url)
104
+ # .with(body: '{"to":"/topics/TopicA","data":{"score":"5x1","time":"15:10"}}',
105
+ # headers: valid_request_headers)
106
+ # .to_return(status: 200, body: '', headers: {})
107
+ # end
108
+ # let!(:stub_with_invalid_topic) do
109
+ # stub_request(:post, send_url)
110
+ # .with(body: '{"condition":"/topics/TopicA$","data":{"score":"5x1","time":"15:10"}}',
111
+ # headers: valid_request_headers)
112
+ # .to_return(status: 200, body: '', headers: {})
113
+ # end
114
+ #
115
+ # describe "#send_to_topic" do
116
+ # it 'should send the data in a post request to fcm' do
117
+ # fcm = FCM.new(api_key)
118
+ # fcm.send_to_topic(valid_topic, data: { score: '5x1', time: '15:10' })
119
+ # stub_with_valid_topic.should have_been_requested
120
+ # end
121
+ #
122
+ # it 'should not send to invalid topics' do
123
+ # fcm = FCM.new(api_key)
124
+ # fcm.send_to_topic(invalid_topic, data: { score: '5x1', time: '15:10' })
125
+ # stub_with_invalid_topic.should_not have_been_requested
126
+ # end
127
+ # end
128
+ # end
129
+ #
130
+ # context "sending notification to a topic condition" do
131
+ # let!(:stub_with_valid_condition) do
132
+ # stub_request(:post, send_url)
133
+ # .with(body: '{"condition":"\'TopicA\' in topics && (\'TopicB\' in topics || \'TopicC\' in topics)","data":{"score":"5x1","time":"15:10"}}',
134
+ # headers: valid_request_headers)
135
+ # .to_return(status: 200, body: '', headers: {})
136
+ # end
137
+ # let!(:stub_with_invalid_condition) do
138
+ # stub_request(:post, send_url)
139
+ # .with(body: '{"condition":"\'TopicA\' in topics and some other text (\'TopicB\' in topics || \'TopicC\' in topics)","data":{"score":"5x1","time":"15:10"}}',
140
+ # headers: valid_request_headers)
141
+ # .to_return(status: 200, body: '', headers: {})
142
+ # end
143
+ # let!(:stub_with_invalid_condition_topic) do
144
+ # stub_request(:post, send_url)
145
+ # .with(body: '{"condition":"\'TopicA$\' in topics","data":{"score":"5x1","time":"15:10"}}',
146
+ # headers: valid_request_headers)
147
+ # .to_return(status: 200, body: '', headers: {})
148
+ # end
149
+ #
150
+ # describe "#send_to_topic_condition" do
151
+ # it 'should send the data in a post request to fcm' do
152
+ # fcm = FCM.new(api_key)
153
+ # fcm.send_to_topic_condition(valid_condition, data: { score: '5x1', time: '15:10' })
154
+ # stub_with_valid_condition.should have_been_requested
155
+ # end
156
+ #
157
+ # it 'should not send to invalid conditions' do
158
+ # fcm = FCM.new(api_key)
159
+ # fcm.send_to_topic_condition(invalid_condition, data: { score: '5x1', time: '15:10' })
160
+ # stub_with_invalid_condition.should_not have_been_requested
161
+ # end
162
+ #
163
+ # it 'should not send to invalid topics in a condition' do
164
+ # fcm = FCM.new(api_key)
165
+ # fcm.send_to_topic_condition(invalid_condition_topic, data: { score: '5x1', time: '15:10' })
166
+ # stub_with_invalid_condition_topic.should_not have_been_requested
167
+ # end
168
+ # end
169
+ # end
170
+ #
171
+ # context 'when send_notification responds with failure' do
172
+ # let(:mock_request_attributes) do
173
+ # {
174
+ # body: valid_request_body.to_json,
175
+ # headers: valid_request_headers
176
+ # }
177
+ # end
178
+ #
179
+ # subject { FCM.new(api_key) }
180
+ #
181
+ # context 'on failure code 400' do
182
+ # before do
183
+ # stub_request(:post, send_url).with(
184
+ # mock_request_attributes
185
+ # ).to_return(
186
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
187
+ # body: '{}',
188
+ # headers: {},
189
+ # status: 400
190
+ # )
191
+ # end
192
+ # it 'should not send notification due to 400' do
193
+ # subject.send(registration_ids).should eq(body: '{}',
194
+ # headers: {},
195
+ # response: 'Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields.',
196
+ # status_code: 400)
197
+ # end
198
+ # end
199
+ #
200
+ # context 'on failure code 401' do
201
+ # before do
202
+ # stub_request(:post, send_url).with(
203
+ # mock_request_attributes
204
+ # ).to_return(
205
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
206
+ # body: '{}',
207
+ # headers: {},
208
+ # status: 401
209
+ # )
210
+ # end
211
+ #
212
+ # it 'should not send notification due to 401' do
213
+ # subject.send(registration_ids).should eq(body: '{}',
214
+ # headers: {},
215
+ # response: 'There was an error authenticating the sender account.',
216
+ # status_code: 401)
217
+ # end
218
+ # end
219
+ #
220
+ # context 'on failure code 503' do
221
+ # before do
222
+ # stub_request(:post, send_url).with(
223
+ # mock_request_attributes
224
+ # ).to_return(
225
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
226
+ # body: '{}',
227
+ # headers: {},
228
+ # status: 503
229
+ # )
230
+ # end
231
+ #
232
+ # it 'should not send notification due to 503' do
233
+ # subject.send(registration_ids).should eq(body: '{}',
234
+ # headers: {},
235
+ # response: 'Server is temporarily unavailable.',
236
+ # status_code: 503)
237
+ # end
238
+ # end
239
+ #
240
+ # context 'on failure code 5xx' do
241
+ # before do
242
+ # stub_request(:post, send_url).with(
243
+ # mock_request_attributes
244
+ # ).to_return(
245
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
246
+ # body: '{"body-key" => "Body value"}',
247
+ # headers: { 'header-key' => 'Header value' },
248
+ # status: 599
249
+ # )
250
+ # end
251
+ #
252
+ # it 'should not send notification due to 599' do
253
+ # subject.send(registration_ids).should eq(body: '{"body-key" => "Body value"}',
254
+ # headers: { 'header-key' => 'Header value' },
255
+ # response: 'There was an internal error in the FCM server while trying to process the request.',
256
+ # status_code: 599)
257
+ # end
258
+ # end
259
+ # end
260
+ #
261
+ # context 'when send_notification responds canonical_ids' do
262
+ # let(:mock_request_attributes) do
263
+ # {
264
+ # body: valid_request_body.to_json,
265
+ # headers: valid_request_headers
266
+ # }
267
+ # end
268
+ #
269
+ # let(:valid_response_body_with_canonical_ids) do
270
+ # {
271
+ # failure: 0, canonical_ids: 1, results: [{ registration_id: '43', message_id: '0:1385025861956342%572c22801bb3' }]
272
+ # }
273
+ # end
274
+ #
275
+ # subject { FCM.new(api_key) }
276
+ #
277
+ # before do
278
+ # stub_request(:post, send_url).with(
279
+ # mock_request_attributes
280
+ # ).to_return(
281
+ # # ref: https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream
282
+ # body: valid_response_body_with_canonical_ids.to_json,
283
+ # headers: {},
284
+ # status: 200
285
+ # )
286
+ # end
287
+ #
288
+ # it 'should contain canonical_ids' do
289
+ # response = subject.send(registration_ids)
290
+ #
291
+ # response.should eq(headers: {},
292
+ # canonical_ids: [{ old: '42', new: '43' }],
293
+ # not_registered_ids: [],
294
+ # status_code: 200,
295
+ # response: 'success',
296
+ # body: '{"failure":0,"canonical_ids":1,"results":[{"registration_id":"43","message_id":"0:1385025861956342%572c22801bb3"}]}')
297
+ # end
298
+ # end
299
+ #
300
+ # context 'when send_notification responds with NotRegistered' do
301
+ # subject { FCM.new(api_key) }
302
+ #
303
+ # let(:mock_request_attributes) do
304
+ # {
305
+ # body: valid_request_body.to_json,
306
+ # headers: valid_request_headers
307
+ # }
308
+ # end
309
+ #
310
+ # let(:valid_response_body_with_not_registered_ids) do
311
+ # {
312
+ # canonical_ids: 0, failure: 1, results: [{ error: 'NotRegistered' }]
313
+ # }
314
+ # end
315
+ #
316
+ # before do
317
+ # stub_request(:post, send_url).with(
318
+ # mock_request_attributes
319
+ # ).to_return(
320
+ # body: valid_response_body_with_not_registered_ids.to_json,
321
+ # headers: {},
322
+ # status: 200
323
+ # )
324
+ # end
325
+ #
326
+ # it 'should contain not_registered_ids' do
327
+ # response = subject.send(registration_ids)
328
+ # response.should eq(
329
+ # headers: {},
330
+ # canonical_ids: [],
331
+ # not_registered_ids: registration_ids,
332
+ # status_code: 200,
333
+ # response: 'success',
334
+ # body: '{"canonical_ids":0,"failure":1,"results":[{"error":"NotRegistered"}]}'
335
+ # )
336
+ # end
337
+ # end
338
+ # end
339
+ #
340
+ # describe 'sending group notifications' do
341
+ # # TODO: refactor to should_behave_like
342
+ # let(:valid_request_headers) do
343
+ # {
344
+ # "Authorization" => "key=#{api_key}",
345
+ # "Content-Type" => 'application/json',
346
+ # "Project-Id" => project_id
347
+ # }
348
+ # end
349
+ # let(:valid_response_body) do
350
+ # { notification_key: "APA91bGHXQBB...9QgnYOEURwm0I3lmyqzk2TXQ" }
351
+ # end
352
+ #
353
+ # let(:default_valid_request_body) do
354
+ # {
355
+ # registration_ids: registration_ids,
356
+ # operation: "create",
357
+ # notification_key_name: key_name
358
+ # }
359
+ # end
360
+ #
361
+ # subject { FCM.new(api_key) }
362
+ #
363
+ # # ref: https://firebase.google.com/docs/cloud-messaging/notifications#managing-device-groups-on-the-app-server
364
+ # context 'create' do
365
+ # let(:valid_request_body) do
366
+ # default_valid_request_body.merge({
367
+ # operation: "create"
368
+ # })
369
+ # end
370
+ #
371
+ # let(:mock_request_attributes) do
372
+ # {
373
+ # body: valid_request_body.to_json,
374
+ # headers: valid_request_headers
375
+ # }
376
+ # end
377
+ #
378
+ # before do
379
+ # stub_request(:post, group_notification_base_uri).with(
380
+ # mock_request_attributes
381
+ # ).to_return(
382
+ # body: valid_response_body.to_json,
383
+ # headers: {},
384
+ # status: 200
385
+ # )
386
+ # end
387
+ #
388
+ # it 'should send a post request' do
389
+ # response = subject.create(key_name, project_id, registration_ids)
390
+ # response.should eq(
391
+ # headers: {},
392
+ # status_code: 200,
393
+ # response: 'success',
394
+ # body: valid_response_body.to_json
395
+ # )
396
+ # end
397
+ # end # create context
398
+ #
399
+ # context 'add' do
400
+ # let(:valid_request_body) do
401
+ # default_valid_request_body.merge({
402
+ # operation: "add",
403
+ # notification_key: notification_key
404
+ # })
405
+ # end
406
+ #
407
+ # let(:mock_request_attributes) do
408
+ # {
409
+ # body: valid_request_body.to_json,
410
+ # headers: valid_request_headers
411
+ # }
412
+ # end
413
+ #
414
+ # before do
415
+ # stub_request(:post, group_notification_base_uri).with(
416
+ # mock_request_attributes
417
+ # ).to_return(
418
+ # body: valid_response_body.to_json,
419
+ # headers: {},
420
+ # status: 200
421
+ # )
422
+ # end
423
+ #
424
+ # it 'should send a post request' do
425
+ # response = subject.add(key_name, project_id, notification_key, registration_ids)
426
+ # response.should eq(
427
+ # headers: {},
428
+ # status_code: 200,
429
+ # response: 'success',
430
+ # body: valid_response_body.to_json
431
+ # )
432
+ # end
433
+ # end # add context
434
+ #
435
+ # context 'remove' do
436
+ # let(:valid_request_body) do
437
+ # default_valid_request_body.merge({
438
+ # operation: "remove",
439
+ # notification_key: notification_key
440
+ # })
441
+ # end
442
+ #
443
+ # let(:mock_request_attributes) do
444
+ # {
445
+ # body: valid_request_body.to_json,
446
+ # headers: valid_request_headers
447
+ # }
448
+ # end
449
+ #
450
+ # before do
451
+ # stub_request(:post, group_notification_base_uri).with(
452
+ # mock_request_attributes
453
+ # ).to_return(
454
+ # body: valid_response_body.to_json,
455
+ # headers: {},
456
+ # status: 200
457
+ # )
458
+ # end
459
+ #
460
+ # it 'should send a post request' do
461
+ # response = subject.remove(key_name, project_id, notification_key, registration_ids)
462
+ # response.should eq(
463
+ # headers: {},
464
+ # status_code: 200,
465
+ # response: 'success',
466
+ # body: valid_response_body.to_json
467
+ # )
468
+ # end
469
+ # end # remove context
470
+ # end
471
+ #
472
+ # describe 'subscribing to a topic' do
473
+ # # TODO
474
+ # end
475
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twinpush
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Amaury González
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.15.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.15.4
27
+ description: TwinPush gem provides ruby bindings to TwinPush a messaging solution
28
+ that lets you reliably deliver messages and notifications at no cost to Android,
29
+ iOS or Web browsers.
30
+ email:
31
+ - amaury.muro@gmail.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/twinpush.rb
37
+ - spec/spec_helper.rb
38
+ - spec/twinpush_spec.rb
39
+ homepage: https://github.com/amaurygonzalez/twinpush
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 2.0.0
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project: twinpush
59
+ rubygems_version: 2.7.6
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Reliably deliver push notifications through TwinPush API
63
+ test_files:
64
+ - spec/spec_helper.rb
65
+ - spec/twinpush_spec.rb