118 lines
4.2 KiB
Go
118 lines
4.2 KiB
Go
package main_test
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"example.com/compatibility/internal/handler"
|
|
"example.com/compatibility/internal/svc"
|
|
omni "git.yuntuo.hk/k2safe/go-omni"
|
|
"git.yuntuo.hk/k2safe/go-omni/logx"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGeneratedCompatibility(t *testing.T) {
|
|
logger, err := logx.New(logx.Config{Writer: io.Discard})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer logger.Close()
|
|
deps, err := svc.New(context.Background(), logger)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer deps.Close()
|
|
app := omni.New()
|
|
defer app.Close()
|
|
if err = handler.RegisterRoutes(app, deps); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
send := func(method, path, body, contentType string) *httptest.ResponseRecorder {
|
|
r := httptest.NewRequest(method, path, strings.NewReader(body))
|
|
r.Header.Set("Content-Type", contentType)
|
|
w := httptest.NewRecorder()
|
|
app.ServeHTTP(w, r)
|
|
return w
|
|
}
|
|
for _, id := range []string{`9223372036854775807`, `"9223372036854775807"`} {
|
|
w := send("POST", "/echo", `{"id":`+id+`,"data":{"n":9223372036854775807}}`, "application/json")
|
|
if w.Code != 200 || !strings.Contains(w.Body.String(), `"id":"9223372036854775807"`) || !strings.Contains(w.Body.String(), `"n":9223372036854775807`) {
|
|
t.Fatalf("scalar/dynamic: %d %s", w.Code, w.Body)
|
|
}
|
|
}
|
|
for _, body := range []string{`{"id":true,"data":null}`, `{"id":9223372036854775808,"data":null}`, `{"id":1,"data":{"x":1,"x":2}}`, `{"id":1,"data":null,"extra":1}`} {
|
|
if w := send("POST", "/echo", body, "application/json"); w.Code != 400 {
|
|
t.Fatalf("accepted %s: %d", body, w.Code)
|
|
}
|
|
}
|
|
payload := `{"id":1,"data":"` + strings.Repeat("x", (1<<20)+1) + `"}`
|
|
if w := send("POST", "/echo", payload, "application/json"); w.Code != 200 {
|
|
t.Fatalf("route limit not passed to Binder: %d", w.Code)
|
|
}
|
|
if w := send("POST", "/echo", `{"id":1,"data":"`+strings.Repeat("x", 2<<20)+`"}`, "application/json"); w.Code != 413 {
|
|
t.Fatalf("large JSON: %d", w.Code)
|
|
}
|
|
if w := send("GET", "/items/9223372036854775807", "", ""); w.Code != 200 || !strings.Contains(w.Body.String(), `"id":"9223372036854775807"`) {
|
|
t.Fatalf("text scalar: %d %s", w.Code, w.Body)
|
|
}
|
|
if w := send("POST", "/custom", `{"value":"hello"}`, "application/json"); w.Code != 200 || !strings.Contains(w.Body.String(), "HELLO") {
|
|
t.Fatalf("custom binder: %d %s", w.Code, w.Body)
|
|
}
|
|
raw := `{ "event": 1, "id": "original bytes" }`
|
|
mac := hmac.New(sha256.New, []byte("fixture-only-key"))
|
|
mac.Write([]byte(raw))
|
|
r := httptest.NewRequest("POST", "/callback", strings.NewReader(raw))
|
|
r.Header.Set("X-Signature", hex.EncodeToString(mac.Sum(nil)))
|
|
w := httptest.NewRecorder()
|
|
app.ServeHTTP(w, r)
|
|
if w.Code != 200 || w.Body.String() != "accepted" {
|
|
t.Fatalf("raw callback: %d %s", w.Code, w.Body)
|
|
}
|
|
r = httptest.NewRequest("POST", "/callback", strings.NewReader(strings.Repeat("x", 129)))
|
|
r.ContentLength = -1
|
|
w = httptest.NewRecorder()
|
|
app.ServeHTTP(w, r)
|
|
if w.Code != 413 {
|
|
t.Fatalf("chunked body limit: %d %s", w.Code, w.Body)
|
|
}
|
|
temp := t.TempDir()
|
|
t.Setenv("TMPDIR", temp)
|
|
var form bytes.Buffer
|
|
writer := multipart.NewWriter(&form)
|
|
part, err := writer.CreateFormFile("file", "sample.bin")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
part.Write(bytes.Repeat([]byte("x"), 8192))
|
|
writer.Close()
|
|
w = send("POST", "/upload", form.String(), writer.FormDataContentType())
|
|
if w.Code != 200 || !strings.Contains(w.Body.String(), `"bytes":8192`) {
|
|
t.Fatalf("upload: %d %s", w.Code, w.Body)
|
|
}
|
|
entries, err := os.ReadDir(temp)
|
|
if err != nil || len(entries) != 0 {
|
|
t.Fatalf("multipart temp files leaked: %v %v", entries, err)
|
|
}
|
|
w = send("GET", "/download", "", "")
|
|
if w.Code != 200 || w.Body.Len() != 128<<10 || w.Header().Get("Content-Disposition") == "" {
|
|
t.Fatalf("download wrapped: %d %d", w.Code, w.Body.Len())
|
|
}
|
|
var doc map[string]any
|
|
if err = json.Unmarshal([]byte(handler.OpenAPIDocument), &doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
paths := doc["paths"].(map[string]any)
|
|
media := paths["/download"].(map[string]any)["get"].(map[string]any)["responses"].(map[string]any)["200"].(map[string]any)["content"].(map[string]any)
|
|
if media["application/octet-stream"] == nil || media["application/json"] != nil {
|
|
t.Fatal("download schema is JSON")
|
|
}
|
|
}
|