braze_ruby 0.2.1 → 0.4.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 (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