120 lines
3.8 KiB
Go
120 lines
3.8 KiB
Go
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())
|
||
}
|
||
|
||
}
|