Aggiunge il rilevamento di invio e apertura delle email di campagna.
CI / scan_ruby (push) Failing after 12m56s
CI / scan_js (push) Successful in 12m23s
CI / lint (push) Failing after 12m15s

Ogni destinatario mostra se la mail è partita e se è stata aperta, con conteggi in dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-20 12:26:14 +02:00
co-authored by Cursor
parent ab57309f5c
commit 2db7504629
18 changed files with 332 additions and 5 deletions
@@ -0,0 +1,51 @@
require "test_helper"
class MailOpensControllerTest < ActionDispatch::IntegrationTest
setup do
opportunities(:deal).update!(send_status: "to_send")
@mailing = create_mailing(audience: "to_send")
@mailing.rebuild_recipients!
@recipient = @mailing.mailing_recipients.first
@recipient.update!(status: "sent", sent_at: Time.current, rendered_subject: "Ciao ASD Test Calcio")
end
test "records the first open without login and returns a gif" do
assert_difference -> { Activity.where(activity_type: "email_opened").count }, 1 do
get mail_open_path(@recipient.tracking_token)
end
assert_response :success
assert_equal "image/gif", response.media_type
@recipient.reload
assert @recipient.opened?
assert_equal 1, @recipient.open_count
assert_equal @recipient.opened_at, @recipient.last_opened_at
end
test "counts later loads without duplicating the timeline activity" do
get mail_open_path(@recipient.tracking_token)
assert_no_difference -> { Activity.where(activity_type: "email_opened").count } do
get mail_open_path(@recipient.tracking_token)
end
@recipient.reload
assert_equal 2, @recipient.open_count
assert @recipient.last_opened_at >= @recipient.opened_at
end
test "unknown token still returns a gif" do
get mail_open_path("missing-token-value-here")
assert_response :success
assert_equal "image/gif", response.media_type
end
test "does not mark pending emails as opened" do
@recipient.update!(status: "pending", sent_at: nil)
get mail_open_path(@recipient.tracking_token)
assert_response :success
@recipient.reload
assert_not @recipient.opened?
assert_equal 0, @recipient.open_count
end
end
@@ -65,6 +65,8 @@ class MailingsControllerTest < ActionDispatch::IntegrationTest
assert_equal "contacted", opportunities(:deal).pipeline_stage
assert_equal 2, ActionMailer::Base.deliveries.size
assert_equal "Ciao ASD Test Calcio", ActionMailer::Base.deliveries.last.subject
body = (ActionMailer::Base.deliveries.last.html_part || ActionMailer::Base.deliveries.last).body.to_s
assert_match(%r{/t/o/#{Regexp.escape(recipient.reload.tracking_token)}\.gif}, body)
end
test "queue send requires test email first" do
@@ -96,7 +98,9 @@ class MailingsControllerTest < ActionDispatch::IntegrationTest
mail = ActionMailer::Base.deliveries.last
assert_equal [users(:admin).email], mail.to
assert_match(/\[TEST\]/, mail.subject)
body = (mail.html_part || mail).body.to_s
assert_match(/Società Prova/, mail.subject)
assert_no_match(%r{/t/o/}, body)
assert mailing.reload.tested?
assert_equal users(:admin).email, mailing.test_sent_to
end
+2
View File
@@ -23,6 +23,8 @@ class CampaignMailerTest < ActionMailer::TestCase
assert_equal "Ciao ASD Test Calcio", email.subject
body = (email.html_part || email).body.to_s
assert_match(/Ciao Mario Rossi di ASD Test Calcio/, body)
recipient.reload
assert_match(%r{/t/o/#{Regexp.escape(recipient.tracking_token)}\.gif}, body)
assert_equal 1, email.attachments.size
assert_equal "brochure.pdf", email.attachments.first.filename
end
+22
View File
@@ -0,0 +1,22 @@
require "test_helper"
class Mailings::OpenPixelTest < ActiveSupport::TestCase
test "injects a tracking pixel before body close" do
mailing = create_mailing
mailing.rebuild_recipients!
recipient = mailing.mailing_recipients.first
html = Mailings::OpenPixel.call("<html><body><p>Ciao</p></body></html>", recipient)
assert_includes html, "/t/o/#{recipient.tracking_token}.gif"
assert_match %r{<img src="http://example.com/t/o/#{Regexp.escape(recipient.tracking_token)}\.gif"[^>]*width="1"}, html
assert_includes html, "</body>"
assert html.index("t/o/") < html.index("</body>")
end
test "skips test recipients without a token" do
html = "<p>Ciao</p>"
recipient = Mailings::TestRecipient.new(mailing: create_mailing, email: "test@example.com")
assert_equal html, Mailings::OpenPixel.call(html, recipient)
end
end