rapns_rails_2 3.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/CHANGELOG.md +83 -0
- data/LICENSE +7 -0
- data/README.md +168 -0
- data/bin/rapns +37 -0
- data/config/database.yml +44 -0
- data/lib/generators/rapns_generator.rb +25 -0
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
- data/lib/generators/templates/add_app_to_rapns.rb +11 -0
- data/lib/generators/templates/add_gcm.rb +95 -0
- data/lib/generators/templates/create_rapns_apps.rb +16 -0
- data/lib/generators/templates/create_rapns_feedback.rb +15 -0
- data/lib/generators/templates/create_rapns_notifications.rb +26 -0
- data/lib/generators/templates/rapns.rb +87 -0
- data/lib/rapns/TODO +3 -0
- data/lib/rapns/apns/app.rb +25 -0
- data/lib/rapns/apns/binary_notification_validator.rb +12 -0
- data/lib/rapns/apns/device_token_format_validator.rb +12 -0
- data/lib/rapns/apns/feedback.rb +16 -0
- data/lib/rapns/apns/notification.rb +91 -0
- data/lib/rapns/apns_feedback.rb +13 -0
- data/lib/rapns/app.rb +16 -0
- data/lib/rapns/configuration.rb +89 -0
- data/lib/rapns/daemon/apns/app_runner.rb +26 -0
- data/lib/rapns/daemon/apns/certificate_expired_error.rb +20 -0
- data/lib/rapns/daemon/apns/connection.rb +142 -0
- data/lib/rapns/daemon/apns/delivery.rb +64 -0
- data/lib/rapns/daemon/apns/delivery_handler.rb +35 -0
- data/lib/rapns/daemon/apns/disconnection_error.rb +20 -0
- data/lib/rapns/daemon/apns/feedback_receiver.rb +89 -0
- data/lib/rapns/daemon/app_runner.rb +179 -0
- data/lib/rapns/daemon/batch.rb +112 -0
- data/lib/rapns/daemon/delivery.rb +23 -0
- data/lib/rapns/daemon/delivery_error.rb +19 -0
- data/lib/rapns/daemon/delivery_handler.rb +52 -0
- data/lib/rapns/daemon/delivery_handler_collection.rb +33 -0
- data/lib/rapns/daemon/feeder.rb +65 -0
- data/lib/rapns/daemon/gcm/app_runner.rb +13 -0
- data/lib/rapns/daemon/gcm/delivery.rb +228 -0
- data/lib/rapns/daemon/gcm/delivery_handler.rb +20 -0
- data/lib/rapns/daemon/interruptible_sleep.rb +65 -0
- data/lib/rapns/daemon/reflectable.rb +13 -0
- data/lib/rapns/daemon/store/active_record/reconnectable.rb +66 -0
- data/lib/rapns/daemon/store/active_record.rb +128 -0
- data/lib/rapns/daemon.rb +129 -0
- data/lib/rapns/deprecatable.rb +23 -0
- data/lib/rapns/deprecation.rb +23 -0
- data/lib/rapns/embed.rb +28 -0
- data/lib/rapns/gcm/app.rb +7 -0
- data/lib/rapns/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +11 -0
- data/lib/rapns/gcm/notification.rb +37 -0
- data/lib/rapns/gcm/payload_data_size_validator.rb +13 -0
- data/lib/rapns/gcm/registration_ids_count_validator.rb +13 -0
- data/lib/rapns/logger.rb +76 -0
- data/lib/rapns/multi_json_helper.rb +16 -0
- data/lib/rapns/notification.rb +62 -0
- data/lib/rapns/notifier.rb +35 -0
- data/lib/rapns/push.rb +17 -0
- data/lib/rapns/rails-2-compatibility.rb +34 -0
- data/lib/rapns/reflection.rb +44 -0
- data/lib/rapns/upgraded.rb +31 -0
- data/lib/rapns/version.rb +3 -0
- data/lib/rapns_rails_2.rb +67 -0
- data/lib/tasks/cane.rake +18 -0
- data/lib/tasks/test.rake +38 -0
- data/spec/support/cert_with_password.pem +90 -0
- data/spec/support/cert_without_password.pem +59 -0
- data/spec/support/simplecov_helper.rb +13 -0
- data/spec/support/simplecov_quality_formatter.rb +8 -0
- data/spec/tmp/.gitkeep +0 -0
- data/spec/unit/apns/app_spec.rb +29 -0
- data/spec/unit/apns/feedback_spec.rb +9 -0
- data/spec/unit/apns/notification_spec.rb +215 -0
- data/spec/unit/apns_feedback_spec.rb +21 -0
- data/spec/unit/app_spec.rb +16 -0
- data/spec/unit/configuration_spec.rb +55 -0
- data/spec/unit/daemon/apns/app_runner_spec.rb +45 -0
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
- data/spec/unit/daemon/apns/connection_spec.rb +287 -0
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +59 -0
- data/spec/unit/daemon/apns/delivery_spec.rb +101 -0
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +18 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +134 -0
- data/spec/unit/daemon/app_runner_shared.rb +83 -0
- data/spec/unit/daemon/app_runner_spec.rb +170 -0
- data/spec/unit/daemon/batch_spec.rb +219 -0
- data/spec/unit/daemon/delivery_error_spec.rb +13 -0
- data/spec/unit/daemon/delivery_handler_collection_spec.rb +37 -0
- data/spec/unit/daemon/delivery_handler_shared.rb +45 -0
- data/spec/unit/daemon/feeder_spec.rb +81 -0
- data/spec/unit/daemon/gcm/app_runner_spec.rb +19 -0
- data/spec/unit/daemon/gcm/delivery_handler_spec.rb +44 -0
- data/spec/unit/daemon/gcm/delivery_spec.rb +289 -0
- data/spec/unit/daemon/interruptible_sleep_spec.rb +68 -0
- data/spec/unit/daemon/reflectable_spec.rb +27 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +114 -0
- data/spec/unit/daemon/store/active_record_spec.rb +281 -0
- data/spec/unit/daemon_spec.rb +157 -0
- data/spec/unit/deprecatable_spec.rb +32 -0
- data/spec/unit/deprecation_spec.rb +15 -0
- data/spec/unit/embed_spec.rb +50 -0
- data/spec/unit/gcm/app_spec.rb +4 -0
- data/spec/unit/gcm/notification_spec.rb +52 -0
- data/spec/unit/logger_spec.rb +180 -0
- data/spec/unit/notification_shared.rb +45 -0
- data/spec/unit/notification_spec.rb +4 -0
- data/spec/unit/notifier_spec.rb +32 -0
- data/spec/unit/push_spec.rb +44 -0
- data/spec/unit/rapns_spec.rb +9 -0
- data/spec/unit/reflection_spec.rb +30 -0
- data/spec/unit/upgraded_spec.rb +40 -0
- data/spec/unit_spec_helper.rb +137 -0
- metadata +232 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
Bag Attributes
|
2
|
+
friendlyName: test certificate
|
3
|
+
localKeyID: 00 93 8F E4 A3 C3 75 64 3D 7E EA 14 0B 0A EA DD 15 85 8A D5
|
4
|
+
subject=/CN=test certificate/O=Example/OU=Example/ST=QLD/C=AU/L=Example/emailAddress=user@example.com
|
5
|
+
issuer=/CN=test certificate/O=Example/OU=Example/ST=QLD/C=AU/L=Example/emailAddress=user@example.com
|
6
|
+
-----BEGIN CERTIFICATE-----
|
7
|
+
MIID5jCCAs6gAwIBAgIBATALBgkqhkiG9w0BAQswgY0xGTAXBgNVBAMMEHRlc3Qg
|
8
|
+
Y2VydGlmaWNhdGUxEDAOBgNVBAoMB0V4YW1wbGUxEDAOBgNVBAsMB0V4YW1wbGUx
|
9
|
+
DDAKBgNVBAgMA1FMRDELMAkGA1UEBhMCQVUxEDAOBgNVBAcMB0V4YW1wbGUxHzAd
|
10
|
+
BgkqhkiG9w0BCQEWEHVzZXJAZXhhbXBsZS5jb20wHhcNMTIwOTA5MDMxODMyWhcN
|
11
|
+
MjIwOTA3MDMxODMyWjCBjTEZMBcGA1UEAwwQdGVzdCBjZXJ0aWZpY2F0ZTEQMA4G
|
12
|
+
A1UECgwHRXhhbXBsZTEQMA4GA1UECwwHRXhhbXBsZTEMMAoGA1UECAwDUUxEMQsw
|
13
|
+
CQYDVQQGEwJBVTEQMA4GA1UEBwwHRXhhbXBsZTEfMB0GCSqGSIb3DQEJARYQdXNl
|
14
|
+
ckBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKF+
|
15
|
+
UDsN1sLen8g+97PNTiWju9+wkSv+H5rQlvb6YFLPx11YvqpK8ms6kFU1OmWeLfmh
|
16
|
+
cpsT+bZtKupC7aGPoSG3RXzzf/YUMgs/ZSXA0idZHA6tkReAEzIX6jL5otfPWbaP
|
17
|
+
luCTUoVMeP4u9ywk628zlqh9IQHC1Agl0R1xGCpULDk8kn1gPyEisl38wI5aDbzy
|
18
|
+
6lYQGNUKOqt1xfVjtIFe/jyY/v0sxFjIJlRLcAFBuJx4sRV+PwRBkusOQtYwcwpI
|
19
|
+
loMxJj+GQe66ueATW81aC4iOU66DAFFEuGzwIwm3bOilimGGQbGb92F339RfmSOo
|
20
|
+
TPAvVhsakI3mzESb4lkCAwEAAaNRME8wDgYDVR0PAQH/BAQDAgeAMCAGA1UdJQEB
|
21
|
+
/wQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAbBgNVHREEFDASgRB1c2VyQGV4YW1w
|
22
|
+
bGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQA5UbNR+83ZdI2DiaB4dRmy0V5RDAqJ
|
23
|
+
k9+QskcTV4gBTjsOBS46Dw1tI6iTrfTyjYJdnyH0Y2Y2YVWBnvtON41UCZak+4ed
|
24
|
+
/IqyzU0dtfZ+frWa0RY4reyl80TwqnzyJfni0nDo4zGGvz70cxyaz2u1BWqwLjqb
|
25
|
+
dh8Dxvt+aHW2MQi0iGKh/HNbgwVanR4+ubNwziK9sR1Rnq9MkHWtwBw16SXQG6ao
|
26
|
+
SZKASWNaH8VL08Zz0E98cwd137UJkPsldCwJ8kHR5OzkcjPdXvnGD3d64yy2TC1Z
|
27
|
+
Gy1Aazt98wPcTYBytlhK8Rvzg9OoY9QmsdpmWxz1ZCXECJNqCa3IKsqO
|
28
|
+
-----END CERTIFICATE-----
|
29
|
+
Bag Attributes
|
30
|
+
friendlyName: test certificate
|
31
|
+
localKeyID: 00 93 8F E4 A3 C3 75 64 3D 7E EA 14 0B 0A EA DD 15 85 8A D5
|
32
|
+
Key Attributes: <No Attributes>
|
33
|
+
-----BEGIN RSA PRIVATE KEY-----
|
34
|
+
MIIEpQIBAAKCAQEAoX5QOw3Wwt6fyD73s81OJaO737CRK/4fmtCW9vpgUs/HXVi+
|
35
|
+
qkryazqQVTU6ZZ4t+aFymxP5tm0q6kLtoY+hIbdFfPN/9hQyCz9lJcDSJ1kcDq2R
|
36
|
+
F4ATMhfqMvmi189Zto+W4JNShUx4/i73LCTrbzOWqH0hAcLUCCXRHXEYKlQsOTyS
|
37
|
+
fWA/ISKyXfzAjloNvPLqVhAY1Qo6q3XF9WO0gV7+PJj+/SzEWMgmVEtwAUG4nHix
|
38
|
+
FX4/BEGS6w5C1jBzCkiWgzEmP4ZB7rq54BNbzVoLiI5TroMAUUS4bPAjCbds6KWK
|
39
|
+
YYZBsZv3YXff1F+ZI6hM8C9WGxqQjebMRJviWQIDAQABAoIBAQCTiLIDQUFSBdAz
|
40
|
+
QFNLD+S0vkCEuunlJuP4q1c/ir006l1YChsluBJ/o6D4NwiCjV+zDquEwVsALftm
|
41
|
+
yH4PewfZpXT2Ef508T5GyEO/mchj6iSXxDkpHvhqay6qIyWBwwxSnBtaTzy0Soi+
|
42
|
+
rmlhCtmLXbXld2sQEM1kJChGnWtWPtvSyrn+mapNPZviGRtgRNK+YsrAti1nUext
|
43
|
+
2syO5mTdHf1D8GR7I98OaX6odREuSocEV9PzfapWZx2GK5tvRiS1skiug5ciieTd
|
44
|
+
Am5/C+bb31h4drFslihLb5BRGO5SFQJvMJL2Sx1f19BCC4XikS01P4/zZbxQNq79
|
45
|
+
kxEQuDGBAoGBANP4pIYZ5xshCkx7cTYqmxzWLClGKE2S7Oa8N89mtOwfmqT9AFun
|
46
|
+
t9Us9Ukbi8BaKlKhGpQ1HlLf/KVcpyW0x2qLou6AyIWYH+/5VaR3graNgUnzpK9f
|
47
|
+
1F5HoaNHbhlAoebqhzhASFlJI2aqUdQjdOv73z+s9szJU4gpILNwGDFnAoGBAMMJ
|
48
|
+
j+vIxtG9J2jldyoXzpg5mbMXSj9u/wFLBVdjXWyOoiqVMMBto53RnoqAom7Ifr9D
|
49
|
+
49LxRAT1Q3l4vs/YnM3ziMsIg2vQK1EbrLsY9OnD/kvPaLXOlNIOdfLM8UeVWZMc
|
50
|
+
I4LPbbZrhv/7CC8RjbRhMoWWdGYPvxmvD6V4ZDY/AoGBALoI6OxA45Htx4okdNHj
|
51
|
+
RstiNNPsnQaoQn6nBhxiubraafEPkzbd1fukP4pwQJELEUX/2sHkdL6rkqLW1GPF
|
52
|
+
a5dZAiBsqpCFWNJWdBGqSfBJ9QSgbxLz+gDcwUH6OOi0zuNJRm/aCyVBiW5bYQHc
|
53
|
+
NIvAPMk31ksZDtTbs7WIVdNVAoGBALZ1+KWNxKqs+fSBT5UahpUUtfy8miJz9a7A
|
54
|
+
/3M8q0cGvSF3Rw+OwpW/aEGMi+l2OlU27ykFuyukRAac9m296RwnbF79TO2M5ylO
|
55
|
+
6a5zb5ROXlWP6RbE96b4DlIidssQJqegmHwlEC+rsrVBpOtb0aThlYEyOxzMOGyP
|
56
|
+
wOR9l8rDAoGADZ4TUHFM6VrvPlUZBkGbqiyXH9IM/y9JWk+22JQCEGnM6RFZemSs
|
57
|
+
jxWqQiPAdJtb3xKryJSCMtFPH9azedoCrSgaMflJ1QgoXgpiKZyoEXWraVUggh/0
|
58
|
+
CEavgZcTZ6SvMuayqJdGGB+zb1V8XwXMtCjApR/kTm47DjxO4DmpOPs=
|
59
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require './spec/support/simplecov_quality_formatter'
|
3
|
+
|
4
|
+
module SimpleCovHelper
|
5
|
+
def start_simple_cov(name)
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter '/spec/'
|
8
|
+
add_filter '/lib/generators'
|
9
|
+
command_name name
|
10
|
+
formatter SimpleCov::Formatter::QualityFormatter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/spec/tmp/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns::App do
|
4
|
+
it 'does not validate an app with an invalid certificate' do
|
5
|
+
app = Rapns::Apns::App.new(:name => 'test', :environment => 'development', :certificate => 'foo')
|
6
|
+
app.valid?
|
7
|
+
app.errors[:certificate].should == 'Certificate value must contain a certificate and a private key.'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'validates a certificate without a password' do
|
11
|
+
app = Rapns::Apns::App.new :name => 'test', :environment => 'development', :certificate => TEST_CERT
|
12
|
+
app.valid?
|
13
|
+
app.errors[:certificate].should be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'validates a certificate with a password' do
|
17
|
+
app = Rapns::Apns::App.new :name => 'test', :environment => 'development',
|
18
|
+
:certificate => TEST_CERT_WITH_PASSWORD, :password => 'fubar'
|
19
|
+
app.valid?
|
20
|
+
app.errors[:certificate].should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'validates a certificate with an incorrect password' do
|
24
|
+
app = Rapns::Apns::App.new :name => 'test', :environment => 'development',
|
25
|
+
:certificate => TEST_CERT_WITH_PASSWORD, :password => 'incorrect'
|
26
|
+
app.valid?
|
27
|
+
app.errors[:certificate].should == "Certificate value must contain a certificate and a private key."
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns::Apns::Feedback do
|
4
|
+
it "should validate the format of the device_token" do
|
5
|
+
notification = Rapns::Apns::Feedback.new(:device_token => "{$%^&*()}")
|
6
|
+
notification.valid?.should be_false
|
7
|
+
notification.errors[:device_token].include?("is invalid").should be_true
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# encoding: US-ASCII
|
2
|
+
|
3
|
+
require File.expand_path("spec/unit_spec_helper")
|
4
|
+
require 'spec/unit/notification_shared.rb'
|
5
|
+
|
6
|
+
describe Rapns::Apns::Notification do
|
7
|
+
it_should_behave_like 'an Notification subclass'
|
8
|
+
|
9
|
+
let(:notification_class) { Rapns::Apns::Notification }
|
10
|
+
let(:notification) { notification_class.new }
|
11
|
+
let(:data_setter) { 'attributes_for_device=' }
|
12
|
+
let(:data_getter) { 'attributes_for_device' }
|
13
|
+
|
14
|
+
it "should validate the format of the device_token" do
|
15
|
+
notification = Rapns::Apns::Notification.new(:device_token => "{$%^&*()}")
|
16
|
+
notification.valid?.should be_false
|
17
|
+
notification.errors[:device_token].include?("is invalid").should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should validate the length of the binary conversion of the notification" do
|
21
|
+
notification.device_token = "a" * 64
|
22
|
+
notification.alert = "way too long!" * 100
|
23
|
+
notification.valid?.should be_false
|
24
|
+
notification.errors[:base].include?("APN notification cannot be larger than 256 bytes. Try condensing your alert and device attributes.").should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should default the sound to 'default'" do
|
28
|
+
notification.sound.should == 'default'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should default the expiry to 1 day" do
|
32
|
+
notification.expiry.should == 1.day.to_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe Rapns::Apns::Notification, "when assigning the device token" do
|
37
|
+
it "should strip spaces from the given string" do
|
38
|
+
notification = Rapns::Apns::Notification.new(:device_token => "o m g")
|
39
|
+
notification.device_token.should == "omg"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should strip chevrons from the given string" do
|
43
|
+
notification = Rapns::Apns::Notification.new(:device_token => "<omg>")
|
44
|
+
notification.device_token.should == "omg"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe Rapns::Apns::Notification, "as_json" do
|
49
|
+
it "should include the alert if present" do
|
50
|
+
notification = Rapns::Apns::Notification.new(:alert => "hi mom")
|
51
|
+
notification.as_json["aps"]["alert"].should == "hi mom"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should not include the alert key if the alert is not present" do
|
55
|
+
notification = Rapns::Apns::Notification.new(:alert => nil)
|
56
|
+
notification.as_json["aps"].key?("alert").should be_false
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should encode the alert as JSON if it is a Hash" do
|
60
|
+
notification = Rapns::Apns::Notification.new(:alert => { 'body' => "hi mom", 'alert-loc-key' => "View" })
|
61
|
+
notification.as_json["aps"]["alert"].should == { 'body' => "hi mom", 'alert-loc-key' => "View" }
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should include the badge if present" do
|
65
|
+
notification = Rapns::Apns::Notification.new(:badge => 6)
|
66
|
+
notification.as_json["aps"]["badge"].should == 6
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not include the badge key if the badge is not present" do
|
70
|
+
notification = Rapns::Apns::Notification.new(:badge => nil)
|
71
|
+
notification.as_json["aps"].key?("badge").should be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should include the sound if present" do
|
75
|
+
notification = Rapns::Apns::Notification.new(:alert => "my_sound.aiff")
|
76
|
+
notification.as_json["aps"]["alert"].should == "my_sound.aiff"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not include the sound key if the sound is not present" do
|
80
|
+
notification = Rapns::Apns::Notification.new(:sound => false)
|
81
|
+
notification.as_json["aps"].key?("sound").should be_false
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should include attributes for the device" do
|
85
|
+
notification = Rapns::Apns::Notification.new
|
86
|
+
notification.attributes_for_device = {:omg => :lol, :wtf => :dunno}
|
87
|
+
notification.as_json["omg"].should == "lol"
|
88
|
+
notification.as_json["wtf"].should == "dunno"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should allow attributes to include a hash" do
|
92
|
+
notification = Rapns::Apns::Notification.new
|
93
|
+
notification.attributes_for_device = {:omg => {:ilike => :hashes}}
|
94
|
+
notification.as_json["omg"]["ilike"].should == "hashes"
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe Rapns::Apns::Notification, 'MDM' do
|
100
|
+
let(:magic) { 'abc123' }
|
101
|
+
let(:notification) { Rapns::Apns::Notification.new }
|
102
|
+
|
103
|
+
it 'includes the mdm magic in the payload' do
|
104
|
+
notification.mdm = magic
|
105
|
+
notification.as_json.should == {'mdm' => magic}
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'does not include aps attribute' do
|
109
|
+
notification.alert = "i'm doomed"
|
110
|
+
notification.mdm = magic
|
111
|
+
notification.as_json.key?('aps').should be_false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe Rapns::Apns::Notification, 'content-available' do
|
116
|
+
let(:notification) { Rapns::Apns::Notification.new }
|
117
|
+
|
118
|
+
it 'includes content-available in the payload' do
|
119
|
+
notification.content_available = true
|
120
|
+
notification.as_json['aps']['content-available'].should == 1
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'does not include content-available in the payload if not set' do
|
124
|
+
notification.as_json['aps'].key?('content-available').should be_false
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'does not include content-available as a non-aps attribute' do
|
128
|
+
notification.content_available = true
|
129
|
+
notification.as_json.key?('content-available').should be_false
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'does not overwrite existing attributes for the device' do
|
133
|
+
notification.data = {:hi => :mom}
|
134
|
+
notification.content_available = true
|
135
|
+
notification.as_json['aps']['content-available'].should == 1
|
136
|
+
notification.as_json['hi'].should == 'mom'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'does not overwrite the content-available flag when setting attributes for the device' do
|
140
|
+
notification.content_available = true
|
141
|
+
notification.data = {:hi => :mom}
|
142
|
+
notification.as_json['aps']['content-available'].should == 1
|
143
|
+
notification.as_json['hi'].should == 'mom'
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe Rapns::Apns::Notification, "to_binary" do
|
149
|
+
it "should correctly convert the notification to binary" do
|
150
|
+
notification = Rapns::Apns::Notification.new
|
151
|
+
notification.device_token = "a" * 64
|
152
|
+
notification.sound = "1.aiff"
|
153
|
+
notification.badge = 3
|
154
|
+
notification.alert = "Don't panic Mr Mainwaring, don't panic!"
|
155
|
+
notification.attributes_for_device = {:hi => :mom}
|
156
|
+
notification.expiry = 86400 # 1 day, \x00\x01Q\x80
|
157
|
+
notification.app = Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT)
|
158
|
+
notification.save!
|
159
|
+
notification.stub(:id).and_return(1234)
|
160
|
+
notification.to_binary.should == "\x01\x00\x00\x04\xD2\x00\x01Q\x80\x00 \xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\x00a{\"aps\":{\"alert\":\"Don't panic Mr Mainwaring, don't panic!\",\"badge\":3,\"sound\":\"1.aiff\"},\"hi\":\"mom\"}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe Rapns::Apns::Notification, "bug #31" do
|
165
|
+
it 'does not confuse a JSON looking string as JSON' do
|
166
|
+
notification = Rapns::Apns::Notification.new
|
167
|
+
notification.alert = "{\"one\":2}"
|
168
|
+
notification.alert.should == "{\"one\":2}"
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'does confuse a JSON looking string as JSON if the alert_is_json attribute is not present' do
|
172
|
+
notification = Rapns::Apns::Notification.new
|
173
|
+
notification.stub(:has_attribute? => false)
|
174
|
+
notification.alert = "{\"one\":2}"
|
175
|
+
notification.alert.should == {"one" => 2}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe Rapns::Apns::Notification, "bug #35" do
|
180
|
+
it "should limit payload size to 256 bytes but not the entire packet" do
|
181
|
+
notification = Rapns::Apns::Notification.new do |n|
|
182
|
+
n.device_token = "a" * 64
|
183
|
+
n.alert = "a" * 210
|
184
|
+
n.app = Rapns::Apns::App.create!(:name => 'my_app', :environment => 'development', :certificate => TEST_CERT)
|
185
|
+
end
|
186
|
+
|
187
|
+
notification.to_binary(:for_validation => true).bytesize.should > 256
|
188
|
+
notification.payload_size.should < 256
|
189
|
+
notification.should be_valid
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe Rapns::Apns::Notification, "multi_json usage" do
|
194
|
+
describe Rapns::Apns::Notification, "alert" do
|
195
|
+
it "should call MultiJson.load when multi_json version is 1.3.0" do
|
196
|
+
Object.stub_constants(:MultiJson => mock) do
|
197
|
+
MultiJson.should_receive(:encode).with(any_args())
|
198
|
+
MultiJson.should_receive(:load).with(any_args())
|
199
|
+
notification = Rapns::Apns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
|
200
|
+
Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.3.0') } )
|
201
|
+
notification.alert
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should call MultiJson.decode when multi_json version is 1.2.9" do
|
206
|
+
Object.stub_constants(:MultiJson => mock) do
|
207
|
+
MultiJson.should_receive(:encode).with(any_args())
|
208
|
+
MultiJson.should_receive(:decode).with(any_args())
|
209
|
+
notification = Rapns::Apns::Notification.new(:alert => { :a => 1 }, :alert_is_json => true)
|
210
|
+
Gem.stub(:loaded_specs).and_return( { 'multi_json' => Gem::Specification.new('multi_json', '1.2.9') } )
|
211
|
+
notification.alert
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns, 'apns_feedback' do
|
4
|
+
let!(:app) { Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT) }
|
5
|
+
let(:receiver) { double(:check_for_feedback => nil) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'initializes the store' do
|
12
|
+
Rapns::Daemon.should_receive(:initialize_store)
|
13
|
+
Rapns.apns_feedback
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'checks feedback for each app' do
|
17
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 0).and_return(receiver)
|
18
|
+
receiver.should_receive(:check_for_feedback)
|
19
|
+
Rapns.apns_feedback
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns::App do
|
4
|
+
it 'validates the uniqueness of name within type and environment' do
|
5
|
+
Rapns::Apns::App.create!(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
|
6
|
+
app = Rapns::Apns::App.new(:name => 'test', :environment => 'production', :certificate => TEST_CERT)
|
7
|
+
app.valid?.should be_false
|
8
|
+
app.errors[:name].should == 'has already been taken'
|
9
|
+
|
10
|
+
app = Rapns::Apns::App.new(:name => 'test', :environment => 'development', :certificate => TEST_CERT)
|
11
|
+
app.valid?.should be_true
|
12
|
+
|
13
|
+
app = Rapns::Gcm::App.new(:name => 'test', :environment => 'production', :auth_key => TEST_CERT)
|
14
|
+
app.valid?.should be_true
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns do
|
4
|
+
let(:config) { double }
|
5
|
+
|
6
|
+
before { Rapns.stub(:config => config) }
|
7
|
+
|
8
|
+
it 'can yields a config block' do
|
9
|
+
yielded_args = nil
|
10
|
+
Rapns.configure do |*a| yielded_args = a end
|
11
|
+
yielded_args.should == [config]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Rapns::Configuration do
|
16
|
+
let(:config) do
|
17
|
+
Rapns::Deprecation.muted do
|
18
|
+
Rapns::Configuration.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'configures a feedback callback' do
|
23
|
+
b = Proc.new {}
|
24
|
+
Rapns::Deprecation.muted do
|
25
|
+
config.on_apns_feedback(&b)
|
26
|
+
end
|
27
|
+
config.apns_feedback_callback.should == b
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'can be updated' do
|
31
|
+
Rapns::Deprecation.muted do
|
32
|
+
new_config = Rapns::Configuration.new
|
33
|
+
new_config.batch_size = 100
|
34
|
+
expect { config.update(new_config) }.to change(config, :batch_size).to(100)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'sets the pid_file relative if not absolute' do
|
39
|
+
Rails.stub(:root => '/rails')
|
40
|
+
config.pid_file = 'tmp/rapns.pid'
|
41
|
+
config.pid_file.should == '/rails/tmp/rapns.pid'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'does not alter an absolute pid_file path' do
|
45
|
+
config.pid_file = '/tmp/rapns.pid'
|
46
|
+
config.pid_file.should == '/tmp/rapns.pid'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not allow foreground to be set to false if the platform is JRuby' do
|
50
|
+
config.foreground = true
|
51
|
+
Rapns.stub(:jruby? => true)
|
52
|
+
config.foreground = false
|
53
|
+
config.foreground.should be_true
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
require File.dirname(__FILE__) + '/../app_runner_shared.rb'
|
3
|
+
|
4
|
+
describe Rapns::Daemon::Apns::AppRunner do
|
5
|
+
it_should_behave_like 'an AppRunner subclass'
|
6
|
+
|
7
|
+
let(:app_class) { Rapns::Apns::App }
|
8
|
+
let(:app) { app_class.create!(:name => 'my_app', :environment => 'development',
|
9
|
+
:certificate => TEST_CERT, :password => 'pass') }
|
10
|
+
let(:runner) { Rapns::Daemon::Apns::AppRunner.new(app) }
|
11
|
+
let(:handler) { double(:start => nil, :queue= => nil, :wakeup => nil, :wait => nil, :stop => nil) }
|
12
|
+
let(:handler_collection) { double(:handler_collection, :push => nil, :size => 1, :stop => nil) }
|
13
|
+
let(:receiver) { double(:start => nil, :stop => nil) }
|
14
|
+
let(:config) { double(:feedback_poll => 60, :push => false) }
|
15
|
+
let(:logger) { double(:info => nil, :warn => nil, :error => nil) }
|
16
|
+
|
17
|
+
before do
|
18
|
+
Rapns.stub(:logger => logger, :config => config)
|
19
|
+
Rapns::Daemon::Apns::DeliveryHandler.stub(:new => handler)
|
20
|
+
Rapns::Daemon::DeliveryHandlerCollection.stub(:new => handler_collection)
|
21
|
+
Rapns::Daemon::Apns::FeedbackReceiver.stub(:new => receiver)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'instantiates a new feedback receiver when started' do
|
25
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_receive(:new).with(app, 60)
|
26
|
+
runner.start
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'starts the feedback receiver' do
|
30
|
+
receiver.should_receive(:start)
|
31
|
+
runner.start
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'stops the feedback receiver' do
|
35
|
+
runner.start
|
36
|
+
receiver.should_receive(:stop)
|
37
|
+
runner.stop
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'does not check for feedback when in push mode' do
|
41
|
+
config.stub(:push => true)
|
42
|
+
Rapns::Daemon::Apns::FeedbackReceiver.should_not_receive(:new)
|
43
|
+
runner.start
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path("spec/unit_spec_helper")
|
2
|
+
|
3
|
+
describe Rapns::Apns::CertificateExpiredError do
|
4
|
+
let(:app) { double(:name => 'test') }
|
5
|
+
let(:error) { Rapns::Apns::CertificateExpiredError.new(app, Time.now) }
|
6
|
+
|
7
|
+
it 'returns a message' do
|
8
|
+
error.message
|
9
|
+
error.to_s
|
10
|
+
end
|
11
|
+
end
|