package main import ( "bytes" "context" "encoding/json" "fmt" "io" "net/http" "net/http/httptest" "net/url" "os" "path" "strconv" "strings" "testing" "time" ) func TestRun(t *testing.T) { ctx, can := context.WithTimeout(context.Background(), time.Second*10) defer can() port := func() int { s := httptest.NewServer(http.HandlerFunc(http.NotFound)) s.Close() u, err := url.Parse(s.URL) if err != nil { t.Fatal(err) } portS := strings.Split(u.Host, ":")[1] port, err := strconv.ParseInt(portS, 10, 32) if err != nil { t.Fatal(err) } return int(port) }() u := fmt.Sprintf("http://localhost:%d", port) cfg := Config{} cfg.Port = port cfg.driver = NewRAM() cfg.storage = NewStorage(cfg.driver) cfg.queue = NewQueue(cfg.driver) cfg.SlackToken = "redacted" cfg.SlackChannels = []string{"C06U1DDBBU4"} go func() { if err := run(ctx, cfg); err != nil && ctx.Err() == nil { t.Fatal(err) } }() for { if resp, err := http.Get(u); err == nil { resp.Body.Close() break } select { case <-ctx.Done(): t.Fatal(ctx.Err()) case <-time.After(time.Millisecond * 50): } } t.Run("POST /api/v1/events/slack", func(t *testing.T) { b, err := os.ReadFile(path.Join("testdata", "slack_events", "opsgenie_alert_3.json")) if err != nil { t.Fatal(err) } resp, err := http.Post(fmt.Sprintf("%s/api/v1/events/slack", u), "application/json", bytes.NewReader(b)) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("(%d) %s", resp.StatusCode, b) } }) t.Run("GET /api/v1/threads", func(t *testing.T) { resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads", u)) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("(%d) %s", resp.StatusCode, b) } var result struct { Threads []string } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { t.Fatal(err) } else if result.Threads[0] != "1712911957.023359" { t.Fatal(result.Threads) } }) t.Run("GET /api/v1/threads/1712911957.023359", func(t *testing.T) { resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads/1712911957.023359", u)) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) t.Fatalf("(%d) %s", resp.StatusCode, b) } var result struct { Thread struct { Messages []Message } } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { t.Fatal(err) } else if len(result.Thread.Messages) != 1 { t.Fatal(result.Thread) } else { t.Logf("%+v", result.Thread.Messages[0]) } }) }