172 lines
4.2 KiB
TypeScript
172 lines
4.2 KiB
TypeScript
|
|
import { describe, it, expect, vi } from 'vitest';
|
||
|
|
import { mountSuspended } from '@nuxt/test-utils/runtime';
|
||
|
|
import Projects from './Projects.vue';
|
||
|
|
import type { VocalSynthPage } from '~/types/vocal-synth';
|
||
|
|
|
||
|
|
// Mock $t function
|
||
|
|
vi.stubGlobal('$t', (key: string) => {
|
||
|
|
const translations: Record<string, string> = {
|
||
|
|
'pages.vocal-synthesis.projects': 'Projects',
|
||
|
|
};
|
||
|
|
return translations[key] || key;
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('VocalSynth Projects', () => {
|
||
|
|
describe('external URL detection logic', () => {
|
||
|
|
const external = (url: string) => url.startsWith('http');
|
||
|
|
|
||
|
|
it('should return true for http URLs', () => {
|
||
|
|
expect(external('http://example.com')).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return true for https URLs', () => {
|
||
|
|
expect(external('https://example.com')).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return false for relative URLs', () => {
|
||
|
|
expect(external('/keine-tashi')).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should return false for paths without protocol', () => {
|
||
|
|
expect(external('/vocal-synthesis/project')).toBe(false);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('component rendering', () => {
|
||
|
|
it('should render the component', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(wrapper.exists()).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should display projects title', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(wrapper.text()).toContain('Projects');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should render projects from injected data', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [
|
||
|
|
{
|
||
|
|
title: 'Test Project',
|
||
|
|
icon: 'mdi:music',
|
||
|
|
description: 'A test vocal synthesis project',
|
||
|
|
link: '/test-project',
|
||
|
|
},
|
||
|
|
],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(wrapper.text()).toContain('Test Project');
|
||
|
|
expect(wrapper.text()).toContain('A test vocal synthesis project');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should render multiple projects', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [
|
||
|
|
{
|
||
|
|
title: 'Project One',
|
||
|
|
icon: 'mdi:music',
|
||
|
|
description: 'First project',
|
||
|
|
link: '/project-one',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'Project Two',
|
||
|
|
icon: 'mdi:microphone',
|
||
|
|
description: 'Second project',
|
||
|
|
link: 'https://example.com/project-two',
|
||
|
|
},
|
||
|
|
],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(wrapper.text()).toContain('Project One');
|
||
|
|
expect(wrapper.text()).toContain('Project Two');
|
||
|
|
expect(wrapper.text()).toContain('First project');
|
||
|
|
expect(wrapper.text()).toContain('Second project');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should render project icons', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [
|
||
|
|
{
|
||
|
|
title: 'Project with Icon',
|
||
|
|
icon: 'mdi:music-note',
|
||
|
|
description: 'Has an icon',
|
||
|
|
link: '/project',
|
||
|
|
},
|
||
|
|
],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
// Icon container should exist
|
||
|
|
expect(wrapper.find('.min-w-13').exists()).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should handle empty projects array', async () => {
|
||
|
|
const pageData: VocalSynthPage = {
|
||
|
|
projects: [],
|
||
|
|
tools: [],
|
||
|
|
};
|
||
|
|
|
||
|
|
const wrapper = await mountSuspended(Projects, {
|
||
|
|
global: {
|
||
|
|
provide: {
|
||
|
|
pageData,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(wrapper.exists()).toBe(true);
|
||
|
|
expect(wrapper.text()).toContain('Projects');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|