206 lines
5.5 KiB
Go
206 lines
5.5 KiB
Go
package lib
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSendTemplate(t *testing.T) {
|
|
// Create a mailer with templates loaded
|
|
m := &Mailer{enabled: true}
|
|
|
|
// Find the email templates directory
|
|
templateDir := "../portal/emails"
|
|
if _, err := os.Stat(templateDir); os.IsNotExist(err) {
|
|
templateDir = "portal/emails"
|
|
if _, err := os.Stat(templateDir); os.IsNotExist(err) {
|
|
t.Skipf("email templates directory not found, skipping test")
|
|
}
|
|
}
|
|
|
|
absPath, err := filepath.Abs(templateDir)
|
|
if err != nil {
|
|
t.Fatalf("failed to get absolute path: %v", err)
|
|
}
|
|
|
|
if err := m.LoadTemplates(absPath); err != nil {
|
|
t.Fatalf("failed to load templates: %v", err)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
tmplName string
|
|
data any
|
|
expected []string
|
|
}{
|
|
{
|
|
name: "invite",
|
|
tmplName: "invite.html",
|
|
data: InviteData{
|
|
InviterName: "Sarah Mitchell",
|
|
InviterOrg: "Goldman Sachs",
|
|
ProjectName: "Project Phoenix",
|
|
InviteURL: "https://app.muskepo.com/invite/abc123",
|
|
RecipientName: "John Smith",
|
|
ExpiresIn: "7 days",
|
|
},
|
|
expected: []string{"Sarah Mitchell", "Goldman Sachs", "Project Phoenix", "Accept Invitation", "DEALSPACE"},
|
|
},
|
|
{
|
|
name: "tasks_assigned",
|
|
tmplName: "tasks_assigned.html",
|
|
data: TasksAssignedData{
|
|
RecipientName: "John Smith",
|
|
ProjectName: "Project Phoenix",
|
|
Count: 3,
|
|
Tasks: []TaskItem{
|
|
{Title: "FIN-001: Audited financials", DueDate: "March 15", Priority: "high"},
|
|
},
|
|
TasksURL: "https://app.muskepo.com/app/tasks",
|
|
},
|
|
expected: []string{"John Smith", "Project Phoenix", "3 new tasks", "View My Tasks"},
|
|
},
|
|
{
|
|
name: "answer_submitted",
|
|
tmplName: "answer_submitted.html",
|
|
data: AnswerSubmittedData{
|
|
AnswererName: "John Smith",
|
|
RequestTitle: "FIN-001: Audited financials",
|
|
WorkstreamName: "Finance",
|
|
ReviewURL: "https://app.muskepo.com/app/review/ans_xyz123",
|
|
},
|
|
expected: []string{"John Smith", "FIN-001: Audited financials", "Finance", "Review Answer"},
|
|
},
|
|
{
|
|
name: "answer_approved",
|
|
tmplName: "answer_approved.html",
|
|
data: AnswerApprovedData{
|
|
RequestTitle: "FIN-001: Audited financials",
|
|
Published: true,
|
|
},
|
|
expected: []string{"Your answer was approved", "FIN-001: Audited financials", "Published to Data Room"},
|
|
},
|
|
{
|
|
name: "answer_rejected",
|
|
tmplName: "answer_rejected.html",
|
|
data: AnswerRejectedData{
|
|
RequestTitle: "FIN-001: Audited financials",
|
|
Reason: "Need final audited version",
|
|
RequestURL: "https://app.muskepo.com/app/tasks/req_001",
|
|
},
|
|
expected: []string{"Your answer needs revision", "FIN-001: Audited financials", "View Feedback"},
|
|
},
|
|
{
|
|
name: "request_forwarded",
|
|
tmplName: "request_forwarded.html",
|
|
data: RequestForwardedData{
|
|
SenderName: "John Smith",
|
|
RequestTitle: "FIN-003: AR aging report",
|
|
RequestURL: "https://app.muskepo.com/app/tasks/req_003",
|
|
DueDate: "March 18, 2026",
|
|
HasDueDate: true,
|
|
},
|
|
expected: []string{"John Smith", "FIN-003: AR aging report", "View Request", "March 18, 2026"},
|
|
},
|
|
{
|
|
name: "welcome",
|
|
tmplName: "welcome.html",
|
|
data: WelcomeData{
|
|
RecipientName: "John Smith",
|
|
TasksURL: "https://app.muskepo.com/app/tasks",
|
|
},
|
|
expected: []string{"Welcome to Dealspace", "John Smith", "Your inbox is your home", "Ask Aria", "Go to My Tasks"},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result, err := m.RenderTemplate(tc.tmplName, tc.data)
|
|
if err != nil {
|
|
t.Fatalf("RenderTemplate(%s) failed: %v", tc.tmplName, err)
|
|
}
|
|
|
|
if len(result) == 0 {
|
|
t.Errorf("RenderTemplate(%s) returned empty result", tc.tmplName)
|
|
}
|
|
|
|
for _, expected := range tc.expected {
|
|
if !strings.Contains(result, expected) {
|
|
t.Errorf("RenderTemplate(%s) missing expected string: %q", tc.tmplName, expected)
|
|
}
|
|
}
|
|
|
|
if !strings.Contains(result, "<!DOCTYPE html>") {
|
|
t.Errorf("RenderTemplate(%s) missing DOCTYPE", tc.tmplName)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMailerDisabled(t *testing.T) {
|
|
m := &Mailer{enabled: false}
|
|
|
|
err := m.Send("test@example.com", "Test Subject", "<html>test</html>")
|
|
if err != nil {
|
|
t.Errorf("Send on disabled mailer should return nil, got: %v", err)
|
|
}
|
|
|
|
err = m.SendTemplate("test@example.com", "Test Subject", "invite.html", nil)
|
|
if err != nil {
|
|
t.Errorf("SendTemplate on disabled mailer should return nil, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestMailerEnabled(t *testing.T) {
|
|
enabled := &Mailer{enabled: true}
|
|
disabled := &Mailer{enabled: false}
|
|
|
|
if !enabled.Enabled() {
|
|
t.Error("enabled mailer should return true for Enabled()")
|
|
}
|
|
if disabled.Enabled() {
|
|
t.Error("disabled mailer should return false for Enabled()")
|
|
}
|
|
}
|
|
|
|
func TestBase64Encode(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{"", ""},
|
|
{"f", "Zg=="},
|
|
{"fo", "Zm8="},
|
|
{"foo", "Zm9v"},
|
|
{"foobar", "Zm9vYmFy"},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
result := base64Encode(tc.input)
|
|
if result != tc.expected {
|
|
t.Errorf("base64Encode(%q) = %q, want %q", tc.input, result, tc.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEmailFuncs(t *testing.T) {
|
|
funcs := emailFuncs()
|
|
|
|
gt := funcs["gt"].(func(int, int) bool)
|
|
if !gt(5, 3) {
|
|
t.Error("gt(5, 3) should be true")
|
|
}
|
|
|
|
sub := funcs["sub"].(func(int, int) int)
|
|
if sub(10, 3) != 7 {
|
|
t.Error("sub(10, 3) should be 7")
|
|
}
|
|
|
|
truncate := funcs["truncate"].(func(string, int) string)
|
|
if truncate("hello world", 5) != "hello..." {
|
|
t.Error("truncate('hello world', 5) should be 'hello...'")
|
|
}
|
|
}
|