Skip to content

Commit fbf15df

Browse files
authored
fix: not being able to copy notes when io.cozy.notes.images db does not exist (#4608)
### issue When attempting to copy a note file, the stack checks for images in the note by checking `io.cozy.notes.images` db. This `io.cozy.notes.images` is created when you insert an image in a note for the first time, which means when this database does not exist, and you attempt to copy a note, the error "Database does not exist." will be thrown. ### what's changed ensure we don't block the copy operation in the case of a "Database does not exist."
2 parents 0c6ba31 + 56550a0 commit fbf15df

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

model/note/image.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ func getImages(db prefixer.Prefixer, fileID string) ([]*Image, error) {
238238
EndKey: endkey(fileID),
239239
}
240240
if err := couchdb.GetAllDocs(db, consts.NotesImages, &req, &images); err != nil {
241+
if couchdb.IsNoDatabaseError(err) {
242+
return images, nil
243+
}
244+
241245
return nil, err
242246
}
243247
return images, nil

web/files/files_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,6 +2418,56 @@ func TestFiles(t *testing.T) {
24182418
meta.ValueEqual("version", meta1.Value("version").Raw())
24192419
})
24202420

2421+
t.Run("CopyNoteWithoutImagesDatabase", func(t *testing.T) {
2422+
e := testutils.CreateTestClient(t, ts.URL)
2423+
2424+
// Upload a note without images.
2425+
noteContent := "# Simple Note\n\nThis is a note without images."
2426+
obj := e.POST("/files/").
2427+
WithQuery("Name", "simple-note.cozy-note").
2428+
WithQuery("Type", "file").
2429+
WithHeader("Content-Type", consts.NoteMimeType).
2430+
WithHeader("Authorization", "Bearer "+token).
2431+
WithBytes([]byte(noteContent)).
2432+
Expect().Status(201).
2433+
JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}).
2434+
Object()
2435+
2436+
fileID = obj.Path("$.data.id").String().NotEmpty().Raw()
2437+
2438+
// Delete the io.cozy.notes.images database to simulate the case
2439+
// where a note has never had images and the database doesn't exist yet.
2440+
// This is the specific case that was fixed in PR #4608.
2441+
_ = couchdb.DeleteDB(testInstance, consts.NotesImages)
2442+
// Restore the database after the test to avoid affecting other tests.
2443+
t.Cleanup(func() {
2444+
_ = couchdb.CreateDB(testInstance, consts.NotesImages)
2445+
})
2446+
2447+
// Copy the note. This should succeed even though the images database
2448+
// doesn't exist. Before the fix, this would fail with a database error.
2449+
// After the fix, getImages() returns an empty slice when the database
2450+
// doesn't exist, allowing the copy to continue.
2451+
copyObj := e.POST("/files/"+fileID+"/copy").
2452+
WithHeader("Authorization", "Bearer "+token).
2453+
Expect().Status(201).
2454+
JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}).
2455+
Object()
2456+
2457+
copyID := copyObj.Path("$.data.id").String().NotEmpty().NotEqual(fileID).Raw()
2458+
2459+
// Verify the copy has the expected name.
2460+
copyObj.Path("$.data.attributes.name").String().Equal("simple-note (copy).cozy-note")
2461+
2462+
// Download and verify the content of the copy.
2463+
res := e.GET("/files/download/"+copyID).
2464+
WithHeader("Authorization", "Bearer "+token).
2465+
Expect().Status(200)
2466+
2467+
res.Header("Content-Type").Equal(consts.NoteMimeType)
2468+
res.Body().NotEmpty()
2469+
})
2470+
24212471
t.Run("ArchiveNoFiles", func(t *testing.T) {
24222472
e := testutils.CreateTestClient(t, ts.URL)
24232473

0 commit comments

Comments
 (0)