mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat(test): add themeStore tests
This commit is contained in:
parent
35b7e952ca
commit
c915507c1a
5 changed files with 123 additions and 26 deletions
|
@ -93,13 +93,8 @@
|
|||
"test:e2e:ci": "kill-port 8080 && start-test 'php artisan serve --port=8080 --quiet' http-get://localhost:8080/api/ping 'cypress run --browser chromium'",
|
||||
"build": "vite build",
|
||||
"build-demo": "cross-env VITE_KOEL_ENV=demo vite build",
|
||||
"dev": "kill-port 8000 && start-test 'php artisan serve --port=8000 --quiet' http-get://localhost:8000/api/ping hot",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "vite",
|
||||
"prod": "npm run production",
|
||||
"production": "mix --production"
|
||||
"dev": "kill-port 8000 && start-test 'php artisan serve --port=8000 --quiet' http-get://localhost:8000/api/ping vite",
|
||||
"prod": "npm run production"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, onMounted, ref } from 'vue'
|
||||
import { defineAsyncComponent, nextTick, onMounted, ref } from 'vue'
|
||||
import { $, eventBus, hideOverlay, showOverlay } from '@/utils'
|
||||
import { commonStore, preferenceStore as preferences } from '@/stores'
|
||||
import { authService, playbackService, socketListener, socketService } from '@/services'
|
||||
|
@ -46,7 +46,7 @@ const authenticated = ref(false)
|
|||
* Request for notification permission if it's not provided and the user is OK with notifications.
|
||||
*/
|
||||
const requestNotificationPermission = async () => {
|
||||
if (window.Notification && preferences.notify && window.Notification.permission !== 'granted') {
|
||||
if (preferences.notify && window.Notification && window.Notification.permission !== 'granted') {
|
||||
preferences.notify = await window.Notification.requestPermission() === 'denied'
|
||||
}
|
||||
}
|
||||
|
@ -73,11 +73,10 @@ const init = async () => {
|
|||
|
||||
try {
|
||||
await commonStore.init()
|
||||
await nextTick()
|
||||
|
||||
window.setTimeout(() => {
|
||||
playbackService.init()
|
||||
hideOverlay()
|
||||
requestNotificationPermission()
|
||||
await requestNotificationPermission()
|
||||
|
||||
window.addEventListener('beforeunload', (e: BeforeUnloadEvent): void => {
|
||||
if (!preferences.confirmClosing) {
|
||||
|
@ -88,11 +87,12 @@ const init = async () => {
|
|||
e.returnValue = ''
|
||||
})
|
||||
|
||||
await socketService.init() && socketListener.listen()
|
||||
|
||||
hideOverlay()
|
||||
|
||||
// Let all other components know we're ready.
|
||||
eventBus.emit('KOEL_READY')
|
||||
}, 100)
|
||||
|
||||
await socketService.init() && socketListener.listen()
|
||||
} catch (err) {
|
||||
authenticated.value = false
|
||||
throw err
|
||||
|
|
102
resources/assets/js/stores/themeStore.spec.ts
Normal file
102
resources/assets/js/stores/themeStore.spec.ts
Normal file
|
@ -0,0 +1,102 @@
|
|||
import { expect, it } from 'vitest'
|
||||
import UnitTestCase from '@/__tests__/UnitTestCase'
|
||||
import { preferenceStore, themeStore } from '@/stores'
|
||||
|
||||
const testTheme: Theme = {
|
||||
id: 'test',
|
||||
thumbnailColor: '#eee',
|
||||
properties: {
|
||||
'--color-text-primary': '#eee',
|
||||
'--color-text-secondary': '#ddd',
|
||||
'--bg-image': '/images/bg.jpg'
|
||||
}
|
||||
}
|
||||
|
||||
new class extends UnitTestCase {
|
||||
protected beforeEach () {
|
||||
super.beforeEach(() => {
|
||||
document.documentElement.style.setProperty('--color-text-primary', '#fff')
|
||||
document.documentElement.style.setProperty('--color-text-secondary', '#ccc')
|
||||
document.documentElement.style.setProperty('--color-bg-primary', '#000')
|
||||
document.documentElement.style.setProperty('--color-highlight', 'orange')
|
||||
})
|
||||
}
|
||||
|
||||
protected afterEach () {
|
||||
super.afterEach(() => {
|
||||
for (let key in themeStore.defaultProperties) {
|
||||
document.documentElement.style.removeProperty(key)
|
||||
}
|
||||
|
||||
document.documentElement.removeAttribute('data-theme')
|
||||
delete preferenceStore.theme
|
||||
})
|
||||
}
|
||||
|
||||
protected test () {
|
||||
it('initializes the store', () => {
|
||||
const applyMock = this.mock(themeStore, 'applyThemeFromPreference')
|
||||
|
||||
themeStore.init()
|
||||
|
||||
expect(themeStore.defaultProperties).toEqual({
|
||||
'--color-text-primary': '#fff',
|
||||
'--color-text-secondary': '#ccc',
|
||||
'--color-bg-primary': '#000',
|
||||
'--color-bg-secondary': '',
|
||||
'--color-highlight': 'orange',
|
||||
'--bg-image': '',
|
||||
'--bg-position': '',
|
||||
'--bg-attachment': '',
|
||||
'--bg-size': ''
|
||||
})
|
||||
|
||||
expect(applyMock).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('sets a theme', () => {
|
||||
themeStore.setTheme(testTheme)
|
||||
|
||||
expect(document.documentElement.getAttribute('data-theme')).toEqual('test')
|
||||
expect(document.documentElement.style.getPropertyValue('--color-text-primary')).toEqual('#eee')
|
||||
expect(document.documentElement.style.getPropertyValue('--color-text-secondary')).toEqual('#ddd')
|
||||
expect(document.documentElement.style.getPropertyValue('--bg-image')).toEqual('/images/bg.jpg')
|
||||
|
||||
themeStore.setTheme({
|
||||
id: 'another',
|
||||
thumbnailColor: '#ccc',
|
||||
properties: {
|
||||
'--color-text-primary': '#ccc'
|
||||
}
|
||||
})
|
||||
|
||||
expect(document.documentElement.getAttribute('data-theme')).toEqual('another')
|
||||
// verify that non-existent theme properties are reset back to the default
|
||||
expect(document.documentElement.style.getPropertyValue('--color-text-primary')).toEqual('#ccc')
|
||||
expect(document.documentElement.style.getPropertyValue('--color-text-secondary')).toEqual('#ccc')
|
||||
expect(document.documentElement.style.getPropertyValue('--bg-image')).toEqual('')
|
||||
})
|
||||
|
||||
it('gets a theme by id', () => {
|
||||
themeStore.state.themes.push(testTheme)
|
||||
expect(themeStore.getThemeById('test')).toEqual(testTheme)
|
||||
})
|
||||
|
||||
it('gets the default theme', () => {
|
||||
expect(themeStore.getDefaultTheme().id).toEqual('classic')
|
||||
})
|
||||
|
||||
it('applies a theme from preference', () => {
|
||||
preferenceStore.theme = 'test'
|
||||
const setMock = this.mock(themeStore, 'setTheme')
|
||||
themeStore.applyThemeFromPreference()
|
||||
|
||||
expect(setMock).toHaveBeenCalledWith(testTheme)
|
||||
|
||||
preferenceStore.theme = 'non-existent-for-sure'
|
||||
themeStore.applyThemeFromPreference()
|
||||
|
||||
expect(setMock).toHaveBeenCalledWith(themeStore.getDefaultTheme())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ export const themeStore = {
|
|||
'--bg-position': undefined,
|
||||
'--bg-attachment': undefined,
|
||||
'--bg-size': undefined
|
||||
} as Record<ThemeableProperty, string>,
|
||||
} as Record<ThemeableProperty, string | undefined>,
|
||||
|
||||
state: reactive({
|
||||
themes
|
||||
|
|
2
resources/assets/js/types.d.ts
vendored
2
resources/assets/js/types.d.ts
vendored
|
@ -363,7 +363,7 @@ interface Theme {
|
|||
thumbnailColor: string
|
||||
thumbnailUrl?: string
|
||||
selected?: boolean
|
||||
properties?: Record<ThemeableProperty, string>
|
||||
properties?: Partial<Record<ThemeableProperty, string>>
|
||||
}
|
||||
|
||||
type ArtistAlbumViewMode = 'list' | 'thumbnails'
|
||||
|
|
Loading…
Reference in a new issue