braze_ruby 0.2.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +30 -0
  3. data/.gitignore +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +39 -39
  6. data/README.md +48 -0
  7. data/Rakefile +2 -0
  8. data/braze_ruby.gemspec +7 -7
  9. data/lib/braze_ruby.rb +2 -0
  10. data/lib/braze_ruby/api.rb +12 -4
  11. data/lib/braze_ruby/deprecated.rb +2 -0
  12. data/lib/braze_ruby/endpoints.rb +3 -0
  13. data/lib/braze_ruby/endpoints/campaigns.rb +3 -1
  14. data/lib/braze_ruby/endpoints/canvas.rb +15 -0
  15. data/lib/braze_ruby/endpoints/delete_users.rb +4 -2
  16. data/lib/braze_ruby/endpoints/email_status.rb +3 -1
  17. data/lib/braze_ruby/endpoints/email_sync.rb +4 -2
  18. data/lib/braze_ruby/endpoints/identify_users.rb +19 -0
  19. data/lib/braze_ruby/endpoints/schedule_messages.rb +3 -1
  20. data/lib/braze_ruby/endpoints/send_messages.rb +3 -1
  21. data/lib/braze_ruby/endpoints/subscription.rb +20 -0
  22. data/lib/braze_ruby/endpoints/track_users.rb +7 -5
  23. data/lib/braze_ruby/http.rb +20 -5
  24. data/lib/braze_ruby/rest.rb +8 -0
  25. data/lib/braze_ruby/rest/base.rb +6 -2
  26. data/lib/braze_ruby/rest/canvas_details.rb +20 -0
  27. data/lib/braze_ruby/rest/delete_users.rb +3 -2
  28. data/lib/braze_ruby/rest/email_hard_bounces.rb +5 -5
  29. data/lib/braze_ruby/rest/email_status.rb +5 -5
  30. data/lib/braze_ruby/rest/email_unsubscribes.rb +5 -5
  31. data/lib/braze_ruby/rest/export_users.rb +7 -7
  32. data/lib/braze_ruby/rest/identify_users.rb +13 -0
  33. data/lib/braze_ruby/rest/list_segments.rb +4 -4
  34. data/lib/braze_ruby/rest/schedule_messages.rb +5 -5
  35. data/lib/braze_ruby/rest/send_messages.rb +5 -5
  36. data/lib/braze_ruby/rest/subscription_status_get.rb +20 -0
  37. data/lib/braze_ruby/rest/subscription_status_set.rb +20 -0
  38. data/lib/braze_ruby/rest/subscription_user_status.rb +20 -0
  39. data/lib/braze_ruby/rest/track_users.rb +3 -2
  40. data/lib/braze_ruby/rest/trigger_campaign_send.rb +6 -8
  41. data/lib/braze_ruby/rest/trigger_canvas_send.rb +20 -0
  42. data/lib/braze_ruby/version.rb +3 -1
  43. data/spec/braze_ruby/api_spec.rb +2 -0
  44. data/spec/braze_ruby/endpoints/delete_users_spec.rb +3 -1
  45. data/spec/braze_ruby/endpoints/track_users_spec.rb +10 -8
  46. data/spec/braze_ruby/http_spec.rb +48 -0
  47. data/spec/braze_ruby/rest/delete_users_spec.rb +5 -3
  48. data/spec/braze_ruby/rest/email_status_spec.rb +3 -2
  49. data/spec/braze_ruby/rest/export_users_spec.rb +5 -3
  50. data/spec/braze_ruby/rest/identify_users_spec.rb +23 -0
  51. data/spec/braze_ruby/rest/schedule_messages_spec.rb +3 -2
  52. data/spec/braze_ruby/rest/send_messages_spec.rb +10 -13
  53. data/spec/braze_ruby/rest/track_users_spec.rb +12 -9
  54. data/spec/factories.rb +2 -0
  55. data/spec/fixtures/responses/campaigns/trigger_send/sends_an_email.yml +17 -15
  56. data/spec/fixtures/responses/canvas/details/returns_error_when_no_canvas.yml +69 -0
  57. data/spec/fixtures/responses/canvas/trigger_send/sends_a_canvas.yml +71 -0
  58. data/spec/fixtures/responses/delete_users/unauthorized/responds_with_unauthorized.yml +20 -18
  59. data/spec/fixtures/responses/delete_users/with_success/responds_with_created.yml +25 -23
  60. data/spec/fixtures/responses/delete_users/with_success/responds_with_success_message.yml +25 -23
  61. data/spec/fixtures/responses/email_status/existing_email/responds_with_created.yml +22 -20
  62. data/spec/fixtures/responses/email_status/existing_email/responds_with_success_message.yml +22 -20
  63. data/spec/fixtures/responses/email_status/unknown_email/responds_with_bad_request.yml +22 -20
  64. data/spec/fixtures/responses/email_status/unknown_email/responds_with_success_message.yml +22 -20
  65. data/spec/fixtures/responses/email_sync/hard_bounces/responds_with_empty_array_when_no_hard_bounces.yml +18 -16
  66. data/spec/fixtures/responses/email_sync/unsubscribes/responds_with_empty_array_when_no_unsubscribes.yml +18 -16
  67. data/spec/fixtures/responses/email_sync/unsubscribes/responds_with_unsubscribed_emails.yml +21 -20
  68. data/spec/fixtures/responses/export_users/by_ids/with_success/responds_with_created.yml +25 -22
  69. data/spec/fixtures/responses/export_users/by_segment/with_success/responds_with_created.yml +24 -22
  70. data/spec/fixtures/responses/identify_users/unauthorized/responds_with_unauthorized.yml +68 -0
  71. data/spec/fixtures/responses/identify_users/with_success/responds_with_created.yml +71 -0
  72. data/spec/fixtures/responses/identify_users/with_success/responds_with_success_message.yml +71 -0
  73. data/spec/fixtures/responses/list_segments/with_success/responds_with_a_list_of_segments.yml +35 -35
  74. data/spec/fixtures/responses/list_segments/with_success/responds_with_success.yml +35 -35
  75. data/spec/fixtures/responses/schedule_messages/unauthorized/responds_with_unauthorize.yml +20 -19
  76. data/spec/fixtures/responses/schedule_messages/with_success/responds_with_created.yml +24 -23
  77. data/spec/fixtures/responses/schedule_messages/with_success/responds_with_success_message.yml +24 -23
  78. data/spec/fixtures/responses/send_messages/unauthorized/responds_with_unauthorized.yml +20 -18
  79. data/spec/fixtures/responses/send_messages/with_success/responds_with_created.yml +24 -22
  80. data/spec/fixtures/responses/send_messages/with_success/responds_with_success_message.yml +24 -22
  81. data/spec/fixtures/responses/subscription/subscription_status_set/when_subscribing/subscribes_the_user.yml +71 -0
  82. data/spec/fixtures/responses/subscription/subscription_status_set/when_subscription_group_does_not_exist/returns_an_error_status.yml +68 -0
  83. data/spec/fixtures/responses/subscription/subscription_status_set/when_unsubscribing/unsubscribes_the_user.yml +139 -0
  84. data/spec/fixtures/responses/subscription/when_getting_subscription_group_statuses/subscription_status_get/when_checking_subscribed_and_unsubscribed_user_status/returns_only_users_that_were_once_subscribed.yml +211 -0
  85. data/spec/fixtures/responses/subscription/when_getting_subscription_group_statuses/subscription_status_get/when_group_does_not_exist/returns_an_error.yml +199 -0
  86. data/spec/fixtures/responses/subscription/when_getting_subscription_group_statuses/subscription_user_status/returns_subscription_groups_and_status_for_every_group.yml +211 -0
  87. data/spec/fixtures/responses/track_users/unauthorized/responds_with_unauthorized.yml +23 -21
  88. data/spec/fixtures/responses/track_users/with_success/responds_with_created.yml +22 -20
  89. data/spec/fixtures/responses/track_users/with_success/responds_with_success_message.yml +22 -20
  90. data/spec/integrations/campaigns_spec.rb +6 -2
  91. data/spec/integrations/canvas_spec.rb +28 -0
  92. data/spec/integrations/delete_users_spec.rb +3 -0
  93. data/spec/integrations/email_status_spec.rb +2 -0
  94. data/spec/integrations/email_sync_spec.rb +4 -2
  95. data/spec/integrations/export_users_spec.rb +4 -2
  96. data/spec/integrations/identify_users_spec.rb +32 -0
  97. data/spec/integrations/list_segments_spec.rb +3 -1
  98. data/spec/integrations/schedule_messages_spec.rb +4 -1
  99. data/spec/integrations/send_messages_spec.rb +4 -1
  100. data/spec/integrations/subscription_spec.rb +149 -0
  101. data/spec/integrations/track_users_spec.rb +3 -0
  102. data/spec/spec_helper.rb +2 -8
  103. data/spec/support/factory_bot.rb +2 -0
  104. data/spec/support/integrations.rb +7 -1
  105. data/spec/support/vcr.rb +5 -1
  106. metadata +63 -21
@@ -5,23 +5,29 @@ http_interactions:
5
5
  uri: "<BRAZE_REST_URL>/users/track"
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"api_key":"<BRAZE_REST_API_KEY>","attributes":[{"external_id":1,"foo":"bar"}],"events":[{"external_id":1,"name":"baz","time":"2019-02-15
8
+ string: '{"attributes":[{"external_id":1,"foo":"bar"}],"events":[{"external_id":1,"name":"baz","time":"2019-02-15
9
9
  00:00:00 -0500"}],"purchases":[{"external_id":1,"product_id":1,"time":"2019-02-15
10
10
  00:00:00 -0500","currency":"CAD","price":1.0}]}'
11
11
  headers:
12
- User-Agent:
13
- - Faraday v0.14.0
14
12
  Content-Type:
15
13
  - application/json
14
+ Accept:
15
+ - application/json
16
+ User-Agent:
17
+ - Braze Ruby gem v0.3.3
18
+ Authorization:
19
+ - Bearer <BRAZE_REST_API_KEY>
16
20
  Accept-Encoding:
17
21
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
- Accept:
19
- - "*/*"
20
22
  response:
21
23
  status:
22
24
  code: 201
23
25
  message: Created
24
26
  headers:
27
+ Connection:
28
+ - keep-alive
29
+ Content-Length:
30
+ - '85'
25
31
  Cache-Control:
26
32
  - max-age=0, private, must-revalidate
27
33
  Content-Type:
@@ -34,38 +40,34 @@ http_interactions:
34
40
  - max-age=0; includeSubDomains
35
41
  - max-age=31536000; includeSubDomains
36
42
  X-Ratelimit-Limit:
37
- - '50000'
43
+ - '250000'
38
44
  X-Ratelimit-Remaining:
39
- - '50000'
45
+ - '250000'
40
46
  X-Ratelimit-Reset:
41
- - '1524002400'
47
+ - '1592427600'
42
48
  X-Request-Id:
43
- - af452a7f-9be9-417d-b9d5-2c4db3de274d
49
+ - 2e7a73fc-7efe-4c04-b837-c696cb10735a
44
50
  X-Runtime:
45
- - '0.020310'
46
- Content-Length:
47
- - '85'
51
+ - '0.007710'
48
52
  Accept-Ranges:
49
53
  - bytes
50
54
  Date:
51
- - Tue, 17 Apr 2018 21:08:07 GMT
55
+ - Wed, 17 Jun 2020 20:31:42 GMT
52
56
  Via:
53
57
  - 1.1 varnish
54
- Connection:
55
- - keep-alive
56
58
  X-Served-By:
57
- - cache-pdk17837-PDK
59
+ - cache-hhn4030-HHN
58
60
  X-Cache:
59
61
  - MISS
60
62
  X-Cache-Hits:
61
63
  - '0'
62
64
  X-Timer:
63
- - S1523999287.293178,VS0,VE220
65
+ - S1592425903.632582,VS0,VE10
64
66
  Vary:
65
- - Accept-Encoding
67
+ - Origin,Accept-Encoding
66
68
  body:
67
69
  encoding: ASCII-8BIT
68
70
  string: '{"attributes_processed":1,"events_processed":1,"purchases_processed":1,"message":"success"}'
69
71
  http_version:
70
- recorded_at: Tue, 17 Apr 2018 21:08:07 GMT
71
- recorded_with: VCR 4.0.0
72
+ recorded_at: Wed, 17 Jun 2020 20:31:42 GMT
73
+ recorded_with: VCR 5.0.0
@@ -5,23 +5,29 @@ http_interactions:
5
5
  uri: "<BRAZE_REST_URL>/users/track"
6
6
  body:
7
7
  encoding: UTF-8
8
- string: '{"api_key":"<BRAZE_REST_API_KEY>","attributes":[{"external_id":1,"foo":"bar"}],"events":[{"external_id":1,"name":"baz","time":"2019-02-15
8
+ string: '{"attributes":[{"external_id":1,"foo":"bar"}],"events":[{"external_id":1,"name":"baz","time":"2019-02-15
9
9
  00:00:00 -0500"}],"purchases":[{"external_id":1,"product_id":1,"time":"2019-02-15
10
10
  00:00:00 -0500","currency":"CAD","price":1.0}]}'
11
11
  headers:
12
- User-Agent:
13
- - Faraday v0.14.0
14
12
  Content-Type:
15
13
  - application/json
14
+ Accept:
15
+ - application/json
16
+ User-Agent:
17
+ - Braze Ruby gem v0.3.3
18
+ Authorization:
19
+ - Bearer <BRAZE_REST_API_KEY>
16
20
  Accept-Encoding:
17
21
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
- Accept:
19
- - "*/*"
20
22
  response:
21
23
  status:
22
24
  code: 201
23
25
  message: Created
24
26
  headers:
27
+ Connection:
28
+ - keep-alive
29
+ Content-Length:
30
+ - '85'
25
31
  Cache-Control:
26
32
  - max-age=0, private, must-revalidate
27
33
  Content-Type:
@@ -34,38 +40,34 @@ http_interactions:
34
40
  - max-age=0; includeSubDomains
35
41
  - max-age=31536000; includeSubDomains
36
42
  X-Ratelimit-Limit:
37
- - '50000'
43
+ - '250000'
38
44
  X-Ratelimit-Remaining:
39
- - '50000'
45
+ - '250000'
40
46
  X-Ratelimit-Reset:
41
- - '1524002400'
47
+ - '1592427600'
42
48
  X-Request-Id:
43
- - e810e390-4c31-49ac-abd4-5b1151cc3c33
49
+ - 75dc3ac0-d4d2-4278-89d0-b29e540dc719
44
50
  X-Runtime:
45
- - '0.012176'
46
- Content-Length:
47
- - '85'
51
+ - '0.008741'
48
52
  Accept-Ranges:
49
53
  - bytes
50
54
  Date:
51
- - Tue, 17 Apr 2018 21:08:07 GMT
55
+ - Wed, 17 Jun 2020 20:31:42 GMT
52
56
  Via:
53
57
  - 1.1 varnish
54
- Connection:
55
- - keep-alive
56
58
  X-Served-By:
57
- - cache-pdk17824-PDK
59
+ - cache-hhn4063-HHN
58
60
  X-Cache:
59
61
  - MISS
60
62
  X-Cache-Hits:
61
63
  - '0'
62
64
  X-Timer:
63
- - S1523999288.612820,VS0,VE214
65
+ - S1592425903.749169,VS0,VE11
64
66
  Vary:
65
- - Accept-Encoding
67
+ - Origin,Accept-Encoding
66
68
  body:
67
69
  encoding: ASCII-8BIT
68
70
  string: '{"attributes_processed":1,"events_processed":1,"purchases_processed":1,"message":"success"}'
69
71
  http_version:
70
- recorded_at: Tue, 17 Apr 2018 21:08:07 GMT
71
- recorded_with: VCR 4.0.0
72
+ recorded_at: Wed, 17 Jun 2020 20:31:42 GMT
73
+ recorded_with: VCR 5.0.0
@@ -1,15 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe 'campaigns' do
4
6
  describe 'trigger_send' do
5
7
  it 'sends an email', vcr: true do
6
8
  response = api.trigger_campaign_send(
7
- campaign_id: '69e9b681-779c-4b4c-b6b8-cd74b17d21d2',
9
+ campaign_id: 'd8b73da7-0b7c-fc72-1d80-e59c7f20f0d3',
8
10
  recipients: [
9
- external_user_id: 132404,
11
+ external_user_id: 12345,
10
12
  trigger_properties: {first_name: 'John'}
11
13
  ]
12
14
  )
15
+
16
+ expect(response.success?).to eq(true)
13
17
  end
14
18
  end
15
19
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'canvas' do
6
+ describe 'trigger_send' do
7
+ it 'sends a canvas', vcr: true do
8
+ response = api.trigger_canvas_send(
9
+ canvas_id: '70a7fb99-cbcb-451a-8224-5f8b8c63e03f',
10
+ recipients: [
11
+ external_user_id: 12345,
12
+ canvas_entry_properties: {first_name: 'John'}
13
+ ]
14
+ )
15
+
16
+ expect(response.success?).to eq(true)
17
+ end
18
+ end
19
+
20
+ describe 'details' do
21
+ it 'returns error when no canvas', vcr: true do
22
+ response = api.canvas_details(
23
+ canvas_id: 'non-existing'
24
+ )
25
+ expect(response.status).to eq(400)
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'delete users' do
@@ -14,6 +16,7 @@ describe 'delete users' do
14
16
 
15
17
  it 'responds with success message' do
16
18
  expect(JSON.parse(delete_users.body)).to include(
19
+ 'deleted' => 3,
17
20
  'message' => 'success'
18
21
  )
19
22
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'email status' do
@@ -1,13 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe 'email sync' do
4
6
  describe 'unsubscribes' do
5
7
  it 'responds with unsubscribed emails', vcr: true do
6
- response = api.email_unsubscribes(start_date: '2019-03-20', end_date: '2019-03-25')
8
+ response = api.email_unsubscribes(start_date: '2020-06-17', end_date: '2020-06-18')
7
9
  emails = JSON.parse(response.body)['emails']
8
10
 
9
11
  expect(emails.size).to eq(1)
10
- expect(emails.first['email']).to eq('wojtek@test.com')
12
+ expect(emails.first['email']).to eq('example@123.com')
11
13
  end
12
14
 
13
15
  it 'responds with empty array when no unsubscribes', vcr: true do
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'export users' do
4
6
  context 'by ids' do
5
- subject(:export_users) { api.export_users(external_ids: [1]) }
7
+ subject(:export_users) { api.export_users(external_ids: [12345]) }
6
8
 
7
9
  context 'with success', :vcr do
8
10
  it 'responds with created' do
@@ -13,7 +15,7 @@ describe 'export users' do
13
15
 
14
16
  context 'by segment' do
15
17
  context 'with success', :vcr do
16
- let(:segment_id) { braze_test_segment }
18
+ let(:segment_id) { "3aca937b-9bbc-4e42-9370-05e411967b2b" }
17
19
 
18
20
  subject(:export_users) do
19
21
  api.export_users(segment_id: segment_id, callback_endpoint: 'https://example.com')
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'identify users' do
6
+ let(:user) { { external_id: 12345, user_alias: { alias_name: 'abc', alias_label: 'foo' } } }
7
+
8
+ subject(:identify_users) do
9
+ api.identify_users(aliases_to_identify: [user])
10
+ end
11
+
12
+ context 'with success', vcr: true do
13
+ it 'responds with created' do
14
+ expect(identify_users.status).to be 201
15
+ end
16
+
17
+ it 'responds with success message' do
18
+ expect(JSON.parse(identify_users.body)).to eq(
19
+ 'aliases_processed' => 1,
20
+ 'message' => 'success'
21
+ )
22
+ end
23
+ end
24
+
25
+ context 'unauthorized', vcr: true do
26
+ let(:api_key) { 'non-existent' }
27
+
28
+ it 'responds with unauthorized' do
29
+ expect(identify_users.status).to be 401
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'list segments' do
@@ -9,7 +11,7 @@ describe 'list segments' do
9
11
  end
10
12
 
11
13
  it 'responds with a list of segments' do
12
- expect(segments.count).to be 13
14
+ expect(segments.count).to be 6
13
15
  end
14
16
 
15
17
  def segments
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'schedule messages' do
4
- let(:user_ids) { [1] }
6
+ let(:user_ids) { [12345] }
7
+ let(:test_time) { "2020-08-07T00:00:00+02:00" }
5
8
  let(:messages) { build(:messages) }
6
9
 
7
10
  subject(:schedule_messages) do
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'send messages' do
4
- let(:user_ids) { [1] }
6
+ let(:user_ids) { [12345] }
5
7
  let(:messages) { build(:messages) }
6
8
 
7
9
  subject(:send_messages) do
@@ -15,6 +17,7 @@ describe 'send messages' do
15
17
 
16
18
  it 'responds with success message' do
17
19
  expect(JSON.parse(send_messages.body)).to eq(
20
+ 'dispatch_id' => "ea0532cddfc97cd4e5767b351d6af0eb",
18
21
  'message' => 'success'
19
22
  )
20
23
  end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'subscription', vcr: true do
6
+ let(:subscription_group_id) { 'ed06e19a-69b1-4f9b-a452-2db2c4e303a8' }
7
+ let(:subscribed_user) { 'test-user-1' }
8
+ let(:unsubscribed_user) { 'test-user-2' }
9
+ let(:never_subscribed_user) { 'test-user-3' }
10
+
11
+ context 'when getting subscription group statuses' do
12
+ let(:json_response) { JSON.parse(response.body) }
13
+
14
+ before do
15
+ api.subscription_status_set(
16
+ external_id: subscribed_user,
17
+ subscription_group_id: subscription_group_id,
18
+ subscription_state: 'subscribed'
19
+ )
20
+
21
+ api.subscription_status_set(
22
+ external_id: unsubscribed_user,
23
+ subscription_group_id: subscription_group_id,
24
+ subscription_state: 'unsubscribed'
25
+ )
26
+ end
27
+
28
+ describe 'subscription_user_status' do
29
+ subject(:response) do
30
+ api.subscription_user_status(
31
+ external_id: external_id,
32
+ )
33
+ end
34
+
35
+ let(:external_id) { [subscribed_user, unsubscribed_user, never_subscribed_user] }
36
+
37
+ it 'returns subscription groups and status for every group' do
38
+ expect(response.status).to eq(200)
39
+ expect(json_response).to match(
40
+ 'message' => 'success',
41
+ 'total_count' => 3,
42
+ 'users' => [
43
+ hash_including(
44
+ 'external_id' => subscribed_user,
45
+ 'subscription_groups' => [
46
+ hash_including(
47
+ 'id' => subscription_group_id,
48
+ 'status' => 'Subscribed'
49
+ )
50
+ ]
51
+ ),
52
+ hash_including(
53
+ 'external_id' => unsubscribed_user,
54
+ 'subscription_groups' => [
55
+ hash_including(
56
+ 'id' => subscription_group_id,
57
+ 'status' => 'Unsubscribed'
58
+ )
59
+ ]
60
+ ),
61
+ hash_including(
62
+ 'external_id' => never_subscribed_user,
63
+ 'subscription_groups' => []
64
+ )
65
+ ]
66
+ )
67
+ end
68
+ end
69
+
70
+ describe 'subscription_status_get' do
71
+ subject(:response) do
72
+ api.subscription_status_get(
73
+ external_id: external_id,
74
+ subscription_group_id: subscription_group_id
75
+ )
76
+ end
77
+
78
+ context 'when checking subscribed and unsubscribed user status' do
79
+ let(:external_id) { [subscribed_user, unsubscribed_user, never_subscribed_user] }
80
+
81
+ it 'returns only users that were once subscribed' do
82
+ expect(response.status).to eq(200)
83
+ expect(json_response).to eq(
84
+ 'message' => 'success',
85
+ 'status' => {
86
+ 'test-user-1' => 'Subscribed',
87
+ 'test-user-2' => 'Unsubscribed',
88
+ 'test-user-3' => 'unknown'
89
+ }
90
+ )
91
+ end
92
+ end
93
+
94
+ context 'when group does not exist' do
95
+ let(:external_id) { subscribed_user }
96
+ let(:subscription_group_id) { 'non-existing-subscription-group' }
97
+
98
+ it 'returns an error' do
99
+ expect(response.status).to eq(400)
100
+ end
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ describe 'subscription_status_set' do
107
+ subject(:response) do
108
+ api.subscription_status_set(
109
+ external_id: external_id,
110
+ subscription_group_id: subscription_group_id,
111
+ subscription_state: subscription_state
112
+ )
113
+ end
114
+
115
+ let(:external_id) { subscribed_user }
116
+ let(:subscription_state) { 'subscribed' }
117
+
118
+ context 'when subscribing' do
119
+ it 'subscribes the user' do
120
+ expect(response.status).to eq(201)
121
+ end
122
+ end
123
+
124
+ context 'when unsubscribing' do
125
+ let(:external_id) { unsubscribed_user }
126
+ let(:subscription_state) { 'unsubscribed' }
127
+
128
+ before do
129
+ api.subscription_status_set(
130
+ external_id: external_id,
131
+ subscription_group_id: subscription_group_id,
132
+ subscription_state: 'subscribed'
133
+ )
134
+ end
135
+
136
+ it 'unsubscribes the user' do
137
+ expect(response.status).to eq(201)
138
+ end
139
+ end
140
+
141
+ context 'when subscription group does not exist' do
142
+ let(:subscription_group_id) { 'non-existing-subscription-group' }
143
+
144
+ it 'returns an error status' do
145
+ expect(response.status).to eq(400)
146
+ end
147
+ end
148
+ end
149
+ end