pushr-fcm 1.0.0.pre
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/MIT-LICENSE +20 -0
- data/README.md +7 -0
- data/lib/pushr-fcm/version.rb +3 -0
- data/lib/pushr/configuration_fcm.rb +16 -0
- data/lib/pushr/daemon/fcm.rb +27 -0
- data/lib/pushr/daemon/fcm_support/authenticator.rb +43 -0
- data/lib/pushr/daemon/fcm_support/connection_fcm.rb +101 -0
- data/lib/pushr/daemon/fcm_support/response_handler.rb +49 -0
- data/lib/pushr/fcm.rb +15 -0
- data/lib/pushr/feedback_fcm.rb +10 -0
- data/lib/pushr/message_fcm.rb +48 -0
- data/spec/lib/pushr/configuration_fcm_spec.rb +35 -0
- data/spec/lib/pushr/daemon/fcm_spec.rb +13 -0
- data/spec/lib/pushr/daemon/fcm_support/connection_fcm_spec.rb +100 -0
- data/spec/lib/pushr/daemon/fcm_support/response_handler_spec.rb +19 -0
- data/spec/lib/pushr/feedback_fcm_spec.rb +27 -0
- data/spec/lib/pushr/message_fcm_spec.rb +34 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/vcr.rb +4 -0
- data/spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_condition_succesful.yml +55 -0
- data/spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_token_succesful.yml +55 -0
- data/spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_topic_succesful.yml +55 -0
- metadata +273 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1a3a8192542a24aa3bd443d64dd96c220ee562ff24f65adc70291d35500ef3e8
|
4
|
+
data.tar.gz: 181f1c7c19232b6df6739e453560f8078c228c0d62197d1794010819511abc93
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ef695a56126a6ac381cbd4bba16b738226e08eaffa709155fa237b11400e0352bb7007915fb8b9f9f8c91305cef404e2ce6830d14709518a41856b9b8c95bd25
|
7
|
+
data.tar.gz: 7dc9d51daf53a39f3f3178388813777416764f971ce1fcedb4ef4e3cd623538872be50bce9ee63063a87fdd74290cb23fa99b1b53c1eb0f45dbea06cb9c4f547
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# PushrFCM
|
2
|
+
|
3
|
+
[](https://travis-ci.org/9to5/pushr-fcm)
|
4
|
+
[](https://codeclimate.com/github/9to5/pushr-fcm)
|
5
|
+
[](https://coveralls.io/r/9to5/pushr-fcm)
|
6
|
+
|
7
|
+
Please see [pushr-core](https://github.com/9to5/pushr-core) for more information.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Pushr
|
2
|
+
class ConfigurationFcm < Pushr::Configuration
|
3
|
+
attr_accessor :service_account, :project_id
|
4
|
+
validates :service_account, presence: true
|
5
|
+
validates :project_id, presence: true
|
6
|
+
|
7
|
+
def name
|
8
|
+
:fcm
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
{ type: self.class.to_s, app: app, enabled: enabled, connections: connections, service_account: service_account,
|
13
|
+
project_id: project_id }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Pushr
|
2
|
+
module Daemon
|
3
|
+
class Fcm
|
4
|
+
attr_accessor :configuration, :handlers
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@configuration = options
|
8
|
+
@handlers = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
configuration.connections.times do |i|
|
13
|
+
connection = FcmSupport::ConnectionFcm.new(configuration, i + 1)
|
14
|
+
connection.connect
|
15
|
+
|
16
|
+
handler = MessageHandler.new("pushr:#{configuration.key}", connection, configuration.app, i + 1)
|
17
|
+
handler.start
|
18
|
+
@handlers << handler
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def stop
|
23
|
+
@handlers.map(&:stop)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Pushr
|
2
|
+
module Daemon
|
3
|
+
module FcmSupport
|
4
|
+
class JsonReader
|
5
|
+
def initialize(configuration)
|
6
|
+
@configuration = configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
def read
|
10
|
+
@configuration.service_account
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Authenticator
|
15
|
+
attr_reader :configuration
|
16
|
+
SCOPE = 'https://www.googleapis.com/auth/firebase.messaging'.freeze
|
17
|
+
|
18
|
+
def initialize(configuration, i)
|
19
|
+
@configuration = configuration
|
20
|
+
@name = "#{@configuration.app}: AuthenticatorFcm #{i}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch_access_token
|
24
|
+
if @response.nil? || (@request_at + @response['expires_in'] < Time.now)
|
25
|
+
Pushr::Daemon.logger.info("[#{@name}] Refresh access token")
|
26
|
+
authorizer = fetch_credentials
|
27
|
+
@request_at = Time.now
|
28
|
+
@response = authorizer.fetch_access_token!
|
29
|
+
end
|
30
|
+
puts @response['access_token'].inspect
|
31
|
+
@response['access_token']
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def fetch_credentials
|
37
|
+
::Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: JsonReader.new(@configuration), scope: SCOPE)
|
38
|
+
# authorizer = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: File.open('/Users/tom/Downloads/api-7505019477374111882-459984-firebase-adminsdk-o569m-8d9bc31fb7.json'), scope: scope)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Pushr
|
2
|
+
module Daemon
|
3
|
+
module FcmSupport
|
4
|
+
class ConnectionError < StandardError; end
|
5
|
+
|
6
|
+
class ConnectionFcm
|
7
|
+
attr_reader :response, :name, :configuration, :authenticator, :url
|
8
|
+
IDLE_PERIOD = 5 * 60
|
9
|
+
|
10
|
+
def initialize(configuration, i)
|
11
|
+
@configuration = configuration
|
12
|
+
@name = "#{@configuration.app}: ConnectionFcm #{i}"
|
13
|
+
@authenticator = Pushr::Daemon::FcmSupport::Authenticator.new(configuration, i)
|
14
|
+
@url = "https://fcm.googleapis.com/v1/projects/#{configuration.project_id}/messages:send"
|
15
|
+
end
|
16
|
+
|
17
|
+
def connect
|
18
|
+
@last_use = Time.now
|
19
|
+
uri = URI.parse(@url)
|
20
|
+
@connection = open_http(uri.host, uri.port)
|
21
|
+
@connection.start
|
22
|
+
Pushr::Daemon.logger.info("[#{@name}] Connected to #{@url}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def write(data)
|
26
|
+
retry_count = 0
|
27
|
+
begin
|
28
|
+
puts data.to_message
|
29
|
+
response = notification_request(data.to_message)
|
30
|
+
handler = Pushr::Daemon::FcmSupport::ResponseHandler.new(response, data, retry_count)
|
31
|
+
handler.handle
|
32
|
+
rescue => e
|
33
|
+
retry_count += 1
|
34
|
+
if retry_count < 10
|
35
|
+
retry
|
36
|
+
else
|
37
|
+
raise e
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def open_http(host, port)
|
45
|
+
http = Net::HTTP.new(host, port)
|
46
|
+
http.use_ssl = true
|
47
|
+
http
|
48
|
+
end
|
49
|
+
|
50
|
+
def notification_request(data)
|
51
|
+
headers = { 'Authorization' => "Bearer #{@authenticator.fetch_access_token}",
|
52
|
+
'Content-type' => 'application/json' }
|
53
|
+
uri = URI.parse(@url)
|
54
|
+
post(uri, data, headers)
|
55
|
+
end
|
56
|
+
|
57
|
+
def post(uri, data, headers)
|
58
|
+
reconnect_idle if idle_period_exceeded?
|
59
|
+
|
60
|
+
retry_count = 0
|
61
|
+
|
62
|
+
begin
|
63
|
+
response = @connection.post(uri.path, data, headers)
|
64
|
+
puts response.inspect
|
65
|
+
@last_use = Time.now
|
66
|
+
rescue EOFError, Errno::ECONNRESET, Timeout::Error => e
|
67
|
+
retry_count += 1
|
68
|
+
|
69
|
+
Pushr::Daemon.logger.error("[#{@name}] Lost connection to #{@url} (#{e.class.name}), reconnecting ##{retry_count}...")
|
70
|
+
|
71
|
+
if retry_count <= 3
|
72
|
+
reconnect
|
73
|
+
sleep 1
|
74
|
+
retry
|
75
|
+
else
|
76
|
+
raise ConnectionError, "#{@name} tried #{retry_count - 1} times to reconnect but failed (#{e.class.name})."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
response
|
81
|
+
end
|
82
|
+
|
83
|
+
def idle_period_exceeded?
|
84
|
+
# Timeout on the http connection is 5 minutes, reconnect after 5 minutes
|
85
|
+
@last_use + IDLE_PERIOD < Time.now
|
86
|
+
end
|
87
|
+
|
88
|
+
def reconnect_idle
|
89
|
+
Pushr::Daemon.logger.info("[#{@name}] Idle period exceeded, reconnecting...")
|
90
|
+
reconnect
|
91
|
+
end
|
92
|
+
|
93
|
+
def reconnect
|
94
|
+
@connection.finish
|
95
|
+
@last_use = Time.now
|
96
|
+
@connection.start
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Pushr
|
2
|
+
module Daemon
|
3
|
+
module FcmSupport
|
4
|
+
class ResponseHandler
|
5
|
+
attr_accessor :response, :data, :retry_count
|
6
|
+
def initialize(response, data, retry_count)
|
7
|
+
@response = response
|
8
|
+
@data = data
|
9
|
+
@retry_count = retry_count
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle
|
13
|
+
case @response.code.to_i
|
14
|
+
when 200
|
15
|
+
handle_success_response
|
16
|
+
when 400
|
17
|
+
# Pushr::Daemon.logger.error("[#{@name}] JSON formatting exception received.")
|
18
|
+
Pushr::Daemon::DeliveryError.new(@response.code, @data, 'JSON formatting exception', 'FCM', false)
|
19
|
+
when 401
|
20
|
+
# Pushr::Daemon.logger.error("[#{@name}] Authentication exception received.")
|
21
|
+
Pushr::Daemon::DeliveryError.new(@response.code, @data, 'Authentication exception', 'FCM', false)
|
22
|
+
when 500..599
|
23
|
+
# internal error FCM server || service unavailable: exponential back-off
|
24
|
+
handle_error_5xx_response()
|
25
|
+
else
|
26
|
+
# Pushr::Daemon.logger.error("[#{@name}] Unknown error: #{@response.code} #{response.message}")
|
27
|
+
Pushr::Daemon::DeliveryError.new(@response.code, @data, "Unknown error: #{response.message}", 'FCM', false)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# sleep if there is a Retry-After header
|
32
|
+
def handle_error_5xx_response
|
33
|
+
value = @response.header['Retry-After']
|
34
|
+
if value && value.to_i.positive?
|
35
|
+
sleep value.to_i # Retry-After: 3600
|
36
|
+
elsif value && Date.rfc2822(value) # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
|
37
|
+
sleep Time.now.utc - Date.rfc2822(value).to_time.utc
|
38
|
+
else
|
39
|
+
sleep 2**@retry_count
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_success_response()
|
44
|
+
puts @response.body.inspect
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/pushr/fcm.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'googleauth'
|
4
|
+
require 'active_model'
|
5
|
+
require 'pushr-fcm/version'
|
6
|
+
require 'pushr/configuration'
|
7
|
+
require 'pushr/configuration_fcm'
|
8
|
+
require 'pushr/message'
|
9
|
+
require 'pushr/message_fcm'
|
10
|
+
require 'pushr/feedback'
|
11
|
+
require 'pushr/feedback_fcm'
|
12
|
+
require 'pushr/daemon/fcm'
|
13
|
+
require 'pushr/daemon/fcm_support/response_handler'
|
14
|
+
require 'pushr/daemon/fcm_support/authenticator'
|
15
|
+
require 'pushr/daemon/fcm_support/connection_fcm'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Pushr
|
2
|
+
class FeedbackFcm < Pushr::Feedback
|
3
|
+
attr_accessor :device, :follow_up, :failed_at, :update_to
|
4
|
+
validates :follow_up, inclusion: { in: %w(delete update), message: '%{value} is not a valid follow-up' }
|
5
|
+
|
6
|
+
def to_hash
|
7
|
+
{ type: 'Pushr::FeedbackFcm', app: app, device: device, follow_up: follow_up, failed_at: failed_at, update_to: update_to }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Pushr
|
2
|
+
class MessageFcm < Pushr::Message
|
3
|
+
POSTFIX = 'fcm'.freeze
|
4
|
+
|
5
|
+
attr_accessor :name, :data, :notification, :android, :webpush, :apns, :token, :topic, :condition
|
6
|
+
|
7
|
+
# {
|
8
|
+
# "name": string,
|
9
|
+
# "data": {
|
10
|
+
# string: string,
|
11
|
+
# ...
|
12
|
+
# },
|
13
|
+
# "notification": {
|
14
|
+
# object(Notification)
|
15
|
+
# },
|
16
|
+
# "android": {
|
17
|
+
# object(AndroidConfig)
|
18
|
+
# },
|
19
|
+
# "webpush": {
|
20
|
+
# object(WebpushConfig)
|
21
|
+
# },
|
22
|
+
# "apns": {
|
23
|
+
# object(ApnsConfig)
|
24
|
+
# },
|
25
|
+
#
|
26
|
+
# // Union field target can be only one of the following:
|
27
|
+
# "token": string,
|
28
|
+
# "topic": string,
|
29
|
+
# "condition": string
|
30
|
+
# // End of list of possible types for union field target.
|
31
|
+
# }
|
32
|
+
|
33
|
+
def to_message
|
34
|
+
hsh = {}
|
35
|
+
%w[name data notification android webpush apns token topic condition].each do |variable|
|
36
|
+
hsh[variable] = send(variable) if send(variable)
|
37
|
+
end
|
38
|
+
MultiJson.dump(message: hsh)
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_hash
|
42
|
+
hsh = { type: self.class.to_s, app: app, name: name, data: data, notification: notification, android: android,
|
43
|
+
webpush: webpush, apns: apns, token: token, topic: topic, condition: condition }
|
44
|
+
hsh[Pushr::Core.external_id_tag] = external_id if external_id
|
45
|
+
hsh
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/configuration_fcm'
|
3
|
+
|
4
|
+
describe Pushr::ConfigurationFcm do
|
5
|
+
before(:each) do
|
6
|
+
Pushr::Core.configure do |config|
|
7
|
+
config.redis = ConnectionPool.new(size: 1, timeout: 1) { MockRedis.new }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'all' do
|
12
|
+
it 'returns all configurations' do
|
13
|
+
expect(Pushr::Configuration.all).to eql([])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'create' do
|
18
|
+
it 'should create a configuration' do
|
19
|
+
config = Pushr::ConfigurationFcm.new(app: 'app_name', connections: 2, enabled: true)
|
20
|
+
expect(config.key).to eql('app_name:fcm')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'save' do
|
25
|
+
let(:config) {
|
26
|
+
Pushr::ConfigurationFcm.new(app: 'app_name', connections: 2, enabled: true, project_id: 'project_id',
|
27
|
+
service_account: '{}')
|
28
|
+
}
|
29
|
+
it 'should save a configuration' do
|
30
|
+
config.save
|
31
|
+
expect(Pushr::Configuration.all.count).to eql(1)
|
32
|
+
expect(Pushr::Configuration.all[0].class).to eql(Pushr::ConfigurationFcm)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/daemon/fcm'
|
3
|
+
require 'pushr/daemon/fcm_support/connection_fcm'
|
4
|
+
|
5
|
+
describe Pushr::Daemon::Fcm do
|
6
|
+
let(:fcm) { Pushr::Daemon::Fcm.new(test: 'test') }
|
7
|
+
|
8
|
+
describe 'responds to' do
|
9
|
+
it 'configuration' do
|
10
|
+
expect(fcm.configuration).to eql(test: 'test')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/daemon'
|
3
|
+
require 'pushr/fcm'
|
4
|
+
require 'pushr/daemon/logger'
|
5
|
+
require 'pushr/message_fcm'
|
6
|
+
require 'pushr/configuration_fcm'
|
7
|
+
require 'pushr/daemon/delivery_error'
|
8
|
+
|
9
|
+
describe Pushr::Daemon::FcmSupport::ConnectionFcm do
|
10
|
+
before(:each) do
|
11
|
+
Pushr::Core.configure do |config|
|
12
|
+
config.redis = ConnectionPool.new(size: 1, timeout: 1) { MockRedis.new }
|
13
|
+
end
|
14
|
+
|
15
|
+
class_double('Pushr::Daemon::FcmSupport::Authenticator',
|
16
|
+
new: instance_double('Pushr::Daemon::FcmSupport::Authenticator',
|
17
|
+
fetch_access_token: 'mock_access_token')).as_stubbed_const
|
18
|
+
|
19
|
+
logger = double('logger')
|
20
|
+
allow(logger).to receive(:info)
|
21
|
+
allow(logger).to receive(:error)
|
22
|
+
allow(logger).to receive(:warn)
|
23
|
+
Pushr::Daemon.logger = logger
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:config) do
|
27
|
+
Pushr::ConfigurationFcm.new(app: 'app_name', connections: 2, enabled: true, project_id: 'project_id',
|
28
|
+
service_account: '{}')
|
29
|
+
end
|
30
|
+
let(:connection) { Pushr::Daemon::FcmSupport::ConnectionFcm.new(config, 1) }
|
31
|
+
|
32
|
+
describe 'sends a message to topic' do
|
33
|
+
let(:message) do
|
34
|
+
hsh = { app: 'app_name', topic: 'test' }
|
35
|
+
Pushr::MessageFcm.new(hsh)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'succesful', :vcr do
|
39
|
+
connection.connect
|
40
|
+
connection.write(message)
|
41
|
+
# TODO: expect(connection.write(message).code).to eql '200'
|
42
|
+
end
|
43
|
+
|
44
|
+
# it 'fails and should Retry-After', :vcr do
|
45
|
+
# expect_any_instance_of(Pushr::Daemon::FcmSupport::ConnectionFcm).to receive(:sleep)
|
46
|
+
# connection.connect
|
47
|
+
# connection.write(message)
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# it 'fails and should Retry-After with date', :vcr do
|
51
|
+
# expect_any_instance_of(Pushr::Daemon::FcmSupport::ConnectionFcm).to receive(:sleep)
|
52
|
+
# connection.connect
|
53
|
+
# connection.write(message)
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# it 'fails and should sleep after fail', :vcr do
|
57
|
+
# expect_any_instance_of(Pushr::Daemon::FcmSupport::ConnectionFcm).to receive(:sleep)
|
58
|
+
# connection.connect
|
59
|
+
# connection.write(message)
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# it 'fails of a json formatting execption', :vcr do
|
63
|
+
# connection.connect
|
64
|
+
# connection.write(message)
|
65
|
+
# # TODO: assert
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# it 'fails of a not authenticated execption', :vcr do
|
69
|
+
# connection.connect
|
70
|
+
# connection.write(message)
|
71
|
+
# # TODO: assert
|
72
|
+
# end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'sends a message to token' do
|
76
|
+
let(:message) do
|
77
|
+
hsh = { app: 'app_name', token: 'token', notification: { title: 'test', body: 'message' } }
|
78
|
+
Pushr::MessageFcm.new(hsh)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'succesful', :vcr do
|
82
|
+
connection.connect
|
83
|
+
connection.write(message)
|
84
|
+
# TODO: expect(connection.write(message).code).to eql '200'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'sends a message to condition' do
|
89
|
+
let(:message) do
|
90
|
+
hsh = { app: 'app_name', condition: "'foo' in topics && 'bar' in topics'" }
|
91
|
+
Pushr::MessageFcm.new(hsh)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'succesful', :vcr do
|
95
|
+
connection.connect
|
96
|
+
connection.write(message)
|
97
|
+
# TODO: expect(connection.write(message).code).to eql '200'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/daemon'
|
3
|
+
require 'pushr/fcm'
|
4
|
+
require 'pushr/feedback_fcm'
|
5
|
+
require 'pushr/message_fcm'
|
6
|
+
|
7
|
+
describe Pushr::Daemon::FcmSupport::ResponseHandler do
|
8
|
+
it 'should handle no errors' do
|
9
|
+
json = '{"name": "projects/project_id/messages/9216177826578065331"}'
|
10
|
+
response = double('response')
|
11
|
+
allow(response).to receive(:body).and_return(json)
|
12
|
+
allow(response).to receive(:code).and_return('200')
|
13
|
+
|
14
|
+
message = double('message')
|
15
|
+
handler = Pushr::Daemon::FcmSupport::ResponseHandler.new(response, message, 0)
|
16
|
+
handler.handle
|
17
|
+
# TODO: assert
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/feedback_fcm'
|
3
|
+
|
4
|
+
describe Pushr::FeedbackFcm do
|
5
|
+
before(:each) do
|
6
|
+
Pushr::Core.configure do |config|
|
7
|
+
config.redis = ConnectionPool.new(size: 1, timeout: 1) { MockRedis.new }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'create' do
|
12
|
+
it 'should create a feedback' do
|
13
|
+
feedback = Pushr::FeedbackFcm.new(app: 'app_name', device: 'ab' * 20, follow_up: 'delete', failed_at: Time.now, update_to: nil)
|
14
|
+
expect(feedback.app).to eql('app_name')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'save' do
|
19
|
+
let!(:feedback) do
|
20
|
+
Pushr::FeedbackFcm.create(app: 'app_name', device: 'ab' * 20, follow_up: 'delete', failed_at: Time.now,
|
21
|
+
update_to: nil)
|
22
|
+
end
|
23
|
+
it 'should save a feedback' do
|
24
|
+
expect(Pushr::Feedback.next.class).to eql(Pushr::FeedbackFcm)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pushr/message_fcm'
|
3
|
+
|
4
|
+
describe Pushr::MessageFcm do
|
5
|
+
before(:each) do
|
6
|
+
Pushr::Core.configure do |config|
|
7
|
+
config.redis = ConnectionPool.new(size: 1, timeout: 1) { MockRedis.new }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'next' do
|
12
|
+
it 'returns next message' do
|
13
|
+
expect(Pushr::Message.next('pushr:app_name:fcm')).to eql(nil)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'save' do
|
18
|
+
let(:message) do
|
19
|
+
hsh = { app: 'app_name', token: 'test' }
|
20
|
+
Pushr::MessageFcm.new(hsh)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return true' do
|
24
|
+
expect(message.save).to eql true
|
25
|
+
end
|
26
|
+
it 'should save a message' do
|
27
|
+
message.save
|
28
|
+
expect(Pushr::Message.next('pushr:app_name:fcm')).to be_kind_of(Pushr::MessageFcm)
|
29
|
+
end
|
30
|
+
it 'should respond to to_message' do
|
31
|
+
expect(message.to_message).to be_kind_of(String)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
|
6
|
+
require 'simplecov'
|
7
|
+
require 'coveralls'
|
8
|
+
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
10
|
+
SimpleCov::Formatter::HTMLFormatter,
|
11
|
+
Coveralls::SimpleCov::Formatter
|
12
|
+
])
|
13
|
+
SimpleCov.start
|
14
|
+
|
15
|
+
require 'vcr'
|
16
|
+
require 'pushr/core'
|
17
|
+
require 'mock_redis'
|
18
|
+
|
19
|
+
Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
|
20
|
+
|
21
|
+
RSpec.configure do |config|
|
22
|
+
config.raise_errors_for_deprecations!
|
23
|
+
config.run_all_when_everything_filtered = true
|
24
|
+
# config.filter_run :focus
|
25
|
+
|
26
|
+
# Run specs in random order to surface order dependencies. If you find an
|
27
|
+
# order dependency and want to debug it, you can fix the order by providing
|
28
|
+
# the seed, which is printed after each run.
|
29
|
+
# --seed 1234
|
30
|
+
config.order = 'random'
|
31
|
+
|
32
|
+
config.around(:each, :vcr) do |example|
|
33
|
+
name = example.metadata[:full_description].split(/\s+/, 2).join('/').underscore.gsub(/[^\w\/]+/, '_')
|
34
|
+
options = example.metadata.slice(:record, :match_requests_on).except(:example_group)
|
35
|
+
VCR.use_cassette(name, options) { example.call }
|
36
|
+
end
|
37
|
+
end
|
data/spec/support/vcr.rb
ADDED
data/spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_condition_succesful.yml
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://fcm.googleapis.com/v1/projects/project_id/messages:send
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"message":{"condition":"''foo'' in topics && ''bar'' in topics''"}}'
|
9
|
+
headers:
|
10
|
+
Authorization:
|
11
|
+
- Bearer mock_access_token
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
User-Agent:
|
19
|
+
- Ruby
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=UTF-8
|
27
|
+
Vary:
|
28
|
+
- Origin
|
29
|
+
- Referer
|
30
|
+
- X-Origin
|
31
|
+
Date:
|
32
|
+
- Thu, 18 Oct 2018 10:51:49 GMT
|
33
|
+
Server:
|
34
|
+
- ESF
|
35
|
+
Cache-Control:
|
36
|
+
- private
|
37
|
+
X-Xss-Protection:
|
38
|
+
- 1; mode=block
|
39
|
+
X-Frame-Options:
|
40
|
+
- SAMEORIGIN
|
41
|
+
X-Content-Type-Options:
|
42
|
+
- nosniff
|
43
|
+
Alt-Svc:
|
44
|
+
- quic=":443"; ma=2592000; v="44,43,39,35"
|
45
|
+
Transfer-Encoding:
|
46
|
+
- chunked
|
47
|
+
body:
|
48
|
+
encoding: ASCII-8BIT
|
49
|
+
string: |
|
50
|
+
{
|
51
|
+
"name": "projects/project_id/messages/6508272921236107021"
|
52
|
+
}
|
53
|
+
http_version:
|
54
|
+
recorded_at: Thu, 18 Oct 2018 10:51:49 GMT
|
55
|
+
recorded_with: VCR 4.0.0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://fcm.googleapis.com/v1/projects/project_id/messages:send
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"message":{"notification":{"title":"test","body":"message"},"token":"token"}}'
|
9
|
+
headers:
|
10
|
+
Authorization:
|
11
|
+
- Bearer mock_access_token
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
User-Agent:
|
19
|
+
- Ruby
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=UTF-8
|
27
|
+
Vary:
|
28
|
+
- Origin
|
29
|
+
- Referer
|
30
|
+
- X-Origin
|
31
|
+
Date:
|
32
|
+
- Thu, 18 Oct 2018 10:45:32 GMT
|
33
|
+
Server:
|
34
|
+
- ESF
|
35
|
+
Cache-Control:
|
36
|
+
- private
|
37
|
+
X-Xss-Protection:
|
38
|
+
- 1; mode=block
|
39
|
+
X-Frame-Options:
|
40
|
+
- SAMEORIGIN
|
41
|
+
X-Content-Type-Options:
|
42
|
+
- nosniff
|
43
|
+
Alt-Svc:
|
44
|
+
- quic=":443"; ma=2592000; v="44,43,39,35"
|
45
|
+
Transfer-Encoding:
|
46
|
+
- chunked
|
47
|
+
body:
|
48
|
+
encoding: ASCII-8BIT
|
49
|
+
string: |
|
50
|
+
{
|
51
|
+
"name": "projects/project_id/messages/0:1539859532406104%b949fa49b949fa49"
|
52
|
+
}
|
53
|
+
http_version:
|
54
|
+
recorded_at: Thu, 18 Oct 2018 10:45:32 GMT
|
55
|
+
recorded_with: VCR 4.0.0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://fcm.googleapis.com/v1/projects/project_id/messages:send
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"message":{"topic":"test"}}'
|
9
|
+
headers:
|
10
|
+
Authorization:
|
11
|
+
- Bearer mock_access_token
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- "*/*"
|
18
|
+
User-Agent:
|
19
|
+
- Ruby
|
20
|
+
response:
|
21
|
+
status:
|
22
|
+
code: 200
|
23
|
+
message: OK
|
24
|
+
headers:
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=UTF-8
|
27
|
+
Vary:
|
28
|
+
- Origin
|
29
|
+
- Referer
|
30
|
+
- X-Origin
|
31
|
+
Date:
|
32
|
+
- Thu, 18 Oct 2018 07:37:33 GMT
|
33
|
+
Server:
|
34
|
+
- ESF
|
35
|
+
Cache-Control:
|
36
|
+
- private
|
37
|
+
X-Xss-Protection:
|
38
|
+
- 1; mode=block
|
39
|
+
X-Frame-Options:
|
40
|
+
- SAMEORIGIN
|
41
|
+
X-Content-Type-Options:
|
42
|
+
- nosniff
|
43
|
+
Alt-Svc:
|
44
|
+
- quic=":443"; ma=2592000; v="44,43,39,35"
|
45
|
+
Transfer-Encoding:
|
46
|
+
- chunked
|
47
|
+
body:
|
48
|
+
encoding: ASCII-8BIT
|
49
|
+
string: |
|
50
|
+
{
|
51
|
+
"name": "projects/project_id/messages/9216177826578065331"
|
52
|
+
}
|
53
|
+
http_version:
|
54
|
+
recorded_at: Thu, 18 Oct 2018 07:37:33 GMT
|
55
|
+
recorded_with: VCR 4.0.0
|
metadata
ADDED
@@ -0,0 +1,273 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pushr-fcm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Pesman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: multi_json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pushr-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activemodel
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: googleauth
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: mock_redis
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: vcr
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rake
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: coveralls
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rubocop
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
description: FCM support for the modular push daemon.
|
210
|
+
email:
|
211
|
+
- tom@tnux.net
|
212
|
+
executables: []
|
213
|
+
extensions: []
|
214
|
+
extra_rdoc_files: []
|
215
|
+
files:
|
216
|
+
- MIT-LICENSE
|
217
|
+
- README.md
|
218
|
+
- lib/pushr-fcm/version.rb
|
219
|
+
- lib/pushr/configuration_fcm.rb
|
220
|
+
- lib/pushr/daemon/fcm.rb
|
221
|
+
- lib/pushr/daemon/fcm_support/authenticator.rb
|
222
|
+
- lib/pushr/daemon/fcm_support/connection_fcm.rb
|
223
|
+
- lib/pushr/daemon/fcm_support/response_handler.rb
|
224
|
+
- lib/pushr/fcm.rb
|
225
|
+
- lib/pushr/feedback_fcm.rb
|
226
|
+
- lib/pushr/message_fcm.rb
|
227
|
+
- spec/lib/pushr/configuration_fcm_spec.rb
|
228
|
+
- spec/lib/pushr/daemon/fcm_spec.rb
|
229
|
+
- spec/lib/pushr/daemon/fcm_support/connection_fcm_spec.rb
|
230
|
+
- spec/lib/pushr/daemon/fcm_support/response_handler_spec.rb
|
231
|
+
- spec/lib/pushr/feedback_fcm_spec.rb
|
232
|
+
- spec/lib/pushr/message_fcm_spec.rb
|
233
|
+
- spec/spec_helper.rb
|
234
|
+
- spec/support/vcr.rb
|
235
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_condition_succesful.yml
|
236
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_token_succesful.yml
|
237
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_topic_succesful.yml
|
238
|
+
homepage: https://github.com/9to5/pushr-fcm
|
239
|
+
licenses:
|
240
|
+
- MIT
|
241
|
+
metadata: {}
|
242
|
+
post_install_message:
|
243
|
+
rdoc_options: []
|
244
|
+
require_paths:
|
245
|
+
- lib
|
246
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - ">="
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: 2.2.0
|
251
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
252
|
+
requirements:
|
253
|
+
- - ">"
|
254
|
+
- !ruby/object:Gem::Version
|
255
|
+
version: 1.3.1
|
256
|
+
requirements: []
|
257
|
+
rubyforge_project:
|
258
|
+
rubygems_version: 2.7.6
|
259
|
+
signing_key:
|
260
|
+
specification_version: 4
|
261
|
+
summary: FCM (Android) part of the modular push daemon.
|
262
|
+
test_files:
|
263
|
+
- spec/lib/pushr/configuration_fcm_spec.rb
|
264
|
+
- spec/lib/pushr/daemon/fcm_spec.rb
|
265
|
+
- spec/lib/pushr/daemon/fcm_support/connection_fcm_spec.rb
|
266
|
+
- spec/lib/pushr/daemon/fcm_support/response_handler_spec.rb
|
267
|
+
- spec/lib/pushr/feedback_fcm_spec.rb
|
268
|
+
- spec/lib/pushr/message_fcm_spec.rb
|
269
|
+
- spec/spec_helper.rb
|
270
|
+
- spec/support/vcr.rb
|
271
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_condition_succesful.yml
|
272
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_token_succesful.yml
|
273
|
+
- spec/vcr/pushr/daemon/fcm_support/connection_fcm/sends_a_message_to_topic_succesful.yml
|