notifiable-apns-grocer 0.13.1 → 0.15.0
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 +4 -4
- data/Gemfile +5 -1
- data/lib/notifiable/apns/grocer.rb +3 -2
- data/lib/notifiable/apns/grocer/grocer_ssl_connection.rb +15 -0
- data/lib/notifiable/apns/grocer/stream.rb +40 -31
- data/lib/notifiable/apns/grocer/version.rb +1 -1
- data/notifiable-apns-grocer.gemspec +1 -2
- data/spec/features/send_notification_spec.rb +30 -0
- data/spec/spec_helper.rb +3 -2
- data/spec/stream_spec.rb +88 -51
- metadata +8 -32
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/lib/tasks/load_test.rake +0 -84
- data/spec/support/db/migrate/20131210115648_create_notifiable_apps.rb +0 -10
- data/spec/support/db/migrate/20131210115649_create_notifiable_device_tokens.rb +0 -19
- data/spec/support/db/migrate/20131210115650_create_notifiable_notifications.rb +0 -16
- data/spec/support/db/migrate/20131210115651_create_notifiable_localized_notifications.rb +0 -22
- data/spec/support/db/migrate/20131210115652_create_notifiable_statuses.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f98e571808f87e99bf9f26f34d31e76aa25aa5b
|
4
|
+
data.tar.gz: 5ef965c6a92674148da9b9ef5e17cd338ac1753c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69e74a7cbafbd3fae7ec9356bceeba1fd547eaaf03e4f86f3c93b1670796ea4fb7d1a4a61e74179dcd5240e2f67a375eb8690e3e7d34469ae95ff6186c9778ea
|
7
|
+
data.tar.gz: 13a79028ce58615c5dddc3134c0c0743f127418eb29750986208e9038d11bd96410a0510fe11abd2869c9a95f94b832505b84c29b473c60e7b4c86711fd7240f
|
data/Gemfile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'notifiable'
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require 'notifiable/apns/grocer/version'
|
3
|
+
require 'notifiable/apns/grocer/stream'
|
4
|
+
require 'notifiable/apns/grocer/grocer_ssl_connection'
|
4
5
|
|
5
6
|
module Notifiable
|
6
7
|
module Apns
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Grocer
|
2
|
+
class SSLConnection
|
3
|
+
def connect
|
4
|
+
context = OpenSSL::SSL::SSLContext.new
|
5
|
+
context.key = OpenSSL::PKey::RSA.new(certificate, passphrase)
|
6
|
+
context.cert = OpenSSL::X509::Certificate.new(certificate)
|
7
|
+
|
8
|
+
@sock = TCPSocket.new(gateway, port)
|
9
|
+
@sock.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true
|
10
|
+
@ssl = OpenSSL::SSL::SSLSocket.new(@sock, context)
|
11
|
+
@ssl.sync = true
|
12
|
+
@ssl.connect
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -7,25 +7,9 @@ module Notifiable
|
|
7
7
|
module Grocer
|
8
8
|
class Stream < Notifiable::NotifierBase
|
9
9
|
|
10
|
-
notifier_attribute :certificate, :passphrase, :
|
10
|
+
notifier_attribute :certificate, :passphrase, :sandbox, :connection_pool_size, :connection_pool_timeout
|
11
11
|
|
12
12
|
attr_reader :certificate, :passphrase
|
13
|
-
|
14
|
-
def gateway_host
|
15
|
-
@gateway_host || "gateway.push.apple.com"
|
16
|
-
end
|
17
|
-
|
18
|
-
def gateway_port
|
19
|
-
@gateway_port || 2195
|
20
|
-
end
|
21
|
-
|
22
|
-
def feedback_host
|
23
|
-
@gateway_host || "feedback.push.apple.com"
|
24
|
-
end
|
25
|
-
|
26
|
-
def feedback_port
|
27
|
-
@feedback_port || 2196
|
28
|
-
end
|
29
13
|
|
30
14
|
def connection_pool_size
|
31
15
|
@connection_pool_size || 10
|
@@ -34,6 +18,10 @@ module Notifiable
|
|
34
18
|
def connection_pool_timeout
|
35
19
|
@connection_pool_timeout || 10
|
36
20
|
end
|
21
|
+
|
22
|
+
def sandbox?
|
23
|
+
@sandbox == "1"
|
24
|
+
end
|
37
25
|
|
38
26
|
def close
|
39
27
|
super
|
@@ -42,31 +30,40 @@ module Notifiable
|
|
42
30
|
end
|
43
31
|
|
44
32
|
protected
|
45
|
-
def enqueue(
|
46
|
-
|
33
|
+
def enqueue(device, notification)
|
47
34
|
raise "Certificate missing" if certificate.nil?
|
48
|
-
|
49
|
-
grocer_notification = ::Grocer::Notification.new(
|
50
|
-
device_token: device_token.token,
|
51
|
-
alert: localized_notification.message,
|
52
|
-
custom: localized_notification.send_params,
|
53
|
-
sound: "default"
|
54
|
-
)
|
35
|
+
|
36
|
+
grocer_notification = ::Grocer::Notification.new(grocer_payload(device, notification))
|
55
37
|
|
56
38
|
pusher_pool.with do |pusher|
|
57
39
|
pusher.push(grocer_notification)
|
58
40
|
end
|
59
41
|
|
60
42
|
# assume processed. Errors will be receieved through a callback
|
61
|
-
processed(
|
43
|
+
processed(device, 0)
|
62
44
|
end
|
63
45
|
|
64
46
|
def flush
|
65
47
|
process_feedback unless self.test_env?
|
66
48
|
end
|
67
49
|
|
68
|
-
private
|
69
|
-
|
50
|
+
private
|
51
|
+
def gateway_host
|
52
|
+
self.sandbox? ? "gateway.sandbox.push.apple.com" : "gateway.push.apple.com"
|
53
|
+
end
|
54
|
+
|
55
|
+
def gateway_port
|
56
|
+
2195
|
57
|
+
end
|
58
|
+
|
59
|
+
def feedback_host
|
60
|
+
self.sandbox? ? "feedback.sandbox.push.apple.com" : "feedback.push.apple.com"
|
61
|
+
end
|
62
|
+
|
63
|
+
def feedback_port
|
64
|
+
2196
|
65
|
+
end
|
66
|
+
|
70
67
|
def gateway_config
|
71
68
|
{
|
72
69
|
certificate: certificate,
|
@@ -87,6 +84,18 @@ module Notifiable
|
|
87
84
|
}
|
88
85
|
end
|
89
86
|
|
87
|
+
def grocer_payload(device, notification)
|
88
|
+
payload = {device_token: device.token, custom: notification.send_params}
|
89
|
+
payload[:alert] = notification.title ? {title: notification.title, body: notification.message} : notification.message
|
90
|
+
payload[:sound] = notification.sound if notification.sound
|
91
|
+
payload[:badge] = notification.badge_count if notification.badge_count
|
92
|
+
payload[:identifier] = notification.identifier if notification.identifier
|
93
|
+
payload[:content_available] = notification.content_available if notification.content_available
|
94
|
+
payload[:mutable_content] = notification.mutable_content if notification.mutable_content
|
95
|
+
payload[:expiry] = notification.expiry if notification.expiry
|
96
|
+
payload
|
97
|
+
end
|
98
|
+
|
90
99
|
def pusher_pool
|
91
100
|
@pusher_pool ||= ConnectionPool.new(size: connection_pool_size, timeout: connection_pool_timeout) do
|
92
101
|
::Grocer.pusher(gateway_config)
|
@@ -102,8 +111,8 @@ module Notifiable
|
|
102
111
|
token = attempt.device_token
|
103
112
|
device_token = DeviceToken.find_by_token(token)
|
104
113
|
if device_token
|
105
|
-
device_token.
|
106
|
-
Rails.logger.info("Device #{token}
|
114
|
+
device_token.destroy if device_token.updated_at < attempt.timestamp
|
115
|
+
Rails.logger.info("Device #{token} removed at #{attempt.timestamp}")
|
107
116
|
end
|
108
117
|
end
|
109
118
|
end
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "notifiable-rails", ">=0.24.1"
|
22
|
-
spec.add_dependency "grocer", '~> 0.
|
22
|
+
spec.add_dependency "grocer", '~> 0.7.0'
|
23
23
|
spec.add_dependency "connection_pool", '~> 2.0.0'
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
@@ -29,7 +29,6 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency "simplecov-rcov"
|
30
30
|
spec.add_development_dependency "sqlite3"
|
31
31
|
spec.add_development_dependency "database_cleaner"
|
32
|
-
spec.add_development_dependency 'ruby-prof'
|
33
32
|
spec.add_development_dependency 'byebug'
|
34
33
|
|
35
34
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Send notification" do
|
4
|
+
|
5
|
+
let(:a1) { Notifiable::App.create }
|
6
|
+
let(:n1) { Notifiable::Notification.create(:app => a1, message: "Test message") }
|
7
|
+
let(:d1) { Notifiable::DeviceToken.create(:token => "ABC123", :provider => :apns, :app => a1) }
|
8
|
+
|
9
|
+
describe "#add_device_token" do
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
a1.save_notification_statuses = true
|
13
|
+
a1.apns_certificate = File.read(File.join(File.dirname(__FILE__), "..", "fixtures", "apns-development.pem"))
|
14
|
+
allow_any_instance_of(Notifiable::Apns::Grocer::Stream).to receive(:gateway_host).and_return("localhost")
|
15
|
+
|
16
|
+
n1.batch do |n|
|
17
|
+
n.add_device_token(d1)
|
18
|
+
end
|
19
|
+
|
20
|
+
Timeout.timeout(2) {
|
21
|
+
@notification = @grocer.notifications.pop
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
it { expect(Notifiable::NotificationStatus.count).to eql 1 }
|
26
|
+
it { expect(Notifiable::NotificationStatus.first.status).to eql 0 }
|
27
|
+
it { expect(@notification.alert).to eql "Test message" }
|
28
|
+
it { expect(@notification.custom[:n_id]).to eql n1.id }
|
29
|
+
end
|
30
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -16,7 +16,7 @@ require 'grocer'
|
|
16
16
|
require File.expand_path("../../lib/notifiable/apns/grocer", __FILE__)
|
17
17
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
18
18
|
|
19
|
-
db_path = 'spec/
|
19
|
+
db_path = 'spec/test.sqlite3'
|
20
20
|
DatabaseCleaner.strategy = :truncation
|
21
21
|
|
22
22
|
Rails.logger = Logger.new(STDOUT)
|
@@ -40,7 +40,8 @@ RSpec.configure do |config|
|
|
40
40
|
)
|
41
41
|
|
42
42
|
ActiveRecord::Migration.verbose = false
|
43
|
-
|
43
|
+
notifiable_rails_path = Gem.loaded_specs['notifiable-rails'].full_gem_path
|
44
|
+
ActiveRecord::Migrator.migrate File.join(notifiable_rails_path, 'db', 'migrate')
|
44
45
|
|
45
46
|
@grocer = Grocer.server(port: 2195)
|
46
47
|
@grocer.accept
|
data/spec/stream_spec.rb
CHANGED
@@ -2,71 +2,108 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Notifiable::Apns::Grocer::Stream do
|
4
4
|
|
5
|
-
|
6
|
-
let(:
|
7
|
-
let
|
8
|
-
let(:d) { Notifiable::DeviceToken.create(:token => "ABC123", :provider => :apns, :app => a, :locale => 'en') }
|
5
|
+
subject { Notifiable::Apns::Grocer::Stream.new(Rails.env, n1) }
|
6
|
+
let(:a1) { Notifiable::App.create! name: "Drum Cussac" }
|
7
|
+
let(:n1) { Notifiable::Notification.create! app: a1 }
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
a.apns_feedback_host = "localhost"
|
14
|
-
a.apns_feedback_port = 2196
|
15
|
-
a.apns_certificate = File.join(File.dirname(__FILE__), "fixtures", "apns-development.pem")
|
16
|
-
a.save_notification_statuses = true
|
9
|
+
describe "#sandbox?" do
|
10
|
+
before(:each) { subject.instance_variable_set("@sandbox", "1") }
|
11
|
+
it { expect(subject.send(:sandbox?)).to eql true }
|
17
12
|
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
describe "#grocer_payload?" do
|
15
|
+
let(:d1) { Notifiable::DeviceToken.create! app: a1, token: "abc123", provider: 'apns' }
|
16
|
+
before(:each) { @grocer_payload = subject.send("grocer_payload", d1, n1) }
|
17
|
+
|
18
|
+
context "message" do
|
19
|
+
let(:n1) { Notifiable::Notification.create! app: a1, message: "New deals!" }
|
20
|
+
it { expect(@grocer_payload).to include(alert: "New deals!") }
|
21
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
22
|
+
it { expect(@grocer_payload).to_not include(:sound) }
|
23
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
22
24
|
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
context "title and message" do
|
27
|
+
let(:n1) { Notifiable::Notification.create! app: a1, title: 'Shopping', message: "New deals!" }
|
28
|
+
it { expect(@grocer_payload[:alert]).to include({title: 'Shopping'}) }
|
29
|
+
it { expect(@grocer_payload[:alert]).to include({body: 'New deals!'}) }
|
30
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
31
|
+
it { expect(@grocer_payload).to_not include(:sound) }
|
32
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
33
|
+
end
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
expect(
|
30
|
-
expect(
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
it "supports custom properties" do
|
35
|
-
n1.batch do |n|
|
36
|
-
n.add_device_token(d)
|
35
|
+
context "sound" do
|
36
|
+
let(:n1) { Notifiable::Notification.create! app: a1, sound: "buzzer" }
|
37
|
+
it { expect(@grocer_payload).to include(sound: "buzzer") }
|
38
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
39
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
37
40
|
end
|
38
|
-
|
39
|
-
expect(Notifiable::NotificationStatus.count).to eql 1
|
40
|
-
expect(Notifiable::NotificationStatus.first.status).to eql 0
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
expect(
|
45
|
-
expect(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it "sets gateway and feedback properties" do
|
50
|
-
g = Notifiable::Apns::Grocer::Stream.new(Rails.env, n1)
|
51
|
-
a.configure(:apns, g)
|
42
|
+
context "badge count" do
|
43
|
+
let(:n1) { Notifiable::Notification.create! app: a1, badge_count: 1 }
|
44
|
+
it { expect(@grocer_payload).to include(badge: 1) }
|
45
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
46
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
47
|
+
end
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
context "parameters" do
|
50
|
+
let(:n1) { Notifiable::Notification.create! app: a1, parameters: {screen: "leaderboard"}}
|
51
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
52
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
53
|
+
it { expect(@grocer_payload[:custom]).to include(screen: "leaderboard") }
|
54
|
+
end
|
57
55
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
context "identifier" do
|
57
|
+
let(:n1) { Notifiable::Notification.create! app: a1, identifier: "23508241"}
|
58
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
59
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
60
|
+
it { expect(@grocer_payload).to include(identifier: "23508241") }
|
61
|
+
end
|
62
62
|
|
63
|
-
|
63
|
+
context "content_available" do
|
64
|
+
let(:n1) { Notifiable::Notification.create! app: a1, content_available: true}
|
65
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
66
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
67
|
+
it { expect(@grocer_payload).to include(content_available: true) }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "mutable_content" do
|
71
|
+
let(:n1) { Notifiable::Notification.create! app: a1, mutable_content: true}
|
72
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
73
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
74
|
+
it { expect(@grocer_payload).to include(mutable_content: true) }
|
75
|
+
end
|
76
|
+
|
77
|
+
context "expiry" do
|
78
|
+
let(:expiry) { Time.now + 60*60 }
|
79
|
+
let(:n1) { Notifiable::Notification.create! app: a1, expiry: expiry}
|
80
|
+
it { expect(@grocer_payload).to include(device_token: "abc123") }
|
81
|
+
it { expect(@grocer_payload[:custom]).to include(n_id: n1.id) }
|
82
|
+
it { expect(@grocer_payload).to include(expiry: expiry) }
|
83
|
+
end
|
64
84
|
end
|
65
85
|
|
66
|
-
|
67
|
-
|
86
|
+
describe "#gateway_host" do
|
87
|
+
context "sandbox" do
|
88
|
+
before(:each) { allow(subject).to receive(:sandbox?) { true } }
|
89
|
+
it { expect(subject.send(:gateway_host)).to eql "gateway.sandbox.push.apple.com" }
|
90
|
+
end
|
68
91
|
|
69
|
-
|
92
|
+
context "production" do
|
93
|
+
before(:each) { allow(subject).to receive(:sandbox?) { false } }
|
94
|
+
it { expect(subject.send(:gateway_host)).to eql "gateway.push.apple.com" }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#feedback" do
|
99
|
+
let!(:d1) { Notifiable::DeviceToken.create! app: a1, token: 'abc123', provider: 'apns' }
|
100
|
+
before(:each) do
|
101
|
+
feedback_double = double('Grocer::Feedback')
|
102
|
+
attempt_double = double('Grocer::FailedDeliveryAttempt', device_token: 'abc123', timestamp: DateTime.now)
|
103
|
+
allow(subject).to receive(:grocer_feedback) { [attempt_double].each }
|
104
|
+
subject.send(:process_feedback)
|
105
|
+
end
|
106
|
+
it { expect(Notifiable::DeviceToken.count).to eq 0 }
|
70
107
|
end
|
71
108
|
|
72
109
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notifiable-apns-grocer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kamil Kocemba
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-03-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: notifiable-rails
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 0.
|
34
|
+
version: 0.7.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 0.
|
41
|
+
version: 0.7.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: connection_pool
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,20 +151,6 @@ dependencies:
|
|
151
151
|
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
|
-
- !ruby/object:Gem::Dependency
|
155
|
-
name: ruby-prof
|
156
|
-
requirement: !ruby/object:Gem::Requirement
|
157
|
-
requirements:
|
158
|
-
- - ">="
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
version: '0'
|
161
|
-
type: :development
|
162
|
-
prerelease: false
|
163
|
-
version_requirements: !ruby/object:Gem::Requirement
|
164
|
-
requirements:
|
165
|
-
- - ">="
|
166
|
-
- !ruby/object:Gem::Version
|
167
|
-
version: '0'
|
168
154
|
- !ruby/object:Gem::Dependency
|
169
155
|
name: byebug
|
170
156
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,26 +175,20 @@ extra_rdoc_files: []
|
|
189
175
|
files:
|
190
176
|
- ".gitignore"
|
191
177
|
- ".rspec"
|
192
|
-
- ".ruby-gemset"
|
193
|
-
- ".ruby-version"
|
194
178
|
- Gemfile
|
195
179
|
- LICENSE
|
196
180
|
- LICENSE.txt
|
197
181
|
- README.md
|
198
182
|
- Rakefile
|
199
183
|
- lib/notifiable/apns/grocer.rb
|
184
|
+
- lib/notifiable/apns/grocer/grocer_ssl_connection.rb
|
200
185
|
- lib/notifiable/apns/grocer/stream.rb
|
201
186
|
- lib/notifiable/apns/grocer/version.rb
|
202
|
-
- lib/tasks/load_test.rake
|
203
187
|
- notifiable-apns-grocer.gemspec
|
188
|
+
- spec/features/send_notification_spec.rb
|
204
189
|
- spec/fixtures/apns-development.pem
|
205
190
|
- spec/spec_helper.rb
|
206
191
|
- spec/stream_spec.rb
|
207
|
-
- spec/support/db/migrate/20131210115648_create_notifiable_apps.rb
|
208
|
-
- spec/support/db/migrate/20131210115649_create_notifiable_device_tokens.rb
|
209
|
-
- spec/support/db/migrate/20131210115650_create_notifiable_notifications.rb
|
210
|
-
- spec/support/db/migrate/20131210115651_create_notifiable_localized_notifications.rb
|
211
|
-
- spec/support/db/migrate/20131210115652_create_notifiable_statuses.rb
|
212
192
|
homepage: http://www.futureworkshops.com
|
213
193
|
licenses:
|
214
194
|
- Apache 2.0
|
@@ -229,16 +209,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
209
|
version: '0'
|
230
210
|
requirements: []
|
231
211
|
rubyforge_project:
|
232
|
-
rubygems_version: 2.
|
212
|
+
rubygems_version: 2.6.14
|
233
213
|
signing_key:
|
234
214
|
specification_version: 4
|
235
215
|
summary: Notifiable APNS plugin for Grocer
|
236
216
|
test_files:
|
217
|
+
- spec/features/send_notification_spec.rb
|
237
218
|
- spec/fixtures/apns-development.pem
|
238
219
|
- spec/spec_helper.rb
|
239
220
|
- spec/stream_spec.rb
|
240
|
-
- spec/support/db/migrate/20131210115648_create_notifiable_apps.rb
|
241
|
-
- spec/support/db/migrate/20131210115649_create_notifiable_device_tokens.rb
|
242
|
-
- spec/support/db/migrate/20131210115650_create_notifiable_notifications.rb
|
243
|
-
- spec/support/db/migrate/20131210115651_create_notifiable_localized_notifications.rb
|
244
|
-
- spec/support/db/migrate/20131210115652_create_notifiable_statuses.rb
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
notifiable-apns-grocer
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.1.5
|
data/lib/tasks/load_test.rake
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'grocer'
|
3
|
-
require 'benchmark'
|
4
|
-
require 'ruby-prof'
|
5
|
-
|
6
|
-
include Benchmark
|
7
|
-
|
8
|
-
namespace :apns do
|
9
|
-
desc "Load tests the notification deliver against stub APNS server"
|
10
|
-
task :load_test => :environment do
|
11
|
-
Rails.env = "test"
|
12
|
-
|
13
|
-
ActiveRecord::Base.establish_connection('load_test_sqlite')
|
14
|
-
|
15
|
-
#ActiveRecord::Base.establish_connection('load_test_pg')
|
16
|
-
#ActiveRecord::Base.establish_connection('load_test_mysql')
|
17
|
-
|
18
|
-
test_apns
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
def test_apns
|
24
|
-
|
25
|
-
RubyProf.start
|
26
|
-
|
27
|
-
Notifiable.configure do |config|
|
28
|
-
config.apns_certificate = nil
|
29
|
-
config.apns_gateway = ENV["NOTIFIABLE_APNS_STUB_HOST"] || "localhost"
|
30
|
-
config.apns_passphrase = nil
|
31
|
-
end
|
32
|
-
|
33
|
-
notification = Notifiable::Notification.create(:message => 'Test notification')
|
34
|
-
user = User.create({ :email => 'test@example.com' })
|
35
|
-
device_token = Notifiable::DeviceToken.create(:token => '852a38d14b5e6df4168d3f7f41b38f6627b2cc0605bd53266f6d6fe8332738', :provider => :apns, :user_id => 'test@example.com')
|
36
|
-
|
37
|
-
iterations = 10
|
38
|
-
batch_size = 10000
|
39
|
-
|
40
|
-
tt = Benchmark::Tms.new
|
41
|
-
|
42
|
-
Benchmark.benchmark(CAPTION, 9, FORMAT, "> TOTAL: ", "> BATCH:") do |x|
|
43
|
-
iterations.times do ;
|
44
|
-
|
45
|
-
tt = tt + x.report("#{batch_size}:") {
|
46
|
-
Notifiable.batch do |batch|
|
47
|
-
batch_size.times do ;
|
48
|
-
batch.add(notification, user)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
}
|
52
|
-
|
53
|
-
end
|
54
|
-
[tt, tt / iterations]
|
55
|
-
end
|
56
|
-
device_token.destroy
|
57
|
-
user.destroy
|
58
|
-
notification.destroy
|
59
|
-
|
60
|
-
result = RubyProf.stop
|
61
|
-
printer = RubyProf::GraphHtmlPrinter.new(result)
|
62
|
-
printer.print(File.new('/tmp/profile.html', 'w'), :min_percent => 2)
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
# Hack to disable server cert verfification
|
67
|
-
|
68
|
-
module Grocer
|
69
|
-
class SSLConnection
|
70
|
-
|
71
|
-
def connect
|
72
|
-
context = OpenSSL::SSL::SSLContext.new
|
73
|
-
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
74
|
-
@sock = TCPSocket.new(gateway, port)
|
75
|
-
@sock.setsockopt Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true
|
76
|
-
@ssl = OpenSSL::SSL::SSLSocket.new(@sock, context)
|
77
|
-
@ssl.sync = true
|
78
|
-
@ssl.connect
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
|
@@ -1,19 +0,0 @@
|
|
1
|
-
class CreateNotifiableDeviceTokens < ActiveRecord::Migration
|
2
|
-
|
3
|
-
def change
|
4
|
-
create_table :notifiable_device_tokens do |t|
|
5
|
-
t.string :token
|
6
|
-
t.string :provider
|
7
|
-
t.string :locale
|
8
|
-
t.boolean :is_valid, :default => true
|
9
|
-
t.integer :user_id
|
10
|
-
t.references :app
|
11
|
-
|
12
|
-
t.timestamps
|
13
|
-
end
|
14
|
-
|
15
|
-
add_index :notifiable_device_tokens, :token, :unique => true
|
16
|
-
add_index :notifiable_device_tokens, :user_id
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
class CreateNotifiableNotifications < ActiveRecord::Migration
|
2
|
-
|
3
|
-
def change
|
4
|
-
create_table :notifiable_notifications do |t|
|
5
|
-
t.references :app
|
6
|
-
|
7
|
-
#stats
|
8
|
-
t.integer :sent_count, :default => 0
|
9
|
-
t.integer :gateway_accepted_count, :default => 0
|
10
|
-
t.integer :opened_count, :default => 0
|
11
|
-
|
12
|
-
t.timestamps
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
class CreateNotifiableLocalizedNotifications < ActiveRecord::Migration
|
2
|
-
|
3
|
-
def change
|
4
|
-
create_table :notifiable_localized_notifications do |t|
|
5
|
-
t.text :message
|
6
|
-
t.text :params
|
7
|
-
t.string :locale
|
8
|
-
t.references :notification
|
9
|
-
|
10
|
-
# APNS - Optional
|
11
|
-
#t.integer :badge
|
12
|
-
#t.text :sound
|
13
|
-
#t.datetime :expiry
|
14
|
-
|
15
|
-
# MPNS - Optional
|
16
|
-
#t.text :title
|
17
|
-
|
18
|
-
t.timestamps
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|