Skip to content

Commit

Permalink
fix(saveFiles): Do not download the same file multiple times
Browse files Browse the repository at this point in the history
When multiple entries are related to the same file, saveFiles does not
try to download the same file multiple times. After the first download,
the index of existing files is updated.

This can happen when saveFiles is called via saveBills when multiple
bills are related to the same file.
  • Loading branch information
doubleface authored and doubleface committed Oct 16, 2024
1 parent bc376a8 commit f6defb4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
14 changes: 11 additions & 3 deletions packages/cozy-clisk/src/launcher/saveFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { dataUriToArrayBuffer } from '../libs/utils'
* @property {import('cozy-client/types/types').IOCozyFile} [existingFile] - already existing file corresponding to the entry
* @property {boolean} [shouldReplace] - Internal result of the shouldReplaceFile function on the entry
* @property {boolean} [forceReplaceFile] - should the konnector force the replace of the current file
* @property {import('cozy-client/types/types').IOCozyFile} [fileDocument] - Resulting cozy file
*/

/**
Expand Down Expand Up @@ -137,9 +138,8 @@ const saveFiles = async (client, entries, folderPath, options) => {

// do not create subPath folder or call saveFile for existing files or files that don't need to be replaced
for (const entry of entries) {
const existingFile = options.existingFilesIndex.get(
calculateFileKey(entry, options.fileIdAttributes)
)
const fileKey = calculateFileKey(entry, options.fileIdAttributes)
const existingFile = options.existingFilesIndex.get(fileKey)
let shouldReplace = false
if (existingFile) {
shouldReplace = shouldReplaceFile(existingFile, entry, saveOptions)
Expand All @@ -161,6 +161,13 @@ const saveFiles = async (client, entries, folderPath, options) => {

let savedFiles = 0
for (const entry of toSaveEntries) {
const fileKey = calculateFileKey(entry, options.fileIdAttributes)
if (options.existingFilesIndex.get(fileKey) && !entry.forceReplaceFile) {
// do not save multiple entries related to the same file. (Can be the case with saveBills
// with multiple bills associated to the same file)
continue
}

const start = Date.now()
;['filename'].forEach(key => addValOrFnResult(entry, key, options))

Expand All @@ -174,6 +181,7 @@ const saveFiles = async (client, entries, folderPath, options) => {
delete savedEntry._cozy_file_to_create
}
savedEntries.push(savedEntry)
options.existingFilesIndex.set(fileKey, savedEntry.fileDocument)
const end = Date.now()
saveOptions.log(
'debug',
Expand Down
47 changes: 47 additions & 0 deletions packages/cozy-clisk/src/launcher/saveFiles.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -576,4 +576,51 @@ describe('saveFiles', function () {
}
])
})
it('should save only one file even with multiple entries related to the same file', async () => {
const client = {
save: jest.fn().mockImplementation(doc => ({
data: doc
})),
query: jest.fn().mockResolvedValue({ included: [], data: null }),
collection: () => ({
statByPath: jest.fn().mockImplementation(path => {
return { data: { _id: path } }
}),
addReferencesTo: jest.fn()
})
}
const documents = [
{
filestream: 'filestream content',
filename: 'file name.txt'
},
{
filestream: 'filestream content 2',
filename: 'file name.txt'
}
]
await saveFiles(client, documents, '/test/folder/path', {
manifest: {
slug: 'testslug'
},
sourceAccount: 'testsourceaccount',
sourceAccountIdentifier: 'testsourceaccountidentifier',
fileIdAttributes: ['filename'],
existingFilesIndex: new Map(),
log: jest.fn()
})
expect(client.save).toHaveBeenCalledTimes(1)
expect(client.save).toHaveBeenNthCalledWith(1, {
_type: 'io.cozy.files',
data: 'filestream content',
dirId: '/test/folder/path',
metadata: {
fileIdAttributes: 'file name.txt'
},
name: 'file name.txt',
sourceAccount: 'testsourceaccount',
sourceAccountIdentifier: 'testsourceaccountidentifier',
type: 'file'
})
})
})

0 comments on commit f6defb4

Please sign in to comment.