@wilboerht/blog-template
Version:
A modern bilingual blog template built with VitePress
126 lines (105 loc) • 3.28 kB
text/typescript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { VueWrapper, mount } from '@vue/test-utils'
import { useData, useRoute } from 'vitepress'
import type { Mock } from 'vitest'
import Comments from '../Comments.vue'
vi.mock('vitepress')
const useDataMock = useData as Mock
const useRouteMock = useRoute as Mock
// 创建模拟的 iframe 和 window
function createMockIframe() {
const postMessage = vi.fn()
const iframe = document.createElement('iframe')
iframe.classList.add('giscus-frame')
// 使用 Object.defineProperty 来模拟 contentWindow
Object.defineProperty(iframe, 'contentWindow', {
value: {
postMessage,
// 添加必要的 Window 接口属性
location: window.location,
navigator: window.navigator,
document: window.document,
},
})
document.body.appendChild(iframe)
return { iframe, postMessage }
}
describe('Comments.vue', () => {
let wrapper: VueWrapper
const mountOptions = {
shallow: true,
}
beforeEach(() => {
// 重置 DOM
document.body.innerHTML = ''
// 重置所有的 mock
vi.clearAllMocks()
// 重置 VitePress hooks
useDataMock.mockReturnValue({
frontmatter: { value: {} },
isDark: { value: false },
})
useRouteMock.mockReturnValue({
path: '/test',
})
})
afterEach(() => {
if (wrapper) {
wrapper.unmount()
}
})
it('renders properly', () => {
wrapper = mount(Comments, mountOptions)
expect(wrapper.exists()).toBe(true)
expect(wrapper.find('.comments')).toBeVisible()
})
it('does not load comments on non-post pages', () => {
useDataMock.mockReturnValue({
frontmatter: { value: { layout: 'page' } },
isDark: { value: false },
})
wrapper = mount(Comments, mountOptions)
expect(wrapper.find('iframe.giscus-frame').exists()).toBe(false)
})
it('loads comments on post pages', async () => {
useDataMock.mockReturnValue({
frontmatter: { value: { layout: 'post' } },
isDark: { value: false },
})
wrapper = mount(Comments, mountOptions)
await wrapper.vm.$nextTick()
const script = document.querySelector('script[src*="giscus.app"]')
expect(script).toBeInTheDocument()
expect(script?.getAttribute('data-theme')).toBe('light')
})
it('updates theme when dark mode changes', async () => {
const { postMessage } = createMockIframe()
useDataMock.mockReturnValue({
frontmatter: { value: { layout: 'post' } },
isDark: { value: true },
})
wrapper = mount(Comments, mountOptions)
await vi.dynamicImportSettled()
expect(postMessage).toHaveBeenCalledWith(
expect.objectContaining({
giscus: { setConfig: { theme: 'dark' } },
}),
'https://giscus.app'
)
})
it('reloads comments when route changes', async () => {
const { postMessage } = createMockIframe()
wrapper = mount(Comments, mountOptions)
await wrapper.vm.$nextTick()
useRouteMock.mockReturnValue({
path: '/new-path',
})
await vi.dynamicImportSettled()
expect(postMessage).toHaveBeenCalledWith(
expect.objectContaining({
giscus: { setConfig: { term: '/new-path' } },
}),
'https://giscus.app'
)
})
})