package main import ( "encoding/json" "html" "net/http/httptest" "os" "strings" "testing" ) func TestTaskBriefDisplaysQuestionsAndDeliverables(t *testing.T) { data, err := os.ReadFile("data/milestones.json") if err != nil { t.Fatal(err) } var milestones []Milestone if err = json.Unmarshal(data, &milestones); err != nil { t.Fatal(err) } var target *Task for _, m := range milestones { for _, e := range m.Epics { for i := range e.Tasks { if e.Tasks[i].ID == "T-303" { copy := e.Tasks[i] target = © } } } } if target == nil || target.Description == "" || len(target.Deliverables) == 0 || len(target.Questions) == 0 { t.Fatal("T-303 needs an actionable brief, deliverables and questions") } for _, q := range target.Questions { if q.ID == "" || q.AskedOf == "" || q.Question == "" || q.Why == "" { t.Fatal("questions must identify recipient and impact") } } mux := newMux(NewStore("data"), NewHub()) w := httptest.NewRecorder() mux.ServeHTTP(w, httptest.NewRequest("GET", "/tasks/T-303", nil)) for _, text := range []string{"รายละเอียดงาน", "ผลลัพธ์ที่ต้องส่งมอบ", "คำถามที่ต้องการข้อมูล", target.Questions[0].ID, target.Questions[0].AskedOf} { if !strings.Contains(html.UnescapeString(w.Body.String()), text) { t.Fatal("missing brief section", text) } } } func TestPreparationBriefsHaveTraceableQuestions(t *testing.T) { data, err := os.ReadFile("data/milestones.json") if err != nil { t.Fatal(err) } var milestones []Milestone if err = json.Unmarshal(data, &milestones); err != nil { t.Fatal(err) } known := map[string]bool{} for _, m := range milestones { for _, e := range m.Epics { for _, task := range e.Tasks { known[task.ID] = true } } } seen := map[string]bool{} for _, m := range milestones { for _, e := range m.Epics { for _, task := range e.Tasks { if task.Status == StatusTodo { if task.Summary == "" || task.Description == "" || len(task.Steps) == 0 || len(task.Deliverables) == 0 || len(task.Questions) == 0 { t.Fatalf("unactionable pending task %s", task.ID) } } for _, id := range task.Dependencies { if !known[id] || id == task.ID { t.Fatalf("invalid dependency %s -> %s", task.ID, id) } } for _, q := range task.Questions { if q.ID == "" || seen[q.ID] || q.AskedOf == "" || q.Why == "" || q.Question == "" { t.Fatalf("untraceable question in %s", task.ID) } seen[q.ID] = true if q.State == "answered" && q.Answer == "" { t.Fatalf("false answer in %s", q.ID) } } } } } if len(seen) == 0 { t.Fatal("no task questions loaded") } }