2020-12-29 02:04:20 +01:00
|
|
|
// Vikunja is a to-do list application to facilitate your life.
|
2021-02-02 20:19:13 +01:00
|
|
|
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
2019-10-16 22:52:29 +02:00
|
|
|
//
|
2020-12-29 02:04:20 +01:00
|
|
|
// This program is free software: you can redistribute it and/or modify
|
2020-12-23 16:41:52 +01:00
|
|
|
// it under the terms of the GNU Affero General Public Licensee as published by
|
2019-10-16 22:52:29 +02:00
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
2020-12-29 02:04:20 +01:00
|
|
|
// This program is distributed in the hope that it will be useful,
|
2019-10-16 22:52:29 +02:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2020-12-23 16:41:52 +01:00
|
|
|
// GNU Affero General Public Licensee for more details.
|
2019-10-16 22:52:29 +02:00
|
|
|
//
|
2020-12-23 16:41:52 +01:00
|
|
|
// You should have received a copy of the GNU Affero General Public Licensee
|
2020-12-29 02:04:20 +01:00
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2019-10-16 22:52:29 +02:00
|
|
|
|
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
2020-10-11 22:10:03 +02:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
"code.vikunja.io/api/pkg/config"
|
2020-02-16 22:42:04 +01:00
|
|
|
"code.vikunja.io/api/pkg/db"
|
2019-10-16 22:52:29 +02:00
|
|
|
"code.vikunja.io/api/pkg/files"
|
2020-01-26 18:08:06 +01:00
|
|
|
"code.vikunja.io/api/pkg/user"
|
2019-10-16 22:52:29 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestTaskAttachment_ReadOne(t *testing.T) {
|
2021-02-02 23:48:37 +01:00
|
|
|
u := &user.User{ID: 1}
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
t.Run("Normal File", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{
|
|
|
|
ID: 1,
|
|
|
|
}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.ReadOne(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotNil(t, ta.File)
|
|
|
|
assert.True(t, ta.File.ID == ta.FileID && ta.FileID != 0)
|
|
|
|
|
|
|
|
// Load the actual attachment file and check its content
|
|
|
|
err = ta.File.LoadFileByID()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, config.FilesBasePath.GetString()+"/1", ta.File.File.Name())
|
|
|
|
content := make([]byte, 9)
|
|
|
|
read, err := ta.File.File.Read(content)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 9, read)
|
|
|
|
assert.Equal(t, []byte("testfile1"), content)
|
|
|
|
})
|
|
|
|
t.Run("Nonexisting Attachment", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{
|
|
|
|
ID: 9999,
|
|
|
|
}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.ReadOne(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.Error(t, err)
|
|
|
|
assert.True(t, IsErrTaskAttachmentDoesNotExist(err))
|
|
|
|
})
|
|
|
|
t.Run("Existing Attachment, Nonexisting File", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{
|
|
|
|
ID: 2,
|
|
|
|
}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.ReadOne(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.Error(t, err)
|
|
|
|
assert.EqualError(t, err, "file 9999 does not exist")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type testfile struct {
|
|
|
|
content []byte
|
|
|
|
done bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *testfile) Read(p []byte) (n int, err error) {
|
|
|
|
if t.done {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
copy(p, t.content)
|
|
|
|
t.done = true
|
|
|
|
return len(p), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *testfile) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskAttachment_NewAttachment(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
// Assert the file is being stored correctly
|
|
|
|
ta := TaskAttachment{
|
|
|
|
TaskID: 1,
|
|
|
|
}
|
|
|
|
tf := &testfile{
|
|
|
|
content: []byte("testingstuff"),
|
|
|
|
}
|
2020-01-26 18:08:06 +01:00
|
|
|
testuser := &user.User{ID: 1}
|
2019-10-16 22:52:29 +02:00
|
|
|
|
2020-12-23 16:32:28 +01:00
|
|
|
err := ta.NewAttachment(s, tf, "testfile", 100, testuser)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NotEqual(t, 0, ta.FileID)
|
|
|
|
_, err = files.FileStat("files/" + strconv.FormatInt(ta.FileID, 10))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, os.IsNotExist(err))
|
|
|
|
assert.Equal(t, testuser.ID, ta.CreatedByID)
|
|
|
|
|
|
|
|
// Check the file was inserted correctly
|
|
|
|
ta.File = &files.File{ID: ta.FileID}
|
|
|
|
err = ta.File.LoadFileMetaByID()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, testuser.ID, ta.File.CreatedByID)
|
|
|
|
assert.Equal(t, "testfile", ta.File.Name)
|
2019-10-18 17:30:25 +02:00
|
|
|
assert.Equal(t, uint64(100), ta.File.Size)
|
2019-10-16 22:52:29 +02:00
|
|
|
|
|
|
|
// Extra test for max size test
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskAttachment_ReadAll(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{TaskID: 1}
|
2020-12-23 16:32:28 +01:00
|
|
|
as, _, _, err := ta.ReadAll(s, &user.User{ID: 1}, "", 0, 50)
|
2019-10-16 22:52:29 +02:00
|
|
|
attachments, _ := as.([]*TaskAttachment)
|
|
|
|
assert.NoError(t, err)
|
2021-04-07 14:44:39 +02:00
|
|
|
assert.Len(t, attachments, 3)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.Equal(t, "test", attachments[0].File.Name)
|
2021-04-07 14:44:39 +02:00
|
|
|
for _, a := range attachments {
|
|
|
|
assert.NotNil(t, a.CreatedBy)
|
|
|
|
}
|
|
|
|
assert.Equal(t, int64(-2), attachments[2].CreatedByID)
|
|
|
|
assert.Equal(t, int64(-2), attachments[2].CreatedBy.ID)
|
2019-10-16 22:52:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestTaskAttachment_Delete(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2021-02-02 23:48:37 +01:00
|
|
|
u := &user.User{ID: 1}
|
|
|
|
|
2019-10-16 22:52:29 +02:00
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
t.Run("Normal", func(t *testing.T) {
|
|
|
|
ta := &TaskAttachment{ID: 1}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.Delete(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.NoError(t, err)
|
|
|
|
// Check if the file itself was deleted
|
|
|
|
_, err = files.FileStat("/1") // The new file has the id 2 since it's the second attachment
|
|
|
|
assert.True(t, os.IsNotExist(err))
|
|
|
|
})
|
|
|
|
t.Run("Nonexisting", func(t *testing.T) {
|
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{ID: 9999}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.Delete(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.Error(t, err)
|
|
|
|
assert.True(t, IsErrTaskAttachmentDoesNotExist(err))
|
|
|
|
})
|
|
|
|
t.Run("Existing attachment, nonexisting file", func(t *testing.T) {
|
|
|
|
files.InitTestFileFixtures(t)
|
|
|
|
ta := &TaskAttachment{ID: 2}
|
2021-02-02 23:48:37 +01:00
|
|
|
err := ta.Delete(s, u)
|
2019-10-16 22:52:29 +02:00
|
|
|
assert.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
2019-11-19 23:07:48 +01:00
|
|
|
|
|
|
|
func TestTaskAttachment_Rights(t *testing.T) {
|
2020-01-26 18:08:06 +01:00
|
|
|
u := &user.User{ID: 1}
|
2019-11-19 23:07:48 +01:00
|
|
|
t.Run("Can Read", func(t *testing.T) {
|
|
|
|
t.Run("Allowed", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 1}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, _, err := ta.CanRead(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.True(t, can)
|
|
|
|
})
|
|
|
|
t.Run("Forbidden", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 14}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, _, err := ta.CanRead(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, can)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
t.Run("Can Delete", func(t *testing.T) {
|
|
|
|
t.Run("Allowed", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 1}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanDelete(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.True(t, can)
|
|
|
|
})
|
|
|
|
t.Run("Forbidden, no access", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 14}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanDelete(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, can)
|
|
|
|
})
|
|
|
|
t.Run("Forbidden, shared read only", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 15}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanDelete(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, can)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
t.Run("Can Create", func(t *testing.T) {
|
|
|
|
t.Run("Allowed", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 1}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanCreate(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.True(t, can)
|
|
|
|
})
|
|
|
|
t.Run("Forbidden, no access", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 14}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanCreate(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, can)
|
|
|
|
})
|
|
|
|
t.Run("Forbidden, shared read only", func(t *testing.T) {
|
2020-02-16 22:42:04 +01:00
|
|
|
db.LoadAndAssertFixtures(t)
|
2020-12-23 16:32:28 +01:00
|
|
|
s := db.NewSession()
|
|
|
|
defer s.Close()
|
|
|
|
|
2019-11-19 23:07:48 +01:00
|
|
|
ta := &TaskAttachment{TaskID: 15}
|
2020-12-23 16:32:28 +01:00
|
|
|
can, err := ta.CanCreate(s, u)
|
2019-11-19 23:07:48 +01:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, can)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|