Skip to content

Commit 586d1ca

Browse files
committed
Refactor EmailTemplates to inherit Client
1 parent fee2a44 commit 586d1ca

File tree

8 files changed

+176
-2
lines changed

8 files changed

+176
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## [2.4.0] - 2025-05-12
2+
3+
- Added Email Templates API support
4+
15
## [2.3.0] - 2025-03-06
26

37
- Drop Ruby 3.0 support

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
mailtrap (2.3.0)
4+
mailtrap (2.4.0)
55

66
GEM
77
remote: https://rubygems.org/

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,16 @@ Refer to the [`examples`](examples) folder for more examples.
6666

6767
- [Full](examples/full.rb)
6868
- [Email template](examples/email_template.rb)
69+
- [Email templates management](examples/email_templates.rb)
6970
- [ActionMailer](examples/action_mailer.rb)
7071

72+
### Email Templates management
73+
74+
```ruby
75+
client = Mailtrap::EmailTemplates.new(api_key: 'your-api-key')
76+
templates = client.all(account_id: 1)
77+
```
78+
7179
### Content-Transfer-Encoding
7280

7381
`mailtrap` gem uses Mailtrap API to send emails. Mailtrap API does not try to

examples/email_templates.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
require 'mailtrap'
2+
3+
client = Mailtrap::EmailTemplates.new(api_key: 'your-api-key')
4+
account_id = 1
5+
6+
# list templates
7+
client.all(account_id:)
8+
9+
# create template
10+
created = client.create(
11+
account_id:,
12+
name: 'Newsletter Template',
13+
subject: 'Subject',
14+
category: 'Newsletter',
15+
body_html: '<div>Hello</div>'
16+
)
17+
18+
# update template
19+
client.update(
20+
account_id:,
21+
email_template_id: created[:id],
22+
name: 'Updated Template'
23+
)
24+
25+
# delete template
26+
client.delete(account_id:, email_template_id: created[:id])

lib/mailtrap.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
require_relative 'mailtrap/mail'
55
require_relative 'mailtrap/errors'
66
require_relative 'mailtrap/version'
7+
require_relative 'mailtrap/email_templates'
78

89
module Mailtrap; end

lib/mailtrap/email_templates.rb

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# frozen_string_literal: true
2+
3+
module Mailtrap
4+
class EmailTemplates < Client
5+
API_HOST = 'mailtrap.io'
6+
API_PORT = 443
7+
8+
def initialize(api_key:, api_host: API_HOST, api_port: API_PORT)
9+
super
10+
end
11+
12+
def all(account_id:)
13+
request(:get, "/api/accounts/#{account_id}/email_templates")
14+
end
15+
16+
def create(account_id:, **params)
17+
request(:post, "/api/accounts/#{account_id}/email_templates", params)
18+
end
19+
20+
def update(account_id:, email_template_id:, **params)
21+
request(
22+
:patch,
23+
"/api/accounts/#{account_id}/email_templates/#{email_template_id}",
24+
params
25+
)
26+
end
27+
28+
def delete(account_id:, email_template_id:)
29+
request(:delete, "/api/accounts/#{account_id}/email_templates/#{email_template_id}")
30+
true
31+
end
32+
33+
private
34+
35+
def request(http_method, path, body = nil) # rubocop:disable Metrics/MethodLength
36+
request_class = {
37+
get: Net::HTTP::Get,
38+
post: Net::HTTP::Post,
39+
patch: Net::HTTP::Patch,
40+
delete: Net::HTTP::Delete
41+
}.fetch(http_method)
42+
43+
request = request_class.new(path)
44+
request['Authorization'] = "Bearer #{api_key}"
45+
request['User-Agent'] = 'mailtrap-ruby (https://github.com/railsware/mailtrap-ruby)'
46+
if body
47+
request['Content-Type'] = 'application/json'
48+
request.body = JSON.generate(body)
49+
end
50+
51+
response = http_client.request(request)
52+
handle_response(response)
53+
end # rubocop:enable Metrics/MethodLength
54+
55+
def handle_response(response) # rubocop:disable Metrics/MethodLength
56+
case response
57+
when Net::HTTPNoContent
58+
true
59+
when Net::HTTPSuccess
60+
json_response(response.body)
61+
when Net::HTTPUnauthorized
62+
raise Mailtrap::AuthorizationError, json_response(response.body)[:errors]
63+
when Net::HTTPForbidden
64+
raise Mailtrap::RejectionError, json_response(response.body)[:errors]
65+
when Net::HTTPClientError, Net::HTTPServerError
66+
raise Mailtrap::Error, json_response(response.body)[:errors]
67+
else
68+
raise Mailtrap::Error, ["unexpected status code=#{response.code}"]
69+
end
70+
end # rubocop:enable Metrics/MethodLength
71+
end
72+
end

lib/mailtrap/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Mailtrap
4-
VERSION = '2.3.0'
4+
VERSION = '2.4.0'
55
end
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe Mailtrap::EmailTemplates do
4+
subject(:templates) { described_class.new(api_key:) }
5+
6+
let(:api_key) { 'correct-api-key' }
7+
let(:account_id) { 123 }
8+
let(:template_id) { 456 }
9+
10+
def stub_api(method, path, status:, body: nil)
11+
stub = stub_request(method, "https://mailtrap.io#{path}")
12+
.to_return(status:, body:)
13+
yield
14+
expect(stub).to have_been_requested
15+
end
16+
17+
describe '#all' do
18+
it 'returns templates list' do
19+
stub_api(:get, "/api/accounts/#{account_id}/email_templates", status: 200, body: '[{"id":1}]') do
20+
expect(templates.all(account_id:)).to eq([{ id: 1 }])
21+
end
22+
end
23+
end
24+
25+
describe '#create' do
26+
let(:params) { { name: 'Test', subject: 'Subj', category: 'Promotion', body_html: '<div>body</div>' } }
27+
28+
it 'sends POST request with JSON body' do
29+
stub = stub_request(:post, "https://mailtrap.io/api/accounts/#{account_id}/email_templates")
30+
.with(body: params.to_json)
31+
.to_return(status: 201, body: '{"id":2}')
32+
expect(templates.create(account_id:, **params)).to eq({ id: 2 })
33+
expect(stub).to have_been_requested
34+
end
35+
end
36+
37+
describe '#update' do
38+
it 'sends PATCH request with JSON body' do # rubocop:disable RSpec/ExampleLength
39+
stub = stub_request(:patch, "https://mailtrap.io/api/accounts/#{account_id}/email_templates/#{template_id}")
40+
.with(body: { name: 'Updated' }.to_json)
41+
.to_return(status: 200, body: '{"id":2,"name":"Updated"}')
42+
expect(templates.update(account_id:, email_template_id: template_id,
43+
name: 'Updated')).to eq({ id: 2, name: 'Updated' })
44+
expect(stub).to have_been_requested
45+
end
46+
end
47+
48+
describe '#delete' do
49+
it 'sends DELETE request' do
50+
stub_api(:delete, "/api/accounts/#{account_id}/email_templates/#{template_id}", status: 204) do
51+
expect(templates.delete(account_id:, email_template_id: template_id)).to be true
52+
end
53+
end
54+
end
55+
56+
describe 'error handling' do
57+
it 'raises authorization error' do
58+
stub_api(:get, "/api/accounts/#{account_id}/email_templates", status: 401, body: '{"errors":["Unauthorized"]}') do
59+
expect { templates.all(account_id:) }.to raise_error(Mailtrap::AuthorizationError)
60+
end
61+
end
62+
end
63+
end

0 commit comments

Comments
 (0)