fcm-ruby-push-notifications 1.2.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 +7 -0
- data/.gitignore +37 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +32 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +82 -0
- data/Rakefile +12 -0
- data/examples/apns.rb +27 -0
- data/examples/gcm.rb +25 -0
- data/examples/mpns.rb +22 -0
- data/examples/wns.rb +25 -0
- data/gemfiles/Gemfile-legacy +8 -0
- data/lib/ruby-push-notifications.rb +7 -0
- data/lib/ruby-push-notifications/apns.rb +44 -0
- data/lib/ruby-push-notifications/apns/apns_connection.rb +70 -0
- data/lib/ruby-push-notifications/apns/apns_notification.rb +91 -0
- data/lib/ruby-push-notifications/apns/apns_pusher.rb +84 -0
- data/lib/ruby-push-notifications/apns/apns_results.rb +30 -0
- data/lib/ruby-push-notifications/fcm.rb +8 -0
- data/lib/ruby-push-notifications/fcm/fcm_connection.rb +60 -0
- data/lib/ruby-push-notifications/fcm/fcm_error.rb +17 -0
- data/lib/ruby-push-notifications/fcm/fcm_notification.rb +31 -0
- data/lib/ruby-push-notifications/fcm/fcm_pusher.rb +29 -0
- data/lib/ruby-push-notifications/fcm/fcm_request.rb +28 -0
- data/lib/ruby-push-notifications/fcm/fcm_response.rb +89 -0
- data/lib/ruby-push-notifications/fcm/fcm_result.rb +52 -0
- data/lib/ruby-push-notifications/gcm.rb +6 -0
- data/lib/ruby-push-notifications/gcm/gcm_connection.rb +54 -0
- data/lib/ruby-push-notifications/gcm/gcm_error.rb +17 -0
- data/lib/ruby-push-notifications/gcm/gcm_notification.rb +31 -0
- data/lib/ruby-push-notifications/gcm/gcm_pusher.rb +35 -0
- data/lib/ruby-push-notifications/gcm/gcm_response.rb +89 -0
- data/lib/ruby-push-notifications/gcm/gcm_result.rb +52 -0
- data/lib/ruby-push-notifications/mpns.rb +5 -0
- data/lib/ruby-push-notifications/mpns/mpns_connection.rb +87 -0
- data/lib/ruby-push-notifications/mpns/mpns_notification.rb +94 -0
- data/lib/ruby-push-notifications/mpns/mpns_pusher.rb +33 -0
- data/lib/ruby-push-notifications/mpns/mpns_response.rb +82 -0
- data/lib/ruby-push-notifications/mpns/mpns_result.rb +182 -0
- data/lib/ruby-push-notifications/notification_results_manager.rb +14 -0
- data/lib/ruby-push-notifications/wns.rb +6 -0
- data/lib/ruby-push-notifications/wns/wns_access.rb +82 -0
- data/lib/ruby-push-notifications/wns/wns_connection.rb +97 -0
- data/lib/ruby-push-notifications/wns/wns_notification.rb +101 -0
- data/lib/ruby-push-notifications/wns/wns_pusher.rb +32 -0
- data/lib/ruby-push-notifications/wns/wns_response.rb +83 -0
- data/lib/ruby-push-notifications/wns/wns_result.rb +208 -0
- data/ruby-push-notifications.gemspec +28 -0
- data/spec/factories.rb +17 -0
- data/spec/factories/notifications.rb +30 -0
- data/spec/ruby-push-notifications/apns/apns_connection_spec.rb +92 -0
- data/spec/ruby-push-notifications/apns/apns_notification_spec.rb +42 -0
- data/spec/ruby-push-notifications/apns/apns_pusher_spec.rb +295 -0
- data/spec/ruby-push-notifications/gcm/gcm_connection_spec.rb +46 -0
- data/spec/ruby-push-notifications/gcm/gcm_notification_spec.rb +37 -0
- data/spec/ruby-push-notifications/gcm/gcm_pusher_spec.rb +45 -0
- data/spec/ruby-push-notifications/gcm/gcm_response_spec.rb +82 -0
- data/spec/ruby-push-notifications/mpns/mpns_connection_spec.rb +46 -0
- data/spec/ruby-push-notifications/mpns/mpns_notification_spec.rb +53 -0
- data/spec/ruby-push-notifications/mpns/mpns_pusher_spec.rb +59 -0
- data/spec/ruby-push-notifications/mpns/mpns_response_spec.rb +64 -0
- data/spec/ruby-push-notifications/wns/wns_access_spec.rb +76 -0
- data/spec/ruby-push-notifications/wns/wns_connection_spec.rb +53 -0
- data/spec/ruby-push-notifications/wns/wns_notification_spec.rb +177 -0
- data/spec/ruby-push-notifications/wns/wns_pusher_spec.rb +58 -0
- data/spec/ruby-push-notifications/wns/wns_response_spec.rb +65 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/dummy.pem +44 -0
- data/spec/support/factory_girl.rb +5 -0
- data/spec/support/results_shared_examples.rb +31 -0
- metadata +249 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
describe WNSConnection do
|
4
|
+
|
5
|
+
describe '::post' do
|
6
|
+
let(:body) { 'abc' }
|
7
|
+
let(:headers) {
|
8
|
+
{
|
9
|
+
'x-wns-notificationstatus' => 'Received',
|
10
|
+
'x-wns-deviceconnectionstatus' => 'Connected',
|
11
|
+
'x-wns-status' => 'Received'
|
12
|
+
}
|
13
|
+
}
|
14
|
+
let(:push_types) { RubyPushNotifications::WNS::WNSConnection::WP_TARGETS }
|
15
|
+
let(:access_token) { 'token' }
|
16
|
+
let(:device_urls) { [generate(:wns_device_url)] }
|
17
|
+
let(:toast_data) { { title: 'Title', message: 'Hello WNS World!', type: :toast } }
|
18
|
+
let(:toast_notification) { build :wns_notification, device_urls: device_urls, data: toast_data }
|
19
|
+
let(:wns_connection) { RubyPushNotifications::WNS::WNSConnection }
|
20
|
+
|
21
|
+
before do
|
22
|
+
stub_request(:post, %r{hk2.notify.windows.com}).
|
23
|
+
to_return status: [200, 'OK'], body: body, headers: headers
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'runs the right request' do
|
27
|
+
WNSConnection.post toast_notification, access_token
|
28
|
+
headers = {
|
29
|
+
wns_connection::CONTENT_TYPE_HEADER => wns_connection::CONTENT_TYPE[:toast],
|
30
|
+
wns_connection::X_WNS_TYPE_HEADER => wns_connection::WP_TARGETS[:toast],
|
31
|
+
wns_connection::CONTENT_LENGTH_HEADER => toast_notification.as_wns_xml.length.to_s,
|
32
|
+
wns_connection::AUTHORIZATION_HEADER => "Bearer #{access_token}",
|
33
|
+
wns_connection::REQUEST_FOR_STATUS_HEADER => 'true'
|
34
|
+
}
|
35
|
+
expect(WebMock).
|
36
|
+
to have_requested(:post, toast_notification.device_urls[0]).
|
37
|
+
with(body: toast_notification.as_wns_xml, headers: headers).
|
38
|
+
once
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns the response encapsulated in a Hash object' do
|
42
|
+
responses = [
|
43
|
+
{ device_url: toast_notification.device_urls[0],
|
44
|
+
headers: headers,
|
45
|
+
code: 200
|
46
|
+
}
|
47
|
+
]
|
48
|
+
expect(WNSConnection.post toast_notification, access_token).to eq WNSResponse.new(responses)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
describe WNSNotification do
|
4
|
+
let(:device_urls) { %w(a b c) }
|
5
|
+
let(:raw_data) { { message: { title: 'Title', message: 'Hello WNS World!'} } }
|
6
|
+
let(:raw_notification) { build :wns_notification, data: raw_data }
|
7
|
+
let(:toast_data) { { title: 'Title', message: 'Hello WNS World!', type: :toast } }
|
8
|
+
let(:toast_notification) { build :wns_notification, device_urls: device_urls, data: toast_data }
|
9
|
+
let(:tile_data) { { message: 'Hello WNS World!', image: 'http://image.com/image.jpg', type: :tile } }
|
10
|
+
let(:tile_notification) { build :wns_notification, device_urls: device_urls, data: tile_data }
|
11
|
+
let(:badge_data) { { value: 10, type: :badge } }
|
12
|
+
let(:badge_notification) { build :wns_notification, device_urls: device_urls, data: badge_data }
|
13
|
+
|
14
|
+
describe 'raw xml' do
|
15
|
+
it 'builds the right wns raw xml' do
|
16
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
17
|
+
xml << '<root><title>Title</title><message>Hello WNS World!</message></root>'
|
18
|
+
expect(raw_notification.as_wns_xml).to eq xml
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'without message' do
|
22
|
+
let(:raw_data) { {} }
|
23
|
+
|
24
|
+
it 'builds the right wns raw xml' do
|
25
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
26
|
+
xml << '<root></root>'
|
27
|
+
expect(raw_notification.as_wns_xml).to eq xml
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'badge xml' do
|
33
|
+
it 'builds the right wns badge xml' do
|
34
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
35
|
+
xml << '<badge value="10"/>'
|
36
|
+
expect(badge_notification.as_wns_xml).to eq xml
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'without value' do
|
40
|
+
let(:badge_data) { { type: :badge } }
|
41
|
+
|
42
|
+
it 'builds the right wns badge xml' do
|
43
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
44
|
+
xml << '<badge value=""/>'
|
45
|
+
expect(badge_notification.as_wns_xml).to eq xml
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'toast xml' do
|
51
|
+
it 'builds the right wns toast xml' do
|
52
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
53
|
+
xml << '<toast>'
|
54
|
+
xml << '<visual>'
|
55
|
+
xml << '<binding template="ToastText02">'
|
56
|
+
xml << '<text id="1">Title</text>'
|
57
|
+
xml << '<text id="2">Hello WNS World!</text>'
|
58
|
+
xml << '</binding>'
|
59
|
+
xml << '</visual>'
|
60
|
+
xml << '</toast>'
|
61
|
+
expect(toast_notification.as_wns_xml).to eq xml
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when params present' do
|
65
|
+
let(:toast_data) { super().merge(param: { var1: 'value1', var2: 'value2'}) }
|
66
|
+
|
67
|
+
it 'builds the right wns toast xml' do
|
68
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
69
|
+
xml << '<toast launch="{"var1":"value1","var2":"value2"}">'
|
70
|
+
xml << '<visual>'
|
71
|
+
xml << '<binding template="ToastText02">'
|
72
|
+
xml << '<text id="1">Title</text>'
|
73
|
+
xml << '<text id="2">Hello WNS World!</text>'
|
74
|
+
xml << '</binding>'
|
75
|
+
xml << '</visual>'
|
76
|
+
xml << '</toast>'
|
77
|
+
expect(toast_notification.as_wns_xml).to eq xml
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when template present' do
|
82
|
+
let(:toast_data) { super().merge(template: 'custom_template') }
|
83
|
+
|
84
|
+
it 'builds the right wns toast xml' do
|
85
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
86
|
+
xml << '<toast>'
|
87
|
+
xml << '<visual>'
|
88
|
+
xml << '<binding template="custom_template">'
|
89
|
+
xml << '<text id="1">Title</text>'
|
90
|
+
xml << '<text id="2">Hello WNS World!</text>'
|
91
|
+
xml << '</binding>'
|
92
|
+
xml << '</visual>'
|
93
|
+
xml << '</toast>'
|
94
|
+
expect(toast_notification.as_wns_xml).to eq xml
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'without title and message' do
|
99
|
+
let(:toast_data) { { type: :toast } }
|
100
|
+
|
101
|
+
it 'builds the right wns toast xml' do
|
102
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
103
|
+
xml << '<toast>'
|
104
|
+
xml << '<visual>'
|
105
|
+
xml << '<binding template="ToastText02">'
|
106
|
+
xml << '<text id="1"></text>'
|
107
|
+
xml << '<text id="2"></text>'
|
108
|
+
xml << '</binding>'
|
109
|
+
xml << '</visual>'
|
110
|
+
xml << '</toast>'
|
111
|
+
expect(toast_notification.as_wns_xml).to eq xml
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'toast xml' do
|
117
|
+
it 'builds the right wns tile xml' do
|
118
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
119
|
+
xml << '<tile>'
|
120
|
+
xml << '<visual>'
|
121
|
+
xml << '<binding template="TileWideImageAndText01">'
|
122
|
+
xml << '<image src="http://image.com/image.jpg"/>'
|
123
|
+
xml << '<text>Hello WNS World!</text>'
|
124
|
+
xml << '</binding>'
|
125
|
+
xml << '</visual>'
|
126
|
+
xml << '</tile>'
|
127
|
+
expect(tile_notification.as_wns_xml).to eq xml
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when template present' do
|
131
|
+
let(:tile_data) { super().merge(template: 'custom_template') }
|
132
|
+
|
133
|
+
it 'builds the right wns toast xml' do
|
134
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
135
|
+
xml << '<tile>'
|
136
|
+
xml << '<visual>'
|
137
|
+
xml << '<binding template="custom_template">'
|
138
|
+
xml << '<image src="http://image.com/image.jpg"/>'
|
139
|
+
xml << '<text>Hello WNS World!</text>'
|
140
|
+
xml << '</binding>'
|
141
|
+
xml << '</visual>'
|
142
|
+
xml << '</tile>'
|
143
|
+
expect(tile_notification.as_wns_xml).to eq xml
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'without image and message' do
|
148
|
+
let(:tile_data) { { type: :tile } }
|
149
|
+
|
150
|
+
it 'builds the right wns toast xml' do
|
151
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
152
|
+
xml << '<tile>'
|
153
|
+
xml << '<visual>'
|
154
|
+
xml << '<binding template="TileWideImageAndText01">'
|
155
|
+
xml << '<image src=""/>'
|
156
|
+
xml << '<text></text>'
|
157
|
+
xml << '</binding>'
|
158
|
+
xml << '</visual>'
|
159
|
+
xml << '</tile>'
|
160
|
+
expect(tile_notification.as_wns_xml).to eq xml
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it_behaves_like 'a proper results manager' do
|
166
|
+
let(:notification) { build :wns_notification }
|
167
|
+
let(:success_count) { 1 }
|
168
|
+
let(:failures_count) { 0 }
|
169
|
+
let(:device_url) { generate :wns_device_url }
|
170
|
+
let(:individual_results) { [WNSResultOK.new(device_url, {})] }
|
171
|
+
let(:results) do
|
172
|
+
WNSResponse.new [{ code: 200, device_url: device_url, headers: {} }]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
describe WNSPusher do
|
4
|
+
let(:access_token) { 'token' }
|
5
|
+
let(:pusher) { WNSPusher.new(access_token) }
|
6
|
+
|
7
|
+
describe '#push' do
|
8
|
+
let(:device_urls) { [generate(:wns_device_url)] }
|
9
|
+
let(:notifications) { build_list(:wns_notification, 2, device_urls: ['http://hk2.notify.windows.com/1'], data: { message: { value1: 'hello' } }).to_a }
|
10
|
+
let(:raw_notification) { build :wns_notification }
|
11
|
+
let(:toast_data) { { title: 'Title', message: 'Hello WNS World!', type: :toast } }
|
12
|
+
let(:toast_notification) { build :wns_notification, device_urls: device_urls, data: toast_data }
|
13
|
+
let(:tile_data) { { message: 'Hello WNS World!', image: 'http://image.com/image.jpg', type: :tile } }
|
14
|
+
let(:tile_notification) { build :wns_notification, device_urls: device_urls, data: tile_data }
|
15
|
+
let(:badge_data) { { value: 10, type: :badge } }
|
16
|
+
let(:badge_notification) { build :wns_notification, device_urls: device_urls, data: badge_data }
|
17
|
+
|
18
|
+
let(:headers) {
|
19
|
+
{
|
20
|
+
'x-wns-notificationstatus' => 'Received',
|
21
|
+
'x-wns-deviceconnectionstatus' => 'Connected',
|
22
|
+
'x-wns-status' => 'Received'
|
23
|
+
}
|
24
|
+
}
|
25
|
+
let(:wns_connection) { RubyPushNotifications::WNS::WNSConnection }
|
26
|
+
let(:response) { [ { device_url: 'http://hk2.notify.windows.com/1', headers: headers, code: 200 } ]}
|
27
|
+
|
28
|
+
before do
|
29
|
+
stub_request(:post, %r{hk2.notify.windows.com}).
|
30
|
+
to_return status: [200, 'OK'], headers: headers
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'submits every notification' do
|
34
|
+
pusher.push [raw_notification, toast_notification, tile_notification, badge_notification]
|
35
|
+
%i(raw toast tile badge).each do |push_type|
|
36
|
+
headers = {
|
37
|
+
wns_connection::CONTENT_TYPE_HEADER => wns_connection::CONTENT_TYPE[push_type],
|
38
|
+
wns_connection::X_WNS_TYPE_HEADER => wns_connection::WP_TARGETS[push_type],
|
39
|
+
wns_connection::CONTENT_LENGTH_HEADER => public_send("#{push_type}_notification").as_wns_xml.length.to_s,
|
40
|
+
wns_connection::AUTHORIZATION_HEADER => "Bearer #{access_token}",
|
41
|
+
wns_connection::REQUEST_FOR_STATUS_HEADER => 'true'
|
42
|
+
}
|
43
|
+
expect(WebMock).
|
44
|
+
to have_requested(:post, public_send("#{push_type}_notification").device_urls[0]).
|
45
|
+
with(body: public_send("#{push_type}_notification").as_wns_xml, headers: headers).
|
46
|
+
once
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'sets results to notifications' do
|
51
|
+
expect do
|
52
|
+
pusher.push notifications
|
53
|
+
end.to change { notifications.map(&:results) }.from([nil, nil]).to [WNSResponse.new(response)] * 2
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RubyPushNotifications
|
2
|
+
module WNS
|
3
|
+
describe WNSResponse do
|
4
|
+
|
5
|
+
describe 'success' do
|
6
|
+
|
7
|
+
let(:successful_messages) { 2 }
|
8
|
+
let(:failed_messages) { 7 }
|
9
|
+
let(:headers) {
|
10
|
+
{
|
11
|
+
'x-wns-notificationstatus' => 'Received',
|
12
|
+
'x-wns-deviceconnectionstatus' => 'Connected',
|
13
|
+
'x-wns-status' => 'Received'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
let(:responses) {
|
18
|
+
[
|
19
|
+
{ device_url: '1', headers: headers, code: 200 },
|
20
|
+
{ device_url: '2', headers: headers, code: 200 },
|
21
|
+
{ device_url: '3', code: 400 },
|
22
|
+
{ device_url: '4', code: 401 },
|
23
|
+
{ device_url: '5', headers: headers, code: 404 },
|
24
|
+
{ device_url: '6', headers: headers, code: 406 },
|
25
|
+
{ device_url: '7', headers: headers, code: 412 },
|
26
|
+
{ device_url: '8', code: 503 },
|
27
|
+
{ device_url: '9', headers: headers, code: 410 }
|
28
|
+
]
|
29
|
+
}
|
30
|
+
|
31
|
+
let(:response) { WNSResponse.new responses }
|
32
|
+
let(:result) { WNSResultOK.new '1', headers }
|
33
|
+
|
34
|
+
it 'parses the number of successfully processed notifications' do
|
35
|
+
expect(response.success).to eq successful_messages
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'parses the number of failed messages' do
|
39
|
+
expect(response.failed).to eq failed_messages
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'parses the results' do
|
43
|
+
expect(response.results).to eq [
|
44
|
+
WNSResultOK.new('1', headers),
|
45
|
+
WNSResultOK.new('2', headers),
|
46
|
+
MalformedWNSResultError.new('3'),
|
47
|
+
WNSAuthError.new('4'),
|
48
|
+
WNSInvalidError.new('5', headers),
|
49
|
+
WNSLimitError.new('6', headers),
|
50
|
+
WNSPreConditionError.new('7', headers),
|
51
|
+
WNSInternalError.new('8'),
|
52
|
+
WNSExpiredError.new('9', headers)
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'parses headers to result attributes' do
|
57
|
+
expect(result.notification_status).to eq 'Received'
|
58
|
+
expect(result.device_connection_status).to eq 'Connected'
|
59
|
+
expect(result.status).to eq 'Received'
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler'
|
7
|
+
Bundler.setup
|
8
|
+
Bundler.require :defaults, :development
|
9
|
+
require 'webmock/rspec'
|
10
|
+
|
11
|
+
require 'ruby-push-notifications'
|
12
|
+
|
13
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
|
14
|
+
|
15
|
+
def apns_binary(json, token, id)
|
16
|
+
json = JSON.dump(json) if json.is_a?(Hash)
|
17
|
+
[
|
18
|
+
2, 56+json.bytesize, 1, 32, token, 2, json.bytesize, json,
|
19
|
+
3, 4, id, 4, 4, (Time.now + RubyPushNotifications::APNS::APNSNotification::WEEKS_4).to_i, 5, 1, 10
|
20
|
+
].pack 'cNcnH64cna*cnNcnNcnc'
|
21
|
+
end
|
22
|
+
|
23
|
+
WebMock.disable_net_connect!(:allow => "codeclimate.com")
|
@@ -0,0 +1,44 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICsDCCAhmgAwIBAgIJALwzrJEIBOaeMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
3
|
+
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
|
4
|
+
aWRnaXRzIFB0eSBMdGQwHhcNMTEwOTMwMTUyNjM2WhcNMjEwOTI3MTUyNjM2WjBF
|
5
|
+
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
|
6
|
+
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
|
7
|
+
gQC88Ckwru9VR2p2KJ1WQyqesLzr95taNbhkYfsd0j8Tl0MGY5h+dczCaMQz0YY3
|
8
|
+
xHXuU5yAQQTZjiks+D3KA3cx+iKDf2p1q77oXxQcx5CkrXBWTaX2oqVtHm3aX23B
|
9
|
+
AIORGuPk00b4rT3cld7VhcEFmzRNbyI0EqLMAxIwceUKSQIDAQABo4GnMIGkMB0G
|
10
|
+
A1UdDgQWBBSGmOdvSXKXclic5UOKPW35JLMEEjB1BgNVHSMEbjBsgBSGmOdvSXKX
|
11
|
+
clic5UOKPW35JLMEEqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
|
12
|
+
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALwzrJEI
|
13
|
+
BOaeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAcPfWn49pgAX54ji5
|
14
|
+
SiUPFFNCuQGSSTHh2I+TMrs1G1Mb3a0X1dV5CNLRyXyuVxsqhiM/H2veFnTz2Q4U
|
15
|
+
wdY/kPxE19Auwcz9AvCkw7ol1LIlLfJvBzjzOjEpZJNtkXTx8ROSooNrDeJl3HyN
|
16
|
+
cciS5hf80XzIFqwhzaVS9gmiyM8=
|
17
|
+
-----END CERTIFICATE-----
|
18
|
+
-----BEGIN RSA PRIVATE KEY-----
|
19
|
+
MIIEogIBAAKCAQEA6Lr0lAvQrywXhMnXpJaTBL6edduZUY20piiT82Vasere343B
|
20
|
+
wcQFUMwGV9CrjSeOMI9jN/0PEw5ZJ5s4AwqYePxy3K05t6MV5UrDx6na7POfUOmC
|
21
|
+
sfp+KgURY4jQUtOvbHeXr4CjXiMEOJcTTuRaiqy24tjcwkNsHW4/QRyZ1BdKI+8H
|
22
|
+
x9HqpdwaVn2rCx36ZVukMUqv6y7m8QkDog02oLrneYQy8oMaVwkIcxNxFJzVqobN
|
23
|
+
SDGXH2Wdh7usoF8P3PD+EuzCgCeP/kqLym4BYXp6tzJj3hT/85xxpsOjIulLuubK
|
24
|
+
wJz9hngJ/C14DBjXjUmkN38R7XEkR3jvp0K09wIDAQABAoIBAF0irEwu6kWf/I18
|
25
|
+
hRrt00obyqhZyGKVtgykwoiuJauCpSgY0q5rdsEd1RABhxXHFaUjTM6ULBsxK8ao
|
26
|
+
3GKDM/9+76yWejmeP13ybKUTuXQIDuK/gDkfiKviOVI+5zeuVU6wEXj/nuFGXCMV
|
27
|
+
enmg8wb6FXp01Ou9NaAVhaTWAE2afOQSZnI52NUNdV8qvic7+CXpq/W5A/eRIR9v
|
28
|
+
aGaEzglyXPq3N8LUEjqx5abFijCT3fcLwvO2yOs8gxVhwrS0cr30JXnRxqmEghk9
|
29
|
+
GsHyJvUyIEz2BFuzJ8sd0xVgej5wxPcdPcmVnGPGYZ/l+tSSw8XaXqmiBhPEElaa
|
30
|
+
wBET0qECgYEA/aJrYviMbKzS0FuTLNVjEM/Zj60xgVMSZZ9GOqrm4nyIkxFLHmGC
|
31
|
+
rnfeLiAnT0FlCZlO2vA71vXj8dNbhWSxD8EOCvu/oCcAJc0rmkmOgPIRrQMGcd7I
|
32
|
+
s3RbT0ZykuX+JW2SlnMWIPPW4QK5MXfqNux42J/6jC/q0iaeGNPBC9ECgYEA6uaf
|
33
|
+
+YdIHgEYkgn8WjY3i8rX98QmXL9565nFmQe7RmzBZrzFLyKd7FjxjYIz1hk+CfFS
|
34
|
+
jhMb4WNdeVvV8AVPTiTHomCxdVasfadfadsfdPFCHbkbizenFJf0DNx14qe7eSds
|
35
|
+
2gQSZ3eTD7XdFNxqwF1dvPXPtDbVBa8SHlijDkcCgYB1tX4e9Xi+Ksq/tfAsu295
|
36
|
+
auzuOBOkkDgWf3+pVI1IiUEc98aj998dNzYes/9qUdAhT0wAYcNztLQwE8YCt0NR
|
37
|
+
K2hoAoPhQJhZ8skMlpyTDUTUxXWlPR5p4lNKDEi6EhELr7l7Jzga3O9Zh9kIsz04
|
38
|
+
djBzYHN3wfk5xIBUx1ltMQKBgBMA8XRIg4cZ45j9AdNyi2/dyzcaQVhDjWOIHzpQ
|
39
|
+
K9B4v/TF1NYJYOlcEL64B+WMST6YrWsdFKZZWZiV22r9ovrZcuUqGXE7PMgpXGcE
|
40
|
+
jZZZTlYFQbszl2rNGEtqEodxtnMIw3+n0K1aOSWOOwKTCnfhldHRuSoFPZqmHTsj
|
41
|
+
RJ3FAoGAXpx+ulBu99kOxOWWofmP7ff9DF3doF+Jmjwo6KdOAIq++74hNRgYCIKM
|
42
|
+
X+4TSnmu8qBOt++r+EaBgxb+m+36iQxJRhU25ggzlA97v7n7KSxdyt7OLCe5zXP5
|
43
|
+
iiMWAO+qJD6ZyHlzVz0wwu3nAvkhjTxQ2c3+7xjUwCZK1lXjvvM=
|
44
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,31 @@
|
|
1
|
+
shared_examples 'right results' do |success, failed, individual_results|
|
2
|
+
it 'has the expected success value' do
|
3
|
+
expect(notification.success).to eq success
|
4
|
+
end
|
5
|
+
|
6
|
+
it 'has the expected failed value' do
|
7
|
+
expect(notification.failed).to eq failed
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'has the expected individual_results' do
|
11
|
+
expect(notification.individual_results).to eq individual_results
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples 'a proper results manager' do
|
16
|
+
describe 'results management' do
|
17
|
+
before { notification.results = results }
|
18
|
+
|
19
|
+
it 'gives the success count' do
|
20
|
+
expect(notification.success).to eq success_count
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'gives the failures count' do
|
24
|
+
expect(notification.failed).to eq failures_count
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'gives the individual results' do
|
28
|
+
expect(notification.individual_results).to eq individual_results
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|