Skip to content

Commit 9c099ba

Browse files
nang2049Nevyana Angelova
andauthored
MM-63792: allow duplicating boards with empty file/attachment blocks (#238)
Co-authored-by: Nevyana Angelova <nevyangelova@Nevy-Macbook-16-2025.local>
1 parent 261bc51 commit 9c099ba

4 files changed

Lines changed: 39 additions & 11 deletions

File tree

server/app/files.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,9 @@ func (a *App) CopyCardFiles(sourceBoardID string, copiedBlocks []*model.Block, a
634634
}
635635

636636
fileID, isOk := block.Fields["fileId"].(string)
637-
if !isOk {
637+
if !isOk || fileID == "" {
638638
fileID, isOk = block.Fields["attachmentId"].(string)
639-
if !isOk {
639+
if !isOk || fileID == "" {
640640
continue
641641
}
642642
}

server/app/files_test.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -672,17 +672,13 @@ func TestCopyAndUpdateCardFiles(t *testing.T) {
672672
})
673673

674674
t.Run("Empty file ID", func(t *testing.T) {
675+
// blocks with an empty fileId/attachmentId should be treated
676+
// as having no attached file
675677
th.Store.EXPECT().GetBoard(validTestBoardID2).Return(&model.Board{ID: validTestBoardID2, TeamID: "validteam12345678901234567", IsTemplate: false}, nil)
676678
mockedFileBackend := &mocks.FileBackend{}
677679
th.App.filesBackend = mockedFileBackend
678680
err := th.App.CopyAndUpdateCardFiles(validTestBoardID2, "userID", []*model.Block{emptyFileBlock}, false)
679-
assert.Error(t, err)
680-
if err != nil {
681-
assert.True(t,
682-
strings.Contains(err.Error(), "Block ID cannot be empty") ||
683-
strings.Contains(err.Error(), "Could not validate file ID"),
684-
"Expected error message to contain 'Block ID cannot be empty' or 'Could not validate file ID', got: %s", err.Error())
685-
}
681+
assert.NoError(t, err)
686682
})
687683
}
688684

server/model/block.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,13 @@ func (b *Block) baseValidations() error {
187187
return ErrBlockFieldsSizeLimitExceeded
188188
}
189189

190-
if fileID, ok := b.Fields[BlockFieldFileId].(string); ok {
190+
if fileID, ok := b.Fields[BlockFieldFileId].(string); ok && fileID != "" {
191191
if err = ValidateFileId(fileID); err != nil {
192192
return err
193193
}
194194
}
195195

196-
if attachmentId, ok := b.Fields[BlockFieldAttachmentId].(string); ok {
196+
if attachmentId, ok := b.Fields[BlockFieldAttachmentId].(string); ok && attachmentId != "" {
197197
if err = ValidateFileId(attachmentId); err != nil {
198198
return err
199199
}

server/model/block_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,38 @@ func TestBlockIsValid(t *testing.T) {
609609
require.ErrorIs(t, err, ErrBlockPropertiesInvalidType)
610610
})
611611

612+
t.Run("Should accept block with empty fileId (no file attached)", func(t *testing.T) {
613+
block := &Block{
614+
ID: string(utils.IDTypeNone) + mmModel.NewId(),
615+
BoardID: string(utils.IDTypeNone) + mmModel.NewId(),
616+
CreatedBy: string(utils.IDTypeNone) + mmModel.NewId(),
617+
ModifiedBy: string(utils.IDTypeNone) + mmModel.NewId(),
618+
Schema: 1,
619+
Type: TypeImage,
620+
Title: "Image with empty fileId",
621+
Fields: map[string]interface{}{BlockFieldFileId: ""},
622+
CreateAt: 1234567890,
623+
UpdateAt: 1234567890,
624+
}
625+
require.NoError(t, block.IsValid())
626+
})
627+
628+
t.Run("Should accept block with empty attachmentId (no file attached)", func(t *testing.T) {
629+
block := &Block{
630+
ID: string(utils.IDTypeNone) + mmModel.NewId(),
631+
BoardID: string(utils.IDTypeNone) + mmModel.NewId(),
632+
CreatedBy: string(utils.IDTypeNone) + mmModel.NewId(),
633+
ModifiedBy: string(utils.IDTypeNone) + mmModel.NewId(),
634+
Schema: 1,
635+
Type: TypeAttachment,
636+
Title: "Attachment with empty attachmentId",
637+
Fields: map[string]interface{}{BlockFieldAttachmentId: ""},
638+
CreateAt: 1234567890,
639+
UpdateAt: 1234567890,
640+
}
641+
require.NoError(t, block.IsValid())
642+
})
643+
612644
t.Run("Should accept block with properties as map", func(t *testing.T) {
613645
block := &Block{
614646
ID: string(utils.IDTypeNone) + mmModel.NewId(),

0 commit comments

Comments
 (0)