mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-10 14:15:42 +00:00
adf6aa4270
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.
73 lines
2.2 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|