Skip to content

Commit 47d1f59

Browse files
committed
feat: add rename action with tests
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
1 parent 20cef4b commit 47d1f59

File tree

4 files changed

+164
-2
lines changed

4 files changed

+164
-2
lines changed

apps/files/src/actions/deleteAction.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import { File, Folder, Permission } from '@nextcloud/files'
2525
import { FileAction } from '../services/FileAction'
2626
import * as eventBus from '@nextcloud/event-bus'
2727
import axios from '@nextcloud/axios'
28-
import type { Navigation } from '../services/Navigation'
2928
import logger from '../logger'
29+
import type { Navigation } from '../services/Navigation'
3030

3131
const view = {
3232
id: 'files',
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
3+
*
4+
* @author John Molakvoæ <skjnldsv@protonmail.com>
5+
*
6+
* @license AGPL-3.0-or-later
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License as
10+
* published by the Free Software Foundation, either version 3 of the
11+
* License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Affero General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public License
19+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
import { action } from './renameAction'
23+
import { expect } from '@jest/globals'
24+
import { File, Permission } from '@nextcloud/files'
25+
import { FileAction } from '../services/FileAction'
26+
import * as eventBus from '@nextcloud/event-bus'
27+
import type { Navigation } from '../services/Navigation'
28+
29+
const view = {
30+
id: 'files',
31+
name: 'Files',
32+
} as Navigation
33+
34+
describe('Rename action conditions tests', () => {
35+
test('Default values', () => {
36+
expect(action).toBeInstanceOf(FileAction)
37+
expect(action.id).toBe('rename')
38+
expect(action.displayName([], view)).toBe('Rename')
39+
expect(action.iconSvgInline([], view)).toBe('SvgMock')
40+
expect(action.default).toBe(false)
41+
expect(action.order).toBe(10)
42+
})
43+
})
44+
45+
describe('Rename action enabled tests', () => {
46+
test('Enabled for node with UPDATE permission', () => {
47+
const file = new File({
48+
id: 1,
49+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
50+
owner: 'admin',
51+
mime: 'text/plain',
52+
permissions: Permission.UPDATE,
53+
})
54+
55+
expect(action.enabled).toBeDefined()
56+
expect(action.enabled!([file], view)).toBe(true)
57+
})
58+
59+
test('Disabled for node without UPDATE permission', () => {
60+
const file = new File({
61+
id: 1,
62+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
63+
owner: 'admin',
64+
mime: 'text/plain',
65+
permissions: Permission.READ,
66+
})
67+
68+
expect(action.enabled).toBeDefined()
69+
expect(action.enabled!([file], view)).toBe(false)
70+
})
71+
72+
test('Disabled if more than one node', () => {
73+
window.OCA = { Files: { Sidebar: {} } }
74+
75+
const file1 = new File({
76+
id: 1,
77+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foo.txt',
78+
owner: 'admin',
79+
mime: 'text/plain',
80+
})
81+
const file2 = new File({
82+
id: 1,
83+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/bar.txt',
84+
owner: 'admin',
85+
mime: 'text/plain',
86+
})
87+
88+
expect(action.enabled).toBeDefined()
89+
expect(action.enabled!([file1, file2], view)).toBe(false)
90+
})
91+
})
92+
93+
describe('Rename action exec tests', () => {
94+
test('Rename', async () => {
95+
jest.spyOn(eventBus, 'emit')
96+
97+
const file = new File({
98+
id: 1,
99+
source: 'https://cloud.domain.com/remote.php/dav/files/admin/foobar.txt',
100+
owner: 'admin',
101+
mime: 'text/plain',
102+
})
103+
104+
const exec = await action.exec(file, view, '/')
105+
106+
// Silent action
107+
expect(exec).toBe(null)
108+
expect(eventBus.emit).toBeCalledTimes(1)
109+
expect(eventBus.emit).toHaveBeenCalledWith('files:node:rename', file)
110+
})
111+
})
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
3+
*
4+
* @author John Molakvoæ <skjnldsv@protonmail.com>
5+
*
6+
* @license AGPL-3.0-or-later
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License as
10+
* published by the Free Software Foundation, either version 3 of the
11+
* License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU Affero General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public License
19+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
import { Permission, type Node } from '@nextcloud/files'
23+
import { translate as t } from '@nextcloud/l10n'
24+
import PencilSvg from '@mdi/svg/svg/pencil.svg?raw'
25+
26+
import { emit } from '@nextcloud/event-bus'
27+
import { registerFileAction, FileAction } from '../services/FileAction'
28+
29+
export const ACTION_DETAILS = 'details'
30+
31+
export const action = new FileAction({
32+
id: 'rename',
33+
displayName: () => t('files', 'Rename'),
34+
iconSvgInline: () => PencilSvg,
35+
36+
enabled: (nodes: Node[]) => {
37+
return nodes.length > 0 && nodes
38+
.map(node => node.permissions)
39+
.every(permission => (permission & Permission.UPDATE) !== 0)
40+
},
41+
42+
async exec(node: Node) {
43+
// Renaming is a built-in feature of the files app
44+
emit('files:node:rename', node)
45+
return null
46+
},
47+
48+
order: 10,
49+
})
50+
51+
registerFileAction(action)

apps/files/src/actions/sidebarAction.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ describe('Open sidebar action conditions tests', () => {
4242
})
4343
})
4444

45-
describe('Open folder action enabled tests', () => {
45+
describe('Open sidebar action enabled tests', () => {
4646
test('Enabled for ressources within user root folder', () => {
4747
window.OCA = { Files: { Sidebar: {} } }
4848

0 commit comments

Comments
 (0)