Files
summercms/modules/pier/catalog_path_fields_test.go
Jakub Zych ccf77b9103 test(19.7-09): named tests for every framework and admin SPA fix of plans 06 and 07
- pier: TestSessionReserve (A-WR-03), TestLockScope (A-WR-07),
  TestScopeWidening (A-WR-04), TestStatelessFanOut (A-WR-05, A-WR-06),
  TestPersonalTokenBinding (A-WR-09), TestDispatchHardening (A-WR-01,
  A-WR-02, A-WR-08, A-IN-04, A-IN-05, A-IN-08), TestCatalogPathFields
  (A-WR-02, A-IN-07), TestPromptWriteCeiling (C-IN-01),
  TestTokenScopedRevoke (B-WR-04, C-IN-02), TestResolveClientAddress
  (B-IN-04); test seam WrapStore
- pact TestFrontendTokenScopes, towel TestClientIP, cabana
  TestTokenScopeNameParity
- cabana TestAccountContributionURL (B-WR-03), TestAccountContributionsIsolation
  (B-WR-06, B-IN-03), TestRecordActionPromptLocalized (B-IN-02), and the
  Postgres TestAccountTokenRevokeEvent (B-WR-04) and
  TestResolveBackendTokenRemote (B-IN-04)
- vitest: hotkeysEditing.test.ts (B-WR-01, B-WR-02) and the extended
  AccountContributions.test.ts (B-WR-03, B-WR-06, B-IN-01)
- check-phase19.7.sh requires every name (GO_TESTS, GO_TAGGED_TESTS,
  DOCKER_TESTS, ADMIN_FILES) and scans the new files (PHASE_TEST_FILES)
2026-10-23 18:36:16 +02:00

66 lines
2.1 KiB
Go

package pier_test
import (
"net/http"
"strings"
"testing"
"git.golem15.com/golem15/summercms/modules/pact"
)
type optionalPathInput struct {
ID string `json:"id,omitempty" path:"id"`
}
type requiredPathInput struct {
ID string `json:"id" path:"id"`
}
type pageFields struct {
Title string `json:"title"`
}
type embeddedInput struct {
pageFields
ID string `json:"id" path:"id"`
}
// TestCatalogPathFields pins plan 06's boot rules for tool inputs (the boot
// half of A-WR-02, A-IN-07): a path field marked omitempty fails boot and
// the error names the field, the same field without it compiles, and an
// embedded struct (whose promoted fields would be body fields) fails boot
// on a GET tool and compiles on a POST tool.
func TestCatalogPathFields(t *testing.T) {
route := func(method string) testRoute { return guarded(method, "/fields/{id}") }
tool := func(method string, input any) pact.MCPTool {
return pact.MCPTool{Name: "f", Description: "Fields.", Method: method, Path: "/fields/{id}", Input: input}
}
mount := func(method string, input any) error {
_, err := catalogMount(t, routePlugin{id: "test.fields", routes: []testRoute{route(method)}, tools: []pact.MCPTool{tool(method, input)}})
return err
}
t.Run("an omitempty path field fails boot naming the field", func(t *testing.T) {
err := mount(http.MethodGet, optionalPathInput{})
if err == nil || !strings.Contains(err.Error(), `path field "id" must be required`) {
t.Fatalf("err = %v", err)
}
})
t.Run("a required path field compiles", func(t *testing.T) {
if err := mount(http.MethodGet, requiredPathInput{}); err != nil {
t.Fatal(err)
}
})
t.Run("an embedded struct fails boot on a GET tool", func(t *testing.T) {
err := mount(http.MethodGet, embeddedInput{})
if err == nil || !strings.Contains(err.Error(), `embedded field "pageFields"`) || !strings.Contains(err.Error(), "GET") {
t.Fatalf("err = %v", err)
}
})
t.Run("an embedded struct compiles on a POST tool", func(t *testing.T) {
if err := mount(http.MethodPost, embeddedInput{}); err != nil {
t.Fatal(err)
}
})
}