// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { flushPromises, mount } from '@vue/test-utils'
import { defineComponent } from 'vue'
const mockFetchSkills = vi.hoisted(() => vi.fn())
const mockFetchPendingWrites = vi.hoisted(() => vi.fn())
const mockProfilesStore = vi.hoisted(() => ({
activeProfileName: 'default',
profiles: [{ name: 'default' }],
fetchProfiles: vi.fn(),
}))
vi.mock('@/api/hermes/skills', () => ({
fetchSkills: mockFetchSkills,
}))
vi.mock('@/api/hermes/write-gate', () => ({
fetchPendingWrites: mockFetchPendingWrites,
}))
vi.mock('@/stores/hermes/profiles', () => ({
useProfilesStore: () => mockProfilesStore,
}))
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: (key: string) => key,
}),
}))
vi.mock('naive-ui', () => ({
NBadge: defineComponent({
props: ['value', 'max', 'show'],
template: '',
}),
NButton: defineComponent({
emits: ['click'],
template: '',
}),
NDrawer: defineComponent({
props: ['show'],
template: '
',
}),
NDrawerContent: defineComponent({
props: ['title', 'closable'],
template: '',
}),
NInput: defineComponent({
props: ['value', 'placeholder', 'size', 'clearable'],
emits: ['update:value'],
template: '',
}),
NSelect: defineComponent({
props: ['value', 'options', 'size'],
emits: ['update:value'],
template: '',
}),
}))
import SkillsView from '@/views/hermes/SkillsView.vue'
describe('SkillsView', () => {
beforeEach(() => {
vi.clearAllMocks()
mockProfilesStore.activeProfileName = 'default'
mockProfilesStore.profiles = [{ name: 'default' }]
mockFetchPendingWrites.mockResolvedValue({ supported: true, records: [] })
vi.stubGlobal('fetch', vi.fn())
window.matchMedia = vi.fn().mockReturnValue({
matches: false,
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
})
})
it('defaults to the first skill instead of loading recommendations', async () => {
mockFetchSkills.mockResolvedValue({
categories: [
{
name: 'alpha',
description: '',
skills: [
{ name: 'first-skill', description: 'First skill' },
{ name: 'second-skill', description: 'Second skill' },
],
},
{
name: 'beta',
description: '',
skills: [{ name: 'third-skill', description: 'Third skill' }],
},
],
archived: [],
})
const wrapper = mount(SkillsView, {
global: {
stubs: {
SkillList: defineComponent({
props: ['categories', 'selectedSkill'],
emits: ['select', 'deleted'],
template: '',
}),
SkillDetail: defineComponent({
props: ['category', 'skill', 'skillName'],
template: '{{ skillName }}',
}),
SkillImportModal: true,
SkillExternalDirsModal: true,
PendingWriteApprovals: true,
},
},
})
await flushPromises()
const detail = wrapper.get('.skill-detail-stub')
expect(detail.attributes('data-category')).toBe('alpha')
expect(detail.attributes('data-skill')).toBe('first-skill')
expect(detail.text()).toBe('first-skill')
expect(wrapper.get('.skill-list-stub').attributes('data-selected')).toBe('alpha/first-skill')
expect(globalThis.fetch).not.toHaveBeenCalled()
})
})