Integration tests (#71)
This commit is contained in:
350
pkg/integrations/_test.go.tpl
Normal file
350
pkg/integrations/_test.go.tpl
Normal file
@ -0,0 +1,350 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test${MODEL}(t *testing.T) {
|
||||
testHandler := webHandlerTest{
|
||||
user: &testuser1,
|
||||
strFunc: func() handler.CObject {
|
||||
return &models.${MODEL}{}
|
||||
},
|
||||
t: t,
|
||||
}
|
||||
t.Run("ReadAll", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
assert.NotContains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Search", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"s": []string{""}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
assert.NotContains(t, rec.Body.String(), ``)
|
||||
})
|
||||
})
|
||||
t.Run("ReadOne", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
assert.NotContains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCode)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
// Owned by user3
|
||||
_, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `You don't have the right to see this`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via Team write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via User write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Update", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCode)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCode)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via User write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"${URL_PLACEHOLDER}": ""})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCode)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
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.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"${URL_PLACEHOLDER}": ""}, `{}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), ``)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
195
pkg/integrations/integrations.go
Normal file
195
pkg/integrations/integrations.go
Normal file
@ -0,0 +1,195 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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/config"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"code.vikunja.io/api/pkg/routes"
|
||||
v1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"code.vikunja.io/web"
|
||||
"code.vikunja.io/web/handler"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/labstack/echo"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// These are the test users, the same way they are in the test database
|
||||
var (
|
||||
testuser1 = models.User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user1@example.com",
|
||||
IsActive: true,
|
||||
}
|
||||
testuser2 = models.User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user2@example.com",
|
||||
}
|
||||
testuser3 = models.User{
|
||||
ID: 3,
|
||||
Username: "user3",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user3@example.com",
|
||||
PasswordResetToken: "passwordresettesttoken",
|
||||
}
|
||||
testuser4 = models.User{
|
||||
ID: 4,
|
||||
Username: "user4",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user4@example.com",
|
||||
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||
}
|
||||
testuser5 = models.User{
|
||||
ID: 4,
|
||||
Username: "user5",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
Email: "user5@example.com",
|
||||
EmailConfirmToken: "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael",
|
||||
IsActive: false,
|
||||
}
|
||||
)
|
||||
|
||||
func setupTestEnv() (e *echo.Echo, err error) {
|
||||
config.InitConfig()
|
||||
models.SetupTests(viper.GetString("service.rootpath"))
|
||||
|
||||
err = models.LoadFixtures()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
e = routes.NewEcho()
|
||||
routes.RegisterRoutes(e)
|
||||
return
|
||||
}
|
||||
|
||||
func bootstrapTestRequest(t *testing.T, method string, payload string, queryParam url.Values) (c echo.Context, rec *httptest.ResponseRecorder) {
|
||||
// Setup
|
||||
e, err := setupTestEnv()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Do the actual request
|
||||
req := httptest.NewRequest(method, "/", strings.NewReader(payload))
|
||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||
req.URL.RawQuery = queryParam.Encode()
|
||||
rec = httptest.NewRecorder()
|
||||
|
||||
c = e.NewContext(req, rec)
|
||||
return
|
||||
}
|
||||
|
||||
func newTestRequest(t *testing.T, method string, handler func(ctx echo.Context) error, payload string) (rec *httptest.ResponseRecorder, err error) {
|
||||
c, rec := bootstrapTestRequest(t, method, payload, nil)
|
||||
err = handler(c)
|
||||
return
|
||||
}
|
||||
|
||||
func addTokenToContext(t *testing.T, user *models.User, c echo.Context) {
|
||||
// Get the token as a string
|
||||
token, err := v1.CreateNewJWTTokenForUser(user)
|
||||
assert.NoError(t, err)
|
||||
// We send the string token through the parsing function to get a valid jwt.Token
|
||||
tken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
|
||||
return []byte(viper.GetString("service.JWTSecret")), nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
c.Set("user", tken)
|
||||
}
|
||||
|
||||
func newTestRequestWithUser(t *testing.T, method string, handler echo.HandlerFunc, user *models.User, payload string, queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
c, rec := bootstrapTestRequest(t, method, payload, queryParams)
|
||||
|
||||
var paramNames []string
|
||||
var paramValues []string
|
||||
for name, value := range urlParams {
|
||||
paramNames = append(paramNames, name)
|
||||
paramValues = append(paramValues, value)
|
||||
}
|
||||
c.SetParamNames(paramNames...)
|
||||
c.SetParamValues(paramValues...)
|
||||
|
||||
addTokenToContext(t, user, c)
|
||||
err = handler(c)
|
||||
return
|
||||
}
|
||||
|
||||
func assertHandlerErrorCode(t *testing.T, err error, expectedErrorCode int) {
|
||||
if err == nil {
|
||||
t.Error("Error is nil")
|
||||
t.FailNow()
|
||||
}
|
||||
httperr, ok := err.(*echo.HTTPError)
|
||||
if !ok {
|
||||
t.Error("Error is not *echo.HTTPError")
|
||||
t.FailNow()
|
||||
}
|
||||
webhttperr, ok := httperr.Message.(web.HTTPError)
|
||||
if !ok {
|
||||
t.Error("Error is not *web.HTTPError")
|
||||
t.FailNow()
|
||||
}
|
||||
assert.Equal(t, expectedErrorCode, webhttperr.Code)
|
||||
}
|
||||
|
||||
type webHandlerTest struct {
|
||||
user *models.User
|
||||
strFunc func() handler.CObject
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) getHandler() handler.WebHandler {
|
||||
return handler.WebHandler{
|
||||
EmptyStruct: func() handler.CObject {
|
||||
return h.strFunc()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) testReadAll(queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
hndl := h.getHandler()
|
||||
return newTestRequestWithUser(h.t, http.MethodGet, hndl.ReadAllWeb, h.user, "", queryParams, urlParams)
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) testReadOne(queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
hndl := h.getHandler()
|
||||
return newTestRequestWithUser(h.t, http.MethodGet, hndl.ReadOneWeb, h.user, "", queryParams, urlParams)
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) testCreate(queryParams url.Values, urlParams map[string]string, payload string) (rec *httptest.ResponseRecorder, err error) {
|
||||
hndl := h.getHandler()
|
||||
return newTestRequestWithUser(h.t, http.MethodPut, hndl.CreateWeb, h.user, payload, queryParams, urlParams)
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) testUpdate(queryParams url.Values, urlParams map[string]string, payload string) (rec *httptest.ResponseRecorder, err error) {
|
||||
hndl := h.getHandler()
|
||||
return newTestRequestWithUser(h.t, http.MethodPost, hndl.UpdateWeb, h.user, payload, queryParams, urlParams)
|
||||
}
|
||||
|
||||
func (h *webHandlerTest) testDelete(queryParams url.Values, urlParams map[string]string) (rec *httptest.ResponseRecorder, err error) {
|
||||
hndl := h.getHandler()
|
||||
return newTestRequestWithUser(h.t, http.MethodDelete, hndl.DeleteWeb, h.user, "", queryParams, urlParams)
|
||||
}
|
425
pkg/integrations/list_test.go
Normal file
425
pkg/integrations/list_test.go
Normal file
@ -0,0 +1,425 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
testHandler := webHandlerTest{
|
||||
user: &testuser1,
|
||||
strFunc: func() handler.CObject {
|
||||
return &models.List{}
|
||||
},
|
||||
t: t,
|
||||
}
|
||||
t.Run("ReadAll", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Test1`)
|
||||
assert.NotContains(t, rec.Body.String(), `Test2`)
|
||||
assert.Contains(t, rec.Body.String(), `Test3`) // Shared directly via users_list
|
||||
assert.Contains(t, rec.Body.String(), `Test4`) // Shared via namespace
|
||||
assert.NotContains(t, rec.Body.String(), `Test5`)
|
||||
})
|
||||
t.Run("Search", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"s": []string{"Test1"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Test1`)
|
||||
assert.NotContains(t, rec.Body.String(), `Test2`)
|
||||
assert.NotContains(t, rec.Body.String(), `Test3`)
|
||||
assert.NotContains(t, rec.Body.String(), `Test4`)
|
||||
assert.NotContains(t, rec.Body.String(), `Test5`)
|
||||
})
|
||||
})
|
||||
t.Run("ReadOne", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test1"`)
|
||||
assert.NotContains(t, rec.Body.String(), `"title":"Test2"`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1,"username":"user1",`)
|
||||
assert.NotContains(t, rec.Body.String(), `"owner":{"id":2,"username":"user2",`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":[{"id":1,"text":"task #1",`)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testReadOne(nil, map[string]string{"list": "9999"})
|
||||
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 user3
|
||||
_, err := testHandler.testReadOne(nil, map[string]string{"list": "2"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `You don't have the right to see this`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "6"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test6"`)
|
||||
})
|
||||
t.Run("Shared Via Team write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "7"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test7"`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "8"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test8"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "9"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test9"`)
|
||||
})
|
||||
t.Run("Shared Via User write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "10"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test10"`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "11"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test11"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "12"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test12"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "13"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test13"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "14"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test14"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "15"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test15"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "16"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test16"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadOne(nil, map[string]string{"list": "17"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Test17"`)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Update", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
// Check the list was loaded successfully afterwards, see testReadOne
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"list": "1"}, `{"title":"TestLoremIpsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
||||
// The description should not be updated but returned correctly
|
||||
assert.Contains(t, rec.Body.String(), `description":"Lorem Ipsum`)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"list": "9999"}, `{"title":"TestLoremIpsum"}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeListDoesNotExist)
|
||||
})
|
||||
t.Run("Normal with updating the description", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"list": "1"}, `{"title":"TestLoremIpsum","description":"Lorem Ipsum dolor sit amet"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"TestLoremIpsum"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":"Lorem Ipsum dolor sit amet`)
|
||||
})
|
||||
t.Run("Empty title", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"list": "1"}, `{"title":""}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
||||
})
|
||||
t.Run("Almost empty title", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"list": "1"}, `{"title":"nn"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
||||
})
|
||||
t.Run("Title too long", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"list": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
// Owned by user3
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"list": "2"}, `{"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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testUpdate(nil, map[string]string{"list": "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.testDelete(nil, map[string]string{"list": "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"message":"Successfully deleted."`)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "999"})
|
||||
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 user3
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "2"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "6"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "7"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"list": "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.testDelete(nil, map[string]string{"list": "9"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via User write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "10"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"list": "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.testDelete(nil, map[string]string{"list": "12"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "13"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"list": "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.testDelete(nil, map[string]string{"list": "15"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser write", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"list": "16"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"list": "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) {
|
||||
// Check the list was loaded successfully after update, see testReadOne
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"namespace": "1"}, `{"title":"Lorem"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
t.Run("Normal with description", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"namespace": "1"}, `{"title":"Lorem","description":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":"Lorem Ipsum"`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
t.Run("Nonexisting Namespace", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "999999"}, `{"title":"Lorem"}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNamespaceDoesNotExist)
|
||||
})
|
||||
t.Run("Empty title", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "1"}, `{"title":""}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields, "title: non zero value required")
|
||||
})
|
||||
t.Run("Almost empty title", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "1"}, `{"title":"nn"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
||||
})
|
||||
t.Run("Title too long", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "1"}, `{"title":"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea taki"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message.(models.ValidationHTTPError).InvalidFields[0], "does not validate as runelength(3|250)")
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
// Owned by user3
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "3"}, `{"title":"Lorem"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "7"}, `{"title":"Lorem"}`)
|
||||
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.testCreate(nil, map[string]string{"namespace": "8"}, `{"title":"Lorem"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"namespace": "9"}, `{"title":"Lorem"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"namespace": "10"}, `{"title":"Lorem"}`)
|
||||
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.testCreate(nil, map[string]string{"namespace": "11"}, `{"title":"Lorem"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"namespace": "12"}, `{"title":"Lorem"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"title":"Lorem"`)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.Contains(t, rec.Body.String(), `"owner":{"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"tasks":null`)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
65
pkg/integrations/login_test.go
Normal file
65
pkg/integrations/login_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLogin(t *testing.T) {
|
||||
t.Run("Normal login", func(t *testing.T) {
|
||||
rec, err := newTestRequest(t, http.MethodPost, apiv1.Login, `{
|
||||
"username": "user1",
|
||||
"password": "1234"
|
||||
}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), "token")
|
||||
})
|
||||
t.Run("Empty payload", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.Login, `{}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Not existing user", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.Login, `{
|
||||
"username": "userWichDoesNotExist",
|
||||
"password": "1234"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeWrongUsernameOrPassword)
|
||||
})
|
||||
t.Run("Wrong password", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.Login, `{
|
||||
"username": "user1",
|
||||
"password": "wrong"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeWrongUsernameOrPassword)
|
||||
})
|
||||
t.Run("user with unconfirmed email", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.Login, `{
|
||||
"username": "user5",
|
||||
"password": "1234"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeEmailNotConfirmed)
|
||||
})
|
||||
}
|
87
pkg/integrations/register_test.go
Normal file
87
pkg/integrations/register_test.go
Normal file
@ -0,0 +1,87 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
t.Run("normal register", func(t *testing.T) {
|
||||
rec, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "newUser",
|
||||
"password": "1234",
|
||||
"email": "email@example.com"
|
||||
}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"username":"newUser"`)
|
||||
})
|
||||
t.Run("Empty payload", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Empty username", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "",
|
||||
"password": "1234",
|
||||
"email": "email@example.com"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Empty password", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "newUser",
|
||||
"password": "",
|
||||
"email": "email@example.com"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Empty email", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "newUser",
|
||||
"password": "1234",
|
||||
"email": ""
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Already existing username", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "user1",
|
||||
"password": "1234",
|
||||
"email": "email@example.com"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrorCodeUsernameExists)
|
||||
})
|
||||
t.Run("Already existing email", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.RegisterUser, `{
|
||||
"username": "newUser",
|
||||
"password": "1234",
|
||||
"email": "user1@example.com"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrorCodeUserEmailExists)
|
||||
})
|
||||
}
|
562
pkg/integrations/task_test.go
Normal file
562
pkg/integrations/task_test.go
Normal file
@ -0,0 +1,562 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestListTask(t *testing.T) {
|
||||
testHandler := webHandlerTest{
|
||||
user: &testuser1,
|
||||
strFunc: func() handler.CObject {
|
||||
return &models.ListTask{}
|
||||
},
|
||||
t: t,
|
||||
}
|
||||
// Only run specific nested tests:
|
||||
// ^TestListTask$/^Update$/^Update_task_items$/^Removing_Assignees_null$
|
||||
t.Run("ReadAll", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(nil, nil)
|
||||
assert.NoError(t, err)
|
||||
// Not using assert.Equal to avoid having the tests break every time we add new fixtures
|
||||
assert.Contains(t, rec.Body.String(), `task #1`)
|
||||
assert.Contains(t, rec.Body.String(), `task #2`)
|
||||
assert.Contains(t, rec.Body.String(), `task #3`)
|
||||
assert.Contains(t, rec.Body.String(), `task #4`)
|
||||
assert.Contains(t, rec.Body.String(), `task #5`)
|
||||
assert.Contains(t, rec.Body.String(), `task #6`)
|
||||
assert.Contains(t, rec.Body.String(), `task #7`)
|
||||
assert.Contains(t, rec.Body.String(), `task #8`)
|
||||
assert.Contains(t, rec.Body.String(), `task #9`)
|
||||
assert.Contains(t, rec.Body.String(), `task #10`)
|
||||
assert.Contains(t, rec.Body.String(), `task #11`)
|
||||
assert.Contains(t, rec.Body.String(), `task #12`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #13`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||
// TODO: add more tasks, since the whole point of this is to get all tasks in all lists where the user
|
||||
// has at least read access
|
||||
})
|
||||
t.Run("Search", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"s": []string{"task #6"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, rec.Body.String(), `task #1`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #2`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #3`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #4`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #5`)
|
||||
assert.Contains(t, rec.Body.String(), `task #6`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #7`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #8`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #9`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #10`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #11`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #12`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #13`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||
})
|
||||
t.Run("Sort Order", func(t *testing.T) {
|
||||
// should equal priority desc
|
||||
t.Run("by priority", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"priority"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":1`)
|
||||
})
|
||||
t.Run("by priority desc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"prioritydesc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":1`)
|
||||
})
|
||||
t.Run("by priority asc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"priorityasc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
|
||||
})
|
||||
// should equal duedate desc
|
||||
t.Run("by duedate", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"dueadate"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
})
|
||||
t.Run("by duedate desc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"dueadatedesc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
})
|
||||
t.Run("by duedate asc", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"duedateasc"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"dueDate":1543616724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
|
||||
})
|
||||
t.Run("invalid parameter", func(t *testing.T) {
|
||||
// Invalid parameter should not sort at all
|
||||
rec, err := testHandler.testReadAll(url.Values{"sort": []string{"loremipsum"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, rec.Body.String(), `[{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":1`)
|
||||
assert.NotContains(t, rec.Body.String(), `{"id":4,"text":"task #4 low prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":1,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":3,"text":"task #3 high prio","description":"","done":false,"dueDate":0,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":100,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
|
||||
assert.NotContains(t, rec.Body.String(), `[{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":6,"text":"task #6 lower due date"`)
|
||||
assert.NotContains(t, rec.Body.String(), `{"id":6,"text":"task #6 lower due date","description":"","done":false,"dueDate":1543616724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}},{"id":5,"text":"task #5 higher due date","description":"","done":false,"dueDate":1543636724,"reminderDates":null,"repeatAfter":0,"parentTaskID":0,"priority":0,"startDate":0,"endDate":0,"assignees":null,"labels":null,"subtasks":null,"created":1543626724,"updated":1543626724,"createdBy":{"id":0,"username":"","email":"","created":0,"updated":0}}]`)
|
||||
})
|
||||
})
|
||||
t.Run("Date range", func(t *testing.T) {
|
||||
t.Run("start and end date", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"startdate": []string{"1540000000"}, "enddate": []string{"1544700001"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, rec.Body.String(), `task #1`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #2`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #3`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #4`)
|
||||
assert.Contains(t, rec.Body.String(), `task #5`)
|
||||
assert.Contains(t, rec.Body.String(), `task #6`)
|
||||
assert.Contains(t, rec.Body.String(), `task #7`)
|
||||
assert.Contains(t, rec.Body.String(), `task #8`)
|
||||
assert.Contains(t, rec.Body.String(), `task #9`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #10`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #11`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #12`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #13`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||
})
|
||||
t.Run("start date only", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"startdate": []string{"1540000000"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, rec.Body.String(), `task #1`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #2`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #3`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #4`)
|
||||
assert.Contains(t, rec.Body.String(), `task #5`)
|
||||
assert.Contains(t, rec.Body.String(), `task #6`)
|
||||
assert.Contains(t, rec.Body.String(), `task #7`)
|
||||
assert.Contains(t, rec.Body.String(), `task #8`)
|
||||
assert.Contains(t, rec.Body.String(), `task #9`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #10`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #11`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #12`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #13`)
|
||||
assert.NotContains(t, rec.Body.String(), `task #14`)
|
||||
})
|
||||
t.Run("end date only", func(t *testing.T) {
|
||||
rec, err := testHandler.testReadAll(url.Values{"enddate": []string{"1544700001"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
// If no start date but an end date is specified, this should be null
|
||||
// since we don't have any tasks in the fixtures with an end date >
|
||||
// the current date.
|
||||
assert.Equal(t, "null\n", rec.Body.String())
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Update", func(t *testing.T) {
|
||||
t.Run("Update task items", func(t *testing.T) {
|
||||
t.Run("Text", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
assert.NotContains(t, rec.Body.String(), `"text":"task #1"`)
|
||||
})
|
||||
t.Run("Description", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"description":"Dolor sit amet"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"description":"Dolor sit amet"`)
|
||||
assert.NotContains(t, rec.Body.String(), `"description":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Description to empty", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"description":""}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"description":""`)
|
||||
assert.NotContains(t, rec.Body.String(), `"description":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Done", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"done":true}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"done":true`)
|
||||
assert.NotContains(t, rec.Body.String(), `"done":false`)
|
||||
})
|
||||
t.Run("Undone", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "2"}, `{"done":false}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"done":false`)
|
||||
assert.NotContains(t, rec.Body.String(), `"done":true`)
|
||||
})
|
||||
t.Run("Due date", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"dueDate": 123456}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"dueDate":123456`)
|
||||
assert.NotContains(t, rec.Body.String(), `"dueDate":0`)
|
||||
})
|
||||
t.Run("Due date unset", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "5"}, `{"dueDate": 0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"dueDate":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"dueDate":1543636724`)
|
||||
})
|
||||
t.Run("Reminders", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"reminderDates": [1555508227,1555511000]}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"reminderDates":[1555508227,1555511000]`)
|
||||
assert.NotContains(t, rec.Body.String(), `"reminderDates": null`)
|
||||
})
|
||||
t.Run("Reminders unset to empty array", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "27"}, `{"reminderDates": []}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"reminderDates":null`)
|
||||
assert.NotContains(t, rec.Body.String(), `"reminderDates":[1543626724,1543626824]`)
|
||||
})
|
||||
t.Run("Reminders unset to null", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "27"}, `{"reminderDates": null}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"reminderDates":null`)
|
||||
assert.NotContains(t, rec.Body.String(), `"reminderDates":[1543626724,1543626824]`)
|
||||
})
|
||||
t.Run("Repeat after", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"repeatAfter":3600}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"repeatAfter":3600`)
|
||||
assert.NotContains(t, rec.Body.String(), `"repeatAfter":0`)
|
||||
})
|
||||
t.Run("Repeat after unset", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "28"}, `{"repeatAfter":0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"repeatAfter":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"repeatAfter":3600`)
|
||||
})
|
||||
t.Run("Repeat after update done", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "28"}, `{"done":true}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"done":false`)
|
||||
assert.NotContains(t, rec.Body.String(), `"done":true`)
|
||||
})
|
||||
t.Run("Parent task", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"parentTaskID":2}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"parentTaskID":2`)
|
||||
assert.NotContains(t, rec.Body.String(), `"parentTaskID":0`)
|
||||
})
|
||||
t.Run("Parent task same task", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"parentTaskID":1}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeParentTaskCannotBeTheSame)
|
||||
})
|
||||
t.Run("Parent task unset", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "29"}, `{"parentTaskID":0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"parentTaskID":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"parentTaskID":1`)
|
||||
})
|
||||
t.Run("Assignees", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"assignees":[{"id":1}]}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"assignees":[{"id":1`)
|
||||
assert.NotContains(t, rec.Body.String(), `"assignees":[]`)
|
||||
})
|
||||
t.Run("Removing Assignees empty array", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "30"}, `{"assignees":[]}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"assignees":null`)
|
||||
assert.NotContains(t, rec.Body.String(), `"assignees":[{"id":1`)
|
||||
})
|
||||
t.Run("Removing Assignees null", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "30"}, `{"assignees":null}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"assignees":null`)
|
||||
assert.NotContains(t, rec.Body.String(), `"assignees":[{"id":1`)
|
||||
})
|
||||
t.Run("Priority", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"priority":100}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"priority":100`)
|
||||
assert.NotContains(t, rec.Body.String(), `"priority":0`)
|
||||
})
|
||||
t.Run("Priority to 0", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "3"}, `{"priority":0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"priority":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"priority":100`)
|
||||
})
|
||||
t.Run("Start date", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"startDate":1234567}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"startDate":1234567`)
|
||||
assert.NotContains(t, rec.Body.String(), `"startDate":0`)
|
||||
})
|
||||
t.Run("Start date unset", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "7"}, `{"startDate":0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"startDate":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"startDate":1544600000`)
|
||||
})
|
||||
t.Run("End date", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "1"}, `{"endDate":123456}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"endDate":123456`)
|
||||
assert.NotContains(t, rec.Body.String(), `"endDate":0`)
|
||||
})
|
||||
t.Run("End date unset", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "8"}, `{"endDate":0}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"endDate":0`)
|
||||
assert.NotContains(t, rec.Body.String(), `"endDate":1544700000`)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "99999"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeListTaskDoesNotExist)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "14"}, `{"text":"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.testUpdate(nil, map[string]string{"listtask": "15"}, `{"text":"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.testUpdate(nil, map[string]string{"listtask": "16"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "17"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "18"}, `{"text":"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.testUpdate(nil, map[string]string{"listtask": "19"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "20"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "21"}, `{"text":"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.testUpdate(nil, map[string]string{"listtask": "22"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "23"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testUpdate(nil, map[string]string{"listtask": "24"}, `{"text":"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.testUpdate(nil, map[string]string{"listtask": "25"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testUpdate(nil, map[string]string{"listtask": "26"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"listtask": "1"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "99999"})
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeListTaskDoesNotExist)
|
||||
})
|
||||
t.Run("Rights check", func(t *testing.T) {
|
||||
t.Run("Forbidden", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "14"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.(*echo.HTTPError).Message, `Forbidden`)
|
||||
})
|
||||
t.Run("Shared Via Team readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "15"})
|
||||
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.testDelete(nil, map[string]string{"listtask": "16"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"listtask": "17"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "18"})
|
||||
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.testDelete(nil, map[string]string{"listtask": "19"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"listtask": "20"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "21"})
|
||||
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.testDelete(nil, map[string]string{"listtask": "22"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"listtask": "23"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testDelete(nil, map[string]string{"listtask": "24"})
|
||||
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.testDelete(nil, map[string]string{"listtask": "25"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testDelete(nil, map[string]string{"listtask": "26"})
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Successfully deleted.`)
|
||||
})
|
||||
})
|
||||
})
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"list": "1"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Nonexisting", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"list": "9999"}, `{"text":"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 user3
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"list": "2"}, `{"text":"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.testCreate(nil, map[string]string{"list": "6"}, `{"text":"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.testCreate(nil, map[string]string{"list": "7"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via Team admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"list": "8"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via User readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"list": "9"}, `{"text":"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.testCreate(nil, map[string]string{"list": "10"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via User admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"list": "11"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceTeam readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"list": "12"}, `{"text":"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.testCreate(nil, map[string]string{"list": "13"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceTeam admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"list": "14"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
|
||||
t.Run("Shared Via NamespaceUser readonly", func(t *testing.T) {
|
||||
_, err := testHandler.testCreate(nil, map[string]string{"list": "15"}, `{"text":"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.testCreate(nil, map[string]string{"list": "16"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
t.Run("Shared Via NamespaceUser admin", func(t *testing.T) {
|
||||
rec, err := testHandler.testCreate(nil, map[string]string{"list": "17"}, `{"text":"Lorem Ipsum"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"text":"Lorem Ipsum"`)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
32
pkg/integrations/token_test.go
Normal file
32
pkg/integrations/token_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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 (
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCheckToken(t *testing.T) {
|
||||
t.Run("Normal test", func(t *testing.T) {
|
||||
rec, err := newTestRequestWithUser(t, http.MethodPost, apiv1.CheckToken, &testuser1, "", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `🍵`)
|
||||
})
|
||||
}
|
60
pkg/integrations/user_change_password_test.go
Normal file
60
pkg/integrations/user_change_password_test.go
Normal file
@ -0,0 +1,60 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserChangePassword(t *testing.T) {
|
||||
t.Run("Normal test", func(t *testing.T) {
|
||||
rec, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserChangePassword, &testuser1, `{
|
||||
"new_password": "12345",
|
||||
"old_password": "1234"
|
||||
}`, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `The password was updated successfully.`)
|
||||
})
|
||||
t.Run("Wrong old password", func(t *testing.T) {
|
||||
_, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserChangePassword, &testuser1, `{
|
||||
"new_password": "12345",
|
||||
"old_password": "invalid"
|
||||
}`, nil, nil)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeWrongUsernameOrPassword)
|
||||
})
|
||||
t.Run("Empty old password", func(t *testing.T) {
|
||||
_, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserChangePassword, &testuser1, `{
|
||||
"new_password": "12345",
|
||||
"old_password": ""
|
||||
}`, nil, nil)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeEmptyOldPassword)
|
||||
})
|
||||
t.Run("Empty new password", func(t *testing.T) {
|
||||
_, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserChangePassword, &testuser1, `{
|
||||
"new_password": "",
|
||||
"old_password": "1234"
|
||||
}`, nil, nil)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeEmptyNewPassword)
|
||||
})
|
||||
}
|
50
pkg/integrations/user_confirm_email_test.go
Normal file
50
pkg/integrations/user_confirm_email_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/labstack/echo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserConfirmEmail(t *testing.T) {
|
||||
t.Run("Normal test", func(t *testing.T) {
|
||||
rec, err := newTestRequest(t, http.MethodPost, apiv1.UserConfirmEmail, `{"token": "tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `The email was confirmed successfully.`)
|
||||
})
|
||||
t.Run("Empty payload", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserConfirmEmail, `{}`)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, http.StatusPreconditionFailed, err.(*echo.HTTPError).Code)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeInvalidEmailConfirmToken)
|
||||
})
|
||||
t.Run("Empty token", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserConfirmEmail, `{"token": ""}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeInvalidEmailConfirmToken)
|
||||
})
|
||||
t.Run("Invalid token", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserConfirmEmail, `{"token": "invalidToken"}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeInvalidEmailConfirmToken)
|
||||
})
|
||||
}
|
45
pkg/integrations/user_list_test.go
Normal file
45
pkg/integrations/user_list_test.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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 (
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserList(t *testing.T) {
|
||||
t.Run("Normal test", func(t *testing.T) {
|
||||
rec, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserList, &testuser1, "", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `user1`)
|
||||
assert.Contains(t, rec.Body.String(), `user2`)
|
||||
assert.Contains(t, rec.Body.String(), `user3`)
|
||||
assert.Contains(t, rec.Body.String(), `user4`)
|
||||
assert.Contains(t, rec.Body.String(), `user5`)
|
||||
})
|
||||
t.Run("Search for user3", func(t *testing.T) {
|
||||
rec, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserList, &testuser1, "", map[string][]string{"s": {"user3"}}, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `user3`)
|
||||
assert.NotContains(t, rec.Body.String(), `user1`)
|
||||
assert.NotContains(t, rec.Body.String(), `user2`)
|
||||
assert.NotContains(t, rec.Body.String(), `user4`)
|
||||
assert.NotContains(t, rec.Body.String(), `user5`)
|
||||
})
|
||||
}
|
49
pkg/integrations/user_password_request_token_test.go
Normal file
49
pkg/integrations/user_password_request_token_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/labstack/echo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserRequestResetPasswordToken(t *testing.T) {
|
||||
t.Run("Normal requesting a password reset token", func(t *testing.T) {
|
||||
rec, err := newTestRequest(t, http.MethodPost, apiv1.UserRequestResetPasswordToken, `{"email": "user1@example.com"}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `Token was sent.`)
|
||||
})
|
||||
t.Run("Empty payload", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserRequestResetPasswordToken, `{}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Invalid email address", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserRequestResetPasswordToken, `{"email": "user1example.com"}`)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, http.StatusBadRequest, err.(*echo.HTTPError).Code)
|
||||
})
|
||||
t.Run("No user with that email address", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserRequestResetPasswordToken, `{"email": "user1000@example.com"}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeUserDoesNotExist)
|
||||
})
|
||||
}
|
58
pkg/integrations/user_password_reset_test.go
Normal file
58
pkg/integrations/user_password_reset_test.go
Normal file
@ -0,0 +1,58 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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"
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/labstack/echo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserPasswordReset(t *testing.T) {
|
||||
t.Run("Normal password reset test", func(t *testing.T) {
|
||||
rec, err := newTestRequest(t, http.MethodPost, apiv1.UserResetPassword, `{
|
||||
"new_password": "1234",
|
||||
"token": "passwordresettesttoken"
|
||||
}`)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `The password was updated successfully.`)
|
||||
})
|
||||
t.Run("Empty payload", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserResetPassword, `{}`)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, http.StatusBadRequest, err.(*echo.HTTPError).Code)
|
||||
})
|
||||
t.Run("No new password", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserResetPassword, `{
|
||||
"new_password": "",
|
||||
"token": "passwordresettesttoken"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeNoUsernamePassword)
|
||||
})
|
||||
t.Run("Invalid password reset token", func(t *testing.T) {
|
||||
_, err := newTestRequest(t, http.MethodPost, apiv1.UserResetPassword, `{
|
||||
"new_password": "1234",
|
||||
"token": "invalidtoken"
|
||||
}`)
|
||||
assert.Error(t, err)
|
||||
assertHandlerErrorCode(t, err, models.ErrCodeInvalidPasswordResetToken)
|
||||
})
|
||||
}
|
34
pkg/integrations/user_show_test.go
Normal file
34
pkg/integrations/user_show_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Vikunja is a todo-list application to facilitate your life.
|
||||
// Copyright 2019 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 (
|
||||
apiv1 "code.vikunja.io/api/pkg/routes/api/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUserShow(t *testing.T) {
|
||||
t.Run("Normal test", func(t *testing.T) {
|
||||
rec, err := newTestRequestWithUser(t, http.MethodPost, apiv1.UserShow, &testuser1, "", nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rec.Body.String(), `"id":1`)
|
||||
assert.Contains(t, rec.Body.String(), `"username":"user1"`)
|
||||
assert.Contains(t, rec.Body.String(), `"email":""`)
|
||||
})
|
||||
}
|
@ -247,6 +247,48 @@ func IsErrEmailNotConfirmed(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrEmptyNewPassword represents a "EmptyNewPassword" kind of error.
|
||||
type ErrEmptyNewPassword struct{}
|
||||
|
||||
// IsErrEmptyNewPassword checks if an error is a ErrEmptyNewPassword.
|
||||
func IsErrEmptyNewPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyNewPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyNewPassword) Error() string {
|
||||
return fmt.Sprintf("New password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyNewPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyNewPassword = 1013
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyNewPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyNewPassword, Message: "Please specify new password."}
|
||||
}
|
||||
|
||||
// ErrEmptyOldPassword represents a "EmptyOldPassword" kind of error.
|
||||
type ErrEmptyOldPassword struct{}
|
||||
|
||||
// IsErrEmptyOldPassword checks if an error is a ErrEmptyOldPassword.
|
||||
func IsErrEmptyOldPassword(err error) bool {
|
||||
_, ok := err.(ErrEmptyOldPassword)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrEmptyOldPassword) Error() string {
|
||||
return fmt.Sprintf("Old password is empty")
|
||||
}
|
||||
|
||||
// ErrCodeEmptyOldPassword holds the unique world-error code of this error
|
||||
const ErrCodeEmptyOldPassword = 1014
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrEmptyOldPassword) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeEmptyOldPassword, Message: "Please specify old password."}
|
||||
}
|
||||
|
||||
// ===================
|
||||
// Empty things errors
|
||||
// ===================
|
||||
@ -502,6 +544,33 @@ func (err ErrNoRightToSeeTask) HTTPError() web.HTTPError {
|
||||
}
|
||||
}
|
||||
|
||||
// ErrParentTaskCannotBeTheSame represents an error where the user tries to set a tasks parent as the same
|
||||
type ErrParentTaskCannotBeTheSame struct {
|
||||
TaskID int64
|
||||
}
|
||||
|
||||
// IsErrParentTaskCannotBeTheSame checks if an error is ErrParentTaskCannotBeTheSame.
|
||||
func IsErrParentTaskCannotBeTheSame(err error) bool {
|
||||
_, ok := err.(ErrParentTaskCannotBeTheSame)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrParentTaskCannotBeTheSame) Error() string {
|
||||
return fmt.Sprintf("Tried to set a parents task as the same [TaskID: %v]", err.TaskID)
|
||||
}
|
||||
|
||||
// ErrCodeParentTaskCannotBeTheSame holds the unique world-error code of this error
|
||||
const ErrCodeParentTaskCannotBeTheSame = 4006
|
||||
|
||||
// HTTPError holds the http error description
|
||||
func (err ErrParentTaskCannotBeTheSame) HTTPError() web.HTTPError {
|
||||
return web.HTTPError{
|
||||
HTTPCode: http.StatusForbidden,
|
||||
Code: ErrCodeParentTaskCannotBeTheSame,
|
||||
Message: "You cannot set a parent task to the task itself.",
|
||||
}
|
||||
}
|
||||
|
||||
// =================
|
||||
// Namespace errors
|
||||
// =================
|
||||
|
@ -38,3 +38,99 @@
|
||||
namespace_id: 5
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 6
|
||||
title: Test6
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 7
|
||||
title: Test7
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 8
|
||||
title: Test8
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 9
|
||||
title: Test9
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 10
|
||||
title: Test10
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 11
|
||||
title: Test11
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 12
|
||||
title: Test12
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 7
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 13
|
||||
title: Test13
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 8
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 14
|
||||
title: Test14
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 9
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 15
|
||||
title: Test15
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 10
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 16
|
||||
title: Test16
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 11
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 17
|
||||
title: Test17
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
namespace_id: 12
|
||||
updated: 0
|
||||
created: 0
|
||||
|
@ -1,21 +1,60 @@
|
||||
-
|
||||
id: 1
|
||||
- id: 1
|
||||
name: testnamespace
|
||||
description: Lorem Ipsum
|
||||
owner_id: 1
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 2
|
||||
- id: 2
|
||||
name: testnamespace2
|
||||
description: Lorem Ipsum
|
||||
owner_id: 2
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 3
|
||||
- id: 3
|
||||
name: testnamespace3
|
||||
description: Lorem Ipsum
|
||||
owner_id: 3
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 6
|
||||
name: testnamespace6
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 7
|
||||
name: testnamespace7
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 8
|
||||
name: testnamespace8
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 9
|
||||
name: testnamespace9
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 10
|
||||
name: testnamespace10
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 11
|
||||
name: testnamespace11
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
- id: 12
|
||||
name: testnamespace12
|
||||
description: Lorem Ipsum
|
||||
owner_id: 6
|
||||
updated: 0
|
||||
created: 0
|
||||
|
8
pkg/models/fixtures/task_assignees.yml
Normal file
8
pkg/models/fixtures/task_assignees.yml
Normal file
@ -0,0 +1,8 @@
|
||||
- id: 1
|
||||
task_id: 30
|
||||
user_id: 1
|
||||
created: 0
|
||||
- id: 2
|
||||
task_id: 30
|
||||
user_id: 2
|
||||
created: 0
|
@ -1,5 +1,6 @@
|
||||
- id: 1
|
||||
text: 'task #1'
|
||||
description: 'Lorem Ipsum'
|
||||
created_by_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
@ -90,4 +91,105 @@
|
||||
created_by_id: 5
|
||||
list_id: 5
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 15
|
||||
text: 'task #15'
|
||||
created_by_id: 6
|
||||
list_id: 6
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 16
|
||||
text: 'task #16'
|
||||
created_by_id: 6
|
||||
list_id: 7
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 17
|
||||
text: 'task #17'
|
||||
created_by_id: 6
|
||||
list_id: 8
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 18
|
||||
text: 'task #18'
|
||||
created_by_id: 6
|
||||
list_id: 9
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 19
|
||||
text: 'task #19'
|
||||
created_by_id: 6
|
||||
list_id: 10
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 20
|
||||
text: 'task #20'
|
||||
created_by_id: 6
|
||||
list_id: 11
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 21
|
||||
text: 'task #21'
|
||||
created_by_id: 6
|
||||
list_id: 12
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 22
|
||||
text: 'task #22'
|
||||
created_by_id: 6
|
||||
list_id: 13
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 23
|
||||
text: 'task #23'
|
||||
created_by_id: 6
|
||||
list_id: 14
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 24
|
||||
text: 'task #24'
|
||||
created_by_id: 6
|
||||
list_id: 15
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 25
|
||||
text: 'task #25'
|
||||
created_by_id: 6
|
||||
list_id: 16
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 26
|
||||
text: 'task #26'
|
||||
created_by_id: 6
|
||||
list_id: 17
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 27
|
||||
text: 'task #27 with reminders'
|
||||
created_by_id: 1
|
||||
reminders_unix: '[1543626724,1543626824]'
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 28
|
||||
text: 'task #28 with repeat after'
|
||||
done: false
|
||||
created_by_id: 1
|
||||
repeat_after: 3600
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 29
|
||||
text: 'task #29 with parent task (1)'
|
||||
created_by_id: 1
|
||||
parent_task_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
- id: 30
|
||||
text: 'task #30 with assignees'
|
||||
created_by_id: 1
|
||||
list_id: 1
|
||||
created: 1543626724
|
||||
updated: 1543626724
|
||||
|
||||
|
@ -1,10 +1,30 @@
|
||||
- id: 1
|
||||
team_id: 1
|
||||
list_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
# This team has read only access on list 6
|
||||
- id: 2
|
||||
team_id: 2
|
||||
list_id: 3
|
||||
list_id: 6
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
# This team has write access on list 7
|
||||
- id: 3
|
||||
team_id: 3
|
||||
list_id: 7
|
||||
right: 1
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
# This team has admin access on list 8
|
||||
- id: 4
|
||||
team_id: 4
|
||||
list_id: 8
|
||||
right: 2
|
||||
updated: 0
|
||||
created: 0
|
@ -7,3 +7,27 @@
|
||||
team_id: 1
|
||||
user_id: 2
|
||||
created: 0
|
||||
-
|
||||
team_id: 2
|
||||
user_id: 1
|
||||
created: 0
|
||||
-
|
||||
team_id: 3
|
||||
user_id: 1
|
||||
created: 0
|
||||
-
|
||||
team_id: 4
|
||||
user_id: 1
|
||||
created: 0
|
||||
-
|
||||
team_id: 5
|
||||
user_id: 1
|
||||
created: 0
|
||||
-
|
||||
team_id: 6
|
||||
user_id: 1
|
||||
created: 0
|
||||
-
|
||||
team_id: 7
|
||||
user_id: 1
|
||||
created: 0
|
||||
|
@ -1,10 +1,34 @@
|
||||
- id: 1
|
||||
team_id: 1
|
||||
namespace_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 2
|
||||
team_id: 2
|
||||
namespace_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 3
|
||||
team_id: 5
|
||||
namespace_id: 7
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 4
|
||||
team_id: 6
|
||||
namespace_id: 8
|
||||
right: 1
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 5
|
||||
team_id: 7
|
||||
namespace_id: 9
|
||||
right: 2
|
||||
updated: 0
|
||||
created: 0
|
||||
|
@ -1,5 +1,22 @@
|
||||
-
|
||||
id: 1
|
||||
- id: 1
|
||||
name: testteam1
|
||||
description: Lorem Ipsum
|
||||
created_by_id: 1
|
||||
- id: 2
|
||||
name: testteam2_read_only_on_list6
|
||||
created_by_id: 1
|
||||
- id: 3
|
||||
name: testteam3_write_on_list7
|
||||
created_by_id: 1
|
||||
- id: 4
|
||||
name: testteam4_admin_on_list8
|
||||
created_by_id: 1
|
||||
- id: 5
|
||||
name: testteam2_read_only_on_namespace7
|
||||
created_by_id: 1
|
||||
- id: 6
|
||||
name: testteam3_write_on_namespace8
|
||||
created_by_id: 1
|
||||
- id: 7
|
||||
name: testteam4_admin_on_namespace9
|
||||
created_by_id: 1
|
@ -1,28 +1,30 @@
|
||||
-
|
||||
id: 1
|
||||
username: 'user1'
|
||||
password: '1234'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user1@example.com'
|
||||
is_active: true
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 2
|
||||
username: 'user2'
|
||||
password: '1234'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user2@example.com'
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 3
|
||||
username: 'user3'
|
||||
password: '1234'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user3@example.com'
|
||||
password_reset_token: passwordresettesttoken
|
||||
updated: 0
|
||||
created: 0
|
||||
-
|
||||
id: 4
|
||||
username: 'user4'
|
||||
password: '1234'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user4@example.com'
|
||||
email_confirm_token: tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael
|
||||
updated: 0
|
||||
@ -30,9 +32,17 @@
|
||||
-
|
||||
id: 5
|
||||
username: 'user5'
|
||||
password: '1234'
|
||||
email: 'user4@example.com'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user5@example.com'
|
||||
email_confirm_token: tiepiQueed8ahc7zeeFe1eveiy4Ein8osooxegiephauph2Ael
|
||||
is_active: false
|
||||
updated: 0
|
||||
created: 0
|
||||
# This use is used to create a whole bunch of lists which are then shared directly with a user
|
||||
- id: 6
|
||||
username: 'user6'
|
||||
password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234
|
||||
email: 'user6@example.com'
|
||||
is_active: true
|
||||
updated: 0
|
||||
created: 0
|
||||
|
@ -1,10 +1,34 @@
|
||||
- id: 1
|
||||
user_id: 1
|
||||
list_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 2
|
||||
user_id: 2
|
||||
list_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 3
|
||||
user_id: 1
|
||||
list_id: 9
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 4
|
||||
user_id: 1
|
||||
list_id: 10
|
||||
right: 1
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 5
|
||||
user_id: 1
|
||||
list_id: 11
|
||||
right: 2
|
||||
updated: 0
|
||||
created: 0
|
||||
|
@ -1,10 +1,34 @@
|
||||
- id: 1
|
||||
user_id: 1
|
||||
namespace_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 2
|
||||
user_id: 2
|
||||
namespace_id: 3
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 3
|
||||
user_id: 1
|
||||
namespace_id: 10
|
||||
right: 0
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 4
|
||||
user_id: 1
|
||||
namespace_id: 11
|
||||
right: 1
|
||||
updated: 0
|
||||
created: 0
|
||||
|
||||
- id: 5
|
||||
user_id: 1
|
||||
namespace_id: 12
|
||||
right: 2
|
||||
updated: 0
|
||||
created: 0
|
||||
|
@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
@ -48,7 +49,7 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
||||
CreatedBy: &User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -95,8 +96,8 @@ func TestLabelTask_ReadAll(t *testing.T) {
|
||||
if (err != nil) && tt.wantErr && !tt.errType(err) {
|
||||
t.Errorf("LabelTask.ReadAll() Wrong error type! Error = %v, want = %v", err, runtime.FuncForPC(reflect.ValueOf(tt.errType).Pointer()).Name())
|
||||
}
|
||||
if !reflect.DeepEqual(gotLabels, tt.wantLabels) {
|
||||
t.Errorf("LabelTask.ReadAll() = %v, want %v", gotLabels, tt.wantLabels)
|
||||
if diff, equal := messagediff.PrettyDiff(gotLabels, tt.wantLabels); !equal {
|
||||
t.Errorf("LabelTask.ReadAll() = %v, want %v, diff: %v", l, tt.wantLabels, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
@ -45,7 +46,8 @@ func TestLabel_ReadAll(t *testing.T) {
|
||||
user1 := &User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -85,7 +87,7 @@ func TestLabel_ReadAll(t *testing.T) {
|
||||
CreatedBy: &User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -115,8 +117,8 @@ func TestLabel_ReadAll(t *testing.T) {
|
||||
t.Errorf("Label.ReadAll() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotLs, tt.wantLs) {
|
||||
t.Errorf("Label.ReadAll() = %v, want %v", gotLs, tt.wantLs)
|
||||
if diff, equal := messagediff.PrettyDiff(gotLs, tt.wantLs); !equal {
|
||||
t.Errorf("Label.ReadAll() = %v, want %v, diff: %v", gotLs, tt.wantLs, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -138,7 +140,8 @@ func TestLabel_ReadOne(t *testing.T) {
|
||||
user1 := &User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -192,7 +195,7 @@ func TestLabel_ReadOne(t *testing.T) {
|
||||
CreatedBy: &User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
},
|
||||
},
|
||||
auth: &User{ID: 1},
|
||||
@ -224,8 +227,8 @@ func TestLabel_ReadOne(t *testing.T) {
|
||||
if (err != nil) && tt.wantErr && !tt.errType(err) {
|
||||
t.Errorf("Label.ReadOne() Wrong error type! Error = %v, want = %v", err, runtime.FuncForPC(reflect.ValueOf(tt.errType).Pointer()).Name())
|
||||
}
|
||||
if !reflect.DeepEqual(l, tt.want) && !tt.wantErr && !tt.wantForbidden {
|
||||
t.Errorf("Label.ReadOne() = %v, want %v", l, tt.want)
|
||||
if diff, equal := messagediff.PrettyDiff(l, tt.want); !equal && !tt.wantErr && !tt.wantForbidden {
|
||||
t.Errorf("Label.ReadAll() = %v, want %v, diff: %v", l, tt.want, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
func TestList_Create(t *testing.T) {
|
||||
// Create test database
|
||||
//assert.NoError(t, PrepareTestDatabase())
|
||||
//assert.NoError(t, LoadFixtures())
|
||||
|
||||
// Get our doer
|
||||
doer, err := GetUserByID(1)
|
||||
@ -78,17 +78,6 @@ func TestList_Create(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrListDoesNotExist(err))
|
||||
|
||||
// Delete a nonexistant list
|
||||
err = dummylist.Delete()
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrListDoesNotExist(err))
|
||||
|
||||
// Check failing with no title
|
||||
list2 := List{}
|
||||
err = list2.Create(&doer)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrListTitleCannotBeEmpty(err))
|
||||
|
||||
// Check creation with a nonexistant namespace
|
||||
list3 := List{
|
||||
Title: "test",
|
||||
|
@ -24,11 +24,6 @@ import (
|
||||
// CreateOrUpdateList updates a list or creates it if it doesn't exist
|
||||
func CreateOrUpdateList(list *List) (err error) {
|
||||
|
||||
// Check we have at least a title
|
||||
if list.Title == "" {
|
||||
return ErrListTitleCannotBeEmpty{}
|
||||
}
|
||||
|
||||
// Check if the namespace exists
|
||||
if list.NamespaceID != 0 {
|
||||
_, err = GetNamespaceByID(list.NamespaceID)
|
||||
@ -73,11 +68,6 @@ func CreateOrUpdateList(list *List) (err error) {
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /lists/{id} [post]
|
||||
func (l *List) Update() (err error) {
|
||||
// Check if it exists
|
||||
lorig := List{ID: l.ID}
|
||||
if err = lorig.GetSimpleByID(); err != nil {
|
||||
return
|
||||
}
|
||||
return CreateOrUpdateList(l)
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,6 @@ import (
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /lists/{id} [delete]
|
||||
func (l *List) Delete() (err error) {
|
||||
// Check if the list exists
|
||||
if err = l.GetSimpleByID(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Delete the list
|
||||
_, err = x.ID(l.ID).Delete(&List{})
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
|
||||
func TestList_ReadAll(t *testing.T) {
|
||||
// Create test database
|
||||
//assert.NoError(t, PrepareTestDatabase())
|
||||
//assert.NoError(t, LoadFixtures())
|
||||
|
||||
// Get all lists for our namespace
|
||||
lists, err := GetListsByNamespaceID(1, &User{})
|
||||
@ -40,7 +40,7 @@ func TestList_ReadAll(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, reflect.TypeOf(lists3).Kind(), reflect.Slice)
|
||||
s := reflect.ValueOf(lists3)
|
||||
assert.Equal(t, s.Len(), 3)
|
||||
assert.Equal(t, 15, s.Len())
|
||||
|
||||
// Try getting lists for a nonexistant user
|
||||
_, err = lists2.ReadAll("", &User{ID: 984234}, 1)
|
||||
|
@ -59,6 +59,7 @@ func (t *ListTask) updateTaskAssignees(assignees []*User) (err error) {
|
||||
if len(assignees) == 0 && len(t.Assignees) > 0 {
|
||||
_, err = x.Where("task_id = ?", t.ID).
|
||||
Delete(ListTaskAssginee{})
|
||||
t.setTaskAssignees(assignees)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -123,9 +124,19 @@ func (t *ListTask) updateTaskAssignees(assignees []*User) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
t.setTaskAssignees(assignees)
|
||||
return
|
||||
}
|
||||
|
||||
// Small helper functions to set the new assignees in various places
|
||||
func (t *ListTask) setTaskAssignees(assignees []*User) {
|
||||
if len(assignees) == 0 {
|
||||
t.Assignees = nil
|
||||
return
|
||||
}
|
||||
t.Assignees = assignees
|
||||
}
|
||||
|
||||
// Delete a task assignee
|
||||
// @Summary Delete an assignee
|
||||
// @Description Un-assign a user from a task.
|
||||
|
@ -32,8 +32,8 @@ const (
|
||||
// @Param p query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
|
||||
// @Param s query string false "Search tasks by task text."
|
||||
// @Param sort query string false "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, dueadate, dueadatedesc, dueadateasc."
|
||||
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp."
|
||||
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp."
|
||||
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time."
|
||||
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time."
|
||||
// @Security JWTKeyAuth
|
||||
// @Success 200 {array} models.List "The tasks"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
|
@ -7,9 +7,8 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"reflect"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
@ -21,6 +20,7 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||
{
|
||||
ID: 1,
|
||||
Text: "task #1",
|
||||
Description: "Lorem Ipsum",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
@ -123,6 +123,128 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 15,
|
||||
Text: "task #15",
|
||||
CreatedByID: 6,
|
||||
ListID: 6,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 16,
|
||||
Text: "task #16",
|
||||
CreatedByID: 6,
|
||||
ListID: 7,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 17,
|
||||
Text: "task #17",
|
||||
CreatedByID: 6,
|
||||
ListID: 8,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 18,
|
||||
Text: "task #18",
|
||||
CreatedByID: 6,
|
||||
ListID: 9,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 19,
|
||||
Text: "task #19",
|
||||
CreatedByID: 6,
|
||||
ListID: 10,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 20,
|
||||
Text: "task #20",
|
||||
CreatedByID: 6,
|
||||
ListID: 11,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 21,
|
||||
Text: "task #21",
|
||||
CreatedByID: 6,
|
||||
ListID: 12,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 22,
|
||||
Text: "task #22",
|
||||
CreatedByID: 6,
|
||||
ListID: 13,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 23,
|
||||
Text: "task #23",
|
||||
CreatedByID: 6,
|
||||
ListID: 14,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 24,
|
||||
Text: "task #24",
|
||||
CreatedByID: 6,
|
||||
ListID: 15,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 25,
|
||||
Text: "task #25",
|
||||
CreatedByID: 6,
|
||||
ListID: 16,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 26,
|
||||
Text: "task #26",
|
||||
CreatedByID: 6,
|
||||
ListID: 17,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 27,
|
||||
Text: "task #27 with reminders",
|
||||
CreatedByID: 1,
|
||||
RemindersUnix: []int64{1543626724, 1543626824},
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 28,
|
||||
Text: "task #28 with repeat after",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
RepeatAfter: 3600,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 30,
|
||||
Text: "task #30 with assignees",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
}
|
||||
|
||||
switch by {
|
||||
@ -138,6 +260,10 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
return tasks[i].DueDateUnix > tasks[j].DueDateUnix
|
||||
})
|
||||
// Swap since sqlite seems to sort differently
|
||||
tmp := tasks[5]
|
||||
tasks[5] = tasks[3]
|
||||
tasks[3] = tmp
|
||||
case SortTasksByDueDateAsc:
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
return tasks[i].DueDateUnix < tasks[j].DueDateUnix
|
||||
@ -148,7 +274,7 @@ func sortTasksForTesting(by SortBy) (tasks []*ListTask) {
|
||||
}
|
||||
|
||||
func TestListTask_ReadAll(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
assert.NoError(t, LoadFixtures())
|
||||
type fields struct {
|
||||
ID int64
|
||||
Text string
|
||||
@ -221,6 +347,7 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
{
|
||||
ID: 1,
|
||||
Text: "task #1",
|
||||
Description: "Lorem Ipsum",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
@ -304,6 +431,127 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
}, {
|
||||
ID: 15,
|
||||
Text: "task #15",
|
||||
CreatedByID: 6,
|
||||
ListID: 6,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 16,
|
||||
Text: "task #16",
|
||||
CreatedByID: 6,
|
||||
ListID: 7,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 17,
|
||||
Text: "task #17",
|
||||
CreatedByID: 6,
|
||||
ListID: 8,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 18,
|
||||
Text: "task #18",
|
||||
CreatedByID: 6,
|
||||
ListID: 9,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 19,
|
||||
Text: "task #19",
|
||||
CreatedByID: 6,
|
||||
ListID: 10,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 20,
|
||||
Text: "task #20",
|
||||
CreatedByID: 6,
|
||||
ListID: 11,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 21,
|
||||
Text: "task #21",
|
||||
CreatedByID: 6,
|
||||
ListID: 12,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 22,
|
||||
Text: "task #22",
|
||||
CreatedByID: 6,
|
||||
ListID: 13,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 23,
|
||||
Text: "task #23",
|
||||
CreatedByID: 6,
|
||||
ListID: 14,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 24,
|
||||
Text: "task #24",
|
||||
CreatedByID: 6,
|
||||
ListID: 15,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 25,
|
||||
Text: "task #25",
|
||||
CreatedByID: 6,
|
||||
ListID: 16,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 26,
|
||||
Text: "task #26",
|
||||
CreatedByID: 6,
|
||||
ListID: 17,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 27,
|
||||
Text: "task #27 with reminders",
|
||||
CreatedByID: 1,
|
||||
RemindersUnix: []int64{1543626724, 1543626824},
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 28,
|
||||
Text: "task #28 with repeat after",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
RepeatAfter: 3600,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 30,
|
||||
Text: "task #30 with assignees",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
@ -349,23 +597,29 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: sortTasksForTesting(SortTasksByDueDateDesc),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks sorted by due date asc",
|
||||
fields: fields{
|
||||
Sorting: "duedateasc",
|
||||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 5,
|
||||
Text: "task #5 higher due date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
DueDateUnix: 1543636724,
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
Text: "task #6 lower due date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
DueDateUnix: 1543616724,
|
||||
},
|
||||
{
|
||||
ID: 1,
|
||||
Text: "task #1",
|
||||
Description: "Lorem Ipsum",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
@ -450,6 +704,352 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 15,
|
||||
Text: "task #15",
|
||||
CreatedByID: 6,
|
||||
ListID: 6,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 16,
|
||||
Text: "task #16",
|
||||
CreatedByID: 6,
|
||||
ListID: 7,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 17,
|
||||
Text: "task #17",
|
||||
CreatedByID: 6,
|
||||
ListID: 8,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 18,
|
||||
Text: "task #18",
|
||||
CreatedByID: 6,
|
||||
ListID: 9,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 19,
|
||||
Text: "task #19",
|
||||
CreatedByID: 6,
|
||||
ListID: 10,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 20,
|
||||
Text: "task #20",
|
||||
CreatedByID: 6,
|
||||
ListID: 11,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 21,
|
||||
Text: "task #21",
|
||||
CreatedByID: 6,
|
||||
ListID: 12,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 22,
|
||||
Text: "task #22",
|
||||
CreatedByID: 6,
|
||||
ListID: 13,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 23,
|
||||
Text: "task #23",
|
||||
CreatedByID: 6,
|
||||
ListID: 14,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 24,
|
||||
Text: "task #24",
|
||||
CreatedByID: 6,
|
||||
ListID: 15,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 25,
|
||||
Text: "task #25",
|
||||
CreatedByID: 6,
|
||||
ListID: 16,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 26,
|
||||
Text: "task #26",
|
||||
CreatedByID: 6,
|
||||
ListID: 17,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 27,
|
||||
Text: "task #27 with reminders",
|
||||
CreatedByID: 1,
|
||||
RemindersUnix: []int64{1543626724, 1543626824},
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 28,
|
||||
Text: "task #28 with repeat after",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
RepeatAfter: 3600,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 30,
|
||||
Text: "task #30 with assignees",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "ReadAll ListTasks sorted by due date asc",
|
||||
fields: fields{
|
||||
Sorting: "duedateasc",
|
||||
},
|
||||
args: args{
|
||||
search: "",
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
want: []*ListTask{
|
||||
{
|
||||
ID: 1,
|
||||
Text: "task #1",
|
||||
Description: "Lorem Ipsum",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Text: "task #2 done",
|
||||
Done: true,
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Text: "task #3 high prio",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
Priority: 100,
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Text: "task #4 low prio",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
ID: 7,
|
||||
Text: "task #7 with start date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
},
|
||||
{
|
||||
ID: 8,
|
||||
Text: "task #8 with end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 9,
|
||||
Text: "task #9 with start and end date",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
StartDateUnix: 1544600000,
|
||||
EndDateUnix: 1544700000,
|
||||
},
|
||||
{
|
||||
ID: 10,
|
||||
Text: "task #10 basic",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 11,
|
||||
Text: "task #11 basic",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 12,
|
||||
Text: "task #12 basic",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 15,
|
||||
Text: "task #15",
|
||||
CreatedByID: 6,
|
||||
ListID: 6,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 16,
|
||||
Text: "task #16",
|
||||
CreatedByID: 6,
|
||||
ListID: 7,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 17,
|
||||
Text: "task #17",
|
||||
CreatedByID: 6,
|
||||
ListID: 8,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 18,
|
||||
Text: "task #18",
|
||||
CreatedByID: 6,
|
||||
ListID: 9,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 19,
|
||||
Text: "task #19",
|
||||
CreatedByID: 6,
|
||||
ListID: 10,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 20,
|
||||
Text: "task #20",
|
||||
CreatedByID: 6,
|
||||
ListID: 11,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 21,
|
||||
Text: "task #21",
|
||||
CreatedByID: 6,
|
||||
ListID: 12,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 22,
|
||||
Text: "task #22",
|
||||
CreatedByID: 6,
|
||||
ListID: 13,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 23,
|
||||
Text: "task #23",
|
||||
CreatedByID: 6,
|
||||
ListID: 14,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 24,
|
||||
Text: "task #24",
|
||||
CreatedByID: 6,
|
||||
ListID: 15,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 25,
|
||||
Text: "task #25",
|
||||
CreatedByID: 6,
|
||||
ListID: 16,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 26,
|
||||
Text: "task #26",
|
||||
CreatedByID: 6,
|
||||
ListID: 17,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 27,
|
||||
Text: "task #27 with reminders",
|
||||
CreatedByID: 1,
|
||||
RemindersUnix: []int64{1543626724, 1543626824},
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 28,
|
||||
Text: "task #28 with repeat after",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
RepeatAfter: 3600,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 30,
|
||||
Text: "task #30 with assignees",
|
||||
CreatedByID: 1,
|
||||
ListID: 1,
|
||||
Created: 1543626724,
|
||||
Updated: 1543626724,
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
Text: "task #6 lower due date",
|
||||
@ -481,6 +1081,7 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
a: &User{ID: 1},
|
||||
page: 0,
|
||||
},
|
||||
|
||||
want: sortTasksForTesting(SortTasksByDueDateDesc),
|
||||
wantErr: false,
|
||||
},
|
||||
@ -612,25 +1213,11 @@ func TestListTask_ReadAll(t *testing.T) {
|
||||
}
|
||||
got, err := lt.ReadAll(tt.args.search, tt.args.a, tt.args.page)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ListTask.ReadAll() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("Test %s, ListTask.ReadAll() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ListTask.ReadAll() = %v, want %v", got, tt.want)
|
||||
fmt.Println("Got:")
|
||||
gotslice := got.([]*ListTask)
|
||||
for _, g := range gotslice {
|
||||
fmt.Println(g.Text)
|
||||
//fmt.Println(g.StartDateUnix)
|
||||
//fmt.Println(g.EndDateUnix)
|
||||
}
|
||||
fmt.Println("Want:")
|
||||
wantslice := tt.want.([]*ListTask)
|
||||
for _, w := range wantslice {
|
||||
fmt.Println(w.Text)
|
||||
//fmt.Println(w.StartDateUnix)
|
||||
//fmt.Println(w.EndDateUnix)
|
||||
}
|
||||
if diff, equal := messagediff.PrettyDiff(got, tt.want); !equal {
|
||||
t.Errorf("Test %s, LabelTask.ReadAll() = %v, want %v, diff: %v", tt.name, got, tt.want, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -96,6 +96,11 @@ func (t *ListTask) Update() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Parent task cannot be the same as the current task
|
||||
if t.ID == t.ParentTaskID {
|
||||
return ErrParentTaskCannotBeTheSame{TaskID: t.ID}
|
||||
}
|
||||
|
||||
// When a repeating task is marked as done, we update all deadlines and reminders and set it as undone
|
||||
updateDone(&ot, t)
|
||||
|
||||
@ -128,15 +133,46 @@ func (t *ListTask) Update() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
// And because a false is considered to be a null value, we need to explicitly check that case here.
|
||||
//////
|
||||
// Mergo does ignore nil values. Because of that, we need to check all parameters and set the updated to
|
||||
// nil/their nil value in the struct which is inserted.
|
||||
////
|
||||
// Done
|
||||
if !t.Done {
|
||||
ot.Done = false
|
||||
}
|
||||
|
||||
// If the priority is 0, we also need to explicitly check that here
|
||||
// Priority
|
||||
if t.Priority == 0 {
|
||||
ot.Priority = 0
|
||||
}
|
||||
// Description
|
||||
if t.Description == "" {
|
||||
ot.Description = ""
|
||||
}
|
||||
// Due date
|
||||
if t.DueDateUnix == 0 {
|
||||
ot.DueDateUnix = 0
|
||||
}
|
||||
// Reminders
|
||||
if len(t.RemindersUnix) == 0 {
|
||||
ot.RemindersUnix = nil
|
||||
}
|
||||
// Repeat after
|
||||
if t.RepeatAfter == 0 {
|
||||
ot.RepeatAfter = 0
|
||||
}
|
||||
// Parent task
|
||||
if t.ParentTaskID == 0 {
|
||||
ot.ParentTaskID = 0
|
||||
}
|
||||
// Start date
|
||||
if t.StartDateUnix == 0 {
|
||||
ot.StartDateUnix = 0
|
||||
}
|
||||
// End date
|
||||
if t.EndDateUnix == 0 {
|
||||
ot.EndDateUnix = 0
|
||||
}
|
||||
|
||||
_, err = x.ID(t.ID).
|
||||
Cols("text",
|
||||
|
@ -41,6 +41,7 @@ func (t *ListTask) CanCreate(a web.Auth) (bool, error) {
|
||||
|
||||
// CanRead determines if a user can read a task
|
||||
func (t *ListTask) CanRead(a web.Auth) (canRead bool, err error) {
|
||||
//return t.canDoListTask(a)
|
||||
// Get the task, error out if it doesn't exist
|
||||
*t, err = getTaskByIDSimple(t.ID)
|
||||
if err != nil {
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
func TestListTask_Create(t *testing.T) {
|
||||
//assert.NoError(t, PrepareTestDatabase())
|
||||
//assert.NoError(t, LoadFixtures())
|
||||
|
||||
// Fake list task
|
||||
listtask := ListTask{
|
||||
|
@ -27,7 +27,7 @@ type ListUser struct {
|
||||
// The list id.
|
||||
ListID int64 `xorm:"int(11) not null INDEX" json:"-" param:"list"`
|
||||
// The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right Right `xorm:"int(11) INDEX null" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -17,6 +17,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
@ -159,7 +160,8 @@ func TestListUser_ReadAll(t *testing.T) {
|
||||
User: User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
},
|
||||
Right: RightRead,
|
||||
},
|
||||
@ -167,7 +169,7 @@ func TestListUser_ReadAll(t *testing.T) {
|
||||
User: User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
},
|
||||
Right: RightRead,
|
||||
},
|
||||
@ -204,8 +206,8 @@ func TestListUser_ReadAll(t *testing.T) {
|
||||
if (err != nil) && tt.wantErr && !tt.errType(err) {
|
||||
t.Errorf("ListUser.ReadAll() Wrong error type! Error = %v, want = %v", err, runtime.FuncForPC(reflect.ValueOf(tt.errType).Pointer()).Name())
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("ListUser.ReadAll() = %v, want %v", got, tt.want)
|
||||
if diff, equal := messagediff.PrettyDiff(got, tt.want); !equal {
|
||||
t.Errorf("ListUser.ReadAll() = %v, want %v, diff: %v", got, tt.want, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
|
||||
func TestNamespace_Create(t *testing.T) {
|
||||
// Create test database
|
||||
//assert.NoError(t, PrepareTestDatabase())
|
||||
//assert.NoError(t, LoadFixtures())
|
||||
|
||||
// Dummy namespace
|
||||
dummynamespace := Namespace{
|
||||
@ -122,5 +122,5 @@ func TestNamespace_Create(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, reflect.TypeOf(nsps).Kind(), reflect.Slice)
|
||||
s := reflect.ValueOf(nsps)
|
||||
assert.Equal(t, 3, s.Len())
|
||||
assert.Equal(t, 9, s.Len())
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ type NamespaceUser struct {
|
||||
// The namespace id
|
||||
NamespaceID int64 `xorm:"int(11) not null INDEX" json:"-" param:"namespace"`
|
||||
// The right this user has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right Right `xorm:"int(11) INDEX null" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -20,6 +20,7 @@ package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/web"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
@ -160,7 +161,8 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
||||
User: User{
|
||||
ID: 1,
|
||||
Username: "user1",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
IsActive: true,
|
||||
},
|
||||
Right: RightRead,
|
||||
},
|
||||
@ -168,7 +170,7 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
||||
User: User{
|
||||
ID: 2,
|
||||
Username: "user2",
|
||||
Password: "1234",
|
||||
Password: "$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.",
|
||||
},
|
||||
Right: RightRead,
|
||||
},
|
||||
@ -206,8 +208,8 @@ func TestNamespaceUser_ReadAll(t *testing.T) {
|
||||
if (err != nil) && tt.wantErr && !tt.errType(err) {
|
||||
t.Errorf("NamespaceUser.ReadAll() Wrong error type! Error = %v, want = %v", err, runtime.FuncForPC(reflect.ValueOf(tt.errType).Pointer()).Name())
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("NamespaceUser.ReadAll() = %v, want %v", got, tt.want)
|
||||
if diff, equal := messagediff.PrettyDiff(got, tt.want); !equal {
|
||||
t.Errorf("NamespaceUser.ReadAll() = %v, want %v, diff: %v", got, tt.want, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ type TeamList struct {
|
||||
// The list id.
|
||||
ListID int64 `xorm:"int(11) not null INDEX" json:"-" param:"list"`
|
||||
// The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right Right `xorm:"int(11) INDEX null" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -88,7 +88,7 @@ func TestTeamList(t *testing.T) {
|
||||
|
||||
// Test read all for a list where the user not has access
|
||||
tl6 := tl
|
||||
tl6.ListID = 4
|
||||
tl6.ListID = 5
|
||||
_, err = tl6.ReadAll("", &u, 1)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrNeedToHaveListReadAccess(err))
|
||||
|
@ -27,7 +27,7 @@ type TeamNamespace struct {
|
||||
// The namespace id.
|
||||
NamespaceID int64 `xorm:"int(11) not null INDEX" json:"-" param:"namespace"`
|
||||
// The right this team has. 0 = Read only, 1 = Read & Write, 2 = Admin. See the docs for more details.
|
||||
Right Right `xorm:"int(11) INDEX null" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
Right Right `xorm:"int(11) INDEX not null default 0" json:"right" valid:"length(0|2)" maximum:"2" default:"0"`
|
||||
|
||||
// A unix timestamp when this relation was created. You cannot change this value.
|
||||
Created int64 `xorm:"created not null" json:"created"`
|
||||
|
@ -59,7 +59,7 @@ func TestTeam_Create(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, reflect.TypeOf(ts).Kind(), reflect.Slice)
|
||||
s := reflect.ValueOf(ts)
|
||||
assert.Equal(t, 2, s.Len())
|
||||
assert.Equal(t, 8, s.Len())
|
||||
|
||||
// Check inserting it with an empty name
|
||||
dummyteam.Name = ""
|
||||
|
@ -33,6 +33,13 @@ import (
|
||||
|
||||
// MainTest creates the test engine
|
||||
func MainTest(m *testing.M, pathToRoot string) {
|
||||
SetupTests(pathToRoot)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// SetupTests takes care of seting up the db, fixtures etc.
|
||||
// This is an extra function to be able to call the fixtures setup from the integration tests.
|
||||
func SetupTests(pathToRoot string) {
|
||||
var err error
|
||||
fixturesDir := filepath.Join(pathToRoot, "pkg", "models", "fixtures")
|
||||
if err = createTestEngine(fixturesDir); err != nil {
|
||||
@ -43,11 +50,9 @@ func MainTest(m *testing.M, pathToRoot string) {
|
||||
mail.StartMailDaemon()
|
||||
|
||||
// Create test database
|
||||
if err = PrepareTestDatabase(); err != nil {
|
||||
if err = LoadFixtures(); err != nil {
|
||||
log.Log.Fatalf("Error preparing test database: %v", err.Error())
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func createTestEngine(fixturesDir string) error {
|
||||
@ -90,8 +95,3 @@ func createTestEngine(fixturesDir string) error {
|
||||
|
||||
return InitFixtures(fixturesHelper, fixturesDir)
|
||||
}
|
||||
|
||||
// PrepareTestDatabase load test fixtures into test database
|
||||
func PrepareTestDatabase() error {
|
||||
return LoadFixtures()
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ func CreateUser(user User) (newUser User, err error) {
|
||||
newUser = user
|
||||
|
||||
// Check if we have all needed informations
|
||||
if newUser.Password == "" || newUser.Username == "" {
|
||||
if newUser.Password == "" || newUser.Username == "" || newUser.Email == "" {
|
||||
return User{}, ErrNoUsernamePassword{}
|
||||
}
|
||||
|
||||
@ -154,6 +154,10 @@ func UpdateUser(user User) (updatedUser User, err error) {
|
||||
// UpdateUserPassword updates the password of a user
|
||||
func UpdateUserPassword(user *User, newPassword string) (err error) {
|
||||
|
||||
if newPassword == "" {
|
||||
return ErrEmptyNewPassword{}
|
||||
}
|
||||
|
||||
// Get all user details
|
||||
theUser, err := GetUserByID(user.ID)
|
||||
if err != nil {
|
||||
|
@ -83,6 +83,10 @@ type PasswordTokenRequest struct {
|
||||
|
||||
// RequestUserPasswordResetToken inserts a random token to reset a users password into the databsse
|
||||
func RequestUserPasswordResetToken(tr *PasswordTokenRequest) (err error) {
|
||||
if tr.Email == "" {
|
||||
return ErrNoUsernamePassword{}
|
||||
}
|
||||
|
||||
// Check if the user exists
|
||||
user, err := GetUser(User{Email: tr.Email})
|
||||
if err != nil {
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
|
||||
func TestCreateUser(t *testing.T) {
|
||||
// Create test database
|
||||
//assert.NoError(t, PrepareTestDatabase())
|
||||
//assert.NoError(t, LoadFixtures())
|
||||
|
||||
// Get our doer
|
||||
doer, err := GetUserByID(1)
|
||||
@ -50,7 +50,7 @@ func TestCreateUser(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
|
||||
// Check if it fails to create a user with just the same username
|
||||
_, err = CreateUser(User{Username: dummyuser.Username, Password: "fsdf"})
|
||||
_, err = CreateUser(User{Username: dummyuser.Username, Password: "12345", Email: "email@example.com"})
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrUsernameExists(err))
|
||||
|
||||
|
@ -57,10 +57,20 @@ func Login(c echo.Context) error {
|
||||
}
|
||||
|
||||
// Create token
|
||||
token := jwt.New(jwt.SigningMethodHS256)
|
||||
t, err := CreateNewJWTTokenForUser(&user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, Token{Token: t})
|
||||
}
|
||||
|
||||
// CreateNewJWTTokenForUser generates and signes a new jwt token for a user. This is a global function to be able to call it from integration tests.
|
||||
func CreateNewJWTTokenForUser(user *models.User) (token string, err error) {
|
||||
t := jwt.New(jwt.SigningMethodHS256)
|
||||
|
||||
// Set claims
|
||||
claims := token.Claims.(jwt.MapClaims)
|
||||
claims := t.Claims.(jwt.MapClaims)
|
||||
claims["username"] = user.Username
|
||||
claims["email"] = user.Email
|
||||
claims["id"] = user.ID
|
||||
@ -70,10 +80,5 @@ func Login(c echo.Context) error {
|
||||
claims["avatar"] = hex.EncodeToString(avatar[:])
|
||||
|
||||
// Generate encoded token and send it as response.
|
||||
t, err := token.SignedString([]byte(viper.GetString("service.JWTSecret")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, Token{Token: t})
|
||||
return t.SignedString([]byte(viper.GetString("service.JWTSecret")))
|
||||
}
|
||||
|
@ -55,6 +55,10 @@ func UserChangePassword(c echo.Context) error {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "No password provided.")
|
||||
}
|
||||
|
||||
if newPW.OldPassword == "" {
|
||||
return handler.HandleHTTPError(models.ErrEmptyOldPassword{}, c)
|
||||
}
|
||||
|
||||
// Check the current password
|
||||
if _, err = models.CheckUserCredentials(&models.UserLogin{Username: doer.Username, Password: newPW.OldPassword}); err != nil {
|
||||
return handler.HandleHTTPError(err, c)
|
||||
|
Reference in New Issue
Block a user