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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +37 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +19 -0
  5. data/CHANGELOG.md +32 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +22 -0
  8. data/README.md +82 -0
  9. data/Rakefile +12 -0
  10. data/examples/apns.rb +27 -0
  11. data/examples/gcm.rb +25 -0
  12. data/examples/mpns.rb +22 -0
  13. data/examples/wns.rb +25 -0
  14. data/gemfiles/Gemfile-legacy +8 -0
  15. data/lib/ruby-push-notifications.rb +7 -0
  16. data/lib/ruby-push-notifications/apns.rb +44 -0
  17. data/lib/ruby-push-notifications/apns/apns_connection.rb +70 -0
  18. data/lib/ruby-push-notifications/apns/apns_notification.rb +91 -0
  19. data/lib/ruby-push-notifications/apns/apns_pusher.rb +84 -0
  20. data/lib/ruby-push-notifications/apns/apns_results.rb +30 -0
  21. data/lib/ruby-push-notifications/fcm.rb +8 -0
  22. data/lib/ruby-push-notifications/fcm/fcm_connection.rb +60 -0
  23. data/lib/ruby-push-notifications/fcm/fcm_error.rb +17 -0
  24. data/lib/ruby-push-notifications/fcm/fcm_notification.rb +31 -0
  25. data/lib/ruby-push-notifications/fcm/fcm_pusher.rb +29 -0
  26. data/lib/ruby-push-notifications/fcm/fcm_request.rb +28 -0
  27. data/lib/ruby-push-notifications/fcm/fcm_response.rb +89 -0
  28. data/lib/ruby-push-notifications/fcm/fcm_result.rb +52 -0
  29. data/lib/ruby-push-notifications/gcm.rb +6 -0
  30. data/lib/ruby-push-notifications/gcm/gcm_connection.rb +54 -0
  31. data/lib/ruby-push-notifications/gcm/gcm_error.rb +17 -0
  32. data/lib/ruby-push-notifications/gcm/gcm_notification.rb +31 -0
  33. data/lib/ruby-push-notifications/gcm/gcm_pusher.rb +35 -0
  34. data/lib/ruby-push-notifications/gcm/gcm_response.rb +89 -0
  35. data/lib/ruby-push-notifications/gcm/gcm_result.rb +52 -0
  36. data/lib/ruby-push-notifications/mpns.rb +5 -0
  37. data/lib/ruby-push-notifications/mpns/mpns_connection.rb +87 -0
  38. data/lib/ruby-push-notifications/mpns/mpns_notification.rb +94 -0
  39. data/lib/ruby-push-notifications/mpns/mpns_pusher.rb +33 -0
  40. data/lib/ruby-push-notifications/mpns/mpns_response.rb +82 -0
  41. data/lib/ruby-push-notifications/mpns/mpns_result.rb +182 -0
  42. data/lib/ruby-push-notifications/notification_results_manager.rb +14 -0
  43. data/lib/ruby-push-notifications/wns.rb +6 -0
  44. data/lib/ruby-push-notifications/wns/wns_access.rb +82 -0
  45. data/lib/ruby-push-notifications/wns/wns_connection.rb +97 -0
  46. data/lib/ruby-push-notifications/wns/wns_notification.rb +101 -0
  47. data/lib/ruby-push-notifications/wns/wns_pusher.rb +32 -0
  48. data/lib/ruby-push-notifications/wns/wns_response.rb +83 -0
  49. data/lib/ruby-push-notifications/wns/wns_result.rb +208 -0
  50. data/ruby-push-notifications.gemspec +28 -0
  51. data/spec/factories.rb +17 -0
  52. data/spec/factories/notifications.rb +30 -0
  53. data/spec/ruby-push-notifications/apns/apns_connection_spec.rb +92 -0
  54. data/spec/ruby-push-notifications/apns/apns_notification_spec.rb +42 -0
  55. data/spec/ruby-push-notifications/apns/apns_pusher_spec.rb +295 -0
  56. data/spec/ruby-push-notifications/gcm/gcm_connection_spec.rb +46 -0
  57. data/spec/ruby-push-notifications/gcm/gcm_notification_spec.rb +37 -0
  58. data/spec/ruby-push-notifications/gcm/gcm_pusher_spec.rb +45 -0
  59. data/spec/ruby-push-notifications/gcm/gcm_response_spec.rb +82 -0
  60. data/spec/ruby-push-notifications/mpns/mpns_connection_spec.rb +46 -0
  61. data/spec/ruby-push-notifications/mpns/mpns_notification_spec.rb +53 -0
  62. data/spec/ruby-push-notifications/mpns/mpns_pusher_spec.rb +59 -0
  63. data/spec/ruby-push-notifications/mpns/mpns_response_spec.rb +64 -0
  64. data/spec/ruby-push-notifications/wns/wns_access_spec.rb +76 -0
  65. data/spec/ruby-push-notifications/wns/wns_connection_spec.rb +53 -0
  66. data/spec/ruby-push-notifications/wns/wns_notification_spec.rb +177 -0
  67. data/spec/ruby-push-notifications/wns/wns_pusher_spec.rb +58 -0
  68. data/spec/ruby-push-notifications/wns/wns_response_spec.rb +65 -0
  69. data/spec/spec_helper.rb +23 -0
  70. data/spec/support/dummy.pem +44 -0
  71. data/spec/support/factory_girl.rb +5 -0
  72. data/spec/support/results_shared_examples.rb +31 -0
  73. 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="{&quot;var1&quot;:&quot;value1&quot;,&quot;var2&quot;:&quot;value2&quot;}">'
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
@@ -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,5 @@
1
+ RSpec.configure do |config|
2
+ config.include FactoryGirl::Syntax::Methods
3
+ end
4
+
5
+ FactoryGirl.find_definitions
@@ -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