This commit is contained in:
pa
2026-03-16 16:01:07 +09:00
parent 4c6f80277e
commit fadead9c80
24 changed files with 183 additions and 92 deletions

View File

@@ -211,6 +211,7 @@
:step="1"
:format-options="{ maximumFractionDigits: 0 }"
class="w-20"
@click.stop
@update:modelValue="setZoomLevel">
<NumberFieldContent>
<NumberFieldDecrement />

View File

@@ -236,7 +236,7 @@ describe('StatusBar.vue - Servers indicator', () => {
expect(wrapper.text()).toContain('Servers');
const serversDots = wrapper.findAll('.bg-status-online');
expect(serversDots.length).toBeGreaterThan(0);
expect(wrapper.find('.bg-\\[\\#e6a23c\\]').exists()).toBe(false);
expect(wrapper.find('.bg-status-askme').exists()).toBe(false);
});
test('shows Servers indicator with yellow dot when there is an issue', () => {
@@ -246,7 +246,7 @@ describe('StatusBar.vue - Servers indicator', () => {
}
});
expect(wrapper.text()).toContain('Servers');
expect(wrapper.find('.bg-\\[\\#e6a23c\\]').exists()).toBe(true);
expect(wrapper.find('.bg-status-askme').exists()).toBe(true);
});
test('shows HoverCard content with status text when there is an issue', () => {

View File

@@ -1,30 +1,26 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { nextTick, ref } from 'vue';
const mocks = vi.hoisted(() => ({
timeToText: vi.fn((ms) => `${ms}ms`)
timeToText: vi.fn((ms) => `${ms}ms`),
nowRef: null
}));
vi.mock('../../shared/utils', () => ({
timeToText: (...args) => mocks.timeToText(...args)
}));
vi.mock('@vueuse/core', () => ({
useNow: () => mocks.nowRef
}));
import Timer from '../Timer.vue';
describe('Timer.vue', () => {
let intervalCallback;
beforeEach(() => {
intervalCallback = null;
mocks.timeToText.mockClear();
vi.spyOn(globalThis, 'setInterval').mockImplementation((cb) => {
intervalCallback = cb;
return 99;
});
vi.spyOn(globalThis, 'clearInterval').mockImplementation(() => {});
vi.spyOn(Date, 'now').mockReturnValue(10000);
mocks.nowRef = ref(10000);
});
afterEach(() => {
@@ -42,15 +38,14 @@ describe('Timer.vue', () => {
expect(mocks.timeToText).toHaveBeenCalledWith(6000);
});
it('updates text when interval callback runs', async () => {
it('updates text when now value changes', async () => {
const wrapper = mount(Timer, {
props: {
epoch: 4000
}
});
vi.mocked(Date.now).mockReturnValue(13000);
intervalCallback?.();
mocks.nowRef.value = 13000;
await nextTick();
expect(wrapper.text()).toBe('9000ms');
@@ -66,15 +61,15 @@ describe('Timer.vue', () => {
expect(wrapper.text()).toBe('-');
});
it('clears interval on unmount', () => {
it('computes correct elapsed time', () => {
mocks.nowRef.value = 20000;
const wrapper = mount(Timer, {
props: {
epoch: 1
epoch: 5000
}
});
wrapper.unmount();
expect(clearInterval).toHaveBeenCalledWith(99);
expect(wrapper.text()).toBe('15000ms');
expect(mocks.timeToText).toHaveBeenCalledWith(15000);
});
});

View File

@@ -38,6 +38,10 @@ vi.mock('../../../../coordinators/imageUploadCoordinator', () => ({
uploadImageLegacy: vi.fn()
}));
vi.mock('../../../../coordinators/avatarCoordinator', () => ({
removeAvatarFromCache: vi.fn()
}));
const { copyToClipboard, openExternalLink } =
await import('../../../../shared/utils');
const { favoriteRequest, avatarRequest, avatarModerationRequest } =

View File

@@ -27,11 +27,15 @@ vi.mock('../../../../stores', () => ({
vi.mock('../../../../composables/useInviteChecks', () => ({
useInviteChecks: () => ({ checkCanInvite: () => true })
}));
vi.mock('../../../../composables/useRecentActions', () => ({
isActionRecent: () => false
}));
vi.mock('../../../ui/dropdown-menu', () => ({
DropdownMenu: { template: '<div><slot /></div>' },
DropdownMenuTrigger: { template: '<div><slot /></div>' },
DropdownMenuContent: { template: '<div><slot /></div>' },
DropdownMenuSeparator: { template: '<hr />' },
DropdownMenuShortcut: { template: '<span><slot /></span>' },
DropdownMenuItem: {
emits: ['click'],
template:
@@ -51,6 +55,7 @@ vi.mock('../../../ui/tooltip', () => ({
vi.mock('lucide-vue-next', () => ({
Check: { template: '<i />' },
CheckCircle: { template: '<i />' },
Clock: { template: '<i />' },
Flag: { template: '<i />' },
LineChart: { template: '<i />' },
Mail: { template: '<i />' },

View File

@@ -223,13 +223,13 @@ describe('UserDialogAvatarsTab.vue', () => {
expect(input.exists()).toBe(true);
});
test('does not render search input for other users', () => {
test('renders search input for other users too', () => {
const wrapper = mountComponent({
id: 'usr_other',
ref: { id: 'usr_other' }
});
const input = wrapper.find('input');
expect(input.exists()).toBe(false);
expect(input.exists()).toBe(true);
});
test('filters avatars by search query', async () => {

View File

@@ -39,6 +39,13 @@ vi.mock('../../../../services/database', () => ({
}
}));
vi.mock('../../../../composables/useRecentActions', () => ({
recordRecentAction: vi.fn(),
useRecentActions: () => ({
isRecentAction: vi.fn(() => false)
})
}));
// Import mocks after vi.mock
const { copyToClipboard } = await import('../../../../shared/utils');
const {

View File

@@ -36,6 +36,10 @@ vi.mock('../../../../coordinators/imageUploadCoordinator', () => ({
uploadImageLegacy: vi.fn()
}));
vi.mock('../../../../coordinators/worldCoordinator', () => ({
removeWorldFromCache: vi.fn()
}));
const { favoriteRequest, miscRequest, userRequest, worldRequest } =
await import('../../../../api');
const { openExternalLink } = await import('../../../../shared/utils');

View File

@@ -84,7 +84,8 @@ describe('NavMenuFolderItem', () => {
hasNotifications: false,
isEntryNotified: () => false,
isNavItemNotified: () => false,
isDashboardItem: () => false
isDashboardItem: () => false,
isToolItem: () => false
}
});
@@ -103,7 +104,8 @@ describe('NavMenuFolderItem', () => {
hasNotifications: false,
isEntryNotified: () => false,
isNavItemNotified: () => false,
isDashboardItem: () => false
isDashboardItem: () => false,
isToolItem: () => false
}
});

View File

@@ -92,7 +92,9 @@ describe('useNavLayout', () => {
await applyCustomNavLayout(layout, []);
await nextTick();
expect(navLayout.value).toEqual(layout);
expect(navLayout.value).toEqual(
expect.arrayContaining(layout)
);
expect(mocks.setString).toHaveBeenCalled();
});
});