Skip to content

Commit

Permalink
API: added helpers support within mailers
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander-Senko committed Oct 29, 2024
1 parent 2b2937f commit a416a87
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- View helpers inside presenter context.
- View helpers for presenters within views.
- View helpers for presenters within controllers.
- View helpers for presenters within mailers.


## [0.3.0] — 2024-10-27
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ end

View context is set automagically to enable helpers:
- in views,
- in controller actions.
- in controller actions,
- in mailer actions.

## Development

Expand Down
1 change: 1 addition & 0 deletions config/initializers/action_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ def set_presenter_context(&)
end

ActiveSupport.on_load :action_controller, &presenter_context
ActiveSupport.on_load :action_mailer, &presenter_context
6 changes: 6 additions & 0 deletions spec/internal/app/mailers/application_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class ApplicationMailer < ActionMailer::Base
default from: '[email protected]'
layout 'mailer'
end
12 changes: 12 additions & 0 deletions spec/internal/app/mailers/person_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class PersonMailer < ApplicationMailer
def welcome
@person = params[:person].decorated
@family = @person.children
@url = @person.url
@urls = @person.class.urls

mail subject: "#{@person.name} joined us"
end
end
3 changes: 2 additions & 1 deletion spec/internal/app/models/person.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

class Person < ApplicationRecord
belongs_to :parent, class_name: 'Person'
belongs_to :parent, class_name: 'Person', inverse_of: :children
has_many :children, class_name: 'Person', inverse_of: :parent
end
6 changes: 6 additions & 0 deletions spec/internal/app/presenters/person_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ def links
link_to('All', model_class),
]
end

def urls
{
all: url_for(model_class),
}
end
end

def name = "#{first_name} #{last_name}"
Expand Down
19 changes: 19 additions & 0 deletions spec/internal/app/views/layouts/mailer.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
/* Email styles need to be inline */
</style>
</head>

<body>
<%= yield %>

<footer>
<nav>
<%= yield :links %>
</nav>
</footer>
</body>
</html>
1 change: 1 addition & 0 deletions spec/internal/app/views/layouts/mailer.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= yield %>
21 changes: 21 additions & 0 deletions spec/internal/app/views/person_mailer/welcome.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<% content_for :links do %>
<ul>
<% for link in @person.class.links do %>
<li><%= link %></li>
<% end %>
</ul>
<% end %>

<h1>Welcome <%= @person.link %>!</h1>

<% if @family %>
<h2>Family</h2>

<ul>
<% for person in @family do %>
<li>
<%= render person %>
</li>
<% end %>
</ul>
<% end %>
12 changes: 12 additions & 0 deletions spec/internal/app/views/person_mailer/welcome.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Welcome <%= @person.name %>!

<% if @family %>Family:
<% for person in @family do %>
* <%= person.name %><% end %>
<% end %>

Details: <%= @url %>

<% for name, url in @urls do %>See also:
* <%= name.to_s.humanize %>: <%= url %>
<% end %>
1 change: 1 addition & 0 deletions spec/internal/config/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Combustion.initialize! *%i[
active_record
action_controller
action_mailer
active_job
], **{
database_reset: false,
Expand Down
52 changes: 52 additions & 0 deletions spec/mailers/person_mailer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

RSpec.describe PersonMailer do
subject { described_class.with person: john }

let(:john) { Person.create! first_name: 'John', last_name: 'Smith' }
let(:mathew) { Person.create! first_name: 'Mathew', last_name: 'Johnson', parent: john }

describe 'welcome' do
subject { super().welcome }

before { mathew } # should exist

it { is_expected.to have_attributes subject: 'John Smith joined us' }

describe 'HTML' do
include RSpecHtmlMatchers

subject { super().html_part.body.to_s }

it { is_expected.to have_tag 'h1', text: 'John Smith' }
it { is_expected.to have_tag 'li .name', text: 'Mathew Johnson' }

describe 'helpers within a view' do
describe 'instance-level' do
it { is_expected.to have_tag 'a', href: url_for(mathew), text: 'Mathew Johnson' }
end

describe 'class-level' do
it { is_expected.to have_tag 'nav a', href: people_path, text: 'All' }
end
end
end

describe 'text' do
subject { super().text_part.body.to_s }

it { is_expected.to include 'Welcome John Smith!' }
it { is_expected.to include '* Mathew Johnson' }

describe 'helpers within a mailer action' do
describe 'instance-level' do
it { is_expected.to include "Details: #{url_for john}" }
end

describe 'class-level' do
it { is_expected.to include "* All: #{people_url}" }
end
end
end
end
end

0 comments on commit a416a87

Please sign in to comment.