Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test(files): Add tests for path handling
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Oct 16, 2024
commit 714ef088ade452c0a7017b20846f4c885271b1ef
130 changes: 130 additions & 0 deletions apps/files/src/store/paths.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { describe, beforeEach, test, expect } from '@jest/globals'
import { setActivePinia, createPinia } from 'pinia'
import { usePathsStore } from './paths.ts'
import { emit } from '@nextcloud/event-bus'
import { File, Folder } from '@nextcloud/files'
import { useFilesStore } from './files.ts'

describe('Path store', () => {

let store: ReturnType<typeof usePathsStore>
let files: ReturnType<typeof useFilesStore>
let root: Folder & { _children?: string[] }

beforeEach(() => {
setActivePinia(createPinia())

root = new Folder({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/', id: 1 })
files = useFilesStore()
files.setRoot({ service: 'files', root })

store = usePathsStore()
})

test('Folder is created', () => {
// no defined paths
expect(store.paths).toEqual({})

// create the folder
const node = new Folder({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/folder', id: 2 })
emit('files:node:created', node)

// see that the path is added
expect(store.paths).toEqual({ files: { [node.path]: node.source } })

// see that the node is added
expect(root._children).toEqual([node.source])
})

test('File is created', () => {
// no defined paths
expect(store.paths).toEqual({})

// create the file
const node = new File({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/file.txt', id: 2, mime: 'text/plain' })
emit('files:node:created', node)

// see that there are still no paths
expect(store.paths).toEqual({})

// see that the node is added
expect(root._children).toEqual([node.source])
})

test('Existing file is created', () => {
// no defined paths
expect(store.paths).toEqual({})

// create the file
const node1 = new File({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/file.txt', id: 2, mime: 'text/plain' })
emit('files:node:created', node1)

// see that there are still no paths
expect(store.paths).toEqual({})

// see that the node is added
expect(root._children).toEqual([node1.source])

// create the same named file again
const node2 = new File({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/file.txt', id: 2, mime: 'text/plain' })
emit('files:node:created', node2)

// see that there are still no paths and the children are not duplicated
expect(store.paths).toEqual({})
expect(root._children).toEqual([node1.source])

})

test('Existing folder is created', () => {
// no defined paths
expect(store.paths).toEqual({})

// create the file
const node1 = new Folder({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/folder', id: 2 })
emit('files:node:created', node1)

// see the path is added
expect(store.paths).toEqual({ files: { [node1.path]: node1.source } })

// see that the node is added
expect(root._children).toEqual([node1.source])

// create the same named file again
const node2 = new Folder({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/folder', id: 2 })
emit('files:node:created', node2)

// see that there is still only one paths and the children are not duplicated
expect(store.paths).toEqual({ files: { [node1.path]: node1.source } })
expect(root._children).toEqual([node1.source])
})

test('Folder is deleted', () => {
const node = new Folder({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/folder', id: 2 })
emit('files:node:created', node)
// see that the path is added and the children are set-up
expect(store.paths).toEqual({ files: { [node.path]: node.source } })
expect(root._children).toEqual([node.source])

emit('files:node:deleted', node)
// See the path is removed
expect(store.paths).toEqual({ files: {} })
// See the child is removed
expect(root._children).toEqual([])
})

test('File is deleted', () => {
const node = new File({ owner: 'test', source: 'http://example.com/remote.php/dav/files/test/file.txt', id: 2, mime: 'text/plain' })
emit('files:node:created', node)
// see that the children are set-up
expect(root._children).toEqual([node.source])

emit('files:node:deleted', node)
// See the child is removed
expect(root._children).toEqual([])
})
})
15 changes: 15 additions & 0 deletions cypress/e2e/files/FilesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ export const triggerInlineActionForFile = (filename: string, actionId: string) =
getActionsForFile(filename).get(`button[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`).should('exist').click()
}

export const createFolder = (folderName: string) => {
cy.intercept('MKCOL', /\/remote.php\/dav\/files\//).as('createFolder')

// TODO: replace by proper data-cy selectors
cy.get('[data-cy-upload-picker] .action-item__menutoggle').first().click()
cy.contains('.upload-picker__menu-entry button', 'New folder').click()
cy.get('[data-cy-files-new-node-dialog]').should('be.visible')
cy.get('[data-cy-files-new-node-dialog-input]').type(`{selectall}${folderName}`)
cy.get('[data-cy-files-new-node-dialog-submit]').click()

cy.wait('@createFolder')

getRowForFile(folderName).should('be.visible')
}

export const moveFile = (fileName: string, dirPath: string) => {
getRowForFile(fileName).should('be.visible')
triggerActionForFile(fileName, 'move-copy')
Expand Down
33 changes: 33 additions & 0 deletions cypress/e2e/files/duplicated-node-regression.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { createFolder, getRowForFile, triggerActionForFile } from './FilesUtils.ts'

before(() => {
cy.createRandomUser()
.then((user) => {
cy.mkdir(user, '/only once')
cy.login(user)
cy.visit('/apps/files')
})
})

/**
* Regression test for https://github.com/nextcloud/server/issues/47904
*/
it('Ensure nodes are not duplicated in the file list', () => {
// See the folder
getRowForFile('only once').should('be.visible')
// Delete the folder
cy.intercept('DELETE', '**/remote.php/dav/**').as('deleteFolder')
triggerActionForFile('only once', 'delete')
cy.wait('@deleteFolder')
getRowForFile('only once').should('not.exist')
// Create the folder again
createFolder('only once')
// See folder exists only once
getRowForFile('only once')
.should('have.length', 1)
})