diff --git a/frontend/src/services/task.ts b/frontend/src/services/task.ts index 9d62e9d0c..7a4f7d5a7 100644 --- a/frontend/src/services/task.ts +++ b/frontend/src/services/task.ts @@ -21,7 +21,7 @@ export default class TaskService extends AbstractService { constructor() { super({ create: '/projects/{projectId}/tasks', - getAll: '/tasks/all', + getAll: '/tasks', get: '/tasks/{id}', update: '/tasks/{id}', delete: '/tasks/{id}', diff --git a/pkg/models/tasks.go b/pkg/models/tasks.go index 87acdd318..e72b43e6d 100644 --- a/pkg/models/tasks.go +++ b/pkg/models/tasks.go @@ -221,7 +221,7 @@ type taskSearchOptions struct { // @Security JWTKeyAuth // @Success 200 {array} models.Task "The tasks" // @Failure 500 {object} models.Message "Internal error" -// @Router /tasks/all [get] +// @Router /tasks [get] func (t *Task) ReadAll(_ *xorm.Session, _ web.Auth, _ string, _ int, _ int) (result interface{}, resultCount int, totalItems int64, err error) { return nil, 0, 0, nil } diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index 11b993cad..f621e1d0f 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -425,7 +425,7 @@ func registerAPIRoutes(a *echo.Group) { } a.PUT("/projects/:project/tasks", taskHandler.CreateWeb) a.GET("/tasks/:projecttask", taskHandler.ReadOneWeb) - a.GET("/tasks/all", taskCollectionHandler.ReadAllWeb) + a.GET("/tasks", taskCollectionHandler.ReadAllWeb) a.DELETE("/tasks/:projecttask", taskHandler.DeleteWeb) a.POST("/tasks/:projecttask", taskHandler.UpdateWeb) diff --git a/pkg/web/handler/read_all.go b/pkg/web/handler/read_all.go index 5c5153463..dc556b45c 100644 --- a/pkg/web/handler/read_all.go +++ b/pkg/web/handler/read_all.go @@ -21,6 +21,7 @@ import ( "fmt" "math" "net/http" + "reflect" "strconv" vconfig "code.vikunja.io/api/pkg/config" @@ -128,6 +129,13 @@ func (c *WebHandler) ReadAllWeb(ctx echo.Context) error { return HandleHTTPError(err) } + // Ensure we return an empty array instead of null when there are no results. + // We need to use reflection here because a nil slice wrapped in an interface{} + // is not equal to nil (the interface contains a nil value but is not nil itself). + if result == nil || (reflect.ValueOf(result).Kind() == reflect.Slice && reflect.ValueOf(result).IsNil()) { + result = []interface{}{} + } + err = ctx.JSON(http.StatusOK, result) if err != nil { return HandleHTTPError(err) diff --git a/pkg/webtests/api_tokens_test.go b/pkg/webtests/api_tokens_test.go index 5b1ffefeb..034ba76da 100644 --- a/pkg/webtests/api_tokens_test.go +++ b/pkg/webtests/api_tokens_test.go @@ -35,7 +35,7 @@ func TestAPIToken(t *testing.T) { t.Run("valid token", func(t *testing.T) { e, err := setupTestEnv() require.NoError(t, err) - req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks/all", nil) + req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks", nil) res := httptest.NewRecorder() c := e.NewContext(req, res) h := routes.SetupTokenMiddleware()(func(c echo.Context) error { @@ -55,7 +55,7 @@ func TestAPIToken(t *testing.T) { t.Run("invalid token", func(t *testing.T) { e, err := setupTestEnv() require.NoError(t, err) - req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks/all", nil) + req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks", nil) res := httptest.NewRecorder() c := e.NewContext(req, res) h := routes.SetupTokenMiddleware()(func(c echo.Context) error { @@ -68,7 +68,7 @@ func TestAPIToken(t *testing.T) { t.Run("expired token", func(t *testing.T) { e, err := setupTestEnv() require.NoError(t, err) - req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks/all", nil) + req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks", nil) res := httptest.NewRecorder() c := e.NewContext(req, res) h := routes.SetupTokenMiddleware()(func(c echo.Context) error { @@ -94,7 +94,7 @@ func TestAPIToken(t *testing.T) { t.Run("jwt", func(t *testing.T) { e, err := setupTestEnv() require.NoError(t, err) - req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks/all", nil) + req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks", nil) res := httptest.NewRecorder() c := e.NewContext(req, res) h := routes.SetupTokenMiddleware()(func(c echo.Context) error {