Adding upstream version 0.28.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
88f1d47ab6
commit
e28c88ef14
933 changed files with 194711 additions and 0 deletions
430
tools/router/group_test.go
Normal file
430
tools/router/group_test.go
Normal file
|
@ -0,0 +1,430 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/hook"
|
||||
)
|
||||
|
||||
func TestRouterGroupGroup(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
g0 := RouterGroup[*Event]{}
|
||||
|
||||
g1 := g0.Group("test1")
|
||||
g2 := g0.Group("test2")
|
||||
|
||||
if total := len(g0.children); total != 2 {
|
||||
t.Fatalf("Expected %d child groups, got %d", 2, total)
|
||||
}
|
||||
|
||||
if g1.Prefix != "test1" {
|
||||
t.Fatalf("Expected g1 with prefix %q, got %q", "test1", g1.Prefix)
|
||||
}
|
||||
if g2.Prefix != "test2" {
|
||||
t.Fatalf("Expected g2 with prefix %q, got %q", "test2", g2.Prefix)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupBindFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
g := RouterGroup[*Event]{}
|
||||
|
||||
calls := ""
|
||||
|
||||
// append one function
|
||||
g.BindFunc(func(e *Event) error {
|
||||
calls += "a"
|
||||
return nil
|
||||
})
|
||||
|
||||
// append multiple functions
|
||||
g.BindFunc(
|
||||
func(e *Event) error {
|
||||
calls += "b"
|
||||
return nil
|
||||
},
|
||||
func(e *Event) error {
|
||||
calls += "c"
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if total := len(g.Middlewares); total != 3 {
|
||||
t.Fatalf("Expected %d middlewares, got %v", 3, total)
|
||||
}
|
||||
|
||||
for _, h := range g.Middlewares {
|
||||
_ = h.Func(nil)
|
||||
}
|
||||
|
||||
if calls != "abc" {
|
||||
t.Fatalf("Expected calls sequence %q, got %q", "abc", calls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupBind(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
g := RouterGroup[*Event]{
|
||||
// mock excluded middlewares to check whether the entry will be deleted
|
||||
excludedMiddlewares: map[string]struct{}{"test2": {}},
|
||||
}
|
||||
|
||||
calls := ""
|
||||
|
||||
// append one handler
|
||||
g.Bind(&hook.Handler[*Event]{
|
||||
Func: func(e *Event) error {
|
||||
calls += "a"
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
// append multiple handlers
|
||||
g.Bind(
|
||||
&hook.Handler[*Event]{
|
||||
Id: "test1",
|
||||
Func: func(e *Event) error {
|
||||
calls += "b"
|
||||
return nil
|
||||
},
|
||||
},
|
||||
&hook.Handler[*Event]{
|
||||
Id: "test2",
|
||||
Func: func(e *Event) error {
|
||||
calls += "c"
|
||||
return nil
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if total := len(g.Middlewares); total != 3 {
|
||||
t.Fatalf("Expected %d middlewares, got %v", 3, total)
|
||||
}
|
||||
|
||||
for _, h := range g.Middlewares {
|
||||
_ = h.Func(nil)
|
||||
}
|
||||
|
||||
if calls != "abc" {
|
||||
t.Fatalf("Expected calls %q, got %q", "abc", calls)
|
||||
}
|
||||
|
||||
// ensures that the previously excluded middleware was removed
|
||||
if len(g.excludedMiddlewares) != 0 {
|
||||
t.Fatalf("Expected test2 to be removed from the excludedMiddlewares list, got %v", g.excludedMiddlewares)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupUnbind(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
g := RouterGroup[*Event]{}
|
||||
|
||||
calls := ""
|
||||
|
||||
// anonymous middlewares
|
||||
g.Bind(&hook.Handler[*Event]{
|
||||
Func: func(e *Event) error {
|
||||
calls += "a"
|
||||
return nil // unused value
|
||||
},
|
||||
})
|
||||
|
||||
// middlewares with id
|
||||
g.Bind(&hook.Handler[*Event]{
|
||||
Id: "test1",
|
||||
Func: func(e *Event) error {
|
||||
calls += "b"
|
||||
return nil // unused value
|
||||
},
|
||||
})
|
||||
g.Bind(&hook.Handler[*Event]{
|
||||
Id: "test2",
|
||||
Func: func(e *Event) error {
|
||||
calls += "c"
|
||||
return nil // unused value
|
||||
},
|
||||
})
|
||||
g.Bind(&hook.Handler[*Event]{
|
||||
Id: "test3",
|
||||
Func: func(e *Event) error {
|
||||
calls += "d"
|
||||
return nil // unused value
|
||||
},
|
||||
})
|
||||
|
||||
// remove
|
||||
g.Unbind("") // should be no-op
|
||||
g.Unbind("test1", "test3")
|
||||
|
||||
if total := len(g.Middlewares); total != 2 {
|
||||
t.Fatalf("Expected %d middlewares, got %v", 2, total)
|
||||
}
|
||||
|
||||
for _, h := range g.Middlewares {
|
||||
if err := h.Func(nil); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if calls != "ac" {
|
||||
t.Fatalf("Expected calls %q, got %q", "ac", calls)
|
||||
}
|
||||
|
||||
// ensure that the ids were added in the exclude list
|
||||
excluded := []string{"test1", "test3"}
|
||||
if len(g.excludedMiddlewares) != len(excluded) {
|
||||
t.Fatalf("Expected excludes %v, got %v", excluded, g.excludedMiddlewares)
|
||||
}
|
||||
for id := range g.excludedMiddlewares {
|
||||
if !slices.Contains(excluded, id) {
|
||||
t.Fatalf("Expected %q to be marked as excluded", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupRoute(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
group := RouterGroup[*Event]{}
|
||||
|
||||
sub := group.Group("sub")
|
||||
|
||||
var called bool
|
||||
route := group.Route(http.MethodPost, "/test", func(e *Event) error {
|
||||
called = true
|
||||
return nil
|
||||
})
|
||||
|
||||
// ensure that the route was registered only to the main one
|
||||
// ---
|
||||
if len(sub.children) != 0 {
|
||||
t.Fatalf("Expected no sub children, got %d", len(sub.children))
|
||||
}
|
||||
|
||||
if len(group.children) != 2 {
|
||||
t.Fatalf("Expected %d group children, got %d", 2, len(group.children))
|
||||
}
|
||||
// ---
|
||||
|
||||
// check the registered route
|
||||
// ---
|
||||
if route != group.children[1] {
|
||||
t.Fatalf("Expected group children %v, got %v", route, group.children[1])
|
||||
}
|
||||
|
||||
if route.Method != http.MethodPost {
|
||||
t.Fatalf("Expected route method %q, got %q", http.MethodPost, route.Method)
|
||||
}
|
||||
|
||||
if route.Path != "/test" {
|
||||
t.Fatalf("Expected route path %q, got %q", "/test", route.Path)
|
||||
}
|
||||
|
||||
route.Action(nil)
|
||||
if !called {
|
||||
t.Fatal("Expected route action to be called")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupRouteAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
group := RouterGroup[*Event]{}
|
||||
|
||||
testErr := errors.New("test")
|
||||
|
||||
testAction := func(e *Event) error {
|
||||
return testErr
|
||||
}
|
||||
|
||||
scenarios := []struct {
|
||||
route *Route[*Event]
|
||||
expectMethod string
|
||||
expectPath string
|
||||
}{
|
||||
{
|
||||
group.Any("/test", testAction),
|
||||
"",
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.GET("/test", testAction),
|
||||
http.MethodGet,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.SEARCH("/test", testAction),
|
||||
"SEARCH",
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.POST("/test", testAction),
|
||||
http.MethodPost,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.DELETE("/test", testAction),
|
||||
http.MethodDelete,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.PATCH("/test", testAction),
|
||||
http.MethodPatch,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.PUT("/test", testAction),
|
||||
http.MethodPut,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.HEAD("/test", testAction),
|
||||
http.MethodHead,
|
||||
"/test",
|
||||
},
|
||||
{
|
||||
group.OPTIONS("/test", testAction),
|
||||
http.MethodOptions,
|
||||
"/test",
|
||||
},
|
||||
}
|
||||
|
||||
for i, s := range scenarios {
|
||||
t.Run(fmt.Sprintf("%d_%s_%s", i, s.expectMethod, s.expectPath), func(t *testing.T) {
|
||||
if s.route.Method != s.expectMethod {
|
||||
t.Fatalf("Expected method %q, got %q", s.expectMethod, s.route.Method)
|
||||
}
|
||||
|
||||
if s.route.Path != s.expectPath {
|
||||
t.Fatalf("Expected path %q, got %q", s.expectPath, s.route.Path)
|
||||
}
|
||||
|
||||
if err := s.route.Action(nil); !errors.Is(err, testErr) {
|
||||
t.Fatal("Expected test action")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouterGroupHasRoute(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
group := RouterGroup[*Event]{}
|
||||
|
||||
group.Any("/any", nil)
|
||||
|
||||
group.GET("/base", nil)
|
||||
group.DELETE("/base", nil)
|
||||
|
||||
sub := group.Group("/sub1")
|
||||
sub.GET("/a", nil)
|
||||
sub.POST("/a", nil)
|
||||
|
||||
sub2 := sub.Group("/sub2")
|
||||
sub2.GET("/b", nil)
|
||||
sub2.GET("/b/{test}", nil)
|
||||
|
||||
// special cases to test the normalizations
|
||||
group.GET("/c/", nil) // the same as /c/{test...}
|
||||
group.GET("/d/{test...}", nil) // the same as /d/
|
||||
|
||||
scenarios := []struct {
|
||||
method string
|
||||
path string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
http.MethodGet,
|
||||
"",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"",
|
||||
"/any",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/base",
|
||||
false,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/base",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodDelete,
|
||||
"/base",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub1",
|
||||
false,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub1/a",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodPost,
|
||||
"/sub1/a",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodDelete,
|
||||
"/sub1/a",
|
||||
false,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub2/b",
|
||||
false,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub1/sub2/b",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub1/sub2/b/{test}",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/sub1/sub2/b/{test2}",
|
||||
false,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/c/{test...}",
|
||||
true,
|
||||
},
|
||||
{
|
||||
http.MethodGet,
|
||||
"/d/",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.method+"_"+s.path, func(t *testing.T) {
|
||||
has := group.HasRoute(s.method, s.path)
|
||||
|
||||
if has != s.expected {
|
||||
t.Fatalf("Expected %v, got %v", s.expected, has)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue