Aggiunge IMAP bounce e flag email non valide nel CRM.
Permette di leggere i bounce dalla stessa MailIdentity SMTP, aggiornare le email in anagrafica e saltare gli indirizzi invalidi nei mailing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -110,6 +110,26 @@ class Api::V1::ApiTest < ActionDispatch::IntegrationTest
|
||||
assert_equal "demo_trial", @opportunity.pipeline_stage
|
||||
end
|
||||
|
||||
test "updates organization email after bounce" do
|
||||
patch "/api/v1/p/matchlivetv/organizations/#{@org.id}/email",
|
||||
params: {
|
||||
organization_id: @org.id,
|
||||
bounced_email: "vecchia@example.com",
|
||||
email: "nuova@example.com",
|
||||
email_invalid: false,
|
||||
bounce_reason: "User unknown",
|
||||
activity_subject: "Email aggiornata dopo bounce"
|
||||
},
|
||||
headers: bearer(@admin_token.plaintext),
|
||||
as: :json
|
||||
assert_response :success
|
||||
@org.reload
|
||||
assert_equal "nuova@example.com", @org.email
|
||||
assert_equal "vecchia@example.com", @org.bounced_email
|
||||
assert_not @org.email_invalid?
|
||||
assert json_body["activity"].present?
|
||||
end
|
||||
|
||||
test "rejects lost stage without reason" do
|
||||
patch "/api/v1/p/matchlivetv/opportunities/#{@opportunity.id}/stage",
|
||||
params: { pipeline_stage: "lost" },
|
||||
|
||||
@@ -27,6 +27,7 @@ class McpControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_includes listed, "list_projects"
|
||||
assert_includes listed, "today"
|
||||
assert_includes listed, "create_activity"
|
||||
assert_includes listed, "check_mail_bounces"
|
||||
assert names || listed.any?
|
||||
end
|
||||
|
||||
|
||||
@@ -51,4 +51,29 @@ class MailIdentityTest < ActiveSupport::TestCase
|
||||
assert_not identity.valid?
|
||||
assert_includes identity.errors[:smtp_port], "con SSL/TLS va usata la porta 465 (es. smtps.aruba.it)"
|
||||
end
|
||||
|
||||
test "infers aruba imap host from smtp" do
|
||||
identity = MailIdentity.new(
|
||||
name: "Aruba",
|
||||
from_name: "Info",
|
||||
from_email: "info@example.com",
|
||||
smtp_host: "smtps.aruba.it",
|
||||
smtp_port: 465,
|
||||
encryption: "tls",
|
||||
smtp_authentication: "plain",
|
||||
smtp_username: "info@example.com",
|
||||
smtp_password: "secret",
|
||||
active: true
|
||||
)
|
||||
assert identity.valid?
|
||||
assert_equal "imaps.aruba.it", identity.effective_imap_host
|
||||
assert_equal 993, identity.effective_imap_port
|
||||
assert identity.imap_ready?
|
||||
settings = identity.imap_settings
|
||||
assert_equal "imaps.aruba.it", settings[:address]
|
||||
assert_equal 993, settings[:port]
|
||||
assert settings[:ssl]
|
||||
assert_equal "info@example.com", settings[:user_name]
|
||||
assert_equal "secret", settings[:password]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
require "test_helper"
|
||||
|
||||
class Mailings::ImapBounceReaderTest < ActiveSupport::TestCase
|
||||
test "parses aruba-style delivery failure from raw rfc822" do
|
||||
identity = create_mail_identity(
|
||||
from_email: "info@matchlivetv.it",
|
||||
smtp_username: "info@matchlivetv.it",
|
||||
smtp_host: "smtps.aruba.it",
|
||||
smtp_port: 465,
|
||||
encryption: "tls"
|
||||
)
|
||||
|
||||
raw = <<~EML
|
||||
From: mail-daemon@example.com
|
||||
To: info@matchlivetv.it
|
||||
Subject: Recapito fallito
|
||||
Date: Mon, 07 Sep 2026 08:14:05 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
Delivery to the following recipients failed permanently:
|
||||
|
||||
* broken@club.it
|
||||
|
||||
Reason: 550 5.1.1 User unknown
|
||||
|
||||
Final-Recipient: rfc822; broken@club.it
|
||||
Diagnostic-Code: smtp; 550 5.1.1 User unknown
|
||||
|
||||
Subject: Più visibilità per ASD Test Club
|
||||
EML
|
||||
|
||||
reader = Mailings::ImapBounceReader.new(identity)
|
||||
parsed = reader.send(:parse_message, raw, uid: 42)
|
||||
assert_not_nil parsed
|
||||
assert_includes parsed[:failed_emails], "broken@club.it"
|
||||
assert_equal "ASD Test Club", parsed[:club_hint]
|
||||
assert_match(/550|User unknown/i, parsed[:reason].to_s)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user