2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-10-03 17:21:20 +08:00

DEV: Add missing e2e tests for viewing admin email logs (#35033)

This commit is contained in:
Alan Guo Xiang Tan 2025-09-30 09:02:30 +08:00 committed by GitHub
parent cc0e2fe00b
commit e2fd3e32d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 298 additions and 9 deletions

View file

@ -37,7 +37,7 @@ export default RouteTemplate(
@filters={{BOUNCED_FILTERS}}
>
<:default as |emailLog|>
<tr>
<tr data-test-email-log-row-id={{emailLog.id}}>
<td>{{formatDate emailLog.created_at}}</td>
<td>
{{#if emailLog.user}}

View file

@ -41,7 +41,7 @@ export default RouteTemplate(
<:default
as |emailLog ccThreshold sortWithAddressFilter handleShowIncomingEmail|
>
<tr>
<tr data-test-email-log-row-id={{emailLog.id}}>
<td>{{formatDate emailLog.created_at}}</td>
<td>{{emailLog.from_address}}</td>
<td>{{emailLog.to_addresses}}</td>

View file

@ -47,7 +47,7 @@ export default RouteTemplate(
<:default
as |emailLog ccThreshold sortWithAddressFilter handleShowIncomingEmail|
>
<tr>
<tr data-test-email-log-row-id={{emailLog.id}}>
<td>{{formatDate emailLog.created_at}}</td>
<td>{{emailLog.from_address}}</td>
<td>{{emailLog.to_addresses}}</td>

View file

@ -55,7 +55,7 @@ export default RouteTemplate(
@extraFilterCells={{array (hash)}}
>
<:default as |emailLog ccThreshold sortWithAddressFilter|>
<tr class="sent-email-item">
<tr class="sent-email-item" data-test-email-log-row-id={{emailLog.id}}>
<td class="sent-email-date">{{formatDate emailLog.created_at}}</td>
<td class="sent-email-username">
{{#if emailLog.user}}

View file

@ -38,7 +38,7 @@ export default RouteTemplate(
@filters={{SKIPPED_FILTERS}}
>
<:default as |emailLog|>
<tr>
<tr data-test-email-log-row-id={{emailLog.id}}>
<td>{{formatDate emailLog.created_at}}</td>
<td>
{{#if emailLog.user}}

View file

@ -1,10 +1,10 @@
# frozen_string_literal: true

Fabricator(:incoming_email) do
message_id "12345@example.com"
subject "Hello world"
from_address "foo@example.com"
to_addresses "someone@else.com"
message_id { sequence(:message_id) { |n| "#{n}@example.com" } }
subject { sequence(:subject) { |n| "Hello world #{n}" } }
from_address { sequence(:from_address) { |n| "foo#{n}@example.com" } }
to_addresses { sequence(:to_addresses) { |n| "someone#{n}@else.com" } }
imap_sync false
created_via 0

@ -22,3 +22,8 @@ Fabricator(:incoming_email) do
The body contains "Hello world" too.
EMAIL
end

Fabricator(:rejected_incoming_email, from: :incoming_email) do
is_bounce false
error { sequence(:error) { |n| "Error #{n}" } }
end

View file

@ -0,0 +1,162 @@
# frozen_string_literal: true

RSpec.describe "Admin viewing email logs" do
fab!(:admin)

let(:admin_email_logs_page) { PageObjects::Pages::AdminEmailLogs.new }

before { sign_in(admin) }

describe "when viewing rejected email logs" do
fab!(:rejected_incoming_email)
fab!(:rejected_incoming_email_2, :rejected_incoming_email)

it "allows an admin to view a list of rejected email logs and their details" do
admin_email_logs_page.visit_rejected

[rejected_incoming_email, rejected_incoming_email_2].each do |incoming_email|
row = admin_email_logs_page.row_for(incoming_email)

expect(row).to have_from_address(incoming_email.from_address)
expect(row).to have_to_address(incoming_email.to_addresses)
expect(row).to have_subject(incoming_email.subject)
expect(row).to have_error(incoming_email.error)
end
end
end

describe "when viewing received email logs" do
fab!(:incoming_email)
fab!(:incoming_email_2, :incoming_email)

it "allows an admin to view a list of received email logs and their details" do
admin_email_logs_page.visit_received

[incoming_email, incoming_email_2].each do |incoming_email|
row = admin_email_logs_page.row_for(incoming_email)

expect(row).to have_from_address(incoming_email.from_address)
expect(row).to have_to_address(incoming_email.to_addresses)
expect(row).to have_subject(incoming_email.subject)
end
end
end

describe "when viewing bounced email logs" do
fab!(:bounced_email_log) { Fabricate(:email_log, bounced: true, email_type: "signup") }
fab!(:bounced_email_log_2) { Fabricate(:email_log, bounced: true, email_type: "digest") }

it "allows an admin to view a list of bounced email logs" do
admin_email_logs_page.visit_bounced

[bounced_email_log, bounced_email_log_2].each do |email_log|
row = admin_email_logs_page.row_for(email_log)

expect(row).to have_user(email_log.user.username)
expect(row).to have_to_address(email_log.to_address)
expect(row).to have_email_type(email_log.email_type)
end
end
end

describe "when viewing skipped email logs" do
fab!(:skipped_email_log) do
Fabricate(
:skipped_email_log,
user: Fabricate(:user),
email_type: "signup",
to_address: "skipped1@example.com",
reason_type: SkippedEmailLog.reason_types[:exceeded_emails_limit],
)
end

fab!(:skipped_email_log_2) do
Fabricate(
:skipped_email_log,
user: Fabricate(:user),
email_type: "digest",
to_address: "skipped2@example.com",
reason_type: SkippedEmailLog.reason_types[:custom],
custom_reason: "Custom skip reason",
)
end

it "allows an admin to view a list of skipped email logs" do
admin_email_logs_page.visit_skipped

[skipped_email_log, skipped_email_log_2].each do |email_log|
row = admin_email_logs_page.row_for(email_log)

expect(row).to have_user(email_log.user.username)
expect(row).to have_to_address(email_log.to_address)
expect(row).to have_email_type(email_log.email_type)
expect(row).to have_skipped_reason(email_log.reason)
end
end
end

describe "when viewing sent email logs" do
fab!(:post)
fab!(:post_2, :post)

fab!(:post_reply_key) do
Fabricate(
:post_reply_key,
user: post.user,
post: post,
reply_key: "11111111-1111-1111-1111-111111111111",
)
end

fab!(:post_reply_key_2) do
Fabricate(
:post_reply_key,
user: post_2.user,
post: post_2,
reply_key: "22222222-2222-2222-2222-222222222222",
)
end

fab!(:sent_email_log) do
Fabricate(
:email_log,
user: post.user,
post: post,
to_address: "sent1@example.com",
email_type: "signup",
smtp_transaction_response: "250 2.0.0 OK",
)
end

fab!(:sent_email_log_2) do
Fabricate(
:email_log,
user: post_2.user,
post: post_2,
to_address: "sent2@example.com",
email_type: "digest",
smtp_transaction_response: "250 2.0.0 Accepted",
)
end

it "allows an admin to view a list of sent email logs" do
admin_email_logs_page.visit_sent

[
[sent_email_log, post_reply_key.reply_key],
[sent_email_log_2, post_reply_key_2.reply_key],
].each do |email_log, expected_reply_key|
row = admin_email_logs_page.row_for(email_log)

expect(row).to have_user(email_log.user.username)
expect(row).to have_to_address(email_log.to_address)
expect(row).to have_email_type(email_log.email_type)
expect(row).to have_reply_key(expected_reply_key.delete("-"))
expect(row).to have_post_description(
"#{email_log.post.topic.title} ##{email_log.post.post_number}",
)
expect(row).to have_smtp_response(email_log.smtp_transaction_response)
end
end
end
end

View file

@ -0,0 +1,122 @@
# frozen_string_literal: true

module PageObjects
module Pages
class AdminEmailLogs < PageObjects::Pages::AdminBase
class BaseRow
attr_reader :element

def initialize(element)
@element = element
end
end

class IncomingEmailRow < BaseRow
def has_subject?(subject)
element.has_css?(".incoming-email-link", text: subject)
end

def has_from_address?(from_address)
element.has_css?("td:nth-of-type(2)", text: from_address)
end

def has_to_address?(to_address)
element.has_css?("td:nth-of-type(3)", text: to_address)
end

def has_error?(error)
element.has_css?("td:nth-of-type(5)", text: error)
end
end

class EmailLogRow < BaseRow
def has_user?(username)
if username.present?
element.has_css?(".email-logs-user", text: username)
else
element.has_no_css?(".email-logs-user")
end
end

def has_to_address?(to_address)
element.has_css?("td:nth-of-type(3)", text: to_address)
end

def has_email_type?(email_type)
element.has_css?("td:nth-of-type(4)", text: email_type)
end
end

class SentEmailLogRow < EmailLogRow
def has_reply_key?(reply_key)
element.has_css?("td:nth-of-type(5) .reply-key", text: reply_key)
end

def has_post_description?(description)
element.has_css?("td:nth-of-type(6)", text: description)
end

def has_smtp_response?(response)
element.has_css?("td:nth-of-type(6) code", text: response)
end
end

class SkippedEmailLogRow < EmailLogRow
def has_skipped_reason?(reason)
element.has_css?("td:nth-of-type(5)", text: reason)
end
end

def visit_rejected
visit_logs(:rejected)
self
end

def visit_received
visit_logs(:received)
self
end

def visit_bounced
visit_logs(:bounced)
self
end

def visit_skipped
visit_logs(:skipped)
self
end

def visit_sent
visit_logs(:sent)
self
end

def row_for(record)
element = find("[data-test-email-log-row-id=\"#{record.id}\"]")
row_class.new(element)
end

private

def row_class
case @current_log_status
when :rejected, :received
IncomingEmailRow
when :skipped
SkippedEmailLogRow
when :sent
SentEmailLogRow
else
EmailLogRow
end
end

def visit_logs(status)
@current_log_status = status.to_sym
page.visit("/admin/email-logs/#{@current_log_status == :sent ? nil : status}")
self
end
end
end
end