package server import ( "net/http" "testing" "time" "g.fc.run/misc/byre/internal/api" ) func TestCheckResponse(t *testing.T) { question := api.InboxItem{ Id: "q1", Kind: api.InboxItemKindQuestion, State: api.Open, Payload: map[string]any{"options": []any{"red", "blue"}}, } report := api.InboxItem{Id: "r1", Kind: api.InboxItemKindReport, State: api.Open, Payload: map[string]any{}} closed := question closed.State = api.Answered str := func(s string) *string { return &s } future := time.Now().Add(time.Hour) past := time.Now().Add(-time.Hour) cases := []struct { name string item api.InboxItem create api.InboxResponseCreate state api.InboxState status int }{ {"option", question, api.InboxResponseCreate{Type: api.InboxResponseTypeOption, Option: str("blue")}, api.Answered, 0}, {"option with note", question, api.InboxResponseCreate{Type: api.InboxResponseTypeOption, Option: str("red"), Text: str("but darker")}, api.Answered, 0}, {"unknown option", question, api.InboxResponseCreate{Type: api.InboxResponseTypeOption, Option: str("green")}, "", http.StatusBadRequest}, {"missing option", question, api.InboxResponseCreate{Type: api.InboxResponseTypeOption}, "", http.StatusBadRequest}, {"free form", question, api.InboxResponseCreate{Type: api.InboxResponseTypeFreeForm, Text: str("green")}, api.Answered, 0}, {"empty free form", question, api.InboxResponseCreate{Type: api.InboxResponseTypeFreeForm, Text: str(" ")}, "", http.StatusBadRequest}, {"follow-up question", question, api.InboxResponseCreate{Type: api.InboxResponseTypeQuestion, Text: str("why?")}, api.Open, 0}, {"redirect question", question, api.InboxResponseCreate{Type: api.InboxResponseTypeRedirect, Text: str("stop")}, api.Redirected, 0}, {"redirect report", report, api.InboxResponseCreate{Type: api.InboxResponseTypeRedirect, Text: str("stop")}, api.Redirected, 0}, {"snooze", question, api.InboxResponseCreate{Type: api.InboxResponseTypeSnooze, SnoozeUntil: &future}, api.Open, 0}, {"snooze into past", question, api.InboxResponseCreate{Type: api.InboxResponseTypeSnooze, SnoozeUntil: &past}, "", http.StatusBadRequest}, {"dismiss report", report, api.InboxResponseCreate{Type: api.InboxResponseTypeDismiss}, api.Dismissed, 0}, {"dismiss question", question, api.InboxResponseCreate{Type: api.InboxResponseTypeDismiss}, "", http.StatusBadRequest}, {"option on report", report, api.InboxResponseCreate{Type: api.InboxResponseTypeOption, Option: str("red")}, "", http.StatusBadRequest}, {"already answered", closed, api.InboxResponseCreate{Type: api.InboxResponseTypeOption, Option: str("red")}, "", http.StatusConflict}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { state, herr := checkResponse(c.item, c.create) if c.status != 0 { if herr == nil || herr.status != c.status { t.Fatalf("want status %d, got %+v", c.status, herr) } return } if herr != nil { t.Fatalf("unexpected error %v", herr.err) } if state != c.state { t.Fatalf("want state %s, got %s", c.state, state) } }) } }