231dc3913f
Add docs for error code Add moving new tasks into the default bucket when none was provided Add moving tasks in default bucket when deleting one Fix tests again Add test for removing a bucket Fix tests Prevent removing the last bucket Remove the empty pseudo bucket Add migration to create a new bucket for each list (and put all tasks in it Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/446
300 lines
14 KiB
Go
300 lines
14 KiB
Go
// Vikunja is a to-do list application to facilitate your life.
|
|
// Copyright 2018-2020 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 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package integrations
|
|
|
|
import (
|
|
"code.vikunja.io/api/pkg/models"
|
|
"code.vikunja.io/web/handler"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stretchr/testify/assert"
|
|
"testing"
|
|
)
|
|
|
|
func TestBucket(t *testing.T) {
|
|
testHandler := webHandlerTest{
|
|
user: &testuser1,
|
|
strFunc: func() handler.CObject {
|
|
return &models.Bucket{}
|
|
},
|
|
t: t,
|
|
}
|
|
t.Run("ReadAll", func(t *testing.T) {
|
|
t.Run("Normal", func(t *testing.T) {
|
|
rec, err := testHandler.testReadAllWithUser(nil, map[string]string{"list": "1"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `testbucket1`)
|
|
assert.Contains(t, rec.Body.String(), `testbucket2`)
|
|
assert.Contains(t, rec.Body.String(), `testbucket3`)
|
|
assert.NotContains(t, rec.Body.String(), `testbucket4`) // Different List
|
|
})
|
|
})
|
|
t.Run("Update", func(t *testing.T) {
|
|
t.Run("Normal", func(t *testing.T) {
|
|
// Check the list was loaded successfully afterwards, see testReadOneWithUser
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "1"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
t.Run("Nonexisting Bucket", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "9999"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assertHandlerErrorCode(t, err, models.ErrCodeBucketDoesNotExist)
|
|
})
|
|
t.Run("Empty title", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "1"}, `{"title":""}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
|
})
|
|
t.Run("Rights check", func(t *testing.T) {
|
|
t.Run("Forbidden", func(t *testing.T) {
|
|
// Owned by user13
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "5"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "6"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team write", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "7"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
t.Run("Shared Via Team admin", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "8"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via User readonly", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "9"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via User write", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "10"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
t.Run("Shared Via User admin", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "11"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "12"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "13"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "14"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
|
_, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "15"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "16"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
|
rec, err := testHandler.testUpdateWithUser(nil, map[string]string{"bucket": "17"}, `{"title":"TestLoremIpsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
|
})
|
|
})
|
|
})
|
|
t.Run("Delete", func(t *testing.T) {
|
|
t.Run("Normal", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "1", "bucket": "1"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
t.Run("Nonexisting", func(t *testing.T) {
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"bucket": "999"})
|
|
assert.Error(t, err)
|
|
assertHandlerErrorCode(t, err, models.ErrCodeBucketDoesNotExist)
|
|
})
|
|
t.Run("Rights check", func(t *testing.T) {
|
|
t.Run("Forbidden", func(t *testing.T) {
|
|
// Owned by user13
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "20", "bucket": "5"})
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "6", "bucket": "6"})
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team write", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "7", "bucket": "7"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
t.Run("Shared Via Team admin", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "8", "bucket": "8"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
|
|
t.Run("Shared Via User readonly", func(t *testing.T) {
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "9", "bucket": "9"})
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via User write", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "10", "bucket": "10"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
t.Run("Shared Via User admin", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "11", "bucket": "11"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "12", "bucket": "12"})
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "13", "bucket": "13"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "14", "bucket": "14"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
|
_, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "15", "bucket": "15"})
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "16", "bucket": "16"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
|
rec, err := testHandler.testDeleteWithUser(nil, map[string]string{"list": "17", "bucket": "17"})
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
|
})
|
|
})
|
|
})
|
|
t.Run("Create", func(t *testing.T) {
|
|
t.Run("Normal", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "1"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
t.Run("Nonexisting", func(t *testing.T) {
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9999"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assertHandlerErrorCode(t, err, models.ErrCodeListDoesNotExist)
|
|
})
|
|
t.Run("Rights check", func(t *testing.T) {
|
|
t.Run("Forbidden", func(t *testing.T) {
|
|
// Owned by user13
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "20"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "6"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via Team write", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "7"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
t.Run("Shared Via Team admin", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "8"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via User readonly", func(t *testing.T) {
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "9"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via User write", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "10"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
t.Run("Shared Via User admin", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "11"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "12"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "13"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "14"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
|
|
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
|
_, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "15"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.Error(t, err)
|
|
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "16"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
|
rec, err := testHandler.testCreateWithUser(nil, map[string]string{"list": "17"}, `{"title":"Lorem Ipsum"}`)
|
|
assert.NoError(t, err)
|
|
assert.Contains(t, rec.Body.String(), `"title":"Lorem Ipsum"`)
|
|
})
|
|
})
|
|
})
|
|
}
|