feat(test): add themeStore tests

This commit is contained in:
Phan An 2022-07-25 10:35:15 +02:00
parent 35b7e952ca
commit c915507c1a
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
5 changed files with 123 additions and 26 deletions

View file

@ -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": {

View file

@ -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,26 +73,26 @@ const init = async () => {
try {
await commonStore.init()
await nextTick()
window.setTimeout(() => {
playbackService.init()
hideOverlay()
requestNotificationPermission()
playbackService.init()
await requestNotificationPermission()
window.addEventListener('beforeunload', (e: BeforeUnloadEvent): void => {
if (!preferences.confirmClosing) {
return
}
window.addEventListener('beforeunload', (e: BeforeUnloadEvent): void => {
if (!preferences.confirmClosing) {
return
}
e.preventDefault()
e.returnValue = ''
})
// Let all other components know we're ready.
eventBus.emit('KOEL_READY')
}, 100)
e.preventDefault()
e.returnValue = ''
})
await socketService.init() && socketListener.listen()
hideOverlay()
// Let all other components know we're ready.
eventBus.emit('KOEL_READY')
} catch (err) {
authenticated.value = false
throw err

View 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())
})
}
}

View file

@ -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

View file

@ -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'