package web
import (
"strings"
"testing"
)
// A robot line carries its own mark and takes no author hue: the row
// says "the channel said this", not "a person did" (RFC 0011 ยง10).
func TestRobotLineIsMarkedAndUnhued(t *testing.T) {
row := string(noHooks.chatMsgHTML(ChatMessage{Seq: 9, Kind: "robot", User: "robot",
Text: "check-in abc1234 on trunk", At: "2026-08-29T14:05:00Z"}, "alpha", "dan", false))
if !strings.Contains(row, `data-hook="robot-mark"`) {
t.Errorf("robot line has no mark:\n%s", row)
}
if strings.Contains(row, "--uh:") {
t.Errorf("robot line took an author hue:\n%s", row)
}
if !strings.Contains(row, `data-kind="robot"`) {
t.Errorf("robot line does not declare its kind:\n%s", row)
}
person := string(noHooks.chatMsgHTML(ChatMessage{Seq: 10, Kind: "msg", User: "dan",
Text: "hi", At: "2026-08-29T14:05:00Z"}, "alpha", "dan", false))
if strings.Contains(person, `data-hook="robot-mark"`) {
t.Errorf("a person's line was marked as the robot's:\n%s", person)
}
if !strings.Contains(person, "--uh:") {
t.Errorf("a person's line lost its hue:\n%s", person)
}
}
// The robot offers only events this forge can actually raise: without
// a CI engine there is no `ci`, because a pattern that cannot match
// reads as a robot that is broken. The webhook list keeps everything.
func TestRobotNounsDropCIWithoutAnEngine(t *testing.T) {
with := robotNouns(true)
without := robotNouns(false)
if !offers(with, "ci") {
t.Fatalf("a forge with an engine was not offered ci: %v", with)
}
if offers(without, "ci") {
t.Fatalf("a forge with no engine was offered ci: %v", without)
}
if len(without) != len(with)-1 {
t.Fatalf("dropping ci took %d nouns", len(with)-len(without))
}
for _, n := range []string{"checkin", "landing", "forum"} {
if !offers(without, n) {
t.Fatalf("%q went missing from the robot's vocabulary: %v", n, without)
}
}
}
func offers(all []string, want string) bool {
for _, s := range all {
if s == want {
return true
}
}
return false
}