// @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() }) })