pntfr 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +31 -0
- data/README.md +64 -26
- data/lib/pntfr/notification.rb +42 -0
- data/lib/pntfr/notifier.rb +85 -6
- data/lib/pntfr/session/android.rb +38 -0
- data/lib/pntfr/session/base.rb +19 -0
- data/lib/pntfr/{virtual_session → session}/base_response.rb +1 -1
- data/lib/pntfr/{virtual_session → session}/gcm_response.rb +2 -2
- data/lib/pntfr/session/ios.rb +58 -0
- data/lib/pntfr/{virtual_session → session}/success_response.rb +2 -2
- data/lib/pntfr/version.rb +9 -6
- data/pntfr.gemspec +1 -2
- data/test/pntfr/android_test.rb +76 -0
- data/test/pntfr/device.rb +6 -0
- data/test/pntfr/ios_badge_test.rb +16 -0
- data/test/pntfr/ios_test.rb +90 -0
- data/test/pntfr/notifier_test.rb +73 -0
- data/test/pntfr/{virtual_session → session}/response_test.rb +6 -6
- data/test/{pntfr_configuration_test.rb → pntfr_global_configuration_test.rb} +0 -0
- metadata +28 -25
- data/lib/pntfr/virtual_session/android.rb +0 -48
- data/lib/pntfr/virtual_session/base.rb +0 -17
- data/lib/pntfr/virtual_session/ios.rb +0 -58
- data/test/pntfr/device_session.rb +0 -6
- data/test/pntfr/push_notifier_test.rb +0 -17
- data/test/pntfr/virtual_session/android_test.rb +0 -61
- data/test/pntfr/virtual_session/ios_badge_test.rb +0 -18
- data/test/pntfr/virtual_session/ios_test.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5cf720813ce033ef80813fd133fc74ef8db6b2b
|
4
|
+
data.tar.gz: 38e3393d5950af33c10bd82e01e5eec01cc01345
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c73fce1055940fec086f8a242deae2ab71ec09d950e269c1bfbc6ae6203b14d36dc5a8476b803d6660ca8f11053f1b914f01d305d17537dccd95b803e9c596f7
|
7
|
+
data.tar.gz: 43d6a4e89c141f6025418a24351bfd967b09f54656b1981cefde5f1c4e3be4545d4e11e2b230194f8ba139a8fbf79201e52a7da98e3869a479adad51bde20958
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pntfr (0.2.0)
|
5
|
+
apns (~> 1.0, >= 1.0.0)
|
6
|
+
gcm (~> 0.0, >= 0.0.9)
|
7
|
+
json (~> 1.8, >= 1.8.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
apns (1.0.0)
|
13
|
+
gcm (0.1.0)
|
14
|
+
httparty
|
15
|
+
json
|
16
|
+
httparty (0.13.4)
|
17
|
+
json (~> 1.8)
|
18
|
+
multi_xml (>= 0.5.2)
|
19
|
+
json (1.8.2)
|
20
|
+
minitest (5.7.0)
|
21
|
+
multi_xml (0.5.5)
|
22
|
+
rake (10.4.2)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (~> 1.6)
|
29
|
+
minitest (~> 5.7.0)
|
30
|
+
pntfr!
|
31
|
+
rake
|
data/README.md
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
# Pntfr
|
2
|
-
Push Notifier is a simple adapter for APNS (Apple Push Notification Service) and GCM (Google Cloud Messaging) gems, that way you can use
|
2
|
+
Push Notifier is a simple adapter for APNS (Apple Push Notification Service) and GCM (Google Cloud Messaging) gems, that way you can use one message format and one library to send push notifications to both devices.
|
3
3
|
|
4
4
|
# Usage
|
5
5
|
## Installation
|
6
6
|
Add it to your Gemfile:
|
7
7
|
|
8
|
-
gem 'pntfr', '~>0.
|
8
|
+
gem 'pntfr', '~>0.3.0'
|
9
9
|
|
10
10
|
## Configuration
|
11
|
+
Pntfr can be configured in two ways.
|
12
|
+
- Setting a global configuration
|
13
|
+
- Setting notification service's configuration on each call.
|
14
|
+
|
15
|
+
### Global configuration
|
11
16
|
To configure the Apple Push Notification Service just set the Hash of keys to be used:
|
12
17
|
```ruby
|
13
18
|
Pntfr.configure do |config|
|
@@ -39,41 +44,55 @@ end
|
|
39
44
|
```
|
40
45
|
|
41
46
|
## Sending messages
|
42
|
-
Pntfr suposes you have
|
47
|
+
Pntfr suposes you have device objects, or other kind of model, with `platform` and `push_id` attributes.
|
43
48
|
Also, and optionally, a `num_notifs` integer attribute will be automagically managed to
|
44
49
|
monitor Apple's badge in notifications.
|
45
50
|
|
46
|
-
|
47
|
-
|
48
|
-
|
51
|
+
In order to avoid having to create a different message for each platform Pntfr
|
52
|
+
expects a "neutral format" for the messages. The neutral format of the messages
|
53
|
+
is a map composed by `title` and `description` keys.
|
54
|
+
This keys are added directly to Android notification's `data` content, on the
|
55
|
+
other side, for Apns notifications, are concatenated with a newline
|
49
56
|
|
50
57
|
Sending a notification is quite simple.
|
51
|
-
- First, create a
|
52
|
-
|
53
|
-
|
58
|
+
- First, create a notifier to manage each recipient's connection. This notifier
|
59
|
+
manages platform specific sessions and will take care of the message structure
|
60
|
+
for each platform and of connecting through the correct driver.
|
54
61
|
- Second, set the message to be sent
|
55
62
|
- Third, notify.
|
56
|
-
|
63
|
+
You're done.
|
57
64
|
|
58
|
-
Given you have a
|
65
|
+
Given you have a Device model in your application. Then to send notifications to a device do:
|
59
66
|
```ruby
|
60
|
-
#
|
61
|
-
|
67
|
+
# SEND ONE NOTIFICATION TO A SINGLE DEVICE
|
68
|
+
# get the device to be notified
|
69
|
+
device= Device.new(platform: Pntfr::Platforms::IOS, push_id: '...')
|
62
70
|
# send notification to the given device
|
63
|
-
Pntfr::Notifier.to(
|
71
|
+
Pntfr::Notifier.to(device).msg({:title => 'Some Title', :description => 'A description'}).notify
|
64
72
|
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
73
|
+
# SEND ONE NOTIFICATION TO MANY DEVICES
|
74
|
+
# using ActiveRecord for example
|
75
|
+
notifier= Pntfr::Notifier.new
|
76
|
+
notifier.notify({
|
69
77
|
:title => 'Some Other Title',
|
70
78
|
:description => 'Another description',
|
71
79
|
:sound => 'flipping-sound.aiff'})
|
72
|
-
|
80
|
+
Device.find_in_batches do |devices|
|
81
|
+
notifier.update_devices(devices)
|
82
|
+
notifier.notify
|
83
|
+
end
|
84
|
+
|
85
|
+
# SEND MANY NOTIFICATIONS TO A GIVEN DEVICE
|
86
|
+
notifier= Pntfr::Notifier.to(device)
|
87
|
+
notifier.msg({:title => 'Title1', :description => 'Description 1'}).notify
|
88
|
+
notifier.msg({:title => 'Title2', :description => 'Description 2'}).notify
|
89
|
+
notifier.msg({:title => 'Title3', :description => 'Description 3'}).notify
|
90
|
+
...
|
73
91
|
|
74
|
-
#
|
75
|
-
|
76
|
-
|
92
|
+
# NOTIFICATIONS WITH CUSTOM CONTENT
|
93
|
+
# send notifications with custom content (extra and optional parameter to #msg)
|
94
|
+
notifier= Pntfr::Notifier.to(device)
|
95
|
+
notifier.msg(
|
77
96
|
{:title => 'Short Title'},
|
78
97
|
{
|
79
98
|
:extra1 => 'extra one',
|
@@ -81,17 +100,36 @@ vsession.msg(
|
|
81
100
|
:'last-extra' => {lastkey: 'last value'}
|
82
101
|
}
|
83
102
|
)
|
84
|
-
|
103
|
+
notifier.notify
|
85
104
|
|
86
|
-
|
105
|
+
|
106
|
+
# Supose you have this configuration for
|
107
|
+
# SETTING ANPS AND GCN CREDENTIALS ON EACH NOTIFICATION
|
108
|
+
# using different configuration on each call
|
109
|
+
credentials= {ios: {
|
110
|
+
host: 'test-host',
|
111
|
+
pem: 'test-pem',
|
112
|
+
port: 'test-port',
|
113
|
+
pass: 'test-password',
|
114
|
+
},
|
115
|
+
andr: 'notification key'
|
116
|
+
}
|
117
|
+
notifier= Pntfr::Notifier.new( credentials )
|
118
|
+
# this Notifier instance overrides the global credentials configuration (if any)
|
119
|
+
notifier.update_devices(device).msg({:title => 'Title', :description => 'Description'}).notify
|
120
|
+
# of course the device's push_id and credentials should belong to the same application.
|
87
121
|
```
|
88
122
|
# Testing
|
89
|
-
For testing one can check the messages
|
123
|
+
For testing, one can check the messages sent to each device the same way
|
90
124
|
that Rails ActiveMailer works: messages are stacked into `Pntfr.deliveries[push_id]`,
|
91
125
|
where for each key (push_id is the identifier of the device) one will get an ordered array
|
92
126
|
with all messages sent to the device while testing. Of course, while testing,
|
93
127
|
notifications are not sent, only stored in the stack.
|
94
128
|
|
129
|
+
# Further development (roadmap)
|
130
|
+
- Update cannonical push id when required for gcm.
|
131
|
+
- Retrieve feedback on sent messages for apns.
|
132
|
+
|
95
133
|
# Resources
|
96
134
|
- Depends on APNS gem: https://rubygems.org/gems/apns
|
97
135
|
- Depends on GCM gem: https://rubygems.org/gems/gcm
|
@@ -99,6 +137,6 @@ notifications are not sent, only stored in the stack.
|
|
99
137
|
|
100
138
|
# Authors
|
101
139
|
|
102
|
-
- Oliver
|
140
|
+
- Oliver Valls <https://github.com/tramuntanal>
|
103
141
|
|
104
142
|
Contributions are always welcome and greatly appreciated!
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Encapsulates the content of a notification in a neutral maneer.
|
2
|
+
# For each platform it can return the notification in the corresponding format
|
3
|
+
# using #to_platform like methods (i.e. #to_ios)
|
4
|
+
#
|
5
|
+
|
6
|
+
module Pntfr
|
7
|
+
class Notification
|
8
|
+
FILE_EXTENSION_REGEXP= /(\.[^\.]+)\z/
|
9
|
+
|
10
|
+
def initialize content, custom=nil
|
11
|
+
@content= content
|
12
|
+
@custom= custom
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_ios
|
16
|
+
alert= @content[:title]
|
17
|
+
alert+= "\n#{@content[:description]}" if @content.key?(:description)
|
18
|
+
sound= @content[:sound]
|
19
|
+
badge= @content[:badge]
|
20
|
+
badge= @content[:badge].to_i if badge
|
21
|
+
n= {:alert => alert, :sound => 'default'}
|
22
|
+
n[:sound]= sound if sound
|
23
|
+
n[:badge]= badge if badge
|
24
|
+
n.merge!({other: {custom: @custom}}) if @custom
|
25
|
+
n
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_android
|
29
|
+
data= {
|
30
|
+
:title => @content[:title],
|
31
|
+
:description => @content[:description],
|
32
|
+
}
|
33
|
+
data[:sound]= remove_extension(@content[:sound]) unless @content[:sound].nil?
|
34
|
+
data[:custom]= @custom if @custom
|
35
|
+
data
|
36
|
+
end
|
37
|
+
def remove_extension filename
|
38
|
+
filename.gsub(FILE_EXTENSION_REGEXP, '')
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
data/lib/pntfr/notifier.rb
CHANGED
@@ -1,15 +1,94 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/
|
1
|
+
require File.dirname(__FILE__) + '/session/base'
|
2
|
+
require File.dirname(__FILE__) + '/notification'
|
2
3
|
|
3
4
|
module Pntfr
|
4
5
|
|
5
6
|
class Notifier
|
6
|
-
def self.to
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def self.to devices, credentials=nil
|
8
|
+
notif= Notifier.new(credentials)
|
9
|
+
notif.update_devices(devices)
|
10
|
+
notif
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :andr_responses
|
14
|
+
attr_reader :ios_responses
|
15
|
+
|
16
|
+
#
|
17
|
+
# +credentials+ is a hash with 2 keys :andr and :ios, each one with its
|
18
|
+
# given credentials:
|
19
|
+
# - :andr => a string with the notification_key
|
20
|
+
# - :ios => a hash of the form {
|
21
|
+
# host: 'test-host',
|
22
|
+
# pem: 'test-pem',
|
23
|
+
# port: 'test-port',
|
24
|
+
# pass: 'test-password',
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
def initialize credentials=nil
|
28
|
+
validate_credentials(credentials)
|
29
|
+
@credentials= credentials || {}
|
30
|
+
|
31
|
+
@andr_responses=[]
|
32
|
+
@ios_responses= []
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_devices(devices)
|
36
|
+
devices= [devices] unless devices.kind_of?(Array)
|
37
|
+
|
38
|
+
# the list of ANDROID push_id to send the notification to
|
39
|
+
@andr_ids= []
|
40
|
+
@ios_devices= []
|
41
|
+
devices.each do |device|
|
42
|
+
if Platforms.android? device.platform
|
43
|
+
@andr_ids << device.push_id
|
44
|
+
elsif Platforms.ios? device.platform
|
45
|
+
@ios_devices << device
|
46
|
+
end
|
47
|
+
end
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
def msg content, custom=nil
|
52
|
+
@msg= Notification.new(content, custom)
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def notify
|
57
|
+
if any_android_device?
|
58
|
+
@andr_responses << andr_session.notify(@andr_ids, @msg.to_android)
|
59
|
+
end
|
60
|
+
if any_ios_device?
|
61
|
+
@ios_responses << ios_session.notify(@ios_devices, @msg.to_ios)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def any_android_device?
|
66
|
+
@andr_ids.any?
|
67
|
+
end
|
68
|
+
|
69
|
+
def any_ios_device?
|
70
|
+
@ios_devices.any?
|
71
|
+
end
|
72
|
+
|
73
|
+
#--------------------------------------------
|
74
|
+
private
|
75
|
+
#--------------------------------------------
|
76
|
+
def andr_session
|
77
|
+
@andr_session||= Pntfr::Session::Android.new(@credentials[:andr])
|
78
|
+
end
|
79
|
+
def ios_session
|
80
|
+
@ios_session||= Pntfr::Session::Ios.new(@credentials[:ios])
|
81
|
+
end
|
82
|
+
def validate_credentials(credentials)
|
83
|
+
return if credentials.nil?
|
84
|
+
if !credentials.is_a?(Hash)
|
85
|
+
raise ArgumentError.new('Credentials should be a Hash with either :andr or :ios keys!')
|
86
|
+
end
|
87
|
+
if !(credentials.has_key?(:andr) or credentials.has_key?(:ios))
|
88
|
+
raise ArgumentError.new('Either :andr or :ios service credentials should have been provided!')
|
11
89
|
end
|
12
90
|
end
|
91
|
+
|
13
92
|
end
|
14
93
|
|
15
94
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Session implementation for Android
|
3
|
+
#
|
4
|
+
require 'gcm'
|
5
|
+
module Pntfr
|
6
|
+
module Session
|
7
|
+
class Android < Pntfr::Session::Base
|
8
|
+
|
9
|
+
attr_reader :gcm
|
10
|
+
|
11
|
+
def initialize notification_key=nil
|
12
|
+
if notification_key.nil?
|
13
|
+
notification_key= Pntfr.config.gcm[:notification_key]
|
14
|
+
end
|
15
|
+
@gcm= ::GCM.new(notification_key)
|
16
|
+
end
|
17
|
+
|
18
|
+
def notify(push_ids, data)
|
19
|
+
options = {data: data}
|
20
|
+
if Pntfr.test_env?
|
21
|
+
push_ids.each { |push_id| Pntfr.add_delivery(push_id, options) }
|
22
|
+
Session::SuccessResponse.new
|
23
|
+
else
|
24
|
+
rs= @gcm.send_notification(push_ids, options)
|
25
|
+
parse_response rs
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#---------------------------------------------------------
|
30
|
+
private
|
31
|
+
#---------------------------------------------------------
|
32
|
+
def parse_response rs
|
33
|
+
Session::GcmResponse.new(rs)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Pntfr
|
2
|
+
module Session
|
3
|
+
class Base
|
4
|
+
def initialize devices
|
5
|
+
@devices= devices
|
6
|
+
end
|
7
|
+
def msg content
|
8
|
+
raise 'not implemented!'
|
9
|
+
end
|
10
|
+
def notify(push_ids, data)
|
11
|
+
raise 'not implemented!'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
require 'pntfr/session/success_response'
|
17
|
+
require 'pntfr/session/android'
|
18
|
+
require 'pntfr/session/gcm_response'
|
19
|
+
require 'pntfr/session/ios'
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#
|
2
2
|
# Google Cloud Messaging json response wrapper.
|
3
3
|
#
|
4
|
-
require 'pntfr/
|
4
|
+
require 'pntfr/session/base_response'
|
5
5
|
require 'json'
|
6
6
|
|
7
7
|
module Pntfr
|
8
|
-
module
|
8
|
+
module Session
|
9
9
|
class GcmResponse < BaseResponse
|
10
10
|
def initialize json
|
11
11
|
@raw= json
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# Session implementation for iOS
|
3
|
+
#
|
4
|
+
require 'apns'
|
5
|
+
module Pntfr
|
6
|
+
module Session
|
7
|
+
class Ios < Pntfr::Session::Base
|
8
|
+
|
9
|
+
attr_reader :apns
|
10
|
+
|
11
|
+
def initialize apns_config=nil
|
12
|
+
if apns_config.nil?
|
13
|
+
configure_apns(Pntfr.config.apns)
|
14
|
+
else
|
15
|
+
configure_apns(apns_config)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def notify devices, notification
|
20
|
+
apns_notifications= []
|
21
|
+
devices.each do |device|
|
22
|
+
if device_controls_badge(device)
|
23
|
+
if !notification[:badge].nil?
|
24
|
+
device.num_notifs= notification[:badge]
|
25
|
+
else
|
26
|
+
device.num_notifs+= 1
|
27
|
+
notification[:badge]= device.num_notifs
|
28
|
+
end
|
29
|
+
end
|
30
|
+
if Pntfr.test_env?
|
31
|
+
Pntfr.add_delivery(device.push_id, notification)
|
32
|
+
else
|
33
|
+
apns_notif= APNS::Notification.new(device.push_id, notification)
|
34
|
+
apns_notifications << apns_notif
|
35
|
+
end
|
36
|
+
end
|
37
|
+
::APNS.send_notifications(apns_notifications) if apns_notifications.any?
|
38
|
+
SuccessResponse.new
|
39
|
+
end
|
40
|
+
|
41
|
+
#-------------------------------------------------
|
42
|
+
private
|
43
|
+
#-------------------------------------------------
|
44
|
+
|
45
|
+
def device_controls_badge(device)
|
46
|
+
device.methods.include?(:num_notifs)
|
47
|
+
end
|
48
|
+
|
49
|
+
def configure_apns config
|
50
|
+
APNS.host = config[:host]
|
51
|
+
APNS.pem = config[:pem]
|
52
|
+
APNS.port = config[:port]
|
53
|
+
APNS.pass = config[:pass]
|
54
|
+
@apns= APNS
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
# Always success.
|
3
3
|
# To be used on cases where no response to be parsed is received.
|
4
4
|
#
|
5
|
-
require 'pntfr/
|
5
|
+
require 'pntfr/session/base_response'
|
6
6
|
|
7
7
|
module Pntfr
|
8
|
-
module
|
8
|
+
module Session
|
9
9
|
class SuccessResponse < BaseResponse
|
10
10
|
# communication with notification service was OK?
|
11
11
|
# implies no +failure?+
|
data/lib/pntfr/version.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Pntfr
|
2
|
-
# For IOS do not prefix custom fields with 'acme-' in the notification,
|
3
|
-
# instead group them all into a :custom key, like in Android.
|
4
2
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
3
|
+
# - Performance improvement: Allow sending one message to many devices in one
|
4
|
+
# single call (on both platforms).
|
5
|
+
# - Allow overriding general configuration credentials when instantiating each
|
6
|
+
# Notifier (on both platforms).
|
7
|
+
# - Internal refactoring.
|
8
|
+
#
|
9
|
+
# As this change don't break the gem's API (it extends it), lets change only
|
10
|
+
# minor version.
|
11
|
+
VERSION = '0.3.0'
|
9
12
|
end
|
data/pntfr.gemspec
CHANGED
@@ -8,9 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Pntfr::VERSION
|
9
9
|
spec.authors = ['oliver']
|
10
10
|
spec.email = ['oliver.hv@coditramuntana.com']
|
11
|
-
spec.summary = %q{Push
|
11
|
+
spec.summary = %q{Push Notifier is a simple adapter for APNS (Apple Push Notification Service) and GCM (Google Cloud Messaging) gems, that way you can use one message format and one library to send push notifications to both devices.}
|
12
12
|
spec.description = %q{One single API to send push notifications to Android and iOS devices.}
|
13
|
-
# spec.homepage = "http://www.coditramuntana.com"
|
14
13
|
spec.homepage = 'https://github.com/tramuntanal/pntfr'
|
15
14
|
spec.license = "MIT"
|
16
15
|
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'pntfr/device'
|
2
|
+
require 'fxtr'
|
3
|
+
|
4
|
+
module Pntfr
|
5
|
+
class AndroidTest < Minitest::Test
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@push_id= 'ANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROID'
|
9
|
+
end
|
10
|
+
def test_received_content_shoud_be_sent_to_gcm
|
11
|
+
device= Device.new(Pntfr::Platforms::ANDROID, @push_id)
|
12
|
+
|
13
|
+
notifier= Pntfr::Notifier.to(device).msg(Fxtr::Android.simple_msg)
|
14
|
+
notifier.notify
|
15
|
+
check_andr_msg_sent(notifier)
|
16
|
+
|
17
|
+
notifs= Pntfr.deliveries[@push_id]
|
18
|
+
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
19
|
+
notif= notifs.last
|
20
|
+
assert_equal 'Some Title', notif[:data][:title]
|
21
|
+
assert_equal 'A description', notif[:data][:description]
|
22
|
+
assert_equal 'bell', notif[:data][:sound]
|
23
|
+
end
|
24
|
+
def test_sound_attribute_shoud_be_sent_to_gcm
|
25
|
+
device= Device.new(Pntfr::Platforms::ANDROID, @push_id)
|
26
|
+
|
27
|
+
notifier= Pntfr::Notifier.to(device).msg(Fxtr::Android.simple_msg)
|
28
|
+
notifier.notify
|
29
|
+
check_andr_msg_sent(notifier)
|
30
|
+
|
31
|
+
notifs= Pntfr.deliveries[@push_id]
|
32
|
+
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
33
|
+
notif= notifs.last
|
34
|
+
assert_equal 'Some Title', notif[:data][:title]
|
35
|
+
assert_equal 'A description', notif[:data][:description]
|
36
|
+
assert_equal 'bell', notif[:data][:sound]
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_sending_custom_content_for_android_should_be_added_as_more_keys
|
40
|
+
device= Device.new(Pntfr::Platforms::ANDROID, @push_id)
|
41
|
+
|
42
|
+
notifier= Pntfr::Notifier.to(device)
|
43
|
+
notifier.msg(Fxtr::Common.simple_msg, Fxtr::Common.custom_msg_content)
|
44
|
+
notifier.notify
|
45
|
+
check_andr_msg_sent(notifier)
|
46
|
+
|
47
|
+
notifs= Pntfr.deliveries[@push_id]
|
48
|
+
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
49
|
+
notif= notifs.last
|
50
|
+
data= notif[:data]
|
51
|
+
assert_equal 'Test Title', data[:title]
|
52
|
+
assert_equal 'extra one', data[:custom][:extra1]
|
53
|
+
assert_equal 'extra 2', data[:custom][:extra_2]
|
54
|
+
assert_equal({lastkey: 'last value'}, data[:custom][:'last-extra'])
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_when_overriding_android_credentials_should_use_new_ones
|
59
|
+
notification_key= 'OVERRIDEN-TEST-KEY'
|
60
|
+
andr_session= Pntfr::Session::Android.new(notification_key)
|
61
|
+
assert_equal 'OVERRIDEN-TEST-KEY', andr_session.gcm.api_key
|
62
|
+
end
|
63
|
+
|
64
|
+
#-------------------------------------------------------
|
65
|
+
private
|
66
|
+
#-------------------------------------------------------
|
67
|
+
def check_andr_msg_sent(notifier)
|
68
|
+
assert notifier.ios_responses.empty?
|
69
|
+
andr_rs= notifier.andr_responses
|
70
|
+
assert_equal 1, andr_rs.size
|
71
|
+
rs= andr_rs.first
|
72
|
+
assert rs.success? and rs.msg_sent?
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Pntfr's expected models to be used for testing purposes
|
2
|
+
|
3
|
+
# minimal expected device
|
4
|
+
Pntfr::Device= Struct.new(:platform, :push_id)
|
5
|
+
# device with num_notifs which will be autoincremented on each sent msg
|
6
|
+
Pntfr::IosDevice= Struct.new(:platform, :push_id, :num_notifs)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'pntfr/device'
|
2
|
+
|
3
|
+
module Pntfr
|
4
|
+
class IosBadgeTest < Minitest::Test
|
5
|
+
def test_sending_a_notification_increments_notifier_notifications_num
|
6
|
+
device= Pntfr::IosDevice.new(Pntfr::Platforms::IOS, '1id2id3id4id5id', 0)
|
7
|
+
|
8
|
+
Pntfr::Notifier.to(device).msg({:title => 't', :description => 'd'}).notify
|
9
|
+
|
10
|
+
notifs= Pntfr.deliveries['1id2id3id4id5id']
|
11
|
+
notif= notifs.last
|
12
|
+
assert_equal 1, notif[:badge]
|
13
|
+
assert_equal 1, device.num_notifs
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'pntfr/device'
|
2
|
+
module Pntfr
|
3
|
+
class IosTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@push_id= 'IOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSios'
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_received_content_shoud_be_ready_to_be_sent_to_apns
|
9
|
+
device= Device.new(Pntfr::Platforms::IOS, @push_id)
|
10
|
+
|
11
|
+
notifier= Pntfr::Notifier.to(device)
|
12
|
+
notifier.msg({:title => 'thatitle', :description => 'thadescription', :sound => 'click.aiff', :badge => 33})
|
13
|
+
notifier.notify
|
14
|
+
check_ios_msg_sent(notifier)
|
15
|
+
|
16
|
+
ios_notifs= Pntfr.deliveries[@push_id]
|
17
|
+
refute_nil ios_notifs, "A notification should have been delivered for #{@push_id}"
|
18
|
+
ios_notif= ios_notifs.last
|
19
|
+
assert_equal "thatitle\nthadescription", ios_notif[:alert]
|
20
|
+
assert_equal 'click.aiff', ios_notif[:sound]
|
21
|
+
assert_equal 33, ios_notif[:badge]
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_ios_information_from_previous_msg_should_be_reset_when_sending_a_new_msg
|
25
|
+
device= IosDevice.new(Pntfr::Platforms::IOS, name, 3)
|
26
|
+
notifier= Pntfr::Notifier.to(device)
|
27
|
+
|
28
|
+
notifier.msg(title: 't1', description: 'd1', sound: 's1').notify
|
29
|
+
check_ios_msg_sent(notifier)
|
30
|
+
notifier.msg(title: 't2', description: 'd2').notify
|
31
|
+
check_ios_msg_sent(notifier, 2)
|
32
|
+
|
33
|
+
notifs= Pntfr.deliveries[device.push_id]
|
34
|
+
assert_equal 5, device.num_notifs
|
35
|
+
assert_equal 2, notifs.size
|
36
|
+
notif= notifs.first
|
37
|
+
assert_equal "t1\nd1", notif[:alert]
|
38
|
+
assert_equal 's1', notif[:sound]
|
39
|
+
assert_equal 4, notif[:badge]
|
40
|
+
notif= notifs.last
|
41
|
+
assert_equal "t2\nd2", notif[:alert]
|
42
|
+
assert_equal 'default', notif[:sound]
|
43
|
+
assert_equal 5, notif[:badge]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_sending_custom_content_for_ios_should_be_added_as_custom_keys
|
47
|
+
device= Device.new(Pntfr::Platforms::IOS, @push_id)
|
48
|
+
|
49
|
+
notifier= Pntfr::Notifier.to(device)
|
50
|
+
notifier.msg(Fxtr::Common.simple_msg, Fxtr::Common.custom_msg_content)
|
51
|
+
notifier.notify
|
52
|
+
check_ios_msg_sent(notifier)
|
53
|
+
|
54
|
+
ios_notifs= Pntfr.deliveries[@push_id]
|
55
|
+
refute_nil ios_notifs, "A notification should have been delivered for #{@push_id}"
|
56
|
+
ios_notif= ios_notifs.last
|
57
|
+
assert_equal 'Test Title', ios_notif[:alert]
|
58
|
+
custom= ios_notif[:other][:custom]
|
59
|
+
assert_equal 'extra one', custom[:'extra1']
|
60
|
+
assert_equal 'extra 2', custom[:'extra_2']
|
61
|
+
assert_equal({lastkey: 'last value'}, custom[:'last-extra'])
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_when_overriding_ios_credentials_should_use_new_ones
|
65
|
+
apns_config= {
|
66
|
+
host: 'test-host',
|
67
|
+
pem: 'test-pem',
|
68
|
+
port: 'test-port',
|
69
|
+
pass: 'test-password',
|
70
|
+
}
|
71
|
+
ios_session= Pntfr::Session::Ios.new(apns_config)
|
72
|
+
apns= ios_session.apns
|
73
|
+
assert_equal 'test-host', apns.host
|
74
|
+
assert_equal 'test-pem', apns.pem
|
75
|
+
assert_equal 'test-port', apns.port
|
76
|
+
assert_equal 'test-password', apns.pass
|
77
|
+
end
|
78
|
+
|
79
|
+
#-----------------------------------------------------------
|
80
|
+
private
|
81
|
+
#-----------------------------------------------------------
|
82
|
+
def check_ios_msg_sent(notifier, num_responses=1)
|
83
|
+
assert notifier.andr_responses.empty?
|
84
|
+
ios_rs= notifier.ios_responses
|
85
|
+
assert_equal num_responses, ios_rs.size
|
86
|
+
rs= ios_rs.first
|
87
|
+
assert rs.success? and rs.msg_sent?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'pntfr/device'
|
2
|
+
module Pntfr
|
3
|
+
class NotifierTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@andr_dev= Device.new(Pntfr::Platforms::ANDROID, 'ANDR_ID')
|
7
|
+
@ios_dev= Device.new(Pntfr::Platforms::IOS, 'IOS_ID')
|
8
|
+
end
|
9
|
+
def test_android_device_should_instantiate_notifier
|
10
|
+
notifier= Pntfr::Notifier.to(@andr_dev)
|
11
|
+
refute_nil notifier
|
12
|
+
assert notifier.any_android_device?
|
13
|
+
end
|
14
|
+
def test_ios_device_should_instantiate_notifier
|
15
|
+
notifier= Pntfr::Notifier.to(@ios_dev)
|
16
|
+
refute_nil notifier
|
17
|
+
assert notifier.any_ios_device?
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_creating_notifier_with_many_devices_should_create_a_notifier
|
21
|
+
devices= [@andr_dev, @ios_dev]
|
22
|
+
notifier= Pntfr::Notifier.to(devices)
|
23
|
+
refute_nil notifier
|
24
|
+
assert notifier.any_android_device?
|
25
|
+
assert notifier.any_ios_device?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_when_updating_only_andr_devices_older_devices_from_ios_platforms_should_be_reseted
|
29
|
+
notifier= Pntfr::Notifier.to([@andr_dev, @ios_dev])
|
30
|
+
assert notifier.any_android_device?
|
31
|
+
assert notifier.any_ios_device?
|
32
|
+
|
33
|
+
notifier.update_devices(@andr_dev)
|
34
|
+
assert notifier.any_android_device?
|
35
|
+
refute notifier.any_ios_device?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_when_updating_only_ios_devices_older_devices_from_andr_platforms_should_be_reseted
|
39
|
+
notifier= Pntfr::Notifier.to([@andr_dev, @ios_dev])
|
40
|
+
assert notifier.any_android_device?
|
41
|
+
assert notifier.any_ios_device?
|
42
|
+
|
43
|
+
notifier.update_devices(@ios_dev)
|
44
|
+
refute notifier.any_android_device?
|
45
|
+
assert notifier.any_ios_device?
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_setting_string_credentials_should_raise_argument_error
|
49
|
+
begin
|
50
|
+
Pntfr::Notifier.to(@andr_dev, 'ios=andr')
|
51
|
+
raise 'Should have raised an ArgumentError'
|
52
|
+
rescue ArgumentError
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_setting_empty_hash_credentials_should_raise_argument_error
|
57
|
+
begin
|
58
|
+
Pntfr::Notifier.to(@andr_dev, {})
|
59
|
+
raise 'Should have raised an ArgumentError'
|
60
|
+
rescue ArgumentError
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_setting_wrong_credentials_should_raise_argument_error
|
65
|
+
begin
|
66
|
+
Pntfr::Notifier.to(@ios_dev, {key1: 'asdf', wrongK: {}, android: [], iphone: ''})
|
67
|
+
raise 'Should have raised an ArgumentError'
|
68
|
+
rescue ArgumentError
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -4,7 +4,7 @@ module Pntfr
|
|
4
4
|
# Success response
|
5
5
|
#
|
6
6
|
def test_success_response_should_have_sent_msg_and_no_error
|
7
|
-
rs=
|
7
|
+
rs= Session::SuccessResponse.new
|
8
8
|
assert rs.success? and rs.msg_sent?
|
9
9
|
refute rs.error?
|
10
10
|
refute rs.failure?
|
@@ -19,20 +19,20 @@ module Pntfr
|
|
19
19
|
GCM_400_RESPONSE= {:body=>"\"registration_ids\" field is not a JSON array\n", :headers=>{"content-type"=>["text/plain; charset=UTF-8"], "date"=>["Tue, 09 Dec 2014 21:27:30 GMT"], "expires"=>["Tue, 09 Dec 2014 21:27:30 GMT"], "cache-control"=>["private, max-age=0"], "x-content-type-options"=>["nosniff"], "x-frame-options"=>["SAMEORIGIN"], "x-xss-protection"=>["1; mode=block"], "server"=>["GSE"], "alternate-protocol"=>["443:quic,p=0.02"], "connection"=>["close"]}, :status_code=>400, :response=>"Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields."}
|
20
20
|
|
21
21
|
def test_gcm_200_responses_with_success_should_have_success_and_no_error
|
22
|
-
rs=
|
22
|
+
rs= Session::GcmResponse.new(GCM_200_WITH_SUCCESS)
|
23
23
|
assert rs.success?
|
24
24
|
refute rs.error?
|
25
25
|
assert_nil rs.error
|
26
26
|
end
|
27
27
|
def test_gcm_200_responses_with_invalid_registration_should_have_failed_and_report_error
|
28
|
-
rs=
|
28
|
+
rs= Session::GcmResponse.new(GCM_200_WITH_INVALID_REGISTRATION)
|
29
29
|
refute rs.failure?
|
30
30
|
refute rs.msg_sent?
|
31
31
|
assert rs.success? and rs.error?
|
32
32
|
assert_equal 'InvalidRegistration', rs.error
|
33
33
|
end
|
34
34
|
def test_gcm_200_responses_with_mismatch_sender_id_should_have_failed_and_report_error
|
35
|
-
rs=
|
35
|
+
rs= Session::GcmResponse.new(GCM_200_WITH_MISMATCH_SENDER_ID)
|
36
36
|
assert rs.success?
|
37
37
|
refute rs.msg_sent?
|
38
38
|
assert rs.error?
|
@@ -40,7 +40,7 @@ module Pntfr
|
|
40
40
|
assert_equal 'MismatchSenderId', rs.error
|
41
41
|
end
|
42
42
|
def test_gcm_400_responses_should_have_failed_and_report_error
|
43
|
-
rs=
|
43
|
+
rs= Session::GcmResponse.new(GCM_400_RESPONSE)
|
44
44
|
refute rs.success? and rs.error?
|
45
45
|
assert rs.failure?
|
46
46
|
expected= "\"registration_ids\" field is not a JSON array\n->Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields."
|
@@ -51,7 +51,7 @@ module Pntfr
|
|
51
51
|
GCM_200_WITH_INVALID_REGISTRATION,
|
52
52
|
GCM_200_WITH_MISMATCH_SENDER_ID,
|
53
53
|
GCM_400_RESPONSE].each do |json|
|
54
|
-
assert_equal json.to_s,
|
54
|
+
assert_equal json.to_s, Session::GcmResponse.new(json).to_s
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pntfr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- oliver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apns
|
@@ -107,31 +107,33 @@ extra_rdoc_files: []
|
|
107
107
|
files:
|
108
108
|
- ".gitignore"
|
109
109
|
- Gemfile
|
110
|
+
- Gemfile.lock
|
110
111
|
- LICENSE
|
111
112
|
- LICENSE.txt
|
112
113
|
- README.md
|
113
114
|
- Rakefile
|
114
115
|
- lib/pntfr.rb
|
116
|
+
- lib/pntfr/notification.rb
|
115
117
|
- lib/pntfr/notifier.rb
|
116
118
|
- lib/pntfr/platforms.rb
|
119
|
+
- lib/pntfr/session/android.rb
|
120
|
+
- lib/pntfr/session/base.rb
|
121
|
+
- lib/pntfr/session/base_response.rb
|
122
|
+
- lib/pntfr/session/gcm_response.rb
|
123
|
+
- lib/pntfr/session/ios.rb
|
124
|
+
- lib/pntfr/session/success_response.rb
|
117
125
|
- lib/pntfr/test_ext.rb
|
118
126
|
- lib/pntfr/version.rb
|
119
|
-
- lib/pntfr/virtual_session/android.rb
|
120
|
-
- lib/pntfr/virtual_session/base.rb
|
121
|
-
- lib/pntfr/virtual_session/base_response.rb
|
122
|
-
- lib/pntfr/virtual_session/gcm_response.rb
|
123
|
-
- lib/pntfr/virtual_session/ios.rb
|
124
|
-
- lib/pntfr/virtual_session/success_response.rb
|
125
127
|
- pntfr.gemspec
|
126
128
|
- test/fxtr.rb
|
127
|
-
- test/pntfr/
|
129
|
+
- test/pntfr/android_test.rb
|
130
|
+
- test/pntfr/device.rb
|
131
|
+
- test/pntfr/ios_badge_test.rb
|
132
|
+
- test/pntfr/ios_test.rb
|
133
|
+
- test/pntfr/notifier_test.rb
|
128
134
|
- test/pntfr/platforms_test.rb
|
129
|
-
- test/pntfr/
|
130
|
-
- test/
|
131
|
-
- test/pntfr/virtual_session/ios_badge_test.rb
|
132
|
-
- test/pntfr/virtual_session/ios_test.rb
|
133
|
-
- test/pntfr/virtual_session/response_test.rb
|
134
|
-
- test/pntfr_configuration_test.rb
|
135
|
+
- test/pntfr/session/response_test.rb
|
136
|
+
- test/pntfr_global_configuration_test.rb
|
135
137
|
- test/test_helper.rb
|
136
138
|
homepage: https://github.com/tramuntanal/pntfr
|
137
139
|
licenses:
|
@@ -153,19 +155,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
155
|
version: '0'
|
154
156
|
requirements: []
|
155
157
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.
|
158
|
+
rubygems_version: 2.4.5
|
157
159
|
signing_key:
|
158
160
|
specification_version: 4
|
159
|
-
summary: Push
|
160
|
-
|
161
|
+
summary: Push Notifier is a simple adapter for APNS (Apple Push Notification Service)
|
162
|
+
and GCM (Google Cloud Messaging) gems, that way you can use one message format and
|
163
|
+
one library to send push notifications to both devices.
|
161
164
|
test_files:
|
162
165
|
- test/fxtr.rb
|
163
|
-
- test/pntfr/
|
166
|
+
- test/pntfr/android_test.rb
|
167
|
+
- test/pntfr/device.rb
|
168
|
+
- test/pntfr/ios_badge_test.rb
|
169
|
+
- test/pntfr/ios_test.rb
|
170
|
+
- test/pntfr/notifier_test.rb
|
164
171
|
- test/pntfr/platforms_test.rb
|
165
|
-
- test/pntfr/
|
166
|
-
- test/
|
167
|
-
- test/pntfr/virtual_session/ios_badge_test.rb
|
168
|
-
- test/pntfr/virtual_session/ios_test.rb
|
169
|
-
- test/pntfr/virtual_session/response_test.rb
|
170
|
-
- test/pntfr_configuration_test.rb
|
172
|
+
- test/pntfr/session/response_test.rb
|
173
|
+
- test/pntfr_global_configuration_test.rb
|
171
174
|
- test/test_helper.rb
|
@@ -1,48 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# VirtualSession implementation for Android
|
3
|
-
#
|
4
|
-
require 'gcm'
|
5
|
-
module Pntfr
|
6
|
-
module VirtualSession
|
7
|
-
class Android < Pntfr::VirtualSession::Base
|
8
|
-
FILE_EXTENSION_REGEXP= /(\.[^\.]+)\z/
|
9
|
-
|
10
|
-
def initialize session
|
11
|
-
super
|
12
|
-
@notification_key= Pntfr.config.gcm[:notification_key]
|
13
|
-
@gcm= ::GCM.new(@notification_key) unless Pntfr.test_env?
|
14
|
-
end
|
15
|
-
|
16
|
-
def msg content, custom=nil
|
17
|
-
@data= {
|
18
|
-
:title => content[:title],
|
19
|
-
:description => content[:description],
|
20
|
-
}
|
21
|
-
@data[:sound]= parse_sound_file(content[:sound]) unless content[:sound].nil?
|
22
|
-
@data[:custom]= custom if custom
|
23
|
-
self
|
24
|
-
end
|
25
|
-
def notify
|
26
|
-
options = {data: @data}
|
27
|
-
if Pntfr.test_env?
|
28
|
-
Pntfr.add_delivery(@push_id, options)
|
29
|
-
VirtualSession::SuccessResponse.new
|
30
|
-
else
|
31
|
-
rs= @gcm.send_notification([@push_id], options)
|
32
|
-
parse_response rs
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
#---------------------------------------------------------
|
37
|
-
private
|
38
|
-
#---------------------------------------------------------
|
39
|
-
def parse_response rs
|
40
|
-
VirtualSession::GcmResponse.new(rs)
|
41
|
-
end
|
42
|
-
|
43
|
-
def parse_sound_file filename
|
44
|
-
filename.gsub(FILE_EXTENSION_REGEXP, '')
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Pntfr
|
2
|
-
module VirtualSession
|
3
|
-
class Base
|
4
|
-
def initialize session
|
5
|
-
@session= session
|
6
|
-
@push_id= @session.push_id
|
7
|
-
end
|
8
|
-
def msg content
|
9
|
-
raise 'not implemented!'
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
require 'pntfr/virtual_session/success_response'
|
15
|
-
require 'pntfr/virtual_session/android'
|
16
|
-
require 'pntfr/virtual_session/gcm_response'
|
17
|
-
require 'pntfr/virtual_session/ios'
|
@@ -1,58 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# VirtualSession implementation for iOS
|
3
|
-
#
|
4
|
-
require 'apns'
|
5
|
-
module Pntfr
|
6
|
-
module VirtualSession
|
7
|
-
class Ios < Pntfr::VirtualSession::Base
|
8
|
-
def msg content, custom=nil
|
9
|
-
configure_apns
|
10
|
-
reset_msg
|
11
|
-
@alert= content[:title]
|
12
|
-
@alert+= "\n#{content[:description]}" if content.key?(:description)
|
13
|
-
@sound= content[:sound]
|
14
|
-
badge= content[:badge]
|
15
|
-
@badge= content[:badge].to_i if badge
|
16
|
-
add_custom_content(custom) if custom
|
17
|
-
self
|
18
|
-
end
|
19
|
-
|
20
|
-
def notify
|
21
|
-
n= {:alert => @alert, :sound => 'default'}
|
22
|
-
if @badge
|
23
|
-
n[:badge]= @badge
|
24
|
-
elsif @session.methods.include?(:num_notifs)
|
25
|
-
@session.num_notifs+= 1
|
26
|
-
n[:badge]= @session.num_notifs
|
27
|
-
end
|
28
|
-
n[:sound]= @sound if @sound
|
29
|
-
n.merge!(@custom) if @custom
|
30
|
-
|
31
|
-
if Pntfr.test_env?
|
32
|
-
Pntfr.add_delivery(@push_id, n)
|
33
|
-
else
|
34
|
-
::APNS.send_notification(@push_id, n)
|
35
|
-
end
|
36
|
-
SuccessResponse.new
|
37
|
-
end
|
38
|
-
|
39
|
-
#-------------------------------------------------
|
40
|
-
private
|
41
|
-
#-------------------------------------------------
|
42
|
-
|
43
|
-
def configure_apns
|
44
|
-
config= Pntfr.config.apns
|
45
|
-
APNS.host = config[:host]
|
46
|
-
APNS.pem = config[:pem]
|
47
|
-
APNS.port = config[:port]
|
48
|
-
APNS.pass = config[:pass]
|
49
|
-
end
|
50
|
-
def reset_msg
|
51
|
-
@alert= @sound= @badge= nil
|
52
|
-
end
|
53
|
-
def add_custom_content custom
|
54
|
-
@custom= {other: {custom: custom}}
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,6 +0,0 @@
|
|
1
|
-
# Pntfr's expected models to be used for testing purposes
|
2
|
-
|
3
|
-
# minimal expected session
|
4
|
-
Pntfr::DeviceSession= Struct.new(:platform, :push_id)
|
5
|
-
# session with num_notifs which will be autoincremented on each sent msg
|
6
|
-
Pntfr::IosDeviceSession= Struct.new(:platform, :push_id, :num_notifs)
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'pntfr/device_session'
|
2
|
-
module Pntfr
|
3
|
-
class NotifierTest < Minitest::Test
|
4
|
-
|
5
|
-
def test_android_sessions_should_instantiate_android_virtual_sessions
|
6
|
-
session= DeviceSession.new(Pntfr::Platforms::ANDROID)
|
7
|
-
vsess= Pntfr::Notifier.to(session)
|
8
|
-
assert vsess.is_a?(Pntfr::VirtualSession::Android)
|
9
|
-
end
|
10
|
-
def test_ios_sessions_should_instantiate_ios_virtual_sessions
|
11
|
-
session= DeviceSession.new(Pntfr::Platforms::IOS)
|
12
|
-
vsess= Pntfr::Notifier.to(session)
|
13
|
-
assert vsess.is_a?(Pntfr::VirtualSession::Ios)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'pntfr/device_session'
|
2
|
-
require 'fxtr'
|
3
|
-
|
4
|
-
module Pntfr
|
5
|
-
module VirtualSession
|
6
|
-
class AndroidTest < Minitest::Test
|
7
|
-
|
8
|
-
def setup
|
9
|
-
@push_id= 'ANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROIDANDROID'
|
10
|
-
end
|
11
|
-
def test_received_content_shoud_be_sent_to_gcm
|
12
|
-
session= DeviceSession.new(Pntfr::Platforms::ANDROID, @push_id)
|
13
|
-
|
14
|
-
vsession= Pntfr::Notifier.to(session).msg(Fxtr::Android.simple_msg)
|
15
|
-
rs= vsession.notify
|
16
|
-
assert rs.success? and rs.msg_sent?
|
17
|
-
|
18
|
-
notifs= Pntfr.deliveries[@push_id]
|
19
|
-
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
20
|
-
notif= notifs.last
|
21
|
-
assert_equal 'Some Title', notif[:data][:title]
|
22
|
-
assert_equal 'A description', notif[:data][:description]
|
23
|
-
assert_equal 'bell', notif[:data][:sound]
|
24
|
-
end
|
25
|
-
def test_sound_attribute_shoud_be_sent_to_gcm
|
26
|
-
session= DeviceSession.new(Pntfr::Platforms::ANDROID, @push_id)
|
27
|
-
|
28
|
-
vsession= Pntfr::Notifier.to(session).msg(Fxtr::Android.simple_msg)
|
29
|
-
rs= vsession.notify
|
30
|
-
assert rs.success? and rs.msg_sent?
|
31
|
-
|
32
|
-
notifs= Pntfr.deliveries[@push_id]
|
33
|
-
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
34
|
-
notif= notifs.last
|
35
|
-
assert_equal 'Some Title', notif[:data][:title]
|
36
|
-
assert_equal 'A description', notif[:data][:description]
|
37
|
-
assert_equal 'bell', notif[:data][:sound]
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_sending_custom_content_for_android_should_be_added_as_more_keys
|
41
|
-
session= DeviceSession.new(Pntfr::Platforms::ANDROID, @push_id)
|
42
|
-
|
43
|
-
vsession= Pntfr::Notifier.to(session)
|
44
|
-
vsession.msg(Fxtr::Common.simple_msg, Fxtr::Common.custom_msg_content)
|
45
|
-
rs= vsession.notify
|
46
|
-
assert rs.success? and rs.msg_sent?
|
47
|
-
|
48
|
-
notifs= Pntfr.deliveries[@push_id]
|
49
|
-
refute_nil notifs, "A notification should have been delivered for #{@push_id}"
|
50
|
-
notif= notifs.last
|
51
|
-
data= notif[:data]
|
52
|
-
assert_equal 'Test Title', data[:title]
|
53
|
-
assert_equal 'extra one', data[:custom][:extra1]
|
54
|
-
assert_equal 'extra 2', data[:custom][:extra_2]
|
55
|
-
assert_equal({lastkey: 'last value'}, data[:custom][:'last-extra'])
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'pntfr/device_session'
|
2
|
-
|
3
|
-
module Pntfr
|
4
|
-
module VirtualSession
|
5
|
-
class IosBadgeTest < Minitest::Test
|
6
|
-
def test_sending_a_notification_increments_session_notifications_num
|
7
|
-
session= Pntfr::IosDeviceSession.new(Pntfr::Platforms::IOS, '1id2id3id4id5id', 0)
|
8
|
-
|
9
|
-
Pntfr::Notifier.to(session).msg({:title => 't', :description => 'd'}).notify
|
10
|
-
|
11
|
-
notifs= Pntfr.deliveries['1id2id3id4id5id']
|
12
|
-
notif= notifs.last
|
13
|
-
assert_equal 1, notif[:badge]
|
14
|
-
assert_equal 1, session.num_notifs
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'pntfr/device_session'
|
2
|
-
module Pntfr
|
3
|
-
module VirtualSession
|
4
|
-
class IosTest < Minitest::Test
|
5
|
-
def setup
|
6
|
-
@push_id= 'IOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSiosIOSios'
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_received_content_shoud_be_ready_to_be_sent_to_apns
|
10
|
-
session= DeviceSession.new(Pntfr::Platforms::IOS, @push_id)
|
11
|
-
|
12
|
-
rs= Pntfr::Notifier.to(session).msg({:title => 'thatitle', :description => 'thadescription', :sound => 'click.aiff', :badge => 33}).notify
|
13
|
-
assert rs.success? and rs.msg_sent?
|
14
|
-
|
15
|
-
ios_notifs= Pntfr.deliveries[@push_id]
|
16
|
-
refute_nil ios_notifs, "A notification should have been delivered for #{@push_id}"
|
17
|
-
ios_notif= ios_notifs.last
|
18
|
-
assert_equal "thatitle\nthadescription", ios_notif[:alert]
|
19
|
-
assert_equal 'click.aiff', ios_notif[:sound]
|
20
|
-
assert_equal 33, ios_notif[:badge]
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_ios_information_from_previous_msg_should_be_reset_when_sending_a_new_msg
|
24
|
-
session= IosDeviceSession.new(Pntfr::Platforms::IOS, name, 3)
|
25
|
-
vsession= Pntfr::Notifier.to(session)
|
26
|
-
|
27
|
-
rs= vsession.msg(title: 't1', description: 'd1', sound: 's1').notify
|
28
|
-
assert rs.success? and rs.msg_sent?
|
29
|
-
rs= vsession.msg(title: 't2', description: 'd2').notify
|
30
|
-
assert rs.success? and rs.msg_sent?
|
31
|
-
|
32
|
-
notifs= Pntfr.deliveries[session.push_id]
|
33
|
-
assert_equal 5, session.num_notifs
|
34
|
-
assert_equal 2, notifs.size
|
35
|
-
notif= notifs.first
|
36
|
-
assert_equal "t1\nd1", notif[:alert]
|
37
|
-
assert_equal 's1', notif[:sound]
|
38
|
-
assert_equal 4, notif[:badge]
|
39
|
-
notif= notifs.last
|
40
|
-
assert_equal "t2\nd2", notif[:alert]
|
41
|
-
assert_equal 'default', notif[:sound]
|
42
|
-
assert_equal 5, notif[:badge]
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_sending_custom_content_for_ios_should_be_added_as_custom_keys
|
46
|
-
session= DeviceSession.new(Pntfr::Platforms::IOS, @push_id)
|
47
|
-
|
48
|
-
vsession= Pntfr::Notifier.to(session)
|
49
|
-
vsession.msg(Fxtr::Common.simple_msg, Fxtr::Common.custom_msg_content)
|
50
|
-
rs= vsession.notify
|
51
|
-
assert rs.success? and rs.msg_sent?
|
52
|
-
|
53
|
-
ios_notifs= Pntfr.deliveries[@push_id]
|
54
|
-
refute_nil ios_notifs, "A notification should have been delivered for #{@push_id}"
|
55
|
-
ios_notif= ios_notifs.last
|
56
|
-
assert_equal 'Test Title', ios_notif[:alert]
|
57
|
-
custom= ios_notif[:other][:custom]
|
58
|
-
assert_equal 'extra one', custom[:'extra1']
|
59
|
-
assert_equal 'extra 2', custom[:'extra_2']
|
60
|
-
assert_equal({lastkey: 'last value'}, custom[:'last-extra'])
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|