rpush 1.0.0-java

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.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +99 -0
  3. data/LICENSE +7 -0
  4. data/README.md +189 -0
  5. data/bin/rpush +36 -0
  6. data/config/database.yml +44 -0
  7. data/lib/generators/rpush_generator.rb +44 -0
  8. data/lib/generators/templates/add_adm.rb +23 -0
  9. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
  10. data/lib/generators/templates/add_app_to_rapns.rb +11 -0
  11. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +9 -0
  12. data/lib/generators/templates/add_gcm.rb +102 -0
  13. data/lib/generators/templates/add_rpush.rb +349 -0
  14. data/lib/generators/templates/add_wpns.rb +16 -0
  15. data/lib/generators/templates/create_rapns_apps.rb +16 -0
  16. data/lib/generators/templates/create_rapns_feedback.rb +18 -0
  17. data/lib/generators/templates/create_rapns_notifications.rb +29 -0
  18. data/lib/generators/templates/rename_rapns_to_rpush.rb +63 -0
  19. data/lib/generators/templates/rpush.rb +104 -0
  20. data/lib/rpush/TODO +3 -0
  21. data/lib/rpush/adm/app.rb +15 -0
  22. data/lib/rpush/adm/data_validator.rb +11 -0
  23. data/lib/rpush/adm/notification.rb +29 -0
  24. data/lib/rpush/apns/app.rb +29 -0
  25. data/lib/rpush/apns/binary_notification_validator.rb +12 -0
  26. data/lib/rpush/apns/device_token_format_validator.rb +12 -0
  27. data/lib/rpush/apns/feedback.rb +16 -0
  28. data/lib/rpush/apns/notification.rb +84 -0
  29. data/lib/rpush/apns_feedback.rb +13 -0
  30. data/lib/rpush/app.rb +18 -0
  31. data/lib/rpush/configuration.rb +75 -0
  32. data/lib/rpush/daemon/adm/delivery.rb +222 -0
  33. data/lib/rpush/daemon/adm.rb +9 -0
  34. data/lib/rpush/daemon/apns/certificate_expired_error.rb +20 -0
  35. data/lib/rpush/daemon/apns/delivery.rb +64 -0
  36. data/lib/rpush/daemon/apns/disconnection_error.rb +20 -0
  37. data/lib/rpush/daemon/apns/feedback_receiver.rb +79 -0
  38. data/lib/rpush/daemon/apns.rb +16 -0
  39. data/lib/rpush/daemon/app_runner.rb +187 -0
  40. data/lib/rpush/daemon/batch.rb +115 -0
  41. data/lib/rpush/daemon/constants.rb +59 -0
  42. data/lib/rpush/daemon/delivery.rb +28 -0
  43. data/lib/rpush/daemon/delivery_error.rb +19 -0
  44. data/lib/rpush/daemon/dispatcher/http.rb +21 -0
  45. data/lib/rpush/daemon/dispatcher/tcp.rb +30 -0
  46. data/lib/rpush/daemon/dispatcher_loop.rb +54 -0
  47. data/lib/rpush/daemon/dispatcher_loop_collection.rb +33 -0
  48. data/lib/rpush/daemon/feeder.rb +68 -0
  49. data/lib/rpush/daemon/gcm/delivery.rb +222 -0
  50. data/lib/rpush/daemon/gcm.rb +9 -0
  51. data/lib/rpush/daemon/interruptible_sleep.rb +61 -0
  52. data/lib/rpush/daemon/loggable.rb +31 -0
  53. data/lib/rpush/daemon/reflectable.rb +13 -0
  54. data/lib/rpush/daemon/retry_header_parser.rb +23 -0
  55. data/lib/rpush/daemon/retryable_error.rb +20 -0
  56. data/lib/rpush/daemon/service_config_methods.rb +33 -0
  57. data/lib/rpush/daemon/store/active_record/reconnectable.rb +68 -0
  58. data/lib/rpush/daemon/store/active_record.rb +154 -0
  59. data/lib/rpush/daemon/tcp_connection.rb +143 -0
  60. data/lib/rpush/daemon/too_many_requests_error.rb +20 -0
  61. data/lib/rpush/daemon/wpns/delivery.rb +132 -0
  62. data/lib/rpush/daemon/wpns.rb +9 -0
  63. data/lib/rpush/daemon.rb +140 -0
  64. data/lib/rpush/deprecatable.rb +23 -0
  65. data/lib/rpush/deprecation.rb +23 -0
  66. data/lib/rpush/embed.rb +28 -0
  67. data/lib/rpush/gcm/app.rb +11 -0
  68. data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +11 -0
  69. data/lib/rpush/gcm/notification.rb +30 -0
  70. data/lib/rpush/logger.rb +63 -0
  71. data/lib/rpush/multi_json_helper.rb +16 -0
  72. data/lib/rpush/notification.rb +69 -0
  73. data/lib/rpush/notifier.rb +52 -0
  74. data/lib/rpush/payload_data_size_validator.rb +10 -0
  75. data/lib/rpush/push.rb +16 -0
  76. data/lib/rpush/railtie.rb +11 -0
  77. data/lib/rpush/reflection.rb +58 -0
  78. data/lib/rpush/registration_ids_count_validator.rb +10 -0
  79. data/lib/rpush/version.rb +3 -0
  80. data/lib/rpush/wpns/app.rb +9 -0
  81. data/lib/rpush/wpns/notification.rb +26 -0
  82. data/lib/rpush.rb +62 -0
  83. data/lib/tasks/cane.rake +18 -0
  84. data/lib/tasks/rpush.rake +16 -0
  85. data/lib/tasks/test.rake +38 -0
  86. data/spec/functional/adm_spec.rb +43 -0
  87. data/spec/functional/apns_spec.rb +58 -0
  88. data/spec/functional/embed_spec.rb +49 -0
  89. data/spec/functional/gcm_spec.rb +42 -0
  90. data/spec/functional/wpns_spec.rb +41 -0
  91. data/spec/support/cert_with_password.pem +90 -0
  92. data/spec/support/cert_without_password.pem +59 -0
  93. data/spec/support/install.sh +32 -0
  94. data/spec/support/simplecov_helper.rb +20 -0
  95. data/spec/support/simplecov_quality_formatter.rb +8 -0
  96. data/spec/tmp/.gitkeep +0 -0
  97. data/spec/unit/adm/app_spec.rb +58 -0
  98. data/spec/unit/adm/notification_spec.rb +45 -0
  99. data/spec/unit/apns/app_spec.rb +29 -0
  100. data/spec/unit/apns/feedback_spec.rb +9 -0
  101. data/spec/unit/apns/notification_spec.rb +208 -0
  102. data/spec/unit/apns_feedback_spec.rb +21 -0
  103. data/spec/unit/app_spec.rb +30 -0
  104. data/spec/unit/configuration_spec.rb +45 -0
  105. data/spec/unit/daemon/adm/delivery_spec.rb +243 -0
  106. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
  107. data/spec/unit/daemon/apns/delivery_spec.rb +101 -0
  108. data/spec/unit/daemon/apns/disconnection_error_spec.rb +18 -0
  109. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +117 -0
  110. data/spec/unit/daemon/app_runner_spec.rb +292 -0
  111. data/spec/unit/daemon/batch_spec.rb +232 -0
  112. data/spec/unit/daemon/delivery_error_spec.rb +13 -0
  113. data/spec/unit/daemon/delivery_spec.rb +38 -0
  114. data/spec/unit/daemon/dispatcher/http_spec.rb +33 -0
  115. data/spec/unit/daemon/dispatcher/tcp_spec.rb +38 -0
  116. data/spec/unit/daemon/dispatcher_loop_collection_spec.rb +37 -0
  117. data/spec/unit/daemon/dispatcher_loop_spec.rb +71 -0
  118. data/spec/unit/daemon/feeder_spec.rb +98 -0
  119. data/spec/unit/daemon/gcm/delivery_spec.rb +310 -0
  120. data/spec/unit/daemon/interruptible_sleep_spec.rb +68 -0
  121. data/spec/unit/daemon/reflectable_spec.rb +27 -0
  122. data/spec/unit/daemon/retryable_error_spec.rb +14 -0
  123. data/spec/unit/daemon/service_config_methods_spec.rb +33 -0
  124. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +114 -0
  125. data/spec/unit/daemon/store/active_record_spec.rb +357 -0
  126. data/spec/unit/daemon/tcp_connection_spec.rb +287 -0
  127. data/spec/unit/daemon/too_many_requests_error_spec.rb +14 -0
  128. data/spec/unit/daemon/wpns/delivery_spec.rb +159 -0
  129. data/spec/unit/daemon_spec.rb +159 -0
  130. data/spec/unit/deprecatable_spec.rb +32 -0
  131. data/spec/unit/deprecation_spec.rb +15 -0
  132. data/spec/unit/embed_spec.rb +50 -0
  133. data/spec/unit/gcm/app_spec.rb +4 -0
  134. data/spec/unit/gcm/notification_spec.rb +36 -0
  135. data/spec/unit/logger_spec.rb +127 -0
  136. data/spec/unit/notification_shared.rb +105 -0
  137. data/spec/unit/notification_spec.rb +15 -0
  138. data/spec/unit/notifier_spec.rb +49 -0
  139. data/spec/unit/push_spec.rb +43 -0
  140. data/spec/unit/reflection_spec.rb +30 -0
  141. data/spec/unit/rpush_spec.rb +9 -0
  142. data/spec/unit/wpns/app_spec.rb +4 -0
  143. data/spec/unit/wpns/notification_spec.rb +30 -0
  144. data/spec/unit_spec_helper.rb +101 -0
  145. metadata +304 -0
@@ -0,0 +1,50 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush, 'embed' do
4
+ before do
5
+ Rpush::Daemon.stub(:start)
6
+ Kernel.stub(:at_exit)
7
+ end
8
+
9
+ it 'sets the embedded config option to true' do
10
+ Rpush.embed
11
+ Rpush.config.embedded.should be_true
12
+ end
13
+
14
+ it 'starts the daemon' do
15
+ Rpush::Daemon.should_receive(:start)
16
+ Rpush.embed
17
+ end
18
+
19
+ it 'overrides the default config options with those given as a hash' do
20
+ Rpush.config.push_poll = 4
21
+ expect { Rpush.embed(:push_poll => 2) }.to change(Rpush.config, :push_poll).to(2)
22
+ end
23
+ end
24
+
25
+ describe Rpush, 'shutdown' do
26
+ before { Rpush.config.embedded = true }
27
+
28
+ it 'shuts down the daemon' do
29
+ Rpush::Daemon.should_receive(:shutdown)
30
+ Rpush.shutdown
31
+ end
32
+ end
33
+
34
+ describe Rpush, 'sync' do
35
+ before { Rpush.config.embedded = true }
36
+
37
+ it 'syncs the AppRunner' do
38
+ Rpush::Daemon::AppRunner.should_receive(:sync)
39
+ Rpush.sync
40
+ end
41
+ end
42
+
43
+ describe Rpush, 'debug' do
44
+ before { Rpush.config.embedded = true }
45
+
46
+ it 'debugs the AppRunner' do
47
+ Rpush::Daemon::AppRunner.should_receive(:debug)
48
+ Rpush.debug
49
+ end
50
+ end
@@ -0,0 +1,4 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Gcm::App do
4
+ end
@@ -0,0 +1,36 @@
1
+ require 'unit_spec_helper'
2
+ require 'unit/notification_shared.rb'
3
+
4
+ describe Rpush::Gcm::Notification do
5
+ it_should_behave_like 'an Notification subclass'
6
+
7
+ let(:app) { Rpush::Gcm::App.create!(:name => 'test', :auth_key => 'abc') }
8
+ let(:notification_class) { Rpush::Gcm::Notification }
9
+ let(:notification) { notification_class.new }
10
+ let(:data_setter) { 'data=' }
11
+ let(:data_getter) { 'data' }
12
+
13
+ it "has a 'data' payload limit of 4096 bytes" do
14
+ notification.data = { :key => "a" * 4096 }
15
+ notification.valid?.should be_false
16
+ notification.errors[:base].should eq ["Notification payload data cannot be larger than 4096 bytes."]
17
+ end
18
+
19
+ it 'limits the number of registration ids to 1000' do
20
+ notification.registration_ids = ['a']*(1000+1)
21
+ notification.valid?.should be_false
22
+ notification.errors[:base].should eq ["Number of registration_ids cannot be larger than 1000."]
23
+ end
24
+
25
+ it 'validates expiry is present if collapse_key is set' do
26
+ notification.collapse_key = 'test'
27
+ notification.expiry = nil
28
+ notification.valid?.should be_false
29
+ notification.errors[:expiry].should eq ['must be set when using a collapse_key']
30
+ end
31
+
32
+ it 'includes time_to_live in the payload' do
33
+ notification.expiry = 100
34
+ notification.as_json['time_to_live'].should eq 100
35
+ end
36
+ end
@@ -0,0 +1,127 @@
1
+ require "unit_spec_helper"
2
+
3
+ module Rails
4
+ def self.logger
5
+ @logger
6
+ end
7
+
8
+ def self.logger=(logger)
9
+ @logger = logger
10
+ end
11
+ end
12
+
13
+ module HoptoadNotifier
14
+ def self.notify(e)
15
+ end
16
+ end
17
+
18
+ describe Rpush::Logger do
19
+ let(:log) { double(:sync= => true) }
20
+
21
+ before do
22
+ Rails.stub(:root).and_return("/rails_root")
23
+
24
+ @logger_class = if defined?(ActiveSupport::BufferedLogger)
25
+ ActiveSupport::BufferedLogger
26
+ else
27
+ ActiveSupport::Logger
28
+ end
29
+
30
+ @logger = double(@logger_class.name, :info => nil, :error => nil, :level => 0, :auto_flushing => 1, :auto_flushing= => nil)
31
+ @logger_class.stub(:new).and_return(@logger)
32
+ Rails.logger = @logger
33
+ File.stub(:open => log)
34
+ FileUtils.stub(:mkdir_p => nil)
35
+ STDERR.stub(:puts)
36
+ end
37
+
38
+ it "disables logging if the log file cannot be opened" do
39
+ File.stub(:open).and_raise(Errno::ENOENT)
40
+ STDERR.should_receive(:puts).with(/No such file or directory/)
41
+ STDERR.should_receive(:puts).with(/Logging disabled/)
42
+ Rpush::Logger.new(:foreground => true)
43
+ end
44
+
45
+ it 'creates the log directory' do
46
+ FileUtils.should_receive(:mkdir_p).with('/rails_root/log')
47
+ Rpush::Logger.new(:foreground => true)
48
+ end
49
+
50
+ it "should open the a log file in the Rails log directory" do
51
+ File.should_receive(:open).with('/rails_root/log/rpush.log', 'a')
52
+ Rpush::Logger.new(:foreground => true)
53
+ end
54
+
55
+ it 'sets sync mode on the log descriptor' do
56
+ log.should_receive(:sync=).with(true)
57
+ Rpush::Logger.new(:foreground => true)
58
+ end
59
+
60
+ it 'uses the user-defined logger' do
61
+ my_logger = double
62
+ Rpush.config.logger = my_logger
63
+ logger = Rpush::Logger.new({})
64
+ my_logger.should_receive(:info)
65
+ logger.info('test')
66
+ end
67
+
68
+ it 'uses ActiveSupport::BufferedLogger if a user-defined logger is not set' do
69
+ if ActiveSupport.const_defined?('BufferedLogger')
70
+ ActiveSupport::BufferedLogger.should_receive(:new).with(log, Rails.logger.level)
71
+ Rpush::Logger.new(:foreground => true)
72
+ end
73
+ end
74
+
75
+ it 'uses ActiveSupport::Logger if BufferedLogger does not exist' do
76
+ stub_const('ActiveSupport::Logger', double)
77
+ ActiveSupport.stub(:const_defined? => false)
78
+ ActiveSupport::Logger.should_receive(:new).with(log, Rails.logger.level)
79
+ Rpush::Logger.new(:foreground => true)
80
+ end
81
+
82
+ it "should print out the msg if running in the foreground" do
83
+ logger = Rpush::Logger.new(:foreground => true)
84
+ STDOUT.should_receive(:puts).with(/hi mom/)
85
+ logger.info("hi mom")
86
+ end
87
+
88
+ it "should not print out the msg if not running in the foreground" do
89
+ logger = Rpush::Logger.new(:foreground => false)
90
+ STDOUT.should_not_receive(:puts).with(/hi mom/)
91
+ logger.info("hi mom")
92
+ end
93
+
94
+ it "should prefix log lines with the current time" do
95
+ now = Time.now
96
+ Time.stub(:now).and_return(now)
97
+ logger = Rpush::Logger.new(:foreground => false)
98
+ @logger.should_receive(:info).with(/#{Regexp.escape("[#{now.to_s(:db)}]")}/)
99
+ logger.info("blah")
100
+ end
101
+
102
+ it "should prefix error logs with the ERROR label" do
103
+ logger = Rpush::Logger.new(:foreground => false)
104
+ @logger.should_receive(:error).with(/#{Regexp.escape("[ERROR]")}/)
105
+ logger.error("eeek")
106
+ end
107
+
108
+ it "should prefix warn logs with the WARNING label" do
109
+ logger = Rpush::Logger.new(:foreground => false)
110
+ @logger.should_receive(:warn).with(/#{Regexp.escape("[WARNING]")}/)
111
+ logger.warn("eeek")
112
+ end
113
+
114
+ it "should handle an Exception instance" do
115
+ e = RuntimeError.new("hi mom")
116
+ e.stub(:backtrace => [])
117
+ logger = Rpush::Logger.new(:foreground => false)
118
+ @logger.should_receive(:error).with(/RuntimeError, hi mom/)
119
+ logger.error(e)
120
+ end
121
+
122
+ it 'defaults auto_flushing to true if the Rails logger does not respond to auto_flushing' do
123
+ rails_logger = double(:info => nil, :error => nil, :level => 0)
124
+ Rails.logger = rails_logger
125
+ @logger.auto_flushing.should be_true
126
+ end
127
+ end
@@ -0,0 +1,105 @@
1
+ shared_examples_for "an Notification subclass" do
2
+ describe "when assigning data for the device" do
3
+ before { Rpush::Deprecation.stub(:warn) }
4
+
5
+ it "calls MultiJson.dump when multi_json responds to :dump" do
6
+ notification = notification_class.new
7
+ MultiJson.stub(:respond_to?).with(:dump).and_return(true)
8
+ MultiJson.should_receive(:dump).with(any_args())
9
+ notification.send(data_setter, { :pirates => 1 })
10
+ end
11
+
12
+ it "calls MultiJson.encode when multi_json does not respond to :dump" do
13
+ notification = notification_class.new
14
+ MultiJson.stub(:respond_to?).with(:dump).and_return(false)
15
+ MultiJson.should_receive(:encode).with(any_args())
16
+ notification.send(data_setter, { :ninjas => 1 })
17
+ end
18
+
19
+ it "raises an ArgumentError if something other than a Hash is assigned" do
20
+ expect do
21
+ notification.send(data_setter, Array.new)
22
+ end.to raise_error(ArgumentError, "must be a Hash")
23
+ end
24
+
25
+ it "encodes the given Hash as JSON" do
26
+ notification.send(data_setter, { :hi => "mom" })
27
+ notification.read_attribute(:data).should eq "{\"hi\":\"mom\"}"
28
+ end
29
+
30
+ it "decodes the JSON when using the reader method" do
31
+ notification.send(data_setter, { :hi => "mom" })
32
+ notification.send(data_getter).should eq ({"hi" => "mom"})
33
+ end
34
+
35
+ describe 'scopes' do
36
+ before do
37
+ Timecop.freeze(Time.now)
38
+
39
+ (@delivered_notification = notification_class.new(:app => app, :delivered => true, :failed => false)).save!(:validate => false)
40
+ (@failed_notification = notification_class.new(:app => app, :delivered => false, :failed => true)).save!(:validate => false)
41
+ (@new_notification = notification_class.new(:app => app, :delivered => false, :failed => false)).save!(:validate => false)
42
+ end
43
+
44
+ after do
45
+ Timecop.return
46
+ end
47
+
48
+ describe '.completed' do
49
+ it 'should return notifications that have been delivered or failed' do
50
+ completed_notification_ids = Rpush::Notification.completed.map(&:id)
51
+
52
+ completed_notification_ids.size.should eq 2
53
+ completed_notification_ids.should include(@delivered_notification.id, @failed_notification.id)
54
+ completed_notification_ids.should_not include(@new_notification.id)
55
+ end
56
+ end
57
+
58
+ describe '.created_before' do
59
+ it 'should return notifications that were created before the specified date' do
60
+ @delivered_notification.created_at = Time.now - 30.days - 1.second
61
+ @delivered_notification.save!(:validate => false)
62
+
63
+ notification_ids = Rpush::Notification.created_before(Time.now - 30.days).map(&:id)
64
+
65
+ notification_ids.size.should eq 1
66
+ notification_ids.should include(@delivered_notification.id)
67
+ end
68
+ end
69
+
70
+ describe '.completed_and_older_than' do
71
+ before do
72
+ @delivered_notification.created_at = Time.now - 30.days - 1.second
73
+ @delivered_notification.save!(:validate => false)
74
+
75
+ @failed_notification.created_at = Time.now - 20.days - 1.second
76
+ @failed_notification.save!(:validate => false)
77
+
78
+ @new_notification.created_at = Time.now - 30.days - 1.second
79
+ @new_notification.save!(:validate => false)
80
+ end
81
+
82
+ it 'should only include completed notifications' do
83
+ notification_ids = Rpush::Notification.completed_and_older_than(Time.now - 30.days).map(&:id)
84
+
85
+ notification_ids.size.should eq 1
86
+ notification_ids.should include(@delivered_notification.id)
87
+ end
88
+
89
+ it 'should not include completed notifications if not older than specified date' do
90
+ notification_ids = Rpush::Notification.completed_and_older_than(Time.now - 30.days).map(&:id)
91
+
92
+ notification_ids.size.should eq 1
93
+ notification_ids.should_not include(@failed_notification.id)
94
+ end
95
+
96
+ it 'should return notifications that are completed and created before the specified date' do
97
+ notification_ids = Rpush::Notification.completed_and_older_than(Time.now - 20.days).map(&:id)
98
+
99
+ notification_ids.size.should eq 2
100
+ notification_ids.should include(@delivered_notification.id, @failed_notification.id)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,15 @@
1
+ require "unit_spec_helper"
2
+
3
+ describe Rpush::Notification do
4
+ let(:notification) { Rpush::Notification.new }
5
+
6
+ it 'allows assignment of many registration IDs' do
7
+ notification.registration_ids = ['a', 'b']
8
+ notification.registration_ids.should eq ['a', 'b']
9
+ end
10
+
11
+ it 'allows assignment of a single registration ID' do
12
+ notification.registration_ids = 'a'
13
+ notification.registration_ids.should eq ['a']
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ require 'unit_spec_helper'
2
+ require 'rpush/notifier'
3
+
4
+ describe Rpush::Notifier do
5
+
6
+ before(:each) { @port = 5000 }
7
+ subject { Rpush::Notifier.new('127.0.0.1', @port) }
8
+ its(:socket) { should_not be_nil }
9
+
10
+ context "when connected" do
11
+ before :each do
12
+ @reader = UDPSocket.new
13
+ @reader.bind('127.0.0.1', 0)
14
+ @port = @reader.addr[1]
15
+ end
16
+
17
+ describe "notify" do
18
+ it "calls write on the socket" do
19
+ UDPSocket.any_instance.should_receive(:write)
20
+ subject.notify
21
+ end
22
+
23
+ it "writes data that can be read from socket" do
24
+ subject.notify
25
+ expect(@reader.recv(1)).to eq 'x'
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "default notifier" do
31
+ it "creates using :connect first" do
32
+ Rpush.config.stub :wakeup => { :connect => '127.0.0.1', :port => 1234 }
33
+ Rpush::Notifier.should_receive(:new).with('127.0.0.1', 1234)
34
+ Rpush.notifier
35
+ end
36
+
37
+ it "creates using :host next" do
38
+ Rpush.config.stub :wakeup => { :host => '127.0.0.1', :port => 1234 }
39
+ Rpush::Notifier.should_receive(:new).with('127.0.0.1', 1234)
40
+ Rpush.notifier
41
+ end
42
+
43
+ it "returns nil when wakeup is not specified" do
44
+ Rpush.config.stub :wakeup => nil
45
+ Rpush::Notifier.should_not_receive(:new)
46
+ expect(Rpush.notifier).to be_nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush, 'push' do
4
+ before do
5
+ Rpush::Daemon::AppRunner.stub(:sync => nil, :wait => nil)
6
+ Rpush::Daemon::Feeder.stub(:start => nil)
7
+ end
8
+
9
+ it 'sets the push config option to true' do
10
+ Rpush.push
11
+ Rpush.config.push.should be_true
12
+ end
13
+
14
+ it 'initializes the store' do
15
+ Rpush::Daemon.should_receive(:initialize_store)
16
+ Rpush.push
17
+ end
18
+
19
+ it 'syncs the app runner' do
20
+ Rpush::Daemon::AppRunner.should_receive(:sync)
21
+ Rpush.push
22
+ end
23
+
24
+ it 'starts the feeder' do
25
+ Rpush::Daemon::Feeder.should_receive(:start)
26
+ Rpush.push
27
+ end
28
+
29
+ it 'waits on the app runner' do
30
+ Rpush::Daemon::AppRunner.should_receive(:wait)
31
+ Rpush.push
32
+ end
33
+
34
+ it 'stops on the app runner' do
35
+ Rpush::Daemon::AppRunner.should_receive(:stop)
36
+ Rpush.push
37
+ end
38
+
39
+ it 'overrides the default config options with those given as a hash' do
40
+ Rpush.config.batch_size = 20
41
+ expect { Rpush.push(:batch_size => 10) }.to change(Rpush.config, :batch_size).to(10)
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush do
4
+ it 'yields reflections for configuration' do
5
+ did_yield = false
6
+ Rpush.reflect { |on| did_yield = true }
7
+ did_yield.should be_true
8
+ end
9
+
10
+ it 'returns all reflections' do
11
+ Rpush.reflections.should be_kind_of(Rpush::Reflections)
12
+ end
13
+ end
14
+
15
+ describe Rpush::Reflections do
16
+ it 'dispatches the given reflection' do
17
+ did_yield = false
18
+ Rpush.reflect do |on|
19
+ on.error { did_yield = true }
20
+ end
21
+ Rpush.reflections.__dispatch(:error)
22
+ did_yield.should be_true
23
+ end
24
+
25
+ it 'raises an error when trying to dispatch and unknown reflection' do
26
+ expect do
27
+ Rpush.reflections.__dispatch(:unknown)
28
+ end.to raise_error(Rpush::Reflections::NoSuchReflectionError)
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush do
4
+ it "lazy initializes the logger" do
5
+ Rpush.config.stub(:foreground => true)
6
+ Rpush::Logger.should_receive(:new).with(:foreground => true)
7
+ Rpush.logger
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'unit_spec_helper'
2
+
3
+ describe Rpush::Wpns::App do
4
+ end
@@ -0,0 +1,30 @@
1
+ require 'unit_spec_helper'
2
+ require 'unit/notification_shared.rb'
3
+
4
+ describe Rpush::Wpns::Notification do
5
+ it_should_behave_like 'an Notification subclass'
6
+ let(:app) { Rpush::Wpns::App.create!(:name => 'test', :auth_key => 'abc') }
7
+ let(:notification_class) { Rpush::Wpns::Notification }
8
+ let(:notification) { notification_class.new }
9
+ let(:data_setter) { 'data=' }
10
+ let(:data_getter) { 'data' }
11
+
12
+ it "should have an url in the uri parameter" do
13
+ notification = Rpush::Wpns::Notification.new(:uri => "somthing")
14
+ notification.valid?
15
+ notification.errors[:uri].include?("is invalid").should be_true
16
+ end
17
+
18
+ it "should be invalid if there's no message" do
19
+ notification = Rpush::Wpns::Notification.new(:alert => "")
20
+ notification.valid?
21
+ notification.errors[:alert].include?("can't be blank").should be_true
22
+ end
23
+ end
24
+
25
+ describe Rpush::Wpns::Notification, "when assigning the url" do
26
+ it "should be a valid url" do
27
+ notification = Rpush::Wpns::Notification.new(:alert => "abc", :uri => "some")
28
+ notification.uri_is_valid?.should be_false
29
+ end
30
+ end
@@ -0,0 +1,101 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
3
+ require 'bundler'
4
+ Bundler.require(:default)
5
+
6
+ require 'active_record'
7
+
8
+ unless ENV['TRAVIS'] && ENV['QUALITY'] == 'false'
9
+ begin
10
+ require './spec/support/simplecov_helper'
11
+ include SimpleCovHelper
12
+ start_simple_cov("unit-#{RUBY_VERSION}")
13
+ rescue LoadError
14
+ puts "Coverage disabled."
15
+ end
16
+ end
17
+
18
+ jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
19
+
20
+ $adapter = ENV['ADAPTER'] || 'postgresql'
21
+ $adapter = 'jdbc' + $adapter if jruby
22
+
23
+ DATABASE_CONFIG = YAML.load_file(File.expand_path("../config/database.yml", File.dirname(__FILE__)))
24
+
25
+ if DATABASE_CONFIG[$adapter].nil?
26
+ puts "No such adapter '#{$adapter}'. Valid adapters are #{DATABASE_CONFIG.keys.join(', ')}."
27
+ exit 1
28
+ end
29
+
30
+ if ENV['TRAVIS']
31
+ DATABASE_CONFIG[$adapter]['username'] = 'postgres'
32
+ else
33
+ require 'etc'
34
+ username = $adapter =~ /mysql/ ? 'root' : Etc.getlogin
35
+ DATABASE_CONFIG[$adapter]['username'] = username
36
+ end
37
+
38
+ puts "Using #{$adapter} adapter."
39
+
40
+ ActiveRecord::Base.configurations = {"test" => DATABASE_CONFIG[$adapter]}
41
+ ActiveRecord::Base.establish_connection(DATABASE_CONFIG[$adapter])
42
+
43
+ require 'generators/templates/add_rpush'
44
+
45
+ migrations = [AddRpush]
46
+
47
+ migrations.reverse.each do |m|
48
+ begin
49
+ m.down
50
+ rescue ActiveRecord::StatementInvalid => e
51
+ p e
52
+ end
53
+ end
54
+
55
+ migrations.each(&:up)
56
+
57
+ require 'database_cleaner'
58
+ DatabaseCleaner.strategy = :truncation
59
+
60
+ require 'rpush'
61
+ require 'rpush/daemon'
62
+
63
+ Rpush::Daemon.initialize_store
64
+ Rpush::Notification.reset_column_information
65
+ Rpush::App.reset_column_information
66
+ Rpush::Apns::Feedback.reset_column_information
67
+
68
+ RSpec.configure do |config|
69
+ # config.before :suite do
70
+ # PerfTools::CpuProfiler.start('/tmp/rpush_profile')
71
+ # end
72
+ # config.after :suite do
73
+ # PerfTools::CpuProfiler.stop
74
+ # end
75
+
76
+ config.before(:each) do
77
+ DatabaseCleaner.clean
78
+ end
79
+
80
+ config.after(:each) do
81
+ Rpush.logger = nil
82
+ Rpush::Daemon.store = nil
83
+ Rpush::Deprecation.muted do
84
+ Rpush.config.set_defaults if Rpush.config.kind_of?(Rpush::Configuration)
85
+ end
86
+ end
87
+ end
88
+
89
+ # a test certificate that contains both an X509 certificate and
90
+ # a private key, similar to those used for connecting to Apple
91
+ # push notification servers.
92
+ #
93
+ # Note that we cannot validate the certificate and private key
94
+ # because we are missing the certificate chain used to validate
95
+ # the certificate, and this is private to Apple. So if the app
96
+ # has a certificate and a private key in it, the only way to find
97
+ # out if it really is valid is to connect to Apple's servers.
98
+
99
+ path = File.join(File.dirname(__FILE__), 'support')
100
+ TEST_CERT = File.read(File.join(path, 'cert_without_password.pem'))
101
+ TEST_CERT_WITH_PASSWORD = File.read(File.join(path, 'cert_with_password.pem'))