diff --git a/app/views/layouts/mailer.html.slim b/app/views/layouts/mailer.html.slim new file mode 100644 index 00000000..7cb1224a --- /dev/null +++ b/app/views/layouts/mailer.html.slim @@ -0,0 +1,5 @@ +html xmlns="http://www.w3.org/1999/xhtml" + head + meta http-equiv="Content-Type" content="text/html; charset=utf-8" + meta name="viewport" content="width=device-width, initial-scale=1.0" + body lang=I18n.locale = yield diff --git a/app/views/user_mailer/login_code.html.slim b/app/views/user_mailer/login_code.html.slim new file mode 100644 index 00000000..58629e0b --- /dev/null +++ b/app/views/user_mailer/login_code.html.slim @@ -0,0 +1 @@ +p Your login code is #{@code} diff --git a/spec/support/mail_helper.rb b/spec/support/mail_helper.rb new file mode 100644 index 00000000..2a7dc7c3 --- /dev/null +++ b/spec/support/mail_helper.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +class TestMail + attr_reader :to, :from, :subject, :body + + def initialize(mail) + @to = mail["to"] + @from = mail["from"] + @subject = mail.subject + @original_body = mail.body.to_s + @body = Nokogiri::HTML(mail.body.to_s) + end + + def link_urls + body.css("a").pluck("href") + end +end + +module MailHelper + class NoMailSentError < StandardError; end + + def last_mail + return nil unless ActionMailer::Base.deliveries.count > 0 + + TestMail.new(ActionMailer::Base.deliveries.last) + end + + def last_mail! + last_mail || raise(NoMailSentError) + end + + def reset_mails + ActionMailer::Base.deliveries = [] + end + + def run_jobs + # recursivly run the job queue until there are no jobs remaining + count = perform_enqueued_jobs + run_jobs if count.to_i > 0 + end +end + +RSpec.configure do |config| + config.before do + ActionMailer::Base.deliveries = [] + end + config.include MailHelper, type: :system + config.include MailHelper, type: :model +end diff --git a/spec/system/session_spec.rb b/spec/system/session_spec.rb new file mode 100644 index 00000000..b6e910cf --- /dev/null +++ b/spec/system/session_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "system_helper" + +RSpec.describe "Sessions" do + fixtures :all + + it "logs a user in via a code" do + visit root_path + expect(page).to have_content "Login" + fill_in "Email", with: "admin@example.com" + click_on "Login" + expect(page).to have_content "Code" + + run_jobs + expect(last_mail!.body).to have_content "Your login code is" + code = last_mail.body.to_s.scan(/\d{6}/).first + expect(code).to be_present + fill_in "Code", with: code + click_on "Login" + expect(page).to have_content "Hello" + end + + it "logs the user out" do + login :john + visit logout_path + expect(page).to have_content "Login" + end +end