Files
libredesk/internal/conversation/transcript_test.go
T
Abhinav Raut adf6aa4270 fall back to email lookup on unknown external ID and let the form opt out of contact sync
Two contact resolution fixes in create conversation:

Under the reuse policy, an unknown external_user_id went straight to
insert. If the email belonged to an existing contact, that inserted a
duplicate contact sharing the email, since the unique email index only
covers rows without an ext_id. The ext_id lookup now falls back to the
email match before inserting. Regression test added.

The new conversation form sends name fields as a snapshot from contact
search, so a contacts:write agent submitting the form could overwrite a
contact that was renamed after the search. The form now sends
reuse_contact: true and the backend downgrades to the reuse policy when
it is set. API callers like an external CRM omit the flag and keep the
full sync/upsert behavior. The flag can only downgrade, never escalate.

Also from review: hoist the repeated password generation block into
newContactPassword, drop testutil.NewLogger and the duplicate
newTestI18n in transcript_test.go in favor of testutil.NewI18n, and
clean up stale comments.
2026-08-11 15:33:32 +05:30

73 lines
2.2 KiB
Go

package conversation
import (
"strings"
"testing"
"time"
"github.com/abhinavxd/libredesk/internal/attachment"
"github.com/abhinavxd/libredesk/internal/conversation/models"
"github.com/abhinavxd/libredesk/internal/testutil"
"github.com/volatiletech/null/v9"
)
func TestBuildTranscript(t *testing.T) {
m := &Manager{i18n: testutil.NewI18n(t)}
created := time.Date(2026, time.May, 11, 10, 0, 0, 0, time.UTC)
downloaded := time.Date(2026, time.June, 2, 16, 10, 0, 0, time.UTC)
conversation := models.Conversation{
ReferenceNumber: "1234",
Subject: null.StringFrom("Refund request"),
CreatedAt: created,
Contact: models.ConversationContact{FirstName: "John", LastName: "Doe"},
}
messages := []models.Message{
{
Type: models.MessageIncoming,
SenderType: models.SenderTypeContact,
CreatedAt: created.Add(time.Minute),
TextContent: "Hi, I need a refund for order #555",
Author: models.MessageAuthor{FirstName: "John", LastName: "Doe"},
},
{
Type: models.MessageOutgoing,
SenderType: models.SenderTypeAgent,
CreatedAt: created.Add(5 * time.Minute),
TextContent: "Sure, processing it now.",
Author: models.MessageAuthor{FirstName: "Priya"},
Attachments: attachment.Attachments{{Name: "invoice.pdf"}},
},
{
Type: models.MessageOutgoing,
SenderType: models.SenderTypeAgent,
CreatedAt: created.Add(6 * time.Minute),
Content: "<p>Falls back to <b>HTML</b></p>",
ContentType: models.ContentTypeHTML,
Author: models.MessageAuthor{FirstName: "Priya"},
},
}
out := string(m.BuildTranscript(conversation, messages, downloaded))
wantContains := []string{
"Conversation #1234",
"Subject: Refund request",
"Contact: John Doe",
"Created at: May 11, 2026 10:00 AM UTC",
"Downloaded at: Jun 02, 2026 04:10 PM UTC",
"[May 11, 2026 10:01 AM UTC] John Doe (Contact):",
"Hi, I need a refund for order #555",
"[May 11, 2026 10:05 AM UTC] Priya (Agent):",
"Attachment: invoice.pdf",
"Falls back to HTML",
}
for _, want := range wantContains {
if !strings.Contains(out, want) {
t.Errorf("transcript missing %q\n---\n%s", want, out)
}
}
}