Files
go-omni/openapi/openapi_test.go

55 lines
2.0 KiB
Go

package openapi_test
import (
"encoding/json"
omni "git.yuntuo.hk/k2safe/go-omni"
"git.yuntuo.hk/k2safe/go-omni/httpx"
"git.yuntuo.hk/k2safe/go-omni/openapi"
"net/http/httptest"
"testing"
)
func TestRouteAndContract(t *testing.T) {
type item struct {
ID int64 `json:"id,string"`
RequestID string `json:"requestId,omitempty"`
Payload json.RawMessage `json:"payload"`
}
schema, err := openapi.SchemaOf[item]()
if err != nil || schema.Properties["id"].Type != "string" || schema.Properties["payload"].Type != "" {
t.Fatal(schema, err)
}
api, _ := openapi.New("Test API", "1")
app := omni.New(omni.WithLogger(false))
op := openapi.Operation{Method: "GET", Path: "/items/:id", OperationID: "getItem", Parameters: []openapi.Parameter{{Name: "id", In: "path", Required: true, Schema: &openapi.Schema{Type: "string"}}}, Responses: map[int]openapi.Response{200: {Description: "OK", Schema: openapi.Envelope(schema)}}}
if err = api.Handle(app, op, func(c *httpx.Context) error { return c.OK(item{ID: 1, Payload: json.RawMessage(`{}`)}) }); err != nil {
t.Fatal(err)
}
// Caller edits must not mutate the published contract.
schema.Properties["id"].Type = "boolean"
if err = api.Handle(app, op, func(*httpx.Context) error { return nil }); err == nil {
t.Fatal("duplicate accepted")
}
app.GET("/openapi.json", api.Handler())
r := httptest.NewRecorder()
app.ServeHTTP(r, httptest.NewRequest("GET", "/openapi.json", nil))
var doc struct {
OpenAPI string `json:"openapi"`
Paths map[string]json.RawMessage `json:"paths"`
}
if err = json.Unmarshal(r.Body.Bytes(), &doc); err != nil || doc.OpenAPI != "3.0.3" || doc.Paths["/items/{id}"] == nil {
t.Fatal(r.Body.String(), err)
}
r = httptest.NewRecorder()
app.ServeHTTP(r, httptest.NewRequest("GET", "/items/1", nil))
if r.Code != 200 {
t.Fatal(r.Code)
}
type recursive struct {
Next *recursive `json:"next"`
}
if _, err = openapi.SchemaOf[recursive](); err == nil {
t.Fatal("recursive DTO silently truncated")
}
}