package transcript import ( "bytes" "html/template" "os" "path/filepath" "testing" "time" "github.com/leolionad58/ticketbot/internal/db" ) func makeTicket() *db.Ticket { return &db.Ticket{ ID: 1, TicketNumber: 1, Type: "support", Panel: "support_panel", ChannelID: "ch123456", UserID: "user123", OpenedAt: time.Now(), Status: "open", } } func TestTemplateRender(t *testing.T) { ticket := makeTicket() tmpl, err := template.New("t").Parse(HTMLTemplate) if err != nil { t.Fatalf("parse template: %v", err) } messages := []Message{ { AuthorName: "TestUser", AuthorInitial: "T", Content: template.HTML("Hello world"), Timestamp: "01/01/2024 12:00:00", }, } data := struct { Ticket *db.Ticket Messages []Message Generated string }{Ticket: ticket, Messages: messages, Generated: "test"} var buf bytes.Buffer if err := tmpl.Execute(&buf, data); err != nil { t.Fatalf("execute template: %v", err) } dir := t.TempDir() outPath := filepath.Join(dir, "support-0001-ch123456.html") os.WriteFile(outPath, buf.Bytes(), 0644) content, _ := os.ReadFile(outPath) if !bytes.Contains(content, []byte("support-0001")) { t.Error("missing ticket reference") } if !bytes.Contains(content, []byte("TestUser")) { t.Error("missing author name") } if !bytes.Contains(content, []byte("Hello world")) { t.Error("missing message content") } } func TestXSSEscaping(t *testing.T) { // renderMessage must escape all user-controlled content // We test the escaping logic by simulating a message with XSS payload msg := &struct { Content string Username string }{ Content: "", Username: "user", } escapedContent := template.HTMLEscapeString(msg.Content) escapedName := template.HTMLEscapeString(msg.Username) if escapedContent == msg.Content { t.Error("content should be escaped") } if escapedName == msg.Username { t.Error("username should be escaped") } if bytes.Contains([]byte(escapedContent), []byte("")), Timestamp: "01/01/2024 12:00:00", }, } data := struct { Ticket *db.Ticket Messages []Message Generated string }{Ticket: ticket, Messages: messages, Generated: "test"} var buf bytes.Buffer tmpl.Execute(&buf, data) if bytes.Contains(buf.Bytes(), []byte("