diff --git a/app/controllers/admin/email_templates_controller.rb b/app/controllers/admin/email_templates_controller.rb
index 4c1df06239c..a29aa0a5ed6 100644
--- a/app/controllers/admin/email_templates_controller.rb
+++ b/app/controllers/admin/email_templates_controller.rb
@@ -47,11 +47,9 @@ class Admin::EmailTemplatesController < Admin::AdminController
error_messages = []
if subject_result[:error_messages].present?
- TranslationOverride.upsert!(I18n.locale, "#{key}.subject_template", subject_result[:old_value])
error_messages << format_error_message(subject_result, "subject")
end
if body_result[:error_messages].present?
- TranslationOverride.upsert!(I18n.locale, "#{key}.text_body_template", body_result[:old_value])
error_messages << format_error_message(body_result, "body")
end
@@ -61,6 +59,9 @@ class Admin::EmailTemplatesController < Admin::AdminController
render_serialized(key, AdminEmailTemplateSerializer, root: 'email_template', rest_serializer: true)
else
+ TranslationOverride.upsert!(I18n.locale, "#{key}.subject_template", subject_result[:old_value])
+ TranslationOverride.upsert!(I18n.locale, "#{key}.text_body_template", body_result[:old_value])
+
render_json_error(error_messages)
end
end
diff --git a/spec/requests/admin/email_templates_controller_spec.rb b/spec/requests/admin/email_templates_controller_spec.rb
new file mode 100644
index 00000000000..6ddd34380ba
--- /dev/null
+++ b/spec/requests/admin/email_templates_controller_spec.rb
@@ -0,0 +1,287 @@
+require 'rails_helper'
+
+RSpec.describe Admin::EmailTemplatesController do
+ let(:admin) { Fabricate(:admin) }
+ let(:user) { Fabricate(:user) }
+
+ def original_text(key)
+ I18n.overrides_disabled { I18n.t(key) }
+ end
+
+ let(:original_subject) { original_text('user_notifications.admin_login.subject_template') }
+ let(:original_body) { original_text('user_notifications.admin_login.text_body_template') }
+ let(:headers) { { ACCEPT: 'application/json' } }
+
+ after do
+ TranslationOverride.delete_all
+ I18n.reload!
+ end
+
+ context "#index" do
+ it "raises an error if you aren't logged in" do
+ expect do
+ get '/admin/customize/email_templates.json'
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ it "raises an error if you aren't an admin" do
+ sign_in(user)
+ expect do
+ get '/admin/customize/email_templates.json'
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ it "should work if you are an admin" do
+ sign_in(admin)
+ get '/admin/customize/email_templates.json'
+
+ expect(response).to be_success
+
+ json = ::JSON.parse(response.body)
+ expect(json['email_templates']).to be_present
+ end
+ end
+
+ context "#update" do
+ it "raises an error if you aren't logged in" do
+ expect do
+ put '/admin/customize/email_templates/some_id', params: {
+ email_template: { subject: 'Subject', body: 'Body' }
+ }, headers: headers
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ it "raises an error if you aren't an admin" do
+ sign_in(user)
+ expect do
+ put '/admin/customize/email_templates/some_id', params: {
+ email_template: { subject: 'Subject', body: 'Body' }
+ }, headers: headers
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ context "when logged in as admin" do
+ before do
+ sign_in(admin)
+ end
+
+ it "returns 'not found' when an unknown email template id is used" do
+ put '/admin/customize/email_templates/non_existent_template', params: {
+ email_template: { subject: 'Foo', body: 'Bar' }
+ }, headers: headers
+
+ expect(response).not_to be_success
+
+ json = ::JSON.parse(response.body)
+ expect(json['error_type']).to eq('not_found')
+ end
+
+ shared_examples "invalid email template" do
+ it "returns the right error messages" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ json = ::JSON.parse(response.body)
+ expect(json).to be_present
+
+ errors = json['errors']
+ expect(errors).to be_present
+ expect(errors).to eq(expected_errors)
+ end
+
+ it "doesn't create translation overrides" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ expect(I18n.t('user_notifications.admin_login.subject_template')).to eq(original_subject)
+ expect(I18n.t('user_notifications.admin_login.text_body_template')).to eq(original_body)
+ end
+
+ it "doesn't create entries in the Staff Log" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.subject_template')
+ expect(log).to be_nil
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.text_body_template')
+ expect(log).to be_nil
+ end
+ end
+
+ context "when subject is invalid" do
+ let(:email_subject) { 'Subject with missing interpolation key' }
+ let(:email_body) { 'The body contains [%{site_name}](%{base_url}) and %{email_token}.' }
+ let(:expected_errors) { ['Subject: The following interpolation key(s) are missing: "email_prefix"'] }
+
+ include_examples "invalid email template"
+ end
+
+ context "when body is invalid" do
+ let(:email_subject) { '%{email_prefix} Foo' }
+ let(:email_body) { 'Body with some missing interpolation keys: %{email_token}' }
+ let(:expected_errors) { ['Body: The following interpolation key(s) are missing: "site_name, base_url"'] }
+
+ include_examples "invalid email template"
+ end
+
+ context "when subject and body are invalid invalid" do
+ let(:email_subject) { 'Subject with missing interpolation key' }
+ let(:email_body) { 'Body with some missing interpolation keys: %{email_token}' }
+ let(:expected_errors) do
+ ['Subject: The following interpolation key(s) are missing: "email_prefix"',
+ 'Body: The following interpolation key(s) are missing: "site_name, base_url"']
+ end
+
+ include_examples "invalid email template"
+ end
+
+ context "when subject and body contain all required interpolation keys" do
+ let(:email_subject) { '%{email_prefix} Foo' }
+ let(:email_body) { 'The body contains [%{site_name}](%{base_url}) and %{email_token}.' }
+
+ it "returns the successfully updated email template" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ expect(response).to be_success
+
+ json = ::JSON.parse(response.body)
+ expect(json).to be_present
+
+ template = json['email_template']
+ expect(template).to be_present
+
+ expect(template['id']).to eq('user_notifications.admin_login')
+ expect(template['title']).to eq('Admin Login')
+ expect(template['subject']).to eq(email_subject)
+ expect(template['body']).to eq(email_body)
+ expect(template['can_revert']).to eq(true)
+ end
+
+ it "creates translation overrides" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ expect(I18n.t('user_notifications.admin_login.subject_template')).to eq(email_subject)
+ expect(I18n.t('user_notifications.admin_login.text_body_template')).to eq(email_body)
+ end
+
+ it "creates entries in the Staff Log" do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.subject_template')
+
+ expect(log).to be_present
+ expect(log.action).to eq(UserHistory.actions[:change_site_text])
+ expect(log.previous_value).to eq(original_subject)
+ expect(log.new_value).to eq(email_subject)
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.text_body_template')
+
+ expect(log).to be_present
+ expect(log.action).to eq(UserHistory.actions[:change_site_text])
+ expect(log.previous_value).to eq(original_body)
+ expect(log.new_value).to eq(email_body)
+ end
+ end
+
+ end
+
+ end
+
+ context "#revert" do
+ it "raises an error if you aren't logged in" do
+ expect do
+ delete '/admin/customize/email_templates/some_id', headers: headers
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ it "raises an error if you aren't an admin" do
+ sign_in(user)
+ expect do
+ delete '/admin/customize/email_templates/some_id', headers: headers
+ end.to raise_error(ActionController::RoutingError)
+ end
+
+ context "when logged in as admin" do
+ before do
+ sign_in(admin)
+ end
+
+ it "returns 'not found' when an unknown email template id is used" do
+ delete '/admin/customize/email_templates/non_existent_template', headers: headers
+ expect(response).not_to be_success
+
+ json = ::JSON.parse(response.body)
+ expect(json['error_type']).to eq('not_found')
+ end
+
+ context "when email template has translation overrides" do
+ let(:email_subject) { '%{email_prefix} Foo' }
+ let(:email_body) { 'The body contains [%{site_name}](%{base_url}) and %{email_token}.' }
+
+ before do
+ put '/admin/customize/email_templates/user_notifications.admin_login', params: {
+ email_template: { subject: email_subject, body: email_body }
+ }, headers: headers
+ end
+
+ it "restores the original subject and body" do
+ expect(I18n.t('user_notifications.admin_login.subject_template')).to eq(email_subject)
+ expect(I18n.t('user_notifications.admin_login.text_body_template')).to eq(email_body)
+
+ delete '/admin/customize/email_templates/user_notifications.admin_login', headers: headers
+
+ expect(I18n.t('user_notifications.admin_login.subject_template')).to eq(original_subject)
+ expect(I18n.t('user_notifications.admin_login.text_body_template')).to eq(original_body)
+ end
+
+ it "returns the restored email template" do
+ delete '/admin/customize/email_templates/user_notifications.admin_login', headers: headers
+ expect(response).to be_success
+
+ json = ::JSON.parse(response.body)
+ expect(json).to be_present
+
+ template = json['email_template']
+ expect(template).to be_present
+
+ expect(template['id']).to eq('user_notifications.admin_login')
+ expect(template['title']).to eq('Admin Login')
+ expect(template['subject']).to eq(original_subject)
+ expect(template['body']).to eq(original_body)
+ expect(template['can_revert']).to eq(false)
+ end
+
+ it "creates entries in the Staff Log" do
+ UserHistory.delete_all
+ delete '/admin/customize/email_templates/user_notifications.admin_login', headers: headers
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.subject_template')
+
+ expect(log).to be_present
+ expect(log.action).to eq(UserHistory.actions[:change_site_text])
+ expect(log.previous_value).to eq(email_subject)
+ expect(log.new_value).to eq(original_subject)
+
+ log = UserHistory.find_by_subject('user_notifications.admin_login.text_body_template')
+
+ expect(log).to be_present
+ expect(log.action).to eq(UserHistory.actions[:change_site_text])
+ expect(log.previous_value).to eq(email_body)
+ expect(log.new_value).to eq(original_body)
+ end
+ end
+ end
+
+ end
+
+end