From e58fa50656700890ccf51338e8b17dd1c7c01900 Mon Sep 17 00:00:00 2001 From: bel Date: Sat, 13 Apr 2024 09:48:28 -0600 Subject: [PATCH] accept Accept:text/csv --- main.go | 54 +++++++++++++++++++++++++++++++++++++++++----------- main_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index 6d59bd7..bf727f7 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "net" "net/http" "os/signal" + "sort" "strconv" "strings" "syscall" @@ -97,7 +98,7 @@ func newHandlerGetAPIV1Messages(cfg Config) http.HandlerFunc { return } - encodeJSONResponse(w, map[string]any{"messages": messages}) + encodeResponse(w, r, map[string]any{"messages": messages}) } } @@ -119,7 +120,7 @@ func newHandlerGetAPIV1Threads(cfg Config) http.HandlerFunc { return } - encodeJSONResponse(w, map[string]any{"threads": threads}) + encodeResponse(w, r, map[string]any{"threads": threads}) } } @@ -137,7 +138,7 @@ func newHandlerGetAPIV1ThreadsThread(cfg Config) http.HandlerFunc { return } - encodeJSONResponse(w, map[string]any{"thread": map[string]any{"messages": messages}}) + encodeResponse(w, r, map[string]any{"thread": messages}) } } @@ -168,7 +169,7 @@ func handlerPostAPIV1EventsSlackInitialize(w http.ResponseWriter, r *http.Reques return } - encodeJSONResponse(w, map[string]any{"challenge": challenge.Challenge}) + encodeResponse(w, r, map[string]any{"challenge": challenge.Challenge}) } func _newHandlerPostAPIV1EventsSlack(cfg Config) http.HandlerFunc { @@ -256,12 +257,43 @@ func encodeJSONResponse(w http.ResponseWriter, v interface{}) error { } func encodeCSVResponse(w http.ResponseWriter, v interface{}) error { - return errors.New("not impl") - /* - enc := csv.NewWriter(w) - if err := enc.Write(fields); err != nil { - return err + b, err := json.Marshal(v) + if err != nil { + return err + } + + var data map[string][]map[string]json.RawMessage + if err := json.Unmarshal(b, &data); err != nil { + return err + } + + var objects []map[string]json.RawMessage + for k := range data { + objects = data[k] + } + + fields := []string{} + for i := range objects { + for k := range objects[i] { + b, _ := json.Marshal(k) + fields = append(fields, string(b)) } - return enc.WriteAll(values) - */ + break + } + sort.Strings(fields) + + w.Write([]byte(strings.Join(fields, ","))) + + for _, object := range objects { + w.Write([]byte("\n")) + for j, field := range fields { + json.Unmarshal([]byte(field), &field) + if j > 0 { + w.Write([]byte(",")) + } + w.Write(object[field]) + } + } + + return nil } diff --git a/main_test.go b/main_test.go index 27c8bc8..8ce7e4a 100644 --- a/main_test.go +++ b/main_test.go @@ -3,6 +3,7 @@ package main import ( "bytes" "context" + "encoding/csv" "encoding/json" "fmt" "io" @@ -139,16 +140,56 @@ func TestRun(t *testing.T) { } var result struct { - Thread struct { - Messages []Message - } + Thread []Message } if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { t.Fatal(err) - } else if len(result.Thread.Messages) != 1 { + } else if len(result.Thread) != 1 { t.Fatal(result.Thread) } else { t.Logf("%+v", result) } }) + + t.Run("CSV GET /api/v1/threads/1712911957.023359", func(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/api/v1/threads/1712911957.023359", u), nil) + if err != nil { + t.Fatal(err) + } + req.Header.Set("Accept", "text/csv") + + resp, err := http.DefaultClient.Do(req) + 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) + } + + dec := csv.NewReader(resp.Body) + var lastLine []string + for { + line, err := dec.Read() + if err == io.EOF { + break + } else if err != nil { + t.Error(err) + } + + if lastLine == nil { + } else if len(lastLine) != len(line) { + t.Errorf("last line had %v elements but this line has %v", len(lastLine), len(line)) + } + + t.Logf("%+v", line) + lastLine = line + } + if lastLine == nil { + t.Error("no lines found") + } + + }) }