mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-11-09 00:22:38 -06:00
172 lines
5.2 KiB
Go
172 lines
5.2 KiB
Go
// Vikunja is a to-do list application to facilitate your life.
|
|
// Copyright 2018-present Vikunja and contributors. All rights reserved.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package mcp
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/danielgtaylor/huma/v2"
|
|
"github.com/danielgtaylor/huma/v2/autopatch"
|
|
"github.com/danielgtaylor/huma/v2/humatest"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newTestModule(t *testing.T) *Module {
|
|
t.Helper()
|
|
m, err := New(newTestAPI(t), nil)
|
|
require.NoError(t, err)
|
|
return m
|
|
}
|
|
|
|
type testThing struct {
|
|
ID int64 `json:"id" readOnly:"true"`
|
|
Title string `json:"title" valid:"required" minLength:"1"`
|
|
Description string `json:"description"`
|
|
Done bool `json:"done"`
|
|
Owner *testOwner `json:"owner" readOnly:"true"`
|
|
Reminders []*testWhen `json:"reminders"`
|
|
}
|
|
type testOwner struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
type testWhen struct {
|
|
At string `json:"at" format:"date-time"`
|
|
}
|
|
type testThingBody struct{ Body *testThing }
|
|
type echoBody struct {
|
|
Body struct {
|
|
Method string `json:"method"`
|
|
Path string `json:"path"`
|
|
Query map[string]string `json:"query"`
|
|
Auth string `json:"auth"`
|
|
CT string `json:"content_type"`
|
|
Body *testThing `json:"body,omitempty"`
|
|
}
|
|
}
|
|
|
|
func newTestAPI(t *testing.T) huma.API {
|
|
t.Helper()
|
|
cfg := huma.DefaultConfig("test", "1")
|
|
cfg.FieldsOptionalByDefault = true
|
|
_, api := humatest.New(t, cfg)
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-list",
|
|
Method: http.MethodGet,
|
|
Path: "/things",
|
|
Summary: "List things",
|
|
},
|
|
func(_ context.Context, in *struct {
|
|
Q string `query:"q"`
|
|
Filter string `query:"filter" doc:"Filter things."`
|
|
Page int `query:"page" default:"1" minimum:"1"`
|
|
Expand []string `query:"expand,explode" enum:"a,b"`
|
|
Format string `query:"format" enum:"html,markdown"`
|
|
Auth string `header:"Authorization"`
|
|
}) (*echoBody, error) {
|
|
out := &echoBody{}
|
|
out.Body.Method, out.Body.Path, out.Body.Auth = http.MethodGet, "/things", in.Auth
|
|
out.Body.Query = map[string]string{
|
|
"q": in.Q,
|
|
"format": in.Format,
|
|
"expand": strings.Join(in.Expand, "|"),
|
|
}
|
|
return out, nil
|
|
})
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-read",
|
|
Method: http.MethodGet,
|
|
Path: "/things/{id}",
|
|
}, func(_ context.Context, in *struct {
|
|
ID int64 `path:"id"`
|
|
}) (*testThingBody, error) {
|
|
if in.ID == 404 {
|
|
return nil, huma.Error404NotFound("no such thing")
|
|
}
|
|
if in.ID == 401 {
|
|
return nil, huma.Error401Unauthorized("Unauthorized")
|
|
}
|
|
return &testThingBody{
|
|
Body: &testThing{
|
|
ID: in.ID,
|
|
Title: "stored",
|
|
Description: "keep me",
|
|
Owner: &testOwner{ID: 1},
|
|
},
|
|
}, nil
|
|
})
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-create",
|
|
Method: http.MethodPost,
|
|
Path: "/things",
|
|
}, func(_ context.Context, in *struct {
|
|
Body testThing
|
|
CT string `header:"Content-Type"`
|
|
}) (*echoBody, error) {
|
|
out := &echoBody{}
|
|
out.Body.Method, out.Body.Path, out.Body.CT = http.MethodPost, "/things", in.CT
|
|
out.Body.Body = &in.Body
|
|
return out, nil
|
|
})
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-update",
|
|
Method: http.MethodPut,
|
|
Path: "/things/{id}",
|
|
Summary: "Update a thing",
|
|
Description: "Moving a thing needs write access to the target.",
|
|
}, func(_ context.Context, in *struct {
|
|
ID int64 `path:"id"`
|
|
Body testThing
|
|
CT string `header:"Content-Type"`
|
|
}) (*echoBody, error) {
|
|
out := &echoBody{}
|
|
out.Body.Method, out.Body.Path, out.Body.CT = http.MethodPut, "/things/"+strconv.FormatInt(in.ID, 10), in.CT
|
|
out.Body.Body = &in.Body
|
|
return out, nil
|
|
})
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-delete",
|
|
Method: http.MethodDelete,
|
|
Path: "/things/{id}",
|
|
}, func(_ context.Context, _ *struct {
|
|
ID int64 `path:"id"`
|
|
}) (*struct{}, error) {
|
|
return nil, nil
|
|
})
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "tokens-create",
|
|
Method: http.MethodPost,
|
|
Path: "/tokens",
|
|
}, func(_ context.Context, _ *struct{ Body testThing }) (*testThingBody, error) { return nil, nil })
|
|
huma.Register(api, huma.Operation{
|
|
OperationID: "things-upload",
|
|
Method: http.MethodPost,
|
|
Path: "/things/{id}/file",
|
|
}, func(_ context.Context, _ *struct {
|
|
ID int64 `path:"id"`
|
|
RawBody huma.MultipartFormFiles[struct{}]
|
|
}) (*struct{}, error) {
|
|
return nil, nil
|
|
})
|
|
autopatch.AutoPatch(api)
|
|
return api
|
|
}
|