rapns_rails_2 3.4.3
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 +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
|