From d8c195b1f87c16505c296a5ca200e3cb30e8228d Mon Sep 17 00:00:00 2001 From: Alex Lebedev <6421109+alex-leb@users.noreply.github.com> Date: Thu, 26 Mar 2026 15:33:28 +0200 Subject: [PATCH 1/2] DE-1740: add suppressions specs Signed-off-by: Alex Lebedev <6421109+alex-leb@users.noreply.github.com> --- spec/integration/suppressions_spec.rb | 232 +++- .../creates_a_single_bounce.yml | 55 + vcr_cassettes/suppressions.yml | 1223 ++++++++++++++--- 3 files changed, 1314 insertions(+), 196 deletions(-) create mode 100644 vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml diff --git a/spec/integration/suppressions_spec.rb b/spec/integration/suppressions_spec.rb index 3f0805f..6679caa 100644 --- a/spec/integration/suppressions_spec.rb +++ b/spec/integration/suppressions_spec.rb @@ -5,19 +5,16 @@ require 'mailgun' require 'mailgun/suppressions' -vcr_opts = { cassette_name: 'suppressions' } +vcr_opts = { cassette_name: 'suppressions', match_requests_on: %i[uri method body] } describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts do - before(:all) do - @mg_obj = Mailgun::Client.new(APIKEY) - @suppress = Mailgun::Suppressions.new(@mg_obj, TESTDOMAIN) - - @addresses = ['test1@example.com', 'test2@example.org', 'test3@example.net', 'test4@example.info'] - end + let(:mg_obj) { Mailgun::Client.new(APIKEY, APIHOST, 'v3') } + let(:suppress) { Mailgun::Suppressions.new(mg_obj, TESTDOMAIN) } + let(:addresses) { %w[test1@example.com test2@example.org test3@example.net test4@example.info] } it 'can batch-add bounces' do bounces = [] - @addresses.each do |addr| + addresses.each do |addr| bounces.push({ address: addr, code: 500, @@ -25,7 +22,7 @@ }) end - response, nested = @suppress.create_bounces bounces + response, nested = suppress.create_bounces bounces response.to_h! expect(response.code).to eq(200) @@ -40,12 +37,40 @@ error: 'integration testing' }) - expect { @suppress.create_bounces bounces }.to raise_error(Mailgun::ParameterError) + expect { suppress.create_bounces bounces }.to raise_error(Mailgun::ParameterError) + end + + it 'returns nil if no bounces passed' do + response = suppress.create_bounces({}) + + expect(response[0]).to eq(nil) + end + + it 'creates a single bounce' do + bounce = { + address: 'test777@example.info', + code: 777, + error: 'integration testing123' + } + + response = suppress.create_bounce bounce + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['message']).to eq('Address has been added to the bounces table') + end + + it 'fetches a single bounce' do + response = suppress.get_bounce('test777@example.info') + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['address']).to eq('test777@example.info') end it 'removes a single bounce address' do - @addresses.each do |addr| - response = @suppress.delete_bounce addr + addresses.each do |addr| + response = suppress.delete_bounce addr response.to_h! expect(response.code).to eq(200) @@ -53,16 +78,24 @@ end end + it 'removes all bounces' do + response = suppress.delete_all_bounces + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['message']).to eq('Bounced addresses for this domain have been removed') + end + it 'can batch-add unsubscribes with tags as string' do unsubscribes = [] - @addresses.each do |addr| + addresses.each do |addr| unsubscribes.push({ address: addr, - tag: 'integration' + tag: '123' }) end - response, nested = @suppress.create_unsubscribes unsubscribes + response, nested = suppress.create_unsubscribes unsubscribes response.to_h! expect(response.code).to eq(200) @@ -72,14 +105,31 @@ it 'can batch-add unsubscribes with tags as array' do unsubscribes = [] - @addresses.each do |addr| + addresses.each do |addr| unsubscribes.push({ address: addr, tags: ['integration'] }) end - response, nested = @suppress.create_unsubscribes unsubscribes + response, nested = suppress.create_unsubscribes unsubscribes + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['message']).to eq('4 addresses have been added to the unsubscribes table') + expect(nested.length).to eq(0) + end + + it 'can batch-add unsubscribes with tags as digits' do + unsubscribes = [] + addresses.each do |addr| + unsubscribes.push({ + address: addr, + tag: 123 + }) + end + + response, nested = suppress.create_unsubscribes unsubscribes response.to_h! expect(response.code).to eq(200) @@ -93,12 +143,18 @@ tag: 'integration' }) - expect { @suppress.create_unsubscribes unsubscribes }.to raise_error(Mailgun::ParameterError) + expect { suppress.create_unsubscribes unsubscribes }.to raise_error(Mailgun::ParameterError) + end + + it 'returns nil if no unsubscribes passed' do + response = suppress.create_unsubscribes({}) + + expect(response[0]).to eq(nil) end it 'removes a single unsubscribe address' do - @addresses.each do |addr| - response = @suppress.delete_unsubscribe addr + addresses.each do |addr| + response = suppress.delete_unsubscribe addr response.to_h! expect(response.code).to eq(200) @@ -106,13 +162,40 @@ end end + it 'creates a single unsubscribe' do + response = suppress.create_unsubscribe({ + address: 'test777@example.com', + tags: ['integration'] + }) + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['message']).to eq('Address has been added to the unsubscribes table') + end + + it 'returns a single unsubscribe' do + response = suppress.get_unsubscribe( 'test777@example.com') + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['address']).to eq('test777@example.com') + end + + it 'returns all unsubscribers' do + response = suppress.list_unsubscribes + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['items'][0]['address']).to eq('test777@example.com') + end + it 'can batch-add complaints' do complaints = [] - @addresses.each do |addr| + addresses.each do |addr| complaints.push address: addr end - response, nested = @suppress.create_complaints complaints + response, nested = suppress.create_complaints complaints response.to_h! expect(response.code).to eq(200) @@ -126,12 +209,42 @@ tag: 'integration' }) - expect { @suppress.create_complaints complaints }.to raise_error(Mailgun::ParameterError) + expect { suppress.create_complaints complaints }.to raise_error(Mailgun::ParameterError) + end + + it 'returns nil if no complaints passed' do + response = suppress.create_complaints({}) + + expect(response[0]).to eq(nil) + end + + it 'creates a single complaint' do + response = suppress.create_complaint({ address: 'test777@example.com'}) + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['message']).to eq('Address has been added to the complaints table') + end + + it 'returns a single complaint' do + response = suppress.get_complaint( 'test777@example.com') + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['address']).to eq('test777@example.com') + end + + it 'returns all complaints' do + response = suppress.list_complaints + response.to_h! + + expect(response.code).to eq(200) + expect(response.body['items'][0]['address']).to eq('test1@example.com') end it 'removes a single complaint address' do - @addresses.each do |addr| - response = @suppress.delete_complaint addr + addresses.each do |addr| + response = suppress.delete_complaint addr response.to_h! expect(response.code).to eq(200) @@ -139,5 +252,72 @@ end end - # TODO: Add tests for pagination support. + describe 'paging' do + before do + suppress.list_bounces + end + + describe '#next' do + it 'returns the response' do + resp = suppress.next + expect(resp.status).to eq(200) + expect(JSON.parse(resp.body)).to include('items') + end + end + + describe '#prev' do + it 'returns the response' do + resp = suppress.prev + expect(resp.status).to eq(200) + expect(JSON.parse(resp.body)).to include('items') + end + end + end + + context 'with 1000 or more entries' do + let(:large_list) { Array.new(1000) { |i| { address: "user#{i}@example.com" } } } + let(:client) { double(:client) } + let(:domain) { 'example.com' } + + def stub_response(body = {}) + double(:response).tap do |r| + allow(r).to receive(:to_h).and_return(body) + allow(r).to receive(:to_h!).and_return(body) + allow(r).to receive(:code).and_return(200) + allow(r).to receive(:body).and_return(body) + end + end + + subject(:suppressions) { Mailgun::Suppressions.new(client, domain) } + + it 'splits bounces list and makes two POST requests' do + expect(client).to receive(:post) + .with('example.com/bounces', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) + + _resp, split = suppressions.create_bounces(large_list) + expect(split).not_to be_empty + end + + it 'splits unsubscribes list and makes two POST requests' do + expect(client).to receive(:post) + .with('example.com/unsubscribes', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) + + _resp, split = suppressions.create_unsubscribes(large_list) + expect(split).not_to be_empty + end + + it 'splits complaints list and makes two POST requests' do + expect(client).to receive(:post) + .with('example.com/complaints', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) + + _resp, split = suppressions.create_complaints(large_list) + expect(split).not_to be_empty + end + end end diff --git a/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml b/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml new file mode 100644 index 0000000..c85c707 --- /dev/null +++ b/vcr_cassettes/For_the_suppressions_handling_class/creates_a_single_bounce.yml @@ -0,0 +1,55 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.mailgun.net/bounces + body: + encoding: UTF-8 + string: address=test5%40example.info&code=500&error=integration+testing + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '89' + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 25 Mar 2026 18:09:17 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2498' + X-Request-Reset: + - '1774462171770' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"message":"Address has been added to the bounces table","address":"test5@example.info"} + + ' + recorded_at: Wed, 25 Mar 2026 18:09:17 GMT +recorded_with: VCR 6.4.0 diff --git a/vcr_cassettes/suppressions.yml b/vcr_cassettes/suppressions.yml index 55dd6f5..5d2bfa8 100644 --- a/vcr_cassettes/suppressions.yml +++ b/vcr_cassettes/suppressions.yml @@ -12,13 +12,13 @@ http_interactions: testing"}]' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Content-Type: - application/json Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -26,15 +26,139 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '63' + Content-Type: + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:17 GMT + - Thu, 26 Mar 2026 12:59:14 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2499' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"message":"4 addresses have been added to the bounces table"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:14 GMT +- request: + method: post + uri: https://api.mailgun.net/bounces + body: + encoding: UTF-8 + string: address=test777%40example.info&code=777&error=integration+testing123 + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '0' + - '91' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:15 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2498' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"message":"Address has been added to the bounces table","address":"test777@example.info"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:15 GMT +- request: + method: get + uri: https://api.mailgun.net/bounces/test777@example.info + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '126' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:15 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2497' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"4 addresses have been added to the bounces table"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:17 GMT + string: '{"address":"test777@example.info","code":"777","error":"integration + testing123","created_at":"Thu, 26 Mar 2026 12:59:15 UTC"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:15 GMT - request: method: delete uri: https://api.mailgun.net/bounces/test1@example.com @@ -43,11 +167,11 @@ http_interactions: string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -55,34 +179,50 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '77' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:18 GMT - Content-Length: - - '19' + - Thu, 26 Mar 2026 12:59:16 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2496' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Bounced address has been removed"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:18 GMT + string: '{"address":"test1@example.com","message":"Bounced address has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:16 GMT - request: - method: post - uri: https://api.mailgun.net/unsubscribes + method: delete + uri: https://api.mailgun.net/bounces/test2@example.org body: - encoding: UTF-8 - string: '[{"address":"test4@example.info","tag":"integration"},{"address":"test3@example.net","tag":"integration"},{"address":"test2@example.org","tag":"integration"},{"address":"test1@example.com","tag":"integration"}]' + encoding: US-ASCII + string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" - Content-Type: - - application/json Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -90,28 +230,101 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '77' + Content-Type: + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:18 GMT + - Thu, 26 Mar 2026 12:59:17 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2495' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test2@example.org","message":"Bounced address has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:17 GMT +- request: + method: delete + uri: https://api.mailgun.net/bounces/test3@example.net + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '0' + - '77' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:17 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2494' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"4 addresses have been added to the unsubscribes table"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:18 GMT + string: '{"address":"test3@example.net","message":"Bounced address has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:17 GMT - request: method: delete - uri: https://api.mailgun.net/unsubscribes/test1@example.com + uri: https://api.mailgun.net/bounces/test4@example.info body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -119,34 +332,102 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '78' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:18 GMT + - Thu, 26 Mar 2026 12:59:18 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2493' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test4@example.info","message":"Bounced address has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:18 GMT +- request: + method: delete + uri: https://api.mailgun.net/bounces + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '19' + - '66' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:19 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2492' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Unsubscribe event has been removed"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:18 GMT + string: '{"message":"Bounced addresses for this domain have been removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:19 GMT - request: method: post - uri: https://api.mailgun.net/complaints + uri: https://api.mailgun.net/unsubscribes body: encoding: UTF-8 - string: '[{"address":"test4@example.info"},{"address":"test3@example.net"},{"address":"test2@example.org"},{"address":"test1@example.com"}]' + string: '[{"address":"test4@example.info","tag":"123"},{"address":"test3@example.net","tag":"123"},{"address":"test2@example.org","tag":"123"},{"address":"test1@example.com","tag":"123"}]' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Content-Type: - application/json Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -154,29 +435,101 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '68' + Content-Type: + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:19 GMT + - Thu, 26 Mar 2026 12:59:19 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2491' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"message":"4 addresses have been added to the unsubscribes table"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:19 GMT +- request: + method: post + uri: https://api.mailgun.net/unsubscribes + body: + encoding: UTF-8 + string: '[{"address":"test4@example.info","tags":["integration"]},{"address":"test3@example.net","tags":["integration"]},{"address":"test2@example.org","tags":["integration"]},{"address":"test1@example.com","tags":["integration"]}]' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Content-Type: + - application/json + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '0' + - '68' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:20 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2490' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"4 complaint addresses have been added to the complaints - table"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:19 GMT + string: '{"message":"4 addresses have been added to the unsubscribes table"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:20 GMT - request: method: delete - uri: https://api.mailgun.net/complaints/test1@example.com + uri: https://api.mailgun.net/unsubscribes/test1@example.com body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -184,32 +537,50 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '79' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:26:19 GMT - Content-Length: - - '19' + - Thu, 26 Mar 2026 12:59:20 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2489' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Spam complaint has been removed"}' - http_version: - recorded_at: Tue, 25 Feb 2025 00:26:19 GMT + string: '{"address":"test1@example.com","message":"Unsubscribe event has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:20 GMT - request: method: delete - uri: https://api.mailgun.net/bounces/test2@example.org + uri: https://api.mailgun.net/unsubscribes/test2@example.org body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -217,104 +588,205 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '79' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT - Content-Length: - - '19' + - Thu, 26 Mar 2026 12:59:21 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2488' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Bounced address has been removed"} + string: '{"address":"test2@example.org","message":"Unsubscribe event has been + removed"} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:21 GMT - request: method: delete - uri: https://api.mailgun.net/bounces/test3@example.net + uri: https://api.mailgun.net/unsubscribes/test3@example.net body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '79' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT - Content-Length: - - '19' + - Thu, 26 Mar 2026 12:59:21 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2487' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Bounced address has been removed"} + string: '{"address":"test3@example.net","message":"Unsubscribe event has been + removed"} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:21 GMT - request: method: delete - uri: https://api.mailgun.net/bounces/test4@example.info + uri: https://api.mailgun.net/unsubscribes/test4@example.info body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '80' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT + - Thu, 26 Mar 2026 12:59:21 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2486' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test4@example.info","message":"Unsubscribe event has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:22 GMT +- request: + method: post + uri: https://api.mailgun.net/unsubscribes + body: + encoding: UTF-8 + string: address=test777%40example.com&tags=integration + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '19' + - '95' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:22 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2485' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Bounced address has been removed"} + string: '{"address":"test777@example.com","message":"Address has been added + to the unsubscribes table"} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:22 GMT - request: - method: delete - uri: https://api.mailgun.net/unsubscribes/test2@example.org + method: get + uri: https://api.mailgun.net/unsubscribes/test777@example.com body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -322,91 +794,350 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '92' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT + - Thu, 26 Mar 2026 12:59:23 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2484' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test777@example.com","tags":["*"],"created_at":"Thu, 26 + Mar 2026 12:59:22 UTC"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:23 GMT +- request: + method: get + uri: https://api.mailgun.net/unsubscribes + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '19' + - '682' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:23 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2483' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Unsubscribe event has been removed"} + string: '{"items":[{"address":"test777@example.com","tags":["*"],"created_at":"Thu, + 26 Mar 2026 12:59:22 UTC"}],"paging":{"first":"https://api.mailgun.net/unsubscribes?limit=100&term=","last":"https://api.mailgun.net/unsubscribes?page=last&limit=100&term=","next":"https://api.mailgun.net/unsubscribes?page=next&address=test777%40example.com&limit=100&term=","previous":"https://api.mailgun.net/unsubscribes?page=previous&address=test777%40example.com&limit=100&term="}} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:23 GMT - request: - method: delete - uri: https://api.mailgun.net/unsubscribes/test3@example.net + method: post + uri: https://api.mailgun.net/complaints + body: + encoding: UTF-8 + string: '[{"address":"test4@example.info"},{"address":"test3@example.net"},{"address":"test2@example.org"},{"address":"test1@example.com"}]' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Content-Type: + - application/json + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '76' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:24 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2482' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"message":"4 complaint addresses have been added to the complaints + table"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:24 GMT +- request: + method: post + uri: https://api.mailgun.net/complaints + body: + encoding: UTF-8 + string: address=test777%40example.com + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '93' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:24 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2481' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test777@example.com","message":"Address has been added + to the complaints table"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:24 GMT +- request: + method: get + uri: https://api.mailgun.net/complaints/test777@example.com body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '79' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT + - Thu, 26 Mar 2026 12:59:25 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2480' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test777@example.com","created_at":"Thu, 26 Mar 2026 12:59:24 + UTC"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:25 GMT +- request: + method: get + uri: https://api.mailgun.net/complaints + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store Content-Length: - - '19' + - '968' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:25 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2479' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Unsubscribe event has been removed"} + string: '{"items":[{"address":"test1@example.com","created_at":"Thu, 26 Mar + 2026 12:59:24 UTC"},{"address":"test2@example.org","created_at":"Thu, 26 Mar + 2026 12:59:24 UTC"},{"address":"test3@example.net","created_at":"Thu, 26 Mar + 2026 12:59:24 UTC"},{"address":"test4@example.info","created_at":"Thu, 26 + Mar 2026 12:59:24 UTC"},{"address":"test777@example.com","created_at":"Thu, + 26 Mar 2026 12:59:24 UTC"}],"paging":{"first":"https://api.mailgun.net/complaints?limit=100&term=","last":"https://api.mailgun.net/complaints?page=last&limit=100&term=","next":"https://api.mailgun.net/complaints?page=next&address=test777%40example.com&limit=100&term=","previous":"https://api.mailgun.net/complaints?page=previous&address=test1%40example.com&limit=100&term="}} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:25 GMT - request: method: delete - uri: https://api.mailgun.net/unsubscribes/test4@example.info + uri: https://api.mailgun.net/complaints/test1@example.com body: encoding: US-ASCII string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '76' Content-Type: - - text/plain; charset=utf-8 - X-Content-Type-Options: - - nosniff + - application/json; charset=utf-8 Date: - - Tue, 25 Feb 2025 00:49:48 GMT - Content-Length: - - '19' + - Thu, 26 Mar 2026 12:59:26 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2478' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Unsubscribe event has been removed"} + string: '{"address":"test1@example.com","message":"Spam complaint has been removed"} ' - http_version: - recorded_at: Tue, 25 Feb 2025 00:49:48 GMT + recorded_at: Thu, 26 Mar 2026 12:59:26 GMT - request: method: delete uri: https://api.mailgun.net/complaints/test2@example.org @@ -415,11 +1146,11 @@ http_interactions: string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: @@ -427,19 +1158,36 @@ http_interactions: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '76' + Content-Type: + - application/json; charset=utf-8 Date: - - Sun, 26 Jan 2025 07:29:45 GMT + - Thu, 26 Mar 2026 12:59:26 GMT Strict-Transport-Security: - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2477' + X-Request-Reset: + - '1774529969637' X-Xss-Protection: - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Spam complaint has been removed"} + string: '{"address":"test2@example.org","message":"Spam complaint has been removed"} ' - http_version: - recorded_at: Sun, 26 Jan 2025 07:29:45 GMT + recorded_at: Thu, 26 Mar 2026 12:59:26 GMT - request: method: delete uri: https://api.mailgun.net/complaints/test3@example.net @@ -448,31 +1196,48 @@ http_interactions: string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '76' + Content-Type: + - application/json; charset=utf-8 Date: - - Sun, 26 Jan 2025 07:29:45 GMT + - Thu, 26 Mar 2026 12:59:27 GMT Strict-Transport-Security: - - max-age=63072000; includeSubDomains + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2476' + X-Request-Reset: + - '1774529969637' X-Xss-Protection: - - 1; mode=block + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Spam complaint has been removed"} + string: '{"address":"test3@example.net","message":"Spam complaint has been removed"} ' - http_version: - recorded_at: Sun, 26 Jan 2025 07:29:45 GMT + recorded_at: Thu, 26 Mar 2026 12:59:27 GMT - request: method: delete uri: https://api.mailgun.net/complaints/test4@example.info @@ -481,29 +1246,147 @@ http_interactions: string: '' headers: User-Agent: - - mailgun-sdk-ruby/1.3.2 + - mailgun-sdk-ruby/1.4.2 Accept: - - "*/*" + - "*/*" Authorization: - - Basic xxx + - Basic XXX Accept-Encoding: - - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 response: status: code: 200 message: OK headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '77' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:27 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2476' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block + body: + encoding: UTF-8 + string: '{"address":"test4@example.info","message":"Spam complaint has been + removed"} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:27 GMT +- request: + method: get + uri: https://api.mailgun.net/bounces + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '477' + Content-Type: + - application/json; charset=utf-8 Date: - - Sun, 26 Jan 2025 07:29:45 GMT + - Thu, 26 Mar 2026 12:59:28 GMT Strict-Transport-Security: - - max-age=63072000; includeSubDomains + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2474' + X-Request-Reset: + - '1774529969637' X-Xss-Protection: - - 1; mode=block + - 1; mode=block + body: + encoding: UTF-8 + string: '{"items":[],"paging":{"first":"https://api.mailgun.net/bounces?limit=100&term=","last":"https://api.mailgun.net/bounces?limit=100&term=","next":"https://api.mailgun.net/bounces?limit=100&term=","previous":"https://api.mailgun.net/bounces?limit=100&term="}} + + ' + recorded_at: Thu, 26 Mar 2026 12:59:28 GMT +- request: + method: get + uri: https://api.mailgun.net/v3?limit=100&term= + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - mailgun-sdk-ruby/1.4.2 + Accept: + - "*/*" + Authorization: + - Basic XXX + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Origin: + - "*" + Cache-Control: + - no-store + Content-Length: + - '477' + Content-Type: + - application/json; charset=utf-8 + Date: + - Thu, 26 Mar 2026 12:59:28 GMT + Strict-Transport-Security: + - max-age=63072000; includeSubDomains + X-Mailgun-Key-Id: + - XXX + X-Request-Limit: + - '2500' + X-Request-Remaining: + - '2473' + X-Request-Reset: + - '1774529969637' + X-Xss-Protection: + - 1; mode=block body: encoding: UTF-8 - string: '{"message":"Spam complaint has been removed"} + string: '{"items":[],"paging":{"first":"https://api.mailgun.net/bounces?limit=100&term=","last":"https://api.mailgun.net/bounces?limit=100&term=","next":"https://api.mailgun.net/bounces?limit=100&term=","previous":"https://api.mailgun.net/bounces?limit=100&term="}} ' - http_version: - recorded_at: Sun, 26 Jan 2025 07:29:45 GMT -recorded_with: VCR 3.0.3 + recorded_at: Thu, 26 Mar 2026 12:59:28 GMT +recorded_with: VCR 6.4.0 From fb47921fdd7dfd543b472ce96ea4ec87878671f6 Mon Sep 17 00:00:00 2001 From: Alex Lebedev <6421109+alex-leb@users.noreply.github.com> Date: Thu, 26 Mar 2026 15:40:23 +0200 Subject: [PATCH 2/2] DE-1740: fix rubocop Signed-off-by: Alex Lebedev <6421109+alex-leb@users.noreply.github.com> --- spec/integration/suppressions_spec.rb | 47 +++++++++++++-------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/spec/integration/suppressions_spec.rb b/spec/integration/suppressions_spec.rb index 6679caa..0b7d005 100644 --- a/spec/integration/suppressions_spec.rb +++ b/spec/integration/suppressions_spec.rb @@ -5,7 +5,7 @@ require 'mailgun' require 'mailgun/suppressions' -vcr_opts = { cassette_name: 'suppressions', match_requests_on: %i[uri method body] } +vcr_opts = { cassette_name: 'suppressions', match_requests_on: %i[uri method body] } describe 'For the suppressions handling class', order: :defined, vcr: vcr_opts do let(:mg_obj) { Mailgun::Client.new(APIKEY, APIHOST, 'v3') } @@ -43,7 +43,7 @@ it 'returns nil if no bounces passed' do response = suppress.create_bounces({}) - expect(response[0]).to eq(nil) + expect(response[0]).to be_nil end it 'creates a single bounce' do @@ -149,7 +149,7 @@ it 'returns nil if no unsubscribes passed' do response = suppress.create_unsubscribes({}) - expect(response[0]).to eq(nil) + expect(response[0]).to be_nil end it 'removes a single unsubscribe address' do @@ -164,9 +164,9 @@ it 'creates a single unsubscribe' do response = suppress.create_unsubscribe({ - address: 'test777@example.com', - tags: ['integration'] - }) + address: 'test777@example.com', + tags: ['integration'] + }) response.to_h! expect(response.code).to eq(200) @@ -174,7 +174,7 @@ end it 'returns a single unsubscribe' do - response = suppress.get_unsubscribe( 'test777@example.com') + response = suppress.get_unsubscribe('test777@example.com') response.to_h! expect(response.code).to eq(200) @@ -215,11 +215,11 @@ it 'returns nil if no complaints passed' do response = suppress.create_complaints({}) - expect(response[0]).to eq(nil) + expect(response[0]).to be_nil end it 'creates a single complaint' do - response = suppress.create_complaint({ address: 'test777@example.com'}) + response = suppress.create_complaint({ address: 'test777@example.com' }) response.to_h! expect(response.code).to eq(200) @@ -227,7 +227,7 @@ end it 'returns a single complaint' do - response = suppress.get_complaint( 'test777@example.com') + response = suppress.get_complaint('test777@example.com') response.to_h! expect(response.code).to eq(200) @@ -275,26 +275,23 @@ end context 'with 1000 or more entries' do + subject(:suppressions) { Mailgun::Suppressions.new(client, domain) } + let(:large_list) { Array.new(1000) { |i| { address: "user#{i}@example.com" } } } let(:client) { double(:client) } let(:domain) { 'example.com' } def stub_response(body = {}) double(:response).tap do |r| - allow(r).to receive(:to_h).and_return(body) - allow(r).to receive(:to_h!).and_return(body) - allow(r).to receive(:code).and_return(200) - allow(r).to receive(:body).and_return(body) + allow(r).to receive_messages(to_h: body, to_h!: body, code: 200, body: body) end end - subject(:suppressions) { Mailgun::Suppressions.new(client, domain) } - it 'splits bounces list and makes two POST requests' do expect(client).to receive(:post) - .with('example.com/bounces', anything, { 'Content-Type' => 'application/json' }) - .twice - .and_return(stub_response) + .with('example.com/bounces', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) _resp, split = suppressions.create_bounces(large_list) expect(split).not_to be_empty @@ -302,9 +299,9 @@ def stub_response(body = {}) it 'splits unsubscribes list and makes two POST requests' do expect(client).to receive(:post) - .with('example.com/unsubscribes', anything, { 'Content-Type' => 'application/json' }) - .twice - .and_return(stub_response) + .with('example.com/unsubscribes', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) _resp, split = suppressions.create_unsubscribes(large_list) expect(split).not_to be_empty @@ -312,9 +309,9 @@ def stub_response(body = {}) it 'splits complaints list and makes two POST requests' do expect(client).to receive(:post) - .with('example.com/complaints', anything, { 'Content-Type' => 'application/json' }) - .twice - .and_return(stub_response) + .with('example.com/complaints', anything, { 'Content-Type' => 'application/json' }) + .twice + .and_return(stub_response) _resp, split = suppressions.create_complaints(large_list) expect(split).not_to be_empty