Files
Auto_Bangumi/webui/src/components/basic/__tests__/ab-switch.test.ts
EstrellaXD a137b54b85 test: add comprehensive API tests for backend and frontend
Backend:
- Add API test files for auth, program, downloader, config, log, bangumi extended, search, and passkey endpoints
- Update conftest.py with new fixtures (app, authed_client, unauthed_client, mock_program, mock_webauthn, mock_download_client)
- Update factories.py with make_config and make_passkey functions

Frontend:
- Setup vitest testing infrastructure with happy-dom environment
- Add test setup file with mocks for axios, router, i18n, localStorage
- Add mock API data for testing
- Add tests for API logic, store logic, hooks, and basic components
- Add @vue/test-utils and happy-dom dev dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:20:39 +01:00

171 lines
4.7 KiB
TypeScript

/**
* Tests for AbSwitch component
*/
import { describe, it, expect, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { h, defineComponent, ref } from 'vue';
import AbSwitch from '../ab-switch.vue';
// Mock @headlessui/vue Switch component
vi.mock('@headlessui/vue', () => ({
Switch: defineComponent({
props: ['modelValue', 'as'],
emits: ['update:modelValue'],
setup(props, { emit, slots }) {
const toggle = () => {
emit('update:modelValue', !props.modelValue);
};
return () =>
h(
'div',
{
class: 'headlessui-switch-mock',
onClick: toggle,
'data-checked': props.modelValue,
},
slots.default?.()
);
},
}),
}));
describe('AbSwitch', () => {
describe('rendering', () => {
it('should render switch track', () => {
const wrapper = mount(AbSwitch);
expect(wrapper.find('.switch-track').exists()).toBe(true);
});
it('should render switch thumb', () => {
const wrapper = mount(AbSwitch);
expect(wrapper.find('.switch-thumb').exists()).toBe(true);
});
});
describe('checked state', () => {
it('should be unchecked by default', () => {
const wrapper = mount(AbSwitch);
const track = wrapper.find('.switch-track');
const thumb = wrapper.find('.switch-thumb');
expect(track.classes()).not.toContain('switch-track--checked');
expect(thumb.classes()).not.toContain('switch-thumb--checked');
});
it('should apply checked classes when checked is true', async () => {
const wrapper = mount(AbSwitch, {
props: {
checked: true,
'onUpdate:checked': (e: boolean) =>
wrapper.setProps({ checked: e }),
},
});
const track = wrapper.find('.switch-track');
const thumb = wrapper.find('.switch-thumb');
expect(track.classes()).toContain('switch-track--checked');
expect(thumb.classes()).toContain('switch-thumb--checked');
});
it('should not have checked classes when checked is false', () => {
const wrapper = mount(AbSwitch, {
props: {
checked: false,
'onUpdate:checked': () => {},
},
});
const track = wrapper.find('.switch-track');
const thumb = wrapper.find('.switch-thumb');
expect(track.classes()).not.toContain('switch-track--checked');
expect(thumb.classes()).not.toContain('switch-thumb--checked');
});
});
describe('v-model', () => {
it('should emit update:checked when toggled', async () => {
const wrapper = mount(AbSwitch, {
props: {
checked: false,
'onUpdate:checked': (e: boolean) =>
wrapper.setProps({ checked: e }),
},
});
// Find the HeadlessUI Switch mock and click it
const switchMock = wrapper.find('.headlessui-switch-mock');
await switchMock.trigger('click');
expect(wrapper.emitted('update:checked')).toBeTruthy();
});
it('should toggle from false to true', async () => {
let checked = false;
const wrapper = mount(AbSwitch, {
props: {
checked,
'onUpdate:checked': (e: boolean) => {
checked = e;
wrapper.setProps({ checked: e });
},
},
});
const switchMock = wrapper.find('.headlessui-switch-mock');
await switchMock.trigger('click');
expect(checked).toBe(true);
});
it('should toggle from true to false', async () => {
let checked = true;
const wrapper = mount(AbSwitch, {
props: {
checked,
'onUpdate:checked': (e: boolean) => {
checked = e;
wrapper.setProps({ checked: e });
},
},
});
const switchMock = wrapper.find('.headlessui-switch-mock');
await switchMock.trigger('click');
expect(checked).toBe(false);
});
});
describe('accessibility', () => {
it('should use HeadlessUI Switch component', () => {
const wrapper = mount(AbSwitch);
// The mock creates a div with this class
expect(wrapper.find('.headlessui-switch-mock').exists()).toBe(true);
});
});
describe('styling', () => {
it('should have correct track dimensions via CSS class', () => {
const wrapper = mount(AbSwitch);
const track = wrapper.find('.switch-track');
expect(track.exists()).toBe(true);
expect(track.classes()).toContain('switch-track');
});
it('should have correct thumb styling via CSS class', () => {
const wrapper = mount(AbSwitch);
const thumb = wrapper.find('.switch-thumb');
expect(thumb.exists()).toBe(true);
expect(thumb.classes()).toContain('switch-thumb');
});
});
});