mirror of
https://github.com/nextcloud/server.git
synced 2026-04-20 22:00:39 -04:00
fix(OC\MimeType): use proper webroot if needed
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
52842415fb
commit
8519b71bf1
2 changed files with 60 additions and 93 deletions
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { generateUrl, getRootUrl } from '@nextcloud/router'
|
||||
|
||||
const iconCache = new Map()
|
||||
|
||||
|
|
@ -23,36 +23,24 @@ export function getIconUrl(mimeType) {
|
|||
}
|
||||
|
||||
if (!iconCache.has(mimeType)) {
|
||||
// First try to get the correct icon from the current theme
|
||||
let gotIcon = null
|
||||
let gotIcon = false
|
||||
let path = ''
|
||||
// First try to get the correct icon from the current legacy-theme
|
||||
if (OC.theme.folder !== '' && Array.isArray(OC.MimeTypeList.themes[OC.theme.folder])) {
|
||||
path = generateUrl('/themes/' + window.OC.theme.folder + '/core/img/filetypes/')
|
||||
path = getRootUrl() + '/themes/' + window.OC.theme.folder + '/core/img/filetypes/'
|
||||
const icon = getMimeTypeIcon(mimeType, window.OC.MimeTypeList.themes[OC.theme.folder])
|
||||
|
||||
if (icon !== null) {
|
||||
if (icon) {
|
||||
gotIcon = true
|
||||
path += icon
|
||||
path += icon + '.svg'
|
||||
}
|
||||
}
|
||||
if (window.OCA.Theming && gotIcon === null) {
|
||||
path = generateUrl('/apps/theming/img/core/filetypes/')
|
||||
path += getMimeTypeIcon(mimeType, window.OC.MimeTypeList.files)
|
||||
gotIcon = true
|
||||
}
|
||||
|
||||
// If we do not yet have an icon fall back to the default
|
||||
if (gotIcon === null) {
|
||||
path = generateUrl('/core/img/filetypes/')
|
||||
path += getMimeTypeIcon(mimeType, window.OC.MimeTypeList.files)
|
||||
}
|
||||
|
||||
path += '.svg'
|
||||
|
||||
if (window.OCA.Theming) {
|
||||
path += '?v=' + window.OCA.Theming.cacheBuster
|
||||
|
||||
// theming is always enabled since Nextcloud 20 so we get it from that
|
||||
if (!gotIcon) {
|
||||
path = generateUrl('/apps/theming/img/core/filetypes/' + getMimeTypeIcon(mimeType, window.OC.MimeTypeList.files) + '.svg')
|
||||
}
|
||||
|
||||
path += '?v=' + window.OCA.Theming.cacheBuster
|
||||
// Cache the result
|
||||
iconCache.set(mimeType, path)
|
||||
}
|
||||
|
|
@ -92,3 +80,10 @@ function getMimeTypeIcon(mimeType, files) {
|
|||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the icon cache
|
||||
*/
|
||||
export function clearIconCache() {
|
||||
iconCache.clear()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,22 +3,11 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { join } from 'node:path'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { beforeEach, describe, expect, it, test } from 'vitest'
|
||||
import { clearIconCache, getIconUrl } from '../../OC/mimeType.js'
|
||||
|
||||
const generateUrl = vi.hoisted(() => vi.fn((url) => join('/ROOT', url)))
|
||||
|
||||
vi.mock('@nextcloud/router', () => ({
|
||||
generateUrl,
|
||||
}))
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetModules()
|
||||
vi.resetAllMocks()
|
||||
})
|
||||
|
||||
describe('OC.MimeType tests', async () => {
|
||||
beforeEach(async () => {
|
||||
describe('OC.MimeType tests', () => {
|
||||
beforeEach(() => {
|
||||
window.OC.MimeTypeList = {
|
||||
aliases: { 'app/foobar': 'foo/bar' },
|
||||
files: ['folder', 'folder-shared', 'folder-external', 'foo-bar', 'foo', 'file'],
|
||||
|
|
@ -26,11 +15,42 @@ describe('OC.MimeType tests', async () => {
|
|||
abc: ['folder'],
|
||||
},
|
||||
}
|
||||
// @ts-expect-error - mocking global variable
|
||||
window._oc_webroot = '/ROOT'
|
||||
// setup for legacy theme
|
||||
window.OC.theme ??= {}
|
||||
window.OC.theme.folder = ''
|
||||
// the theming app is always enabled since Nextcloud 20
|
||||
window.OCA.Theming ??= {}
|
||||
window.OCA.Theming.cacheBuster = '1cacheBuster2'
|
||||
clearIconCache()
|
||||
})
|
||||
|
||||
describe('no theme', async () => {
|
||||
beforeEach(async () => {
|
||||
window.OC.theme ??= {}
|
||||
test('uses icon cache if availble', async () => {
|
||||
window.OC.theme.folder = 'abc'
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/themes/abc/core/img/filetypes/folder.svg?v=1cacheBuster2')
|
||||
window.OC.theme.folder = ''
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/themes/abc/core/img/filetypes/folder.svg?v=1cacheBuster2')
|
||||
clearIconCache()
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/index.php/apps/theming/img/core/filetypes/folder.svg?v=1cacheBuster2')
|
||||
})
|
||||
|
||||
describe('with legacy themes', async () => {
|
||||
beforeEach(() => {
|
||||
window.OC.theme.folder = 'abc'
|
||||
})
|
||||
|
||||
it('uses theme path if a theme icon is availble', async () => {
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/themes/abc/core/img/filetypes/folder.svg?v=1cacheBuster2')
|
||||
})
|
||||
|
||||
it('fallbacks to the default theme if no icon is available in the theme', async () => {
|
||||
expect(getIconUrl('dir-shared')).toEqual('/ROOT/index.php/apps/theming/img/core/filetypes/folder-shared.svg?v=1cacheBuster2')
|
||||
})
|
||||
})
|
||||
|
||||
describe('no legacy theme', async () => {
|
||||
beforeEach(() => {
|
||||
window.OC.theme.folder = ''
|
||||
})
|
||||
|
||||
|
|
@ -47,72 +67,24 @@ describe('OC.MimeType tests', async () => {
|
|||
// return the file mimetype if we have no matching icon but do have a file icon
|
||||
{ mimeType: 'foobar', icon: 'file' },
|
||||
])('returns correct icon', async ({ icon, mimeType }) => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl(mimeType)).toEqual(`/ROOT/core/img/filetypes/${icon}.svg`)
|
||||
expect(getIconUrl(mimeType)).toEqual(`/ROOT/index.php/apps/theming/img/core/filetypes/${icon}.svg?v=1cacheBuster2`)
|
||||
})
|
||||
|
||||
it('returns undefined if the an icon for undefined is requested', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
// @ts-expect-error - testing invalid input
|
||||
expect(getIconUrl(undefined)).toEqual(undefined)
|
||||
})
|
||||
|
||||
it('uses the cache if available', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(generateUrl).not.toHaveBeenCalled()
|
||||
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/core/img/filetypes/folder.svg')
|
||||
expect(generateUrl).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/core/img/filetypes/folder.svg')
|
||||
expect(generateUrl).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(getIconUrl('dir-shared')).toEqual('/ROOT/core/img/filetypes/folder-shared.svg')
|
||||
expect(generateUrl).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('converts aliases correctly', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl('app/foobar')).toEqual('/ROOT/core/img/filetypes/foo-bar.svg')
|
||||
})
|
||||
})
|
||||
|
||||
describe('with legacy themes', async () => {
|
||||
beforeEach(async () => {
|
||||
window.OC.theme ??= {}
|
||||
window.OC.theme.folder = 'abc'
|
||||
})
|
||||
|
||||
it('uses theme path if a theme icon is availble', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl('dir')).toEqual('/ROOT/themes/abc/core/img/filetypes/folder.svg')
|
||||
})
|
||||
|
||||
it('fallbacks to the default theme if no icon is available in the theme', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl('dir-shared')).toEqual('/ROOT/core/img/filetypes/folder-shared.svg')
|
||||
})
|
||||
})
|
||||
|
||||
describe('with theming app', async () => {
|
||||
beforeEach(async () => {
|
||||
window.OC.theme ??= {}
|
||||
window.OC.theme.folder = ''
|
||||
window.OCA.Theming ??= {}
|
||||
window.OCA.Theming.cacheBuster = '1cacheBuster2'
|
||||
expect(getIconUrl('app/foobar')).toEqual('/ROOT/index.php/apps/theming/img/core/filetypes/foo-bar.svg?v=1cacheBuster2')
|
||||
})
|
||||
|
||||
it('uses the correct theming URL', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl('dir')).toMatch('/apps/theming/img/core/filetypes/folder.svg')
|
||||
expect(getIconUrl('dir')).toMatch('/ROOT/index.php/apps/theming/img/core/filetypes/folder.svg?v=1cacheBuster2')
|
||||
})
|
||||
|
||||
it('uses the cache buster', async () => {
|
||||
const { getIconUrl } = await getMethod()
|
||||
expect(getIconUrl('file')).toMatch(/\?v=1cacheBuster2$/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
async function getMethod() {
|
||||
return await import('../../OC/mimeType.js')
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue