feat(ui): hide absolute paths from regular users
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push Docker manifest (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan
2025-03-25 20:05:24 -04:00
parent 3394580413
commit 46a2ec0ba1
2 changed files with 97 additions and 13 deletions

View File

@@ -1,24 +1,22 @@
import PropTypes from 'prop-types'
import React from 'react'
import { useRecordContext } from 'react-admin'
import { usePermissions, useRecordContext } from 'react-admin'
import config from '../config'
export const PathField = (props) => {
const record = useRecordContext(props)
return (
<span>
{record.libraryPath}
{config.separator}
{record.path}
</span>
)
const { permissions } = usePermissions()
let path = permissions === 'admin' ? record.libraryPath : ''
if (path && path.endsWith(config.separator)) {
path = `${path}${record.path}`
} else {
path = path ? `${path}${config.separator}${record.path}` : record.path
}
return <span>{path}</span>
}
PathField.propTypes = {
label: PropTypes.string,
record: PropTypes.object,
}
PathField.defaultProps = {
addLabel: true,
}

View File

@@ -0,0 +1,86 @@
import React from 'react'
import { render } from '@testing-library/react'
import { PathField } from './PathField'
import { usePermissions, useRecordContext } from 'react-admin'
import config from '../config'
// Mock react-admin hooks
vi.mock('react-admin', () => ({
usePermissions: vi.fn(),
useRecordContext: vi.fn(),
}))
// Mock config
vi.mock('../config', () => ({
default: {
separator: '/',
},
}))
describe('PathField', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('renders path without libraryPath for non-admin users', () => {
// Setup
usePermissions.mockReturnValue({ permissions: 'user' })
useRecordContext.mockReturnValue({
path: 'music/song.mp3',
libraryPath: '/data/media',
})
// Act
const { container } = render(<PathField />)
// Assert
expect(container.textContent).toBe('music/song.mp3')
expect(container.textContent).not.toContain('/data/media')
})
it('renders combined path for admin users when libraryPath does not end with separator', () => {
// Setup
usePermissions.mockReturnValue({ permissions: 'admin' })
useRecordContext.mockReturnValue({
path: 'music/song.mp3',
libraryPath: '/data/media',
})
// Act
const { container } = render(<PathField />)
// Assert
expect(container.textContent).toBe('/data/media/music/song.mp3')
})
it('renders combined path for admin users when libraryPath ends with separator', () => {
// Setup
usePermissions.mockReturnValue({ permissions: 'admin' })
useRecordContext.mockReturnValue({
path: 'music/song.mp3',
libraryPath: '/data/media/',
})
// Act
const { container } = render(<PathField />)
// Assert
expect(container.textContent).toBe('/data/media/music/song.mp3')
})
it('works with a different separator from config', () => {
// Setup
config.separator = '\\'
usePermissions.mockReturnValue({ permissions: 'admin' })
useRecordContext.mockReturnValue({
path: 'music\\song.mp3',
libraryPath: 'C:\\data',
})
// Act
const { container } = render(<PathField />)
// Assert
expect(container.textContent).toBe('C:\\data\\music\\song.mp3')
})
})