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,46 @@
1
+
2
+ module RubyPushNotifications
3
+ module GCM
4
+ describe GCMConnection do
5
+
6
+ describe '::post' do
7
+
8
+ let(:body) { 'abc' }
9
+ let(:key) { 'def' }
10
+ let(:response) { JSON.dump a: 1 }
11
+
12
+ before do
13
+ stub_request(:post, 'https://android.googleapis.com/gcm/send').
14
+ to_return status: [200, 'OK'], body: response
15
+ end
16
+
17
+ it 'runs the right request' do
18
+ GCMConnection.post body, key
19
+
20
+ expect(WebMock).
21
+ to have_requested(:post, 'https://android.googleapis.com/gcm/send').
22
+ with(body: body, headers: { 'Content-Type' => 'application/json', 'Authorization' => "key=#{key}" }).
23
+ once
24
+ end
25
+
26
+ context 'when :url option is present' do
27
+ it 'posts data to a custom GCM endpoint' do
28
+ stub_request(:post, 'https://example.com/gcm/send').
29
+ to_return status: [200, 'OK'], body: response
30
+
31
+ GCMConnection.post body, key, url: 'https://example.com/gcm/send'
32
+
33
+ expect(WebMock).
34
+ to have_requested(:post, 'https://example.com/gcm/send').
35
+ with(body: body, headers: { 'Content-Type' => 'application/json', 'Authorization' => "key=#{key}" }).
36
+ once
37
+ end
38
+ end
39
+
40
+ it 'returns the response encapsulated in a GCMResponse object' do
41
+ expect(GCMConnection.post body, key).to eq GCMResponse.new(200, response)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,37 @@
1
+
2
+ module RubyPushNotifications
3
+ module GCM
4
+ describe GCMNotification do
5
+
6
+ let(:registration_ids) { %w(a b c) }
7
+ let(:data) { { a: 1 } }
8
+ let(:notification) { build :gcm_notification, registration_ids: registration_ids, data: data }
9
+
10
+ it 'builds the right gcm json' do
11
+ expect(notification.as_gcm_json).to eq JSON.dump(
12
+ registration_ids: registration_ids,
13
+ data: data
14
+ )
15
+ end
16
+
17
+ it 'validates the registration_ids format'
18
+
19
+ # According to https://developer.android.com/google/gcm/server-ref.html#table1
20
+ it 'validates the data'
21
+
22
+ it_behaves_like 'a proper results manager' do
23
+ let(:success_count) { 2 }
24
+ let(:failures_count) { 1 }
25
+ let(:canonical_id) { 'abcd' }
26
+ let(:individual_results) { [GCMCanonicalIDResult.new(canonical_id)] }
27
+ let(:results) do
28
+ GCMResponse.new 200, JSON.dump(
29
+ success: success_count, failure: failures_count, results: [
30
+ registration_id: canonical_id
31
+ ]
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module RubyPushNotifications
3
+ module GCM
4
+ describe GCMPusher do
5
+
6
+ let(:gcm_key) { 'gcm key' }
7
+ let(:pusher) { GCMPusher.new gcm_key }
8
+
9
+ describe '#push' do
10
+
11
+ let(:notif1) { build :gcm_notification }
12
+ let(:notif2) { build :gcm_notification }
13
+ let(:response) { JSON.dump a: 1 }
14
+
15
+ before do
16
+ stub_request(:post, 'https://android.googleapis.com/gcm/send').
17
+ to_return status: [200, 'OK'], body: response
18
+ end
19
+
20
+ it 'submits every notification' do
21
+ pusher.push [notif1, notif2]
22
+
23
+ expect(WebMock).
24
+ to have_requested(:post, 'https://android.googleapis.com/gcm/send').
25
+ with(body: notif1.as_gcm_json, headers: { 'Content-Type' => 'application/json', 'Authorization' => "key=#{gcm_key}" }).
26
+ once
27
+
28
+ expect(WebMock).
29
+ to have_requested(:post, 'https://android.googleapis.com/gcm/send').
30
+ with(body: notif2.as_gcm_json, headers: { 'Content-Type' => 'application/json', 'Authorization' => "key=#{gcm_key}" }).
31
+ once
32
+ end
33
+
34
+ it 'sets results to notifications' do
35
+ expect do
36
+ pusher.push [notif1, notif2]
37
+ end.to change { [notif1, notif2].map &:results }.from([nil, nil]).to [GCMResponse.new(200, response)]*2
38
+ end
39
+
40
+ it 'splits notifications with more than 1000 destinations in parts'
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,82 @@
1
+
2
+ module RubyPushNotifications
3
+ module GCM
4
+ describe GCMResponse do
5
+
6
+ describe 'success' do
7
+
8
+ let(:successful_messages) { 3 }
9
+ let(:failed_messages) { 1 }
10
+ let(:canonical_ids) { 2 }
11
+ let(:body) { JSON.dump(
12
+ multicast_id: 123456789,
13
+ success: successful_messages,
14
+ failure: failed_messages,
15
+ canonical_ids: canonical_ids,
16
+ results: [
17
+ { message_id: 1,
18
+ registration_id: 'new_reg_id' },
19
+ { message_id: 2,
20
+ registration_id: 'new_reg_id_2' },
21
+ { message_id: 3 },
22
+ { message_id: 4,
23
+ error: 'NotRegistered' }
24
+ ]
25
+ ) }
26
+
27
+ let(:response) { GCMResponse.new 200, body }
28
+
29
+ it 'parses the number of successfully processed notifications' do
30
+ expect(response.success).to eq successful_messages
31
+ end
32
+
33
+ it 'parses the number of failed messages' do
34
+ expect(response.failed).to eq failed_messages
35
+ end
36
+
37
+ it 'parses the number of canonical ids received' do
38
+ expect(response.canonical_ids).to eq canonical_ids
39
+ end
40
+
41
+ it 'parses the results' do
42
+ expect(response.results).to eq [GCMCanonicalIDResult.new('new_reg_id'), GCMCanonicalIDResult.new('new_reg_id_2'), GCMResultOK.new, GCMResultError.new('NotRegistered')]
43
+ end
44
+ end
45
+
46
+ describe 'errors' do
47
+ let(:dummy_response_body) { 'dummy response body' }
48
+ describe '400 Bad Request error code' do
49
+ it 'raises a MalformedGCMJSONError' do
50
+ expect do
51
+ GCMResponse.new 400, dummy_response_body
52
+ end.to raise_error MalformedGCMJSONError, dummy_response_body
53
+ end
54
+ end
55
+
56
+ describe '401 Unauthorized error code' do
57
+ it 'raises a GCMAuthError' do
58
+ expect do
59
+ GCMResponse.new 401, dummy_response_body
60
+ end.to raise_error GCMAuthError, dummy_response_body
61
+ end
62
+ end
63
+
64
+ describe '500 Internal Server Error error code' do
65
+ it 'raises a GCMInternalError' do
66
+ expect do
67
+ GCMResponse.new 500, dummy_response_body
68
+ end.to raise_error GCMInternalError, dummy_response_body
69
+ end
70
+ end
71
+
72
+ describe '302 Found error code' do
73
+ it 'raises a UnexpectedGCMResponseError' do
74
+ expect do
75
+ GCMResponse.new 302, dummy_response_body
76
+ end.to raise_error UnexpectedGCMResponseError, '302'
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,46 @@
1
+
2
+ module RubyPushNotifications
3
+ module MPNS
4
+ describe MPNSConnection do
5
+
6
+ describe '::post' do
7
+
8
+ let(:body) { 'abc' }
9
+ let(:headers) {
10
+ {
11
+ 'x-notificationstatus' => 'Received',
12
+ 'x-deviceconnectionstatus' => 'Connected',
13
+ 'x-subscriptionstatus' => 'Active'
14
+ }
15
+ }
16
+ let(:device_urls) { [generate(:mpns_device_url)] }
17
+ let(:toast_data) { { title: 'Title', message: 'Hello MPNS World!', type: :toast } }
18
+ let(:toast_notification) { build :mpns_notification, device_urls: device_urls, data: toast_data }
19
+
20
+ before do
21
+ stub_request(:post, %r{s.notify.live.net}).
22
+ to_return status: [200, 'OK'], body: body, headers: headers
23
+ end
24
+
25
+ it 'runs the right request' do
26
+ MPNSConnection.post toast_notification
27
+
28
+ expect(WebMock).
29
+ to have_requested(:post, toast_notification.device_urls[0]).
30
+ with(body: toast_notification.as_mpns_xml, headers: { 'Content-Type' => 'text/xml', 'X-NotificationClass' => '2', 'X-WindowsPhone-Target' => :toast}).
31
+ once
32
+ end
33
+
34
+ it 'returns the response encapsulated in a Hash object' do
35
+ responses = [
36
+ { device_url: toast_notification.device_urls[0],
37
+ headers: headers,
38
+ code: 200
39
+ }
40
+ ]
41
+ expect(MPNSConnection.post toast_notification).to eq MPNSResponse.new(responses)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+
2
+ module RubyPushNotifications
3
+ module MPNS
4
+ describe MPNSNotification do
5
+
6
+ let(:device_urls) { %w(a b c) }
7
+ let(:raw_notification) { build :mpns_notification }
8
+ let(:toast_data) { { title: 'Title', message: 'Hello MPNS World!', type: :toast } }
9
+ let(:toast_notification) { build :mpns_notification, device_urls: device_urls, data: toast_data }
10
+ let(:tile_data) { { count: 1, title: 'Hello MPNS World!', type: :tile } }
11
+ let(:tile_notification) { build :mpns_notification, device_urls: device_urls, data: tile_data }
12
+
13
+ it 'builds the right mpns raw xml' do
14
+ xml = '<?xml version="1.0" encoding="UTF-8"?>'
15
+ xml << '<root><value1>hello</value1></root>'
16
+ expect(raw_notification.as_mpns_xml).to eq xml
17
+ end
18
+
19
+ it 'builds the right mpns toast xml' do
20
+ xml = '<?xml version="1.0" encoding="UTF-8"?>'
21
+ xml << '<wp:Notification xmlns:wp="WPNotification"><wp:Toast>'
22
+ xml << '<wp:Text1>Title</wp:Text1>'
23
+ xml << '<wp:Text2>Hello MPNS World!</wp:Text2>'
24
+ xml << '</wp:Toast></wp:Notification>'
25
+ expect(toast_notification.as_mpns_xml).to eq xml
26
+ end
27
+
28
+ it 'builds the right mpns tile xml' do
29
+ xml = '<?xml version="1.0" encoding="UTF-8"?>'
30
+ xml << '<wp:Notification xmlns:wp="WPNotification"><wp:Tile>'
31
+ xml << '<wp:Count>1</wp:Count>'
32
+ xml << '<wp:Title>Hello MPNS World!</wp:Title>'
33
+ xml << '</wp:Tile></wp:Notification>'
34
+ expect(tile_notification.as_mpns_xml).to eq xml
35
+ end
36
+
37
+ it 'validates the mpns format'
38
+
39
+ it 'validates the data'
40
+
41
+ it_behaves_like 'a proper results manager' do
42
+ let(:notification) { build :mpns_notification }
43
+ let(:success_count) { 1 }
44
+ let(:failures_count) { 0 }
45
+ let(:device_url) { generate :mpns_device_url }
46
+ let(:individual_results) { [MPNSResultOK.new(device_url, {})] }
47
+ let(:results) do
48
+ MPNSResponse.new [{ code: 200, device_url: device_url, headers: {} }]
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,59 @@
1
+
2
+ module RubyPushNotifications
3
+ module MPNS
4
+ describe MPNSPusher do
5
+
6
+ let(:pusher) { MPNSPusher.new }
7
+
8
+ describe '#push' do
9
+
10
+ let(:device_urls) { [generate(:mpns_device_url)] }
11
+ let(:notif1) { build :mpns_notification, device_urls: ['http://s.notify.live.net/1'], data: { message: { value1: 'hello' } } }
12
+ let(:notif2) { build :mpns_notification, device_urls: ['http://s.notify.live.net/1'], data: { message: { value1: 'hello' } } }
13
+ let(:raw_notification) { build :mpns_notification }
14
+ let(:toast_data) { { title: 'Title', message: 'Hello MPNS World!', type: :toast } }
15
+ let(:toast_notification) { build :mpns_notification, device_urls: device_urls, data: toast_data }
16
+ let(:tile_data) { { count: 1, title: 'Hello MPNS World!', type: :tile } }
17
+ let(:tile_notification) { build :mpns_notification, device_urls: device_urls, data: tile_data }
18
+ let(:headers) {
19
+ {
20
+ 'x-notificationstatus' => 'Received',
21
+ 'x-deviceconnectionstatus' => 'Connected',
22
+ 'x-subscriptionstatus' => 'Active'
23
+ }
24
+ }
25
+ let(:response) { [ { device_url: 'http://s.notify.live.net/1', headers: headers, code: 200 } ]}
26
+
27
+ before do
28
+ stub_request(:post, %r{s.notify.live.net}).
29
+ to_return status: [200, 'OK'], headers: headers
30
+ end
31
+
32
+ it 'submits every notification' do
33
+ pusher.push [raw_notification, toast_notification, tile_notification]
34
+ expect(WebMock).
35
+ to have_requested(:post, raw_notification.device_urls[0]).
36
+ with(body: raw_notification.as_mpns_xml, headers: { 'Content-Type' => 'text/xml', 'X-NotificationClass' => '3'}).
37
+ once
38
+
39
+ expect(WebMock).
40
+ to have_requested(:post, toast_notification.device_urls[0]).
41
+ with(body: toast_notification.as_mpns_xml, headers: { 'Content-Type' => 'text/xml', 'X-NotificationClass' => '2', 'X-WindowsPhone-Target' => :toast}).
42
+ once
43
+
44
+ expect(WebMock).
45
+ to have_requested(:post, tile_notification.device_urls[0]).
46
+ with(body: tile_notification.as_mpns_xml, headers: { 'Content-Type' => 'text/xml', 'X-NotificationClass' => '1', 'X-WindowsPhone-Target' => 'token'}).
47
+ once
48
+ end
49
+
50
+ it 'sets results to notifications' do
51
+ expect do
52
+ pusher.push [notif1, notif2]
53
+ end.to change { [notif1, notif2].map &:results }.from([nil, nil]).to [MPNSResponse.new(response)]*2
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+
2
+ module RubyPushNotifications
3
+ module MPNS
4
+ describe MPNSResponse do
5
+
6
+ describe 'success' do
7
+
8
+ let(:successful_messages) { 2 }
9
+ let(:failed_messages) { 6 }
10
+ let(:headers) {
11
+ {
12
+ 'x-notificationstatus' => 'Received',
13
+ 'x-deviceconnectionstatus' => 'Connected',
14
+ 'x-subscriptionstatus' => 'Active'
15
+ }
16
+ }
17
+
18
+ let(:responses) {
19
+ [
20
+ { device_url: '1', headers: headers, code: 200 },
21
+ { device_url: '2', headers: headers, code: 200 },
22
+ { device_url: '3', code: 400 },
23
+ { device_url: '4', code: 401 },
24
+ { device_url: '5', headers: headers, code: 404 },
25
+ { device_url: '6', headers: headers, code: 406 },
26
+ { device_url: '7', headers: headers, code: 412 },
27
+ { device_url: '8', code: 503 }
28
+ ]
29
+ }
30
+
31
+ let(:response) { MPNSResponse.new responses }
32
+ let(:result) { MPNSResultOK.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
+ MPNSResultOK.new('1', headers),
45
+ MPNSResultOK.new('2', headers),
46
+ MalformedMPNSResultError.new('3'),
47
+ MPNSAuthError.new('4'),
48
+ MPNSInvalidError.new('5', headers),
49
+ MPNSLimitError.new('6', headers),
50
+ MPNSPreConditionError.new('7', headers),
51
+ MPNSInternalError.new('8')
52
+ ]
53
+ end
54
+
55
+ it 'parses headers to result attributes' do
56
+ expect(result.notification_status).to eq 'Received'
57
+ expect(result.device_connection_status).to eq 'Connected'
58
+ expect(result.subscription_status).to eq 'Active'
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,76 @@
1
+ module RubyPushNotifications
2
+ module WNS
3
+ describe WNSAccess do
4
+ describe '::access_token' do
5
+ let(:sid) { 'sid' }
6
+ let(:secret) { 'secret' }
7
+
8
+ context 'when service return status OK' do
9
+ let(:body) {
10
+ "{\"token_type\":\"bearer\",\"access_token\":\"real_access_token\",\"expires_in\":86400}"
11
+ }
12
+ before do
13
+ stub_request(:post, "https://login.live.com/accesstoken.srf").
14
+ to_return status: [200, 'OK'], body: body
15
+ end
16
+
17
+ it 'returns correct response' do
18
+ response = OpenStruct.new(
19
+ status_code: 200,
20
+ status: 'OK',
21
+ error: nil,
22
+ error_description: nil,
23
+ access_token: 'real_access_token',
24
+ token_ttl: 86400
25
+ )
26
+ expect(WNSAccess.new(sid, secret).get_token.response).to eq(response)
27
+ end
28
+ end
29
+
30
+ context 'when service return an error' do
31
+ context 'when bad credentials' do
32
+ let(:body) {
33
+ "{\"error\":\"invalid_client\",\"error_description\":\"Invalid client id\"}"
34
+ }
35
+ before do
36
+ stub_request(:post, "https://login.live.com/accesstoken.srf").
37
+ to_return status: [400, 'Bad Request'], body: body
38
+ end
39
+
40
+ it 'returns correct response' do
41
+ response = OpenStruct.new(
42
+ status_code: 400,
43
+ status: 'Bad Request',
44
+ error: 'invalid_client',
45
+ error_description: 'Invalid client id',
46
+ access_token: nil,
47
+ token_ttl: nil
48
+ )
49
+ expect(WNSAccess.new(sid, secret).get_token.response).to eq(response)
50
+ end
51
+ end
52
+
53
+ context 'when bad request' do
54
+ let(:body) { '' }
55
+ before do
56
+ stub_request(:post, "https://login.live.com/accesstoken.srf").
57
+ to_return status: [500, 'Internal Server Error'], body: body
58
+ end
59
+
60
+ it 'returns correct response' do
61
+ response = OpenStruct.new(
62
+ status_code: 500,
63
+ status: 'Internal Server Error',
64
+ error: nil,
65
+ error_description: nil,
66
+ access_token: nil,
67
+ token_ttl: nil
68
+ )
69
+ expect(WNSAccess.new(sid, secret).get_token.response).to eq(response)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end