diff --git a/apps/files_sharing/src/files_actions/sharingStatusAction.spec.ts b/apps/files_sharing/src/files_actions/sharingStatusAction.spec.ts new file mode 100644 index 0000000000000..80fccb3bf900c --- /dev/null +++ b/apps/files_sharing/src/files_actions/sharingStatusAction.spec.ts @@ -0,0 +1,46 @@ +/*! + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { IFolder, IView } from '@nextcloud/files' + +import AccountGroupSvg from '@mdi/svg/svg/account-group-outline.svg?raw' +import LinkSvg from '@mdi/svg/svg/link.svg?raw' +import { Folder, Permission } from '@nextcloud/files' +import { ShareType } from '@nextcloud/sharing' +import { describe, expect, test, vi } from 'vitest' +import { action } from './sharingStatusAction.ts' + +vi.mock('@nextcloud/auth', () => ({ + getCurrentUser: () => ({ uid: 'alice' }), +})) + +const view = { id: 'files', name: 'Files' } as IView + +function getIcon(owner: string, shareTypes: ShareType[]): string { + const node = new Folder({ + id: 1, + source: 'https://cloud.example.com/remote.php/dav/files/alice/Shared', + owner, + root: '/files/alice', + permissions: Permission.ALL, + attributes: { 'share-types': { 'share-type': shareTypes } }, + }) + return action.iconSvgInline({ nodes: [node], view, folder: {} as IFolder, contents: [] }) +} + +describe('Sharing status action icon', () => { + test('a folder shared with the user shows the owner avatar', () => { + expect(getIcon('bob', [])).toContain('/avatar/bob/32') + }) + + test('a folder shared with the user through a group still shows the owner avatar', () => { + expect(getIcon('bob', [ShareType.Group])).toContain('/avatar/bob/32') + }) + + test('a folder shared by the user shows the share type', () => { + expect(getIcon('alice', [ShareType.Group])).toBe(AccountGroupSvg) + expect(getIcon('alice', [ShareType.Link])).toBe(LinkSvg) + }) +}) diff --git a/apps/files_sharing/src/files_actions/sharingStatusAction.ts b/apps/files_sharing/src/files_actions/sharingStatusAction.ts index 086d507ad4953..48d5b1e28a504 100644 --- a/apps/files_sharing/src/files_actions/sharingStatusAction.ts +++ b/apps/files_sharing/src/files_actions/sharingStatusAction.ts @@ -74,6 +74,11 @@ export const action: IFileAction = { iconSvgInline({ nodes }) { const node = nodes[0]! + // Shared by someone else, like the title. The share types also hold the received share in some responses + if (node.owner && (node.owner !== getCurrentUser()?.uid || isExternal(node))) { + return generateAvatarSvg(node.owner, isExternal(node)) + } + const shareTypes = Object.values(node?.attributes?.['share-types'] || {}).flat() as number[] // Mixed share types @@ -98,10 +103,6 @@ export const action: IFileAction = { return CircleSvg } - if (node.owner && (node.owner !== getCurrentUser()?.uid || isExternal(node))) { - return generateAvatarSvg(node.owner, isExternal(node)) - } - return AccountPlusSvg },