Skip to content

Commit

Permalink
[pocketbase#2914] register the eagerRequestDataCache middleware only …
Browse files Browse the repository at this point in the history
…for the api grroup to avoid conflicts with custom routes
  • Loading branch information
ganigeorgiev committed Jul 14, 2023
1 parent c384425 commit f0bcffe
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 45 deletions.
6 changes: 1 addition & 5 deletions apis/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func InitApi(app core.App) (*echo.Echo, error) {
bindStaticAdminUI(app, e)

// default routes
api := e.Group("/api")
api := e.Group("/api", eagerRequestDataCache(app))
bindSettingsApi(app, api)
bindAdminApi(app, api)
bindCollectionApi(app, api)
Expand All @@ -126,10 +126,6 @@ func InitApi(app core.App) (*echo.Echo, error) {
return nil, err
}

// note: it is after the OnBeforeServe hook to ensure that the implicit
// cache is after any user custom defined middlewares
e.Use(eagerRequestDataCache(app))

// catch all any route
api.Any("/*", func(c echo.Context) error {
return echo.ErrNotFound
Expand Down
104 changes: 64 additions & 40 deletions apis/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,16 @@ func TestRemoveTrailingSlashMiddleware(t *testing.T) {
}

func TestEagerRequestDataCache(t *testing.T) {

scenarios := []tests.ApiScenario{
{
Name: "[UNKNOWN] unsupported eager cached request method",
Method: "UNKNOWN",
Name: "custom non-api group route",
Method: "POST",
Url: "/custom",
Body: strings.NewReader(`{"name":"test123"}`),
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
e.AddRoute(echo.Route{
Method: "UNKNOWN",
Method: "POST",
Path: "/custom",
Handler: func(c echo.Context) error {
data := &struct {
Expand All @@ -240,52 +241,75 @@ func TestEagerRequestDataCache(t *testing.T) {
t.Fatalf("Expected empty request data body, got, %v", r.Data)
}

return c.String(200, data.Name)
return c.NoContent(200)
},
})
},
ExpectedStatus: 200,
ExpectedContent: []string{"test123"},
ExpectedStatus: 200,
},
}
{
Name: "api group route with unsupported eager cache request method",
Method: "GET",
Url: "/api/admins",
Body: strings.NewReader(`{"name":"test123"}`),
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
next(c)

// supported eager cache request methods
supportedMethods := []string{"POST", "PUT", "PATCH", "DELETE"}
for _, m := range supportedMethods {
scenarios = append(
scenarios,
tests.ApiScenario{
Name: fmt.Sprintf("[%s] valid cached json body request", m),
Method: http.MethodPost,
Url: "/custom",
Body: strings.NewReader(`{"name":"test123"}`),
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
e.AddRoute(echo.Route{
Method: http.MethodPost,
Path: "/custom",
Handler: func(c echo.Context) error {
data := &struct {
Name string `json:"name"`
}{}
// ensure that the body is always read at least once
// (bind errors due to eof are not important)
data := &struct {
Name string `json:"name"`
}{}
c.Bind(data)

if err := c.Bind(data); err != nil {
return err
}
// since the unknown method is not eager cache support
// it should fail reading the json body twice
r := apis.RequestData(c)
if v := cast.ToString(r.Data["name"]); v != "" {
t.Fatalf("Expected empty request data body, got, %v", r.Data)
}

// try to read the body again
r := apis.RequestData(c)
if v := cast.ToString(r.Data["name"]); v != "test123" {
t.Fatalf("Expected request data with name %q, got, %q", "test123", v)
}
return nil
}
})
},
ExpectedStatus: 200,
},
{
Name: "api group route with supported eager cache request method",
Method: "POST",
Url: "/api/admins",
RequestHeaders: map[string]string{
"Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhZG1pbiIsImV4cCI6MjIwODk4NTI2MX0.M1m--VOqGyv0d23eeUc0r9xE8ZzHaYVmVFw1VZW6gT8",
},
Body: strings.NewReader(`{"name":"test123"}`),
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
next(c)

return c.String(200, data.Name)
},
})
},
ExpectedStatus: 200,
ExpectedContent: []string{"test123"},
// ensure that the body is always read at least once
// (bind errors due to eof are not important)
data := &struct {
Name string `json:"name"`
}{}
c.Bind(data)

// try to read the body again
r := apis.RequestData(c)
fmt.Println(r)
if v := cast.ToString(r.Data["name"]); v != "test123" {
t.Fatalf("Expected request data with name %q, got, %q", "test123", v)
}

return nil
}
})
},
)
ExpectedStatus: 200,
},
}

for _, scenario := range scenarios {
Expand Down

0 comments on commit f0bcffe

Please sign in to comment.