Commit 77985826 authored by Alexandru Croitor's avatar Alexandru Croitor

Show header and footer system messages in email

* Add email_header_and_footer_enabled flag to appearances table
* Set email_header_and_footer_enabled default value to false
* Add checkbox to appearance to toggle show header and footer in emails
* Add email_header_and_footer_enabled to allowed params in controller
* Add header and footer messages to the html and text email layouts
* Remove the color styling for emails header and footer
* Add empty_mailer layout for emails without layout,
to have the header and footer applied
parent 177f9ca8
......@@ -78,6 +78,7 @@ class Admin::AppearancesController < Admin::ApplicationController
footer_message
message_background_color
message_font_color
email_header_and_footer_enabled
]
end
end
# frozen_string_literal: true
module AppearancesHelper
include MarkupHelper
def brand_title
current_appearance&.title.presence || default_brand_title
end
......@@ -47,7 +49,7 @@ module AppearancesHelper
class_names = []
class_names << 'with-performance-bar' if performance_bar_enabled?
render_message(:header_message, class_names)
render_message(:header_message, class_names: class_names)
end
def footer_message
......@@ -58,10 +60,10 @@ module AppearancesHelper
private
def render_message(field_sym, class_names = [])
def render_message(field_sym, class_names: [], style: message_style)
class_names << field_sym.to_s.dasherize
content_tag :div, class: class_names, style: message_style do
content_tag :div, class: class_names, style: style do
markdown_field(current_appearance, field_sym)
end
end
......
......@@ -131,4 +131,42 @@ module EmailsHelper
project.id.to_s + "." + project_path_as_domain + "." + Gitlab.config.gitlab.host
end
def html_header_message
return unless show_header?
render_message(:header_message, style: '')
end
def html_footer_message
return unless show_footer?
render_message(:footer_message, style: '')
end
def text_header_message
return unless show_header?
strip_tags(render_message(:header_message, style: ''))
end
def text_footer_message
return unless show_footer?
strip_tags(render_message(:footer_message, style: ''))
end
private
def show_footer?
email_header_and_footer_enabled? && current_appearance&.show_footer?
end
def show_header?
email_header_and_footer_enabled? && current_appearance&.show_header?
end
def email_header_and_footer_enabled?
current_appearance&.email_header_and_footer_enabled?
end
end
# frozen_string_literal: true
class AbuseReportMailer < BaseMailer
layout 'empty_mailer'
helper EmailsHelper
def notify(abuse_report_id)
return unless deliverable?
......
# frozen_string_literal: true
class EmailRejectionMailer < BaseMailer
layout 'empty_mailer'
helper EmailsHelper
def rejection(reason, original_raw, can_retry = false)
@reason = reason
@original_message = Mail::Message.new(original_raw)
......
......@@ -2,6 +2,10 @@
class RepositoryCheckMailer < BaseMailer
# rubocop: disable CodeReuse/ActiveRecord
layout 'empty_mailer'
helper EmailsHelper
def notify(failed_count)
@message =
if failed_count == 1
......
......@@ -20,6 +20,7 @@ class Appearance < ActiveRecord::Base
default_value_for :message_background_color, '#E75E40'
default_value_for :message_font_color, '#FFFFFF'
default_value_for :email_header_and_footer_enabled, false
mount_uploader :logo, AttachmentUploader
mount_uploader :header_logo, AttachmentUploader
......
......@@ -13,6 +13,15 @@
.form-group
= form.label :footer_message, _('Footer message'), class: 'col-form-label label-bold'
= form.text_area :footer_message, placeholder: _('State your message to activate'), class: "form-control js-autosize"
.form-group
.form-check
= form.check_box :email_header_and_footer_enabled, class: 'form-check-input'
= form.label :email_header_and_footer_enabled, class: 'label-bold' do
= _('Enable header and footer in emails')
.hint
= _('Add header and footer to emails. Please note that color settings will only be applied within the application interface')
.form-group.js-toggle-colors-container
%button.btn.btn-link.js-toggle-colors-link{ type: 'button' }
= _('Customize colors')
......
......@@ -52,6 +52,7 @@
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" }
%tr.header
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
= html_header_message
= header_logo
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" }
......@@ -72,3 +73,6 @@
= _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} &middot; %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link }
= yield :additional_footer
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" }
= html_footer_message
= html_header_message
= yield
= html_footer_message
<%= text_header_message %>
<%= yield -%>
<%= text_footer_message %>
<%= text_header_message %>
<%= yield -%>
-- <%# signature marker %>
<%= _("You're receiving this email because of your account on %{host}.") % { host: Gitlab.config.gitlab.host } %>
<%= text_footer_message %>
......@@ -7,6 +7,7 @@
= yield :head
%body
.content
= html_header_message
= yield
.footer{ style: "margin-top: 10px;" }
%p
......@@ -30,3 +31,4 @@
adjust your notification settings.
= email_action @target_url
= html_footer_message
<%= text_header_message %>
<%= yield -%>
-- <%# signature marker %>
......@@ -10,3 +12,5 @@
<% end -%>
<%= "You're receiving this email because #{notification_reason_text(@reason)}." %>
<%= text_footer_message -%>
---
title: Show header and footer system messages in email
merge_request: 25474
author:
type: added
# frozen_string_literal: true
class AddEmailHeaderAndFooterEnabledFlagToAppearancesTable < ActiveRecord::Migration[5.0]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
DOWNTIME = false
def up
add_column_with_default(:appearances, :email_header_and_footer_enabled, :boolean, default: false)
end
def down
remove_column(:appearances, :email_header_and_footer_enabled)
end
end
......@@ -44,6 +44,7 @@ ActiveRecord::Schema.define(version: 20190220150130) do
t.text "message_background_color"
t.text "message_font_color"
t.string "favicon"
t.boolean "email_header_and_footer_enabled", default: false, null: false
end
create_table "application_setting_terms", force: :cascade do |t|
......
......@@ -7,6 +7,10 @@ Navigate to the **Admin** area and go to the **Appearance** page.
Under **System header and footer** insert your header message and/or footer message.
Both background and font color of the header and footer are customizable.
You can also apply the header and footer messages to gitlab emails,
by checking the **Enable header and footer in emails** checkbox.
Note that color settings will only be applied within the app interface and not to emails
![appearance](system_header_and_footer_messages/appearance.png)
After saving, all GitLab pages will contain the custom system header and/or footer messages:
......
......@@ -393,6 +393,9 @@ msgstr ""
msgid "Add a table"
msgstr ""
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr ""
msgid "Add image comment"
msgstr ""
......@@ -2959,6 +2962,9 @@ msgstr ""
msgid "Enable group Runners"
msgstr ""
msgid "Enable header and footer in emails"
msgstr ""
msgid "Enable or disable version check and usage ping."
msgstr ""
......
# frozen_string_literal: true
require 'spec_helper'
describe Admin::AppearancesController do
let(:admin) { create(:admin) }
let(:header_message) { "Header message" }
let(:footer_message) { "Footer" }
let(:header_message) { 'Header message' }
let(:footer_message) { 'Footer' }
describe 'POST #create' do
let(:create_params) do
{
title: "Foo",
description: "Bar",
title: 'Foo',
description: 'Bar',
header_message: header_message,
footer_message: footer_message
}
......@@ -24,9 +26,26 @@ describe Admin::AppearancesController do
expect(Appearance.current).to have_attributes(
header_message: header_message,
footer_message: footer_message
footer_message: footer_message,
email_header_and_footer_enabled: false,
message_background_color: '#E75E40',
message_font_color: '#FFFFFF'
)
end
context 'when enabling header and footer in email' do
it 'creates appearance with enabled flag' do
create_params[:email_header_and_footer_enabled] = true
post :create, params: { appearance: create_params }
expect(Appearance.current).to have_attributes(
header_message: header_message,
footer_message: footer_message,
email_header_and_footer_enabled: true
)
end
end
end
describe 'PUT #update' do
......@@ -48,8 +67,25 @@ describe Admin::AppearancesController do
expect(Appearance.current).to have_attributes(
header_message: header_message,
footer_message: footer_message
footer_message: footer_message,
email_header_and_footer_enabled: false,
message_background_color: '#E75E40',
message_font_color: '#FFFFFF'
)
end
context 'when enabling header and footer in email' do
it 'updates appearance with enabled flag' do
update_params[:email_header_and_footer_enabled] = true
post :update, params: { appearance: update_params }
expect(Appearance.current).to have_attributes(
header_message: header_message,
footer_message: footer_message,
email_header_and_footer_enabled: true
)
end
end
end
end
......@@ -142,4 +142,58 @@ describe EmailsHelper do
end
end
end
describe 'header and footer messages' do
context 'when email_header_and_footer_enabled is enabled' do
it 'returns header and footer messages' do
create :appearance, header_message: 'Foo', footer_message: 'Bar', email_header_and_footer_enabled: true
aggregate_failures do
expect(html_header_message).to eq(%{<div class="header-message" style=""><p>Foo</p></div>})
expect(html_footer_message).to eq(%{<div class="footer-message" style=""><p>Bar</p></div>})
expect(text_header_message).to eq('Foo')
expect(text_footer_message).to eq('Bar')
end
end
context 'when header and footer messages are empty' do
it 'returns nil' do
create :appearance, header_message: '', footer_message: '', email_header_and_footer_enabled: true
aggregate_failures do
expect(html_header_message).to eq(nil)
expect(html_footer_message).to eq(nil)
expect(text_header_message).to eq(nil)
expect(text_footer_message).to eq(nil)
end
end
end
context 'when header and footer messages are nil' do
it 'returns nil' do
create :appearance, header_message: nil, footer_message: nil, email_header_and_footer_enabled: true
aggregate_failures do
expect(html_header_message).to eq(nil)
expect(html_footer_message).to eq(nil)
expect(text_header_message).to eq(nil)
expect(text_footer_message).to eq(nil)
end
end
end
end
context 'when email_header_and_footer_enabled is disabled' do
it 'returns header and footer messages' do
create :appearance, header_message: 'Foo', footer_message: 'Bar', email_header_and_footer_enabled: false
aggregate_failures do
expect(html_header_message).to eq(nil)
expect(html_footer_message).to eq(nil)
expect(text_header_message).to eq(nil)
expect(text_footer_message).to eq(nil)
end
end
end
end
end
......@@ -4,25 +4,24 @@ describe AbuseReportMailer do
include EmailSpec::Matchers
describe '.notify' do
context 'with admin_notification_email set' do
before do
stub_application_setting(admin_notification_email: 'admin@example.com')
end
before do
stub_application_setting(admin_notification_email: 'admin@example.com')
end
it 'sends to the admin_notification_email' do
report = create(:abuse_report)
let(:report) { create(:abuse_report) }
subject { described_class.notify(report.id) }
mail = described_class.notify(report.id)
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
expect(mail).to deliver_to 'admin@example.com'
context 'with admin_notification_email set' do
it 'sends to the admin_notification_email' do
is_expected.to deliver_to 'admin@example.com'
end
it 'includes the user in the subject' do
report = create(:abuse_report)
mail = described_class.notify(report.id)
expect(mail).to have_subject "#{report.user.name} (#{report.user.username}) was reported for abuse"
is_expected.to have_subject "#{report.user.name} (#{report.user.username}) was reported for abuse"
end
end
......
# frozen_string_literal: true
require 'rails_helper'
describe EmailRejectionMailer do
include EmailSpec::Matchers
describe '#rejection' do
let(:raw_email) { 'From: someone@example.com\nraw email here' }
subject { described_class.rejection('some rejection reason', raw_email) }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
end
end
......@@ -13,6 +13,9 @@ describe Emails::AutoDevops do
subject { Notify.autodevops_disabled_email(pipeline, owner.email) }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
it 'sents email with correct subject' do
is_expected.to have_subject("#{project.name} | Auto DevOps pipeline was disabled for #{project.name}")
end
......
......@@ -29,5 +29,14 @@ describe Emails::Issues do
expect(subject).to have_body_text "23, 34, 58"
end
context 'with header and footer' do
let(:results) { { success: 165, error_lines: [], parse_error: false } }
subject { Notify.import_issues_csv_email(user.id, project.id, results) }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
end
end
end
This diff is collapsed.
......@@ -17,5 +17,12 @@ describe RepositoryCheckMailer do
expect(mail).to have_subject 'GitLab Admin | 3 projects failed their last repository check'
end
context 'with footer and header' do
subject { described_class.notify(1) }
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
end
end
end
......@@ -78,4 +78,22 @@ describe Appearance do
it { is_expected.to allow_value(hex).for(:message_font_color) }
it { is_expected.not_to allow_value('000').for(:message_font_color) }
end
describe 'email_header_and_footer_enabled' do
context 'default email_header_and_footer_enabled flag value' do
it 'returns email_header_and_footer_enabled as true' do
appearance = build(:appearance)
expect(appearance.email_header_and_footer_enabled?).to eq(false)
end
end
context 'when setting email_header_and_footer_enabled flag value' do
it 'returns email_header_and_footer_enabled as true' do
appearance = build(:appearance, email_header_and_footer_enabled: true)
expect(appearance.email_header_and_footer_enabled?).to eq(true)
end
end
end
end
......@@ -252,3 +252,31 @@ shared_examples 'a note email' do
end
end
end
shared_examples 'appearance header and footer enabled' do
it "contains header and footer" do
create :appearance, header_message: "Foo", footer_message: "Bar", email_header_and_footer_enabled: true
aggregate_failures do
expect(subject.html_part).to have_body_text("<div class=\"header-message\" style=\"\"><p>Foo</p></div>")
expect(subject.html_part).to have_body_text("<div class=\"footer-message\" style=\"\"><p>Bar</p></div>")
expect(subject.text_part).to have_body_text(/^Foo/)
expect(subject.text_part).to have_body_text(/Bar$/)
end
end
end
shared_examples 'appearance header and footer not enabled' do
it "does not contain header and footer" do
create :appearance, header_message: "Foo", footer_message: "Bar", email_header_and_footer_enabled: false
aggregate_failures do
expect(subject.html_part).not_to have_body_text("<div class=\"header-message\" style=\"\"><p>Foo</p></div>")
expect(subject.html_part).not_to have_body_text("<div class=\"footer-message\" style=\"\"><p>Bar</p></div>")
expect(subject.text_part).not_to have_body_text(/^Foo/)
expect(subject.text_part).not_to have_body_text(/Bar$/)
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment