mailgun-ruby 1.4.4 → 1.4.5

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.
data/README.md CHANGED
@@ -19,7 +19,7 @@ gem install mailgun-ruby
19
19
  Gemfile:
20
20
 
21
21
  ```ruby
22
- gem 'mailgun-ruby', '~>1.4.4'
22
+ gem 'mailgun-ruby', '~>1.4.5'
23
23
  ```
24
24
 
25
25
  Usage
@@ -187,6 +187,7 @@ This SDK includes the following components:
187
187
  - [Domains](docs/Domains.md)
188
188
  - [Webhooks](docs/Webhooks.md)
189
189
  - [Account Webhooks](docs/AccountWebhooks.md)
190
+ - [API Keys](docs/ApiKeys.md)
190
191
  - [Events](docs/Events.md)
191
192
  - [Snippets](docs/Snippets.md)
192
193
  - [Subaccounts](docs/Subaccounts.md)
data/docs/ApiKeys.md ADDED
@@ -0,0 +1,65 @@
1
+ Mailgun - API Keys
2
+ ====================
3
+
4
+ This is the Mailgun Ruby *API Keys* utilities.
5
+
6
+ The below assumes you've already installed the Mailgun Ruby SDK in to your
7
+ project. If not, go back to the master README for instructions.
8
+
9
+ Usage - API Keys
10
+ -----------------------
11
+
12
+ ```ruby
13
+ # First, instantiate the Mailgun Client with your API key
14
+ mg_client = Mailgun::Client.new('your-api-key', 'api.mailgun.net', 'v1')
15
+ api_keys = Mailgun::ApiKeys.new(mg_client)
16
+ ```
17
+
18
+ API Keys methods:
19
+
20
+ ```ruby
21
+ # List API keys
22
+ api_keys.list
23
+
24
+ # List API keys filtered by kind and domain
25
+ api_keys.list(kind: 'domain', domain_name: 'my.perfect.domain')
26
+
27
+ # Create a user API key
28
+ api_keys.create(
29
+ kind: 'user',
30
+ role: 'admin',
31
+ description: 'desc'
32
+ )
33
+
34
+ # Create a sending key for a domain, expiring in 1 day
35
+ api_keys.create(
36
+ kind: 'domain',
37
+ domain_name: 'my.perfect.domain',
38
+ role: 'sending',
39
+ expiration: 86_400
40
+ )
41
+
42
+ # Delete an API key
43
+ api_keys.remove('key-id')
44
+
45
+ # Regenerate the public API key
46
+ api_keys.regenerate
47
+ ```
48
+
49
+ Supported `create` options:
50
+
51
+ | Option | Description |
52
+ |---------------|-------------|
53
+ | `kind` | Type of API key: `domain`, `user` or `web`. Defaults to `user` |
54
+ | `role` | Key role: `admin`, `basic`, `sending` (for `domain` keys) or `developer` |
55
+ | `domain_name` | Domain to associate with the key, for `domain` keys |
56
+ | `description` | Key description |
57
+ | `expiration` | Key lifetime in seconds, must be greater than 0 if set |
58
+ | `user_id` | API key user's ID, should be provided for `web` keys |
59
+ | `user_name` | API key user's name |
60
+ | `email` | API key user's email address, should be provided for `web` keys |
61
+
62
+ More Documentation
63
+ ------------------
64
+ See the official [Mailgun API Keys Docs](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/keys)
65
+ for more information
data/docs/Webhooks.md CHANGED
@@ -18,24 +18,47 @@ hook = Mailgun::Webhooks.new(mg_client)
18
18
  hook.list 'my.perfect.domain'
19
19
 
20
20
  # View a single webhook detail
21
- hook.info 'my.perfect.domain', 'deliver'
21
+ hook.info 'my.perfect.domain', 'delivered'
22
22
 
23
23
  # Add a single url for all webhooks
24
24
  hook.create_all 'my.perfect.domain', 'https://the.webhook.url/'
25
25
 
26
26
  # Add a url for a specific webhook
27
- hook.create 'my.perfect.domain', 'deliver', 'https://the.webhook.url/'
27
+ hook.create 'my.perfect.domain', 'delivered', 'https://the.webhook.url/'
28
28
 
29
29
  # Update the url for a specific webhook
30
- hook.update 'my.perfect.domain', 'deliver', 'https://the.webhook.url/'
30
+ hook.update 'my.perfect.domain', 'delivered', 'https://the.webhook.url/'
31
31
 
32
32
  # Remove a url for a specific webhook
33
- hook.remove 'my.perfect.domain', 'deliver'
33
+ hook.remove 'my.perfect.domain', 'delivered'
34
34
 
35
35
  # Remove all webhooks for a domain
36
36
  hook.remove_all 'my.perfect.domain'
37
37
  ```
38
38
 
39
+ Usage - Webhooks (v4)
40
+ -----------------------
41
+
42
+ The v4 endpoints work with a URL across multiple event types in a single request.
43
+ They require a client configured for the `v4` API.
44
+
45
+ ```ruby
46
+ mg_client = Mailgun::Client.new('your-api-key', 'api.mailgun.net', 'v4')
47
+ hook = Mailgun::Webhooks.new(mg_client)
48
+
49
+ # Associate a url with one or more event types
50
+ hook.create_v4 'my.perfect.domain', url: 'https://the.webhook.url/', event_types: %w[delivered opened]
51
+
52
+ # Replace the event types associated with a url
53
+ hook.update_v4 'my.perfect.domain', url: 'https://the.webhook.url/', event_types: %w[clicked]
54
+
55
+ # Remove one or more urls from all event types they are associated with
56
+ hook.remove_v4 'my.perfect.domain', url: 'https://the.webhook.url/'
57
+ hook.remove_v4 'my.perfect.domain', url: ['https://the.webhook.url/', 'https://another.webhook.url/']
58
+ ```
59
+
60
+ Each v4 method returns a Hash of the domain's webhooks keyed by event type.
61
+
39
62
  More Documentation
40
63
  ------------------
41
64
  See the official [Mailgun Webhooks Docs](https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/domain-webhooks)
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mailgun
4
+ # A Mailgun::ApiKeys object is a simple CRUD interface to Mailgun Api Keys.
5
+ # Uses Mailgun
6
+ class ApiKeys
7
+ include ApiVersionChecker
8
+
9
+ # Public creates a new Mailgun::ApiKeys instance.
10
+ # Defaults to Mailgun::Client
11
+ def initialize(client = Mailgun::Client.new(Mailgun.api_key, Mailgun.api_host || 'api.mailgun.net', 'v1'))
12
+ @client = client
13
+ end
14
+
15
+ # Public: List Mailgun API keys
16
+ #
17
+ # options - [Hash] of
18
+ # domain_name - [String] Domain name filter for domain keys
19
+ # kind - [String] Key kind filter ('domain', 'user', or 'web')
20
+ #
21
+ # Retrieve filtered api keys.
22
+ def list(options = {})
23
+ res = @client.get('keys', options)
24
+ res.to_h['items']
25
+ end
26
+
27
+ # Public: Create Mailgun API key
28
+
29
+ # options - [Hash] of
30
+ # domain_name - [String] Web domain to associate with the key, for keys of 'domain' kind
31
+ # kind - [String] Type of API key ('domain', 'user', or 'web'). Defaults to 'user' if not provided.
32
+ # description - [String] Key description
33
+ # expiration - [String] Key lifetime in seconds, must be greater than 0 if set
34
+ # role - [String] Key role ('admin', 'basic' [use in place of analyst],
35
+ # 'sending' [use with keys of domain kind], or 'developer')
36
+ # user_id - [String] API Key user's string user ID; should be provided for all keys of 'web' kind
37
+ # user_name - [String] API Key user's name
38
+ # email - [String] API Key user's email address; should be provided for all keys of 'web' kind
39
+ #
40
+ # Returns the Api Key object
41
+ def create(options = {})
42
+ res = @client.post('keys', options)
43
+ res.to_h['key']
44
+ end
45
+
46
+ # Public: Delete Mailgun API key
47
+ #
48
+ # key_id - [String] The Key ID generated by Mailgun on key creation
49
+ #
50
+ # Returns a Boolean of the success
51
+ def remove(key_id)
52
+ @client.delete("keys/#{key_id}").status == 200
53
+ end
54
+
55
+ # Public: Regenerate Mailgun Public API key
56
+ #
57
+ # Returns new Mailgun Public API key.
58
+ def regenerate
59
+ res = @client.post('keys/public', {})
60
+ res.to_h['key']
61
+ end
62
+
63
+ enforces_api_version 'v1', :list, :create, :remove, :regenerate
64
+ end
65
+ end
@@ -13,7 +13,7 @@ module Mailgun
13
13
  api_host = Mailgun.api_host || 'api.mailgun.net',
14
14
  api_version = Mailgun.api_version || 'v3',
15
15
  ssl = true,
16
- test_mode = !Mailgun.test_mode.nil?,
16
+ test_mode = Mailgun.test_mode ? true : false,
17
17
  timeout = nil,
18
18
  proxy_url = Mailgun.proxy_url)
19
19
  endpoint = endpoint_generator(api_host, api_version, ssl)
@@ -2,5 +2,5 @@
2
2
 
3
3
  # It's the version. Yeay!
4
4
  module Mailgun
5
- VERSION = '1.4.4'
5
+ VERSION = '1.4.5'
6
6
  end
@@ -58,12 +58,13 @@ module Mailgun
58
58
  #
59
59
  # domain - A String of the domain name (ex. domain.com)
60
60
  # action - A String of the action to create a webhook for
61
- # url - A String of the url of the webhook
61
+ # url - A String of the url of the webhook, or an Array of up to 3 urls
62
62
  #
63
63
  # Returns a Boolean of whether the webhook was created
64
64
  def create(domain, action, url = '')
65
65
  res = @client.post("domains/#{domain}/webhooks", id: action, url: url)
66
- res.to_h['webhook']['urls'].include?(url) && res.to_h['message'] == 'Webhook has been created'
66
+ urls = res.to_h['webhook']['urls']
67
+ Array(url).all? { |u| urls.include?(u) } && res.to_h['message'] == 'Webhook has been created'
67
68
  end
68
69
 
69
70
  # :nocov:
@@ -84,7 +85,8 @@ module Mailgun
84
85
  # Returns true or false
85
86
  # :nocov:
86
87
  %i[create_all add_all_webhooks].each do |method|
87
- define_method(method) do |domain|
88
+ define_method(method) do |domain, url|
89
+ url ||= ''
88
90
  warn("`#{method}` method will be deprecated in future versions of Mailgun. Please use `create` instead.")
89
91
 
90
92
  ACTIONS.each do |action|
@@ -97,13 +99,13 @@ module Mailgun
97
99
  # Public: Update webhook
98
100
  #
99
101
  # domain - A String of the domain name (ex. domain.com)
100
- # action - A String of the action to create a webhook for
101
- # url - A String of the url of the webhook
102
+ # action - A String of the action to update the webhook for
103
+ # url - A String of the url of the webhook, or an Array of up to 3 urls
102
104
  #
103
105
  # Returns a Boolean of whether the webhook was updated
104
106
  def update(domain, action, url = '')
105
- raise Mailgun::ParameterError('Domain not provided to update webhooks') unless domain
106
- raise Mailgun::ParameterError('Action not provided to identify webhook to update') unless action
107
+ raise Mailgun::ParameterError, 'Domain not provided to update webhooks' if domain.to_s.empty?
108
+ raise Mailgun::ParameterError, 'Action not provided to identify webhook to update' if action.to_s.empty?
107
109
 
108
110
  res = @client.put("domains/#{domain}/webhooks/#{action}", id: action, url: url)
109
111
  res.to_h['message'] == 'Webhook has been updated'
@@ -123,8 +125,8 @@ module Mailgun
123
125
  #
124
126
  # Returns a Boolean of the success
125
127
  def remove(domain, action)
126
- raise Mailgun::ParameterError('Domain not provided to remove webhook from') unless domain
127
- raise Mailgun::ParameterError('Action not provided to identify webhook to remove') unless action
128
+ raise Mailgun::ParameterError, 'Domain not provided to remove webhook from' if domain.to_s.empty?
129
+ raise Mailgun::ParameterError, 'Action not provided to identify webhook to remove' if action.to_s.empty?
128
130
 
129
131
  @client.delete("domains/#{domain}/webhooks/#{action}").to_h['message'] == 'Webhook has been deleted'
130
132
  end
@@ -148,7 +150,7 @@ module Mailgun
148
150
  define_method(method) do |domain|
149
151
  warn("`#{method}` method will be deprecated in future versions of Mailgun. Please use `remove` instead.")
150
152
 
151
- raise Mailgun::ParameterError('Domain not provided to remove webhooks from') unless domain
153
+ raise Mailgun::ParameterError, 'Domain not provided to remove webhooks from' if domain.to_s.empty?
152
154
 
153
155
  ACTIONS.each do |action|
154
156
  remove domain, action
@@ -157,6 +159,43 @@ module Mailgun
157
159
  end
158
160
  # :nocov:
159
161
 
162
+ # Public: Create webhooks for multiple event types (v4)
163
+ #
164
+ # domain - [String] The domain name to create webhooks for
165
+ # url - [String] The webhook URL that will receive POST requests
166
+ # event_types - [String, Array<String>] Event types to associate with the URL
167
+ #
168
+ # Returns a Hash of the domain webhooks keyed by event type
169
+ def create_v4(domain, url:, event_types:)
170
+ res = @client.post("domains/#{domain}/webhooks", { url: url, event_types: event_types })
171
+ res.to_h['webhooks']
172
+ end
173
+
174
+ # Public: Update the event types associated with a webhook URL (v4)
175
+ #
176
+ # domain - [String] The domain name to update webhooks for
177
+ # url - [String] The webhook URL to update
178
+ # event_types - [String, Array<String>] Event types to associate with the URL.
179
+ # Replaces the existing associations.
180
+ #
181
+ # Returns a Hash of the domain webhooks keyed by event type
182
+ def update_v4(domain, url:, event_types:)
183
+ res = @client.put("domains/#{domain}/webhooks", { url: url, event_types: event_types })
184
+ res.to_h['webhooks']
185
+ end
186
+
187
+ # Public: Delete webhook URLs from all event types they are associated with (v4)
188
+ #
189
+ # domain - [String] The domain name to delete webhooks from
190
+ # url - [String, Array<String>] The webhook URL(s) to delete
191
+ #
192
+ # Returns a Hash of the remaining domain webhooks keyed by event type
193
+ def remove_v4(domain, url:)
194
+ res = @client.delete("domains/#{domain}/webhooks", { url: url })
195
+ res.to_h['webhooks']
196
+ end
197
+
160
198
  enforces_api_version 'v3', :list, :get, :create, :update, :remove
199
+ enforces_api_version 'v4', :create_v4, :update_v4, :remove_v4
161
200
  end
162
201
  end
data/lib/mailgun.rb CHANGED
@@ -23,6 +23,7 @@ Zeitwerk::Loader.for_gem.tap do |loader|
23
23
  loader.ignore("#{__dir__}/railgun.rb")
24
24
  loader.ignore("#{__dir__}/railgun")
25
25
 
26
+ loader.collapse("#{__dir__}/mailgun/api_keys")
26
27
  loader.collapse("#{__dir__}/mailgun/analytics_tags")
27
28
  loader.collapse("#{__dir__}/mailgun/domains")
28
29
  loader.collapse("#{__dir__}/mailgun/events")
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'mailgun'
5
+
6
+ vcr_opts = { cassette_name: 'api_keys' }
7
+
8
+ describe 'ApiKeys', order: :defined, vcr: vcr_opts do
9
+ let(:api_version) { 'v1' }
10
+ let(:mg_client) { Mailgun::Client.new(APIKEY, APIHOST, api_version, SSL) }
11
+ let(:mg_obj) { Mailgun::ApiKeys.new(mg_client) }
12
+
13
+ it 'creates an api key' do
14
+ result = mg_obj.create(
15
+ {
16
+ kind: 'user',
17
+ 'description': 'test test',
18
+ 'role': 'admin'
19
+ }
20
+ )
21
+
22
+ expect(result['description']).to eq('test test')
23
+ end
24
+
25
+ it 'gets api keys' do
26
+ result = mg_obj.list
27
+
28
+ expect(result[0]['id']).to eq('test')
29
+ end
30
+
31
+ it 'gets api keys filtered by kind and domain' do
32
+ result = mg_obj.list(kind: 'domain', domain_name: 'DOMAIN.TEST')
33
+
34
+ domain_keys = result.select { |key| key['kind'] == 'domain' }
35
+ expect(domain_keys.map { |key| key['domain_name'] }).to eq(['DOMAIN.TEST'])
36
+ expect(result.map { |key| key['kind'] }).not_to include('user', 'web')
37
+ end
38
+
39
+ it 'removes an api key' do
40
+ result = mg_obj.remove('test')
41
+
42
+ expect(result).to be_truthy
43
+ end
44
+
45
+ it 'regenerates public api key' do
46
+ result = mg_obj.regenerate
47
+
48
+ expect(result).to be_truthy
49
+ end
50
+ end
@@ -43,3 +43,37 @@ describe 'For the webhooks endpoint', order: :defined, vcr: vcr_opts do
43
43
  expect(result).to be_truthy
44
44
  end
45
45
  end
46
+
47
+ describe 'For the v4 webhooks endpoint', vcr: { cassette_name: 'webhooks_v4' } do
48
+ let(:mg_client) { Mailgun::Client.new(APIKEY, APIHOST, 'v4', SSL) }
49
+ let(:mg_obj) { Mailgun::Webhooks.new(mg_client) }
50
+ let(:domain) { 'DOMAIN.TEST' }
51
+ let(:url) { 'http://example.com/mailgun/events/v4' }
52
+
53
+ describe '#create_v4' do
54
+ it 'creates webhooks for multiple event types' do
55
+ result = mg_obj.create_v4(domain, url: url, event_types: %w[accepted delivered])
56
+
57
+ expect(result.keys).to contain_exactly('accepted', 'delivered')
58
+ expect(result['accepted']['urls']).to include(url)
59
+ expect(result['delivered']['urls']).to include(url)
60
+ end
61
+ end
62
+
63
+ describe '#update_v4' do
64
+ it 'replaces the event types associated with a url' do
65
+ result = mg_obj.update_v4(domain, url: url, event_types: %w[clicked opened])
66
+
67
+ expect(result.keys).to contain_exactly('clicked', 'opened')
68
+ expect(result['clicked']['urls']).to include(url)
69
+ end
70
+ end
71
+
72
+ describe '#remove_v4' do
73
+ it 'removes the urls from all event types' do
74
+ result = mg_obj.remove_v4(domain, url: [url, 'http://example.com/mailgun/events/v4-other'])
75
+
76
+ expect(result).to eq({})
77
+ end
78
+ end
79
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,6 +17,8 @@ require 'mailgun'
17
17
 
18
18
  require 'vcr'
19
19
  require 'webmock/rspec'
20
+ # Keep repeated query keys (e.g. ?url=a&url=b) instead of collapsing them to the last value
21
+ WebMock::Config.instance.query_values_notation = :flat_array
20
22
  require 'rspec/its'
21
23
 
22
24
  # WebMock.disable_net_connect!(allow_localhost: true)
@@ -43,6 +45,7 @@ VCR.configure do |c|
43
45
  c.hook_into :webmock
44
46
  c.default_cassette_options = { record: :new_episodes }
45
47
  c.filter_sensitive_data('<APIKEY>') { APIKEY }
48
+ c.filter_sensitive_data('<BASIC_AUTH>') { ["api:#{APIKEY}"].pack('m0') } if APIKEY
46
49
  c.filter_sensitive_data('DOMAIN.TEST') { TESTDOMAIN }
47
50
  c.filter_sensitive_data('<PUBKEY>') { PUB_APIKEY }
48
51
 
@@ -54,6 +54,30 @@ describe Mailgun::Client do
54
54
  it 'supports EU api host' do
55
55
  expect { described_class.new(api_key, 'api.eu.mailgun.net') }.not_to raise_error
56
56
  end
57
+
58
+ context 'when test_mode is not passed' do
59
+ around do |example|
60
+ original = Mailgun.test_mode
61
+ example.run
62
+ ensure
63
+ Mailgun.test_mode = original
64
+ end
65
+
66
+ it 'enables test mode when Mailgun.test_mode is true' do
67
+ Mailgun.test_mode = true
68
+ expect(described_class.new(api_key).test_mode?).to be(true)
69
+ end
70
+
71
+ it 'disables test mode when Mailgun.test_mode is false' do
72
+ Mailgun.test_mode = false
73
+ expect(described_class.new(api_key).test_mode?).to be(false)
74
+ end
75
+
76
+ it 'disables test mode when Mailgun.test_mode is not set' do
77
+ Mailgun.test_mode = nil
78
+ expect(described_class.new(api_key).test_mode?).to be(false)
79
+ end
80
+ end
57
81
  end
58
82
 
59
83
  # ---------------------------------------------------------------------------
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Mailgun::Webhooks do
6
+ let(:client) { double(:client) }
7
+ let(:webhooks) { described_class.new(client) }
8
+ let(:domain) { 'example.com' }
9
+ let(:url) { 'https://example.com/mailgun/events' }
10
+
11
+ %i[create_all add_all_webhooks].each do |method|
12
+ describe "##{method}" do
13
+ it 'creates every webhook action with the provided URL' do
14
+ described_class::ACTIONS.each do |action|
15
+ expect(webhooks).to receive(:create).with(domain, action, url).ordered
16
+ end
17
+
18
+ expect { webhooks.public_send(method, domain, url) }
19
+ .to output(/`#{method}` method will be deprecated/).to_stderr
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'with v3 endpoints' do
25
+ let(:client) { instance_double(Mailgun::Client, api_version: 'v3') }
26
+
27
+ describe '#create' do
28
+ let(:urls) { [url, 'https://example.com/other'] }
29
+ let(:response) do
30
+ instance_double(Mailgun::Response,
31
+ to_h: { 'message' => 'Webhook has been created', 'webhook' => { 'urls' => urls } })
32
+ end
33
+
34
+ before { allow(client).to receive(:post).and_return(response) }
35
+
36
+ it 'returns true when a single url was created' do
37
+ expect(webhooks.create(domain, 'delivered', url)).to be(true)
38
+ end
39
+
40
+ it 'returns true when multiple urls were created' do
41
+ expect(webhooks.create(domain, 'delivered', urls)).to be(true)
42
+ end
43
+
44
+ it 'returns false when a url is missing from the response' do
45
+ expect(webhooks.create(domain, 'delivered', [url, 'https://example.com/missing'])).to be(false)
46
+ end
47
+ end
48
+
49
+ describe 'parameter validation' do
50
+ it 'raises a ParameterError when the domain is missing' do
51
+ [nil, ''].each do |blank|
52
+ expect { webhooks.update(blank, 'delivered', url) }
53
+ .to raise_error(Mailgun::ParameterError, 'Domain not provided to update webhooks')
54
+ expect { webhooks.remove(blank, 'delivered') }
55
+ .to raise_error(Mailgun::ParameterError, 'Domain not provided to remove webhook from')
56
+ end
57
+ end
58
+
59
+ it 'raises a ParameterError when the action is missing' do
60
+ [nil, ''].each do |blank|
61
+ expect { webhooks.update(domain, blank, url) }
62
+ .to raise_error(Mailgun::ParameterError, 'Action not provided to identify webhook to update')
63
+ expect { webhooks.remove(domain, blank) }
64
+ .to raise_error(Mailgun::ParameterError, 'Action not provided to identify webhook to remove')
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'with v4 endpoints' do
71
+ let(:api_version) { 'v4' }
72
+ let(:client) { instance_double(Mailgun::Client, api_version: api_version) }
73
+ let(:response) { instance_double(Mailgun::Response, to_h: { 'webhooks' => { 'accepted' => { 'urls' => [url] } } }) }
74
+
75
+ describe '#create_v4' do
76
+ it 'posts the url and event types to the domain webhooks endpoint' do
77
+ expect(client).to receive(:post)
78
+ .with("domains/#{domain}/webhooks", { url: url, event_types: %w[accepted delivered] })
79
+ .and_return(response)
80
+
81
+ expect(webhooks.create_v4(domain, url: url, event_types: %w[accepted delivered]))
82
+ .to eq('accepted' => { 'urls' => [url] })
83
+ end
84
+ end
85
+
86
+ describe '#update_v4' do
87
+ it 'puts the url and event types to the domain webhooks endpoint' do
88
+ expect(client).to receive(:put)
89
+ .with("domains/#{domain}/webhooks", { url: url, event_types: 'accepted' })
90
+ .and_return(response)
91
+
92
+ expect(webhooks.update_v4(domain, url: url, event_types: 'accepted'))
93
+ .to eq('accepted' => { 'urls' => [url] })
94
+ end
95
+ end
96
+
97
+ describe '#remove_v4' do
98
+ it 'sends the urls as query params' do
99
+ urls = [url, 'https://example.com/other']
100
+ expect(client).to receive(:delete)
101
+ .with("domains/#{domain}/webhooks", { url: urls })
102
+ .and_return(response)
103
+
104
+ webhooks.remove_v4(domain, url: urls)
105
+ end
106
+ end
107
+
108
+ context 'when the client api version is not v4' do
109
+ let(:api_version) { 'v3' }
110
+
111
+ it 'raises a ParameterError' do
112
+ expect { webhooks.create_v4(domain, url: url, event_types: 'accepted') }
113
+ .to raise_error(Mailgun::ParameterError, /must be v4/)
114
+ expect { webhooks.update_v4(domain, url: url, event_types: 'accepted') }
115
+ .to raise_error(Mailgun::ParameterError, /must be v4/)
116
+ expect { webhooks.remove_v4(domain, url: url) }
117
+ .to raise_error(Mailgun::ParameterError, /must be v4/)
118
+ end
119
+ end
120
+ end
121
+ end