diff --git a/server/app/files.go b/server/app/files.go index 386c1de9..d43b5c27 100644 --- a/server/app/files.go +++ b/server/app/files.go @@ -634,9 +634,9 @@ func (a *App) CopyCardFiles(sourceBoardID string, copiedBlocks []*model.Block, a } fileID, isOk := block.Fields["fileId"].(string) - if !isOk { + if !isOk || fileID == "" { fileID, isOk = block.Fields["attachmentId"].(string) - if !isOk { + if !isOk || fileID == "" { continue } } diff --git a/server/app/files_test.go b/server/app/files_test.go index 0400c224..35b627f7 100644 --- a/server/app/files_test.go +++ b/server/app/files_test.go @@ -672,17 +672,13 @@ func TestCopyAndUpdateCardFiles(t *testing.T) { }) t.Run("Empty file ID", func(t *testing.T) { + // blocks with an empty fileId/attachmentId should be treated + // as having no attached file th.Store.EXPECT().GetBoard(validTestBoardID2).Return(&model.Board{ID: validTestBoardID2, TeamID: "validteam12345678901234567", IsTemplate: false}, nil) mockedFileBackend := &mocks.FileBackend{} th.App.filesBackend = mockedFileBackend err := th.App.CopyAndUpdateCardFiles(validTestBoardID2, "userID", []*model.Block{emptyFileBlock}, false) - assert.Error(t, err) - if err != nil { - assert.True(t, - strings.Contains(err.Error(), "Block ID cannot be empty") || - strings.Contains(err.Error(), "Could not validate file ID"), - "Expected error message to contain 'Block ID cannot be empty' or 'Could not validate file ID', got: %s", err.Error()) - } + assert.NoError(t, err) }) } diff --git a/server/model/block.go b/server/model/block.go index e17a85df..194c97aa 100644 --- a/server/model/block.go +++ b/server/model/block.go @@ -187,13 +187,13 @@ func (b *Block) baseValidations() error { return ErrBlockFieldsSizeLimitExceeded } - if fileID, ok := b.Fields[BlockFieldFileId].(string); ok { + if fileID, ok := b.Fields[BlockFieldFileId].(string); ok && fileID != "" { if err = ValidateFileId(fileID); err != nil { return err } } - if attachmentId, ok := b.Fields[BlockFieldAttachmentId].(string); ok { + if attachmentId, ok := b.Fields[BlockFieldAttachmentId].(string); ok && attachmentId != "" { if err = ValidateFileId(attachmentId); err != nil { return err } diff --git a/server/model/block_test.go b/server/model/block_test.go index ab7a3468..059d5e55 100644 --- a/server/model/block_test.go +++ b/server/model/block_test.go @@ -609,6 +609,38 @@ func TestBlockIsValid(t *testing.T) { require.ErrorIs(t, err, ErrBlockPropertiesInvalidType) }) + t.Run("Should accept block with empty fileId (no file attached)", func(t *testing.T) { + block := &Block{ + ID: string(utils.IDTypeNone) + mmModel.NewId(), + BoardID: string(utils.IDTypeNone) + mmModel.NewId(), + CreatedBy: string(utils.IDTypeNone) + mmModel.NewId(), + ModifiedBy: string(utils.IDTypeNone) + mmModel.NewId(), + Schema: 1, + Type: TypeImage, + Title: "Image with empty fileId", + Fields: map[string]interface{}{BlockFieldFileId: ""}, + CreateAt: 1234567890, + UpdateAt: 1234567890, + } + require.NoError(t, block.IsValid()) + }) + + t.Run("Should accept block with empty attachmentId (no file attached)", func(t *testing.T) { + block := &Block{ + ID: string(utils.IDTypeNone) + mmModel.NewId(), + BoardID: string(utils.IDTypeNone) + mmModel.NewId(), + CreatedBy: string(utils.IDTypeNone) + mmModel.NewId(), + ModifiedBy: string(utils.IDTypeNone) + mmModel.NewId(), + Schema: 1, + Type: TypeAttachment, + Title: "Attachment with empty attachmentId", + Fields: map[string]interface{}{BlockFieldAttachmentId: ""}, + CreateAt: 1234567890, + UpdateAt: 1234567890, + } + require.NoError(t, block.IsValid()) + }) + t.Run("Should accept block with properties as map", func(t *testing.T) { block := &Block{ ID: string(utils.IDTypeNone) + mmModel.NewId(),