Files
go-omni/cmd/go-omni/apigen/testdata/business/consumer_test.go

120 lines
3.8 KiB
Go
Raw Blame History

package main
import (
"bytes"
"context"
"encoding/json"
"example.com/business/internal/config"
"example.com/business/internal/handler"
"example.com/business/internal/svc"
"git.yuntuo.hk/k2safe/go-omni/logx"
"io"
"mime/multipart"
"net/http/httptest"
"strings"
"testing"
)
func TestShapesAndPolicy(t *testing.T) {
cfg := config.Default()
cfg.Server.Log.Writer = io.Discard
logger, err := logx.New(cfg.Server.Log)
if err != nil {
t.Fatal(err)
}
defer logger.Close()
deps, err := svc.New(context.Background(), logger, cfg)
if err != nil {
t.Fatal(err)
}
defer deps.Close()
app, err := handler.NewApp(deps)
if err != nil {
t.Fatal(err)
}
defer app.Close()
for _, tt := range []struct {
method, path, body, media string
status int
data string
raw bool
}{
{"GET", "/list", "", "", 200, `[]`, false},
{"GET", "/list?mode=full&tags=a&tags=b", "", "", 200, `[{"name":"one"}]`, false},
{"GET", "/nullable", "", "", 200, `null`, false},
{"GET", "/nullable?mode=full", "", "", 200, `{"name":"one"}`, false},
{"POST", "/nothing", "", "", 200, `null`, false},
{"GET", "/rawNull", "", "", 200, `null`, true},
{"GET", "/rawArray", "", "", 200, `[]`, true},
{"DELETE", "/noContent", "", "", 204, "", true},
{"POST", "/empty", `{}`, "application/json", 200, `null`, false},
{"POST", "/empty", ``, "application/json", 400, "", false},
{"POST", "/empty", `{"unknown":1}`, "application/json", 400, "", false},
{"POST", "/absent", ``, "", 200, `null`, false},
{"POST", "/absent", `{}`, "application/json", 400, "", false},
{"POST", "/optional", ``, "", 200, `{"name":""}`, false},
{"POST", "/optional", `{}`, "application/json", 400, "", false},
{"POST", "/echo", `{"name":"ok"}`, "application/json", 200, `{"name":"ok"}`, false},
{"POST", "/echo", `{"name":"ok"}`, "application/json; charset=latin1", 415, "", false},
{"POST", "/echo", "{\"name\":\"\xff\"}", "application/json", 400, "", false},
{"GET", "/list?unknown=1", "", "", 400, "", false},
{"GET", "/rawNull?unknown=1", "", "", 400, "", false},
{"POST", "/tolerant?unknown=1", "{\"name\":\"\xff\"}", "application/json; charset=latin1", 200, `{"name":"<22>"}`, false},
} {
t.Run(tt.method+tt.path+tt.body+tt.media, func(t *testing.T) {
r := httptest.NewRequest(tt.method, tt.path, strings.NewReader(tt.body))
if tt.media != "" {
r.Header.Set("Content-Type", tt.media)
}
w := httptest.NewRecorder()
app.ServeHTTP(w, r)
if w.Code != tt.status {
t.Fatalf("%d %s", w.Code, w.Body)
}
if tt.status >= 400 {
return
}
data := strings.TrimSpace(w.Body.String())
if !tt.raw {
var obj map[string]json.RawMessage
if err := json.Unmarshal(w.Body.Bytes(), &obj); err != nil {
t.Fatal(err)
}
v, ok := obj["data"]
if !ok {
t.Fatal("missing data")
}
data = string(v)
}
if data != tt.data {
t.Fatalf("data %s expected %s", data, tt.data)
}
})
}
var body bytes.Buffer
form := multipart.NewWriter(&body)
_ = form.WriteField("title", "title")
_ = form.WriteField("metadata", `{"name":"meta"}`)
f, err := form.CreateFormFile("attachment", "a.txt")
if err != nil {
t.Fatal(err)
}
_, _ = io.WriteString(f, "content")
_ = form.Close()
r := httptest.NewRequest("POST", "/upload", &body)
r.Header.Set("Content-Type", form.FormDataContentType())
w := httptest.NewRecorder()
app.ServeHTTP(w, r)
if w.Code != 200 || !strings.Contains(w.Body.String(), "title:meta:content") {
t.Fatal(w.Code, w.Body.String())
}
denied := httptest.NewRequest("GET", "/list", nil)
denied.Header.Set("Authorization", "reject")
result := httptest.NewRecorder()
app.ServeHTTP(result, denied)
if result.Code != 403 {
t.Fatal("injected middleware did not run", result.Code, result.Body.String())
}
}