mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-24 01:03:50 +02:00
use oxfmt instead of prettier
This commit is contained in:
@@ -695,11 +695,7 @@
|
||||
const platforms = [];
|
||||
if (ref.unityPackages) {
|
||||
for (const unityPackage of ref.unityPackages) {
|
||||
if (
|
||||
unityPackage.variant &&
|
||||
unityPackage.variant !== 'standard' &&
|
||||
unityPackage.variant !== 'security'
|
||||
) {
|
||||
if (unityPackage.variant && unityPackage.variant !== 'standard' && unityPackage.variant !== 'security') {
|
||||
// skip imposters
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -426,12 +426,7 @@
|
||||
if (byId) return byId;
|
||||
}
|
||||
|
||||
if (
|
||||
allowIndexFallback &&
|
||||
typeof entity.index === 'number' &&
|
||||
entity.index >= 0 &&
|
||||
entity.index < nodes.length
|
||||
) {
|
||||
if (allowIndexFallback && typeof entity.index === 'number' && entity.index >= 0 && entity.index < nodes.length) {
|
||||
return nodes[entity.index] || null;
|
||||
}
|
||||
|
||||
@@ -620,8 +615,7 @@
|
||||
const sourceNode =
|
||||
(sourceIdSnapshot
|
||||
? visibleNodes.find(
|
||||
(node) =>
|
||||
node.id === sourceIdSnapshot && node.type === (sourceIsFolderSnapshot ? 'folder' : 'item')
|
||||
(node) => node.id === sourceIdSnapshot && node.type === (sourceIsFolderSnapshot ? 'folder' : 'item')
|
||||
)
|
||||
: null) || resolveNodeFromDnDEntity(source, visibleNodes);
|
||||
if (!sourceNode) return;
|
||||
|
||||
@@ -381,8 +381,7 @@
|
||||
const { showFullscreenImageDialog } = useGalleryStore();
|
||||
const instanceStore = useInstanceStore();
|
||||
|
||||
const { pastCalenderEvents, upcomingCalenderEvents, updateFollowingCalendarData } =
|
||||
useGroupCalendarEvents(groupDialog);
|
||||
const { pastCalenderEvents, upcomingCalenderEvents, updateFollowingCalendarData } = useGroupCalendarEvents(groupDialog);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -122,11 +122,7 @@
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores';
|
||||
import {
|
||||
applyGroupMember,
|
||||
handleGroupMember,
|
||||
handleGroupMemberProps
|
||||
} from '../../../coordinators/groupCoordinator';
|
||||
import { applyGroupMember, handleGroupMember, handleGroupMemberProps } from '../../../coordinators/groupCoordinator';
|
||||
import { hasGroupPermission } from '../../../shared/utils';
|
||||
import { useUserDisplay } from '../../../composables/useUserDisplay';
|
||||
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
|
||||
|
||||
@@ -74,13 +74,7 @@
|
||||
{ label: 'description', text: 'dialog.group_member_moderation.description' },
|
||||
{ label: 'data', text: 'dialog.group_member_moderation.data' }
|
||||
];
|
||||
const checkedGroupLogsExportLogsOptions = ref([
|
||||
'created_at',
|
||||
'eventType',
|
||||
'actorDisplayName',
|
||||
'description',
|
||||
'data'
|
||||
]);
|
||||
const checkedGroupLogsExportLogsOptions = ref(['created_at', 'eventType', 'actorDisplayName', 'description', 'data']);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -10,7 +10,7 @@ vi.mock('vue-i18n', () => ({
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { t: (key) => key , locale: require('vue').ref('en') },
|
||||
global: { t: (key) => key, locale: require('vue').ref('en') },
|
||||
install: vi.fn()
|
||||
})
|
||||
}));
|
||||
|
||||
@@ -3,12 +3,11 @@ import { mount } from '@vue/test-utils';
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
,
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
t: (key) => key,
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { t: (key) => key , locale: require('vue').ref('en') },
|
||||
global: { t: (key) => key, locale: require('vue').ref('en') },
|
||||
install: vi.fn()
|
||||
})
|
||||
}));
|
||||
@@ -53,7 +52,8 @@ function mountComponent(props = {}) {
|
||||
Trash2: { template: '<svg class="trash-icon" />' },
|
||||
X: { template: '<svg class="x-icon" />' },
|
||||
TooltipWrapper: {
|
||||
template: '<div class="tooltip-stub"><slot /><slot name="content" /></div>'
|
||||
template:
|
||||
'<div class="tooltip-stub"><slot /><slot name="content" /></div>'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,24 +68,32 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
describe('rendering', () => {
|
||||
test('renders user ID input field', () => {
|
||||
const wrapper = mountComponent();
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.user_id');
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.user_id'
|
||||
);
|
||||
});
|
||||
|
||||
test('renders selected users section', () => {
|
||||
const wrapper = mountComponent();
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.selected_users');
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.selected_users'
|
||||
);
|
||||
});
|
||||
|
||||
test('renders roles dropdown with available roles', () => {
|
||||
const wrapper = mountComponent();
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.selected_roles');
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.selected_roles'
|
||||
);
|
||||
});
|
||||
|
||||
test('renders action buttons', () => {
|
||||
const wrapper = mountComponent();
|
||||
const text = wrapper.text();
|
||||
expect(text).toContain('dialog.group_member_moderation.add_roles');
|
||||
expect(text).toContain('dialog.group_member_moderation.remove_roles');
|
||||
expect(text).toContain(
|
||||
'dialog.group_member_moderation.remove_roles'
|
||||
);
|
||||
expect(text).toContain('dialog.group_member_moderation.save_note');
|
||||
expect(text).toContain('dialog.group_member_moderation.kick');
|
||||
expect(text).toContain('dialog.group_member_moderation.ban');
|
||||
@@ -95,8 +103,18 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
test('renders selected user badges', () => {
|
||||
const wrapper = mountComponent({
|
||||
selectedUsersArray: [
|
||||
{ id: 'usr_1', userId: 'usr_1', membershipStatus: 'member', user: { displayName: 'Alice' } },
|
||||
{ id: 'usr_2', userId: 'usr_2', membershipStatus: 'member', user: { displayName: 'Bob' } }
|
||||
{
|
||||
id: 'usr_1',
|
||||
userId: 'usr_1',
|
||||
membershipStatus: 'member',
|
||||
user: { displayName: 'Alice' }
|
||||
},
|
||||
{
|
||||
id: 'usr_2',
|
||||
userId: 'usr_2',
|
||||
membershipStatus: 'member',
|
||||
user: { displayName: 'Bob' }
|
||||
}
|
||||
]
|
||||
});
|
||||
expect(wrapper.text()).toContain('Alice');
|
||||
@@ -106,54 +124,88 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
test('shows warning tooltip for non-member users', () => {
|
||||
const wrapper = mountComponent({
|
||||
selectedUsersArray: [
|
||||
{ id: 'usr_1', userId: 'usr_1', membershipStatus: 'banned', user: { displayName: 'Charlie' } }
|
||||
{
|
||||
id: 'usr_1',
|
||||
userId: 'usr_1',
|
||||
membershipStatus: 'banned',
|
||||
user: { displayName: 'Charlie' }
|
||||
}
|
||||
]
|
||||
});
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.user_isnt_in_group');
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.user_isnt_in_group'
|
||||
);
|
||||
});
|
||||
|
||||
test('does not show warning for member users', () => {
|
||||
const wrapper = mountComponent({
|
||||
selectedUsersArray: [
|
||||
{ id: 'usr_1', userId: 'usr_1', membershipStatus: 'member', user: { displayName: 'Alice' } }
|
||||
{
|
||||
id: 'usr_1',
|
||||
userId: 'usr_1',
|
||||
membershipStatus: 'member',
|
||||
user: { displayName: 'Alice' }
|
||||
}
|
||||
]
|
||||
});
|
||||
expect(wrapper.text()).not.toContain('dialog.group_member_moderation.user_isnt_in_group');
|
||||
expect(wrapper.text()).not.toContain(
|
||||
'dialog.group_member_moderation.user_isnt_in_group'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('progress indicator', () => {
|
||||
test('shows progress when progressCurrent > 0', () => {
|
||||
const wrapper = mountComponent({ progressCurrent: 3, progressTotal: 10 });
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.progress');
|
||||
const wrapper = mountComponent({
|
||||
progressCurrent: 3,
|
||||
progressTotal: 10
|
||||
});
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.progress'
|
||||
);
|
||||
expect(wrapper.text()).toContain('3/10');
|
||||
});
|
||||
|
||||
test('shows cancel button during progress', () => {
|
||||
const wrapper = mountComponent({ progressCurrent: 3, progressTotal: 10 });
|
||||
expect(wrapper.text()).toContain('dialog.group_member_moderation.cancel');
|
||||
const wrapper = mountComponent({
|
||||
progressCurrent: 3,
|
||||
progressTotal: 10
|
||||
});
|
||||
expect(wrapper.text()).toContain(
|
||||
'dialog.group_member_moderation.cancel'
|
||||
);
|
||||
});
|
||||
|
||||
test('hides progress when not in progress', () => {
|
||||
const wrapper = mountComponent({ progressCurrent: 0 });
|
||||
expect(wrapper.text()).not.toContain('dialog.group_member_moderation.progress');
|
||||
expect(wrapper.text()).not.toContain(
|
||||
'dialog.group_member_moderation.progress'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('button disabled states', () => {
|
||||
test('add/remove roles disabled when no roles selected', () => {
|
||||
const wrapper = mountComponent({ selectedRoles: [] });
|
||||
const addBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.add_roles')
|
||||
);
|
||||
const addBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b
|
||||
.text()
|
||||
.includes('dialog.group_member_moderation.add_roles')
|
||||
);
|
||||
expect(addBtn.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
|
||||
test('add/remove roles enabled when roles are selected', () => {
|
||||
const wrapper = mountComponent({ selectedRoles: ['role_1'] });
|
||||
const addBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.add_roles')
|
||||
);
|
||||
const addBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b
|
||||
.text()
|
||||
.includes('dialog.group_member_moderation.add_roles')
|
||||
);
|
||||
expect(addBtn.attributes('disabled')).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -163,25 +215,35 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
progressCurrent: 5,
|
||||
progressTotal: 10
|
||||
});
|
||||
const kickBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.kick')
|
||||
);
|
||||
const kickBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.kick')
|
||||
);
|
||||
expect(kickBtn.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
|
||||
test('select user button disabled when no user ID entered', () => {
|
||||
const wrapper = mountComponent({ selectUserId: '' });
|
||||
const selectBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
const selectBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b
|
||||
.text()
|
||||
.includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
expect(selectBtn.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
|
||||
test('select user button enabled when user ID is entered', () => {
|
||||
const wrapper = mountComponent({ selectUserId: 'usr_test' });
|
||||
const selectBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
const selectBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b
|
||||
.text()
|
||||
.includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
expect(selectBtn.attributes('disabled')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -194,9 +256,11 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
_mockPermissions: ['group-bans-manage']
|
||||
}
|
||||
});
|
||||
const kickBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.kick')
|
||||
);
|
||||
const kickBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.kick')
|
||||
);
|
||||
expect(kickBtn.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -207,12 +271,16 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
_mockPermissions: ['group-members-remove']
|
||||
}
|
||||
});
|
||||
const banBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.ban')
|
||||
);
|
||||
const unbanBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.unban')
|
||||
);
|
||||
const banBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.ban')
|
||||
);
|
||||
const unbanBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.unban')
|
||||
);
|
||||
expect(banBtn.attributes('disabled')).toBeDefined();
|
||||
expect(unbanBtn.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
@@ -221,9 +289,13 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
describe('events', () => {
|
||||
test('emits select-user on select button click', async () => {
|
||||
const wrapper = mountComponent({ selectUserId: 'usr_test' });
|
||||
const selectBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
const selectBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b
|
||||
.text()
|
||||
.includes('dialog.group_member_moderation.select_user')
|
||||
);
|
||||
await selectBtn.trigger('click');
|
||||
expect(wrapper.emitted('select-user')).toBeTruthy();
|
||||
});
|
||||
@@ -241,7 +313,12 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
});
|
||||
|
||||
test('emits delete-user when removing a selected user', async () => {
|
||||
const user = { id: 'usr_1', userId: 'usr_1', membershipStatus: 'member', user: { displayName: 'Alice' } };
|
||||
const user = {
|
||||
id: 'usr_1',
|
||||
userId: 'usr_1',
|
||||
membershipStatus: 'member',
|
||||
user: { displayName: 'Alice' }
|
||||
};
|
||||
const wrapper = mountComponent({ selectedUsersArray: [user] });
|
||||
// The X button is a native <button type="button"> inside each Badge
|
||||
const deleteBtn = wrapper.find('button[type="button"]');
|
||||
@@ -251,18 +328,25 @@ describe('GroupModerationBulkActions.vue', () => {
|
||||
|
||||
test('emits ban on ban button click', async () => {
|
||||
const wrapper = mountComponent();
|
||||
const banBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.ban')
|
||||
);
|
||||
const banBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.ban')
|
||||
);
|
||||
await banBtn.trigger('click');
|
||||
expect(wrapper.emitted('ban')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('emits cancel-progress on cancel click', async () => {
|
||||
const wrapper = mountComponent({ progressCurrent: 3, progressTotal: 10 });
|
||||
const cancelBtn = wrapper.findAll('button').find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.cancel')
|
||||
);
|
||||
const wrapper = mountComponent({
|
||||
progressCurrent: 3,
|
||||
progressTotal: 10
|
||||
});
|
||||
const cancelBtn = wrapper
|
||||
.findAll('button')
|
||||
.find((b) =>
|
||||
b.text().includes('dialog.group_member_moderation.cancel')
|
||||
);
|
||||
await cancelBtn.trigger('click');
|
||||
expect(wrapper.emitted('cancel-progress')).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -54,7 +54,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('returns early when dialog is not visible', () => {
|
||||
const groupDialog = createGroupDialog({ visible: false });
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Refresh');
|
||||
expect(deps.showGroupDialog).not.toHaveBeenCalled();
|
||||
@@ -63,7 +66,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('Share copies group URL', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Share');
|
||||
expect(copyToClipboard).toHaveBeenCalledWith(
|
||||
@@ -74,7 +80,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('Invite To Group dispatches invite callback', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Invite To Group');
|
||||
expect(deps.showInviteGroupDialog).toHaveBeenCalledWith('grp_123', '');
|
||||
@@ -83,7 +92,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('Refresh calls showGroupDialog with forceRefresh', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Refresh');
|
||||
expect(deps.showGroupDialog).toHaveBeenCalledWith('grp_123', {
|
||||
@@ -94,7 +106,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('Block Group confirms and calls blockGroup', async () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Block Group');
|
||||
await vi.waitFor(() => {
|
||||
@@ -109,7 +124,10 @@ describe('useGroupDialogCommands', () => {
|
||||
it('Unblock Group confirms and calls unblockGroup', async () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Unblock Group');
|
||||
await vi.waitFor(() => {
|
||||
@@ -129,7 +147,10 @@ describe('useGroupDialogCommands', () => {
|
||||
confirm: vi.fn().mockResolvedValue({ ok: false })
|
||||
}
|
||||
});
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
const { groupDialogCommand } = useGroupDialogCommands(
|
||||
groupDialog,
|
||||
deps
|
||||
);
|
||||
|
||||
groupDialogCommand('Block Group');
|
||||
await vi.waitFor(() => {
|
||||
|
||||
@@ -233,9 +233,7 @@ describe('useGroupGalleries', () => {
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
queryRequest.fetch.mockRejectedValueOnce(
|
||||
new Error('API Error')
|
||||
);
|
||||
queryRequest.fetch.mockRejectedValueOnce(new Error('API Error'));
|
||||
|
||||
await expect(
|
||||
getGroupGallery('grp_1', 'g1')
|
||||
|
||||
@@ -4,12 +4,11 @@ import { describe, expect, test, vi, beforeEach } from 'vitest';
|
||||
vi.mock('vue-sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
,
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
t: (key) => key,
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { t: (key) => key , locale: require('vue').ref('en') },
|
||||
global: { t: (key) => key, locale: require('vue').ref('en') },
|
||||
install: vi.fn()
|
||||
})
|
||||
}));
|
||||
@@ -95,11 +94,19 @@ import { queryRequest } from '../../../../api';
|
||||
function createTables() {
|
||||
return {
|
||||
members: reactive({ data: [], pageSize: 15 }),
|
||||
bans: reactive({ data: [], filters: [{ prop: ['$displayName'], value: '' }], pageSize: 15 }),
|
||||
bans: reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['$displayName'], value: '' }],
|
||||
pageSize: 15
|
||||
}),
|
||||
invites: reactive({ data: [], pageSize: 15 }),
|
||||
joinRequests: reactive({ data: [], pageSize: 15 }),
|
||||
blocked: reactive({ data: [], pageSize: 15 }),
|
||||
logs: reactive({ data: [], filters: [{ prop: ['description'], value: '' }], pageSize: 15 })
|
||||
logs: reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['description'], value: '' }],
|
||||
pageSize: 15
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,11 +174,19 @@ describe('useGroupModerationData', () => {
|
||||
userId: `usr_${i}`,
|
||||
user: { displayName: `User${i}` }
|
||||
}));
|
||||
const page2 = [{ userId: 'usr_100', user: { displayName: 'User100' } }];
|
||||
const page2 = [
|
||||
{ userId: 'usr_100', user: { displayName: 'User100' } }
|
||||
];
|
||||
|
||||
deps.groupRequest.getGroupBans
|
||||
.mockResolvedValueOnce({ json: page1, params: { groupId: 'grp_test' } })
|
||||
.mockResolvedValueOnce({ json: page2, params: { groupId: 'grp_test' } });
|
||||
.mockResolvedValueOnce({
|
||||
json: page1,
|
||||
params: { groupId: 'grp_test' }
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
json: page2,
|
||||
params: { groupId: 'grp_test' }
|
||||
});
|
||||
|
||||
const { getAllGroupBans } = useGroupModerationData(deps);
|
||||
await getAllGroupBans('grp_test');
|
||||
@@ -198,12 +213,17 @@ describe('useGroupModerationData', () => {
|
||||
test('handles API error gracefully', async () => {
|
||||
const { toast } = await import('vue-sonner');
|
||||
const deps = createDeps();
|
||||
deps.groupRequest.getGroupBans.mockRejectedValue(new Error('Network error'));
|
||||
deps.groupRequest.getGroupBans.mockRejectedValue(
|
||||
new Error('Network error')
|
||||
);
|
||||
|
||||
const { getAllGroupBans, isGroupMembersLoading } = useGroupModerationData(deps);
|
||||
const { getAllGroupBans, isGroupMembersLoading } =
|
||||
useGroupModerationData(deps);
|
||||
await getAllGroupBans('grp_test');
|
||||
|
||||
expect(toast.error).toHaveBeenCalledWith('Failed to get group bans');
|
||||
expect(toast.error).toHaveBeenCalledWith(
|
||||
'Failed to get group bans'
|
||||
);
|
||||
expect(isGroupMembersLoading.value).toBe(false);
|
||||
});
|
||||
|
||||
@@ -213,10 +233,16 @@ describe('useGroupModerationData', () => {
|
||||
userId: `usr_${i}`
|
||||
}));
|
||||
deps.groupRequest.getGroupBans
|
||||
.mockResolvedValueOnce({ json: page1, params: { groupId: 'grp_test' } })
|
||||
.mockResolvedValueOnce({
|
||||
json: page1,
|
||||
params: { groupId: 'grp_test' }
|
||||
})
|
||||
.mockImplementation(() => {
|
||||
deps.groupMemberModeration.value.visible = false;
|
||||
return Promise.resolve({ json: [{ userId: 'usr_extra' }], params: { groupId: 'grp_test' } });
|
||||
return Promise.resolve({
|
||||
json: [{ userId: 'usr_extra' }],
|
||||
params: { groupId: 'grp_test' }
|
||||
});
|
||||
});
|
||||
|
||||
const { getAllGroupBans } = useGroupModerationData(deps);
|
||||
@@ -254,7 +280,10 @@ describe('useGroupModerationData', () => {
|
||||
});
|
||||
|
||||
const { getAllGroupLogs } = useGroupModerationData(deps);
|
||||
await getAllGroupLogs('grp_test', ['group.member.ban', 'group.member.kick']);
|
||||
await getAllGroupLogs('grp_test', [
|
||||
'group.member.ban',
|
||||
'group.member.kick'
|
||||
]);
|
||||
|
||||
expect(deps.groupRequest.getGroupLogs).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -281,7 +310,8 @@ describe('useGroupModerationData', () => {
|
||||
params: { groupId: 'grp_test' }
|
||||
});
|
||||
|
||||
const { getAllGroupInvitesAndJoinRequests } = useGroupModerationData(deps);
|
||||
const { getAllGroupInvitesAndJoinRequests } =
|
||||
useGroupModerationData(deps);
|
||||
await getAllGroupInvitesAndJoinRequests('grp_test');
|
||||
|
||||
expect(deps.tables.invites.data).toHaveLength(1);
|
||||
@@ -294,7 +324,10 @@ describe('useGroupModerationData', () => {
|
||||
test('parses multiple user IDs from input', async () => {
|
||||
const deps = createDeps();
|
||||
deps.groupRequest.getGroupMember.mockResolvedValue({
|
||||
json: { userId: 'usr_aaaa1111-2222-3333-4444-555566667777', user: { displayName: 'A' } },
|
||||
json: {
|
||||
userId: 'usr_aaaa1111-2222-3333-4444-555566667777',
|
||||
user: { displayName: 'A' }
|
||||
},
|
||||
params: {}
|
||||
});
|
||||
|
||||
@@ -344,7 +377,10 @@ describe('useGroupModerationData', () => {
|
||||
const { addGroupMemberToSelection } = useGroupModerationData(deps);
|
||||
await addGroupMemberToSelection('usr_1');
|
||||
|
||||
expect(deps.selection.setSelectedUsers).toHaveBeenCalledWith('usr_1', member);
|
||||
expect(deps.selection.setSelectedUsers).toHaveBeenCalledWith(
|
||||
'usr_1',
|
||||
member
|
||||
);
|
||||
expect(queryRequest.fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -362,11 +398,16 @@ describe('useGroupModerationData', () => {
|
||||
const { addGroupMemberToSelection } = useGroupModerationData(deps);
|
||||
await addGroupMemberToSelection('usr_1');
|
||||
|
||||
expect(queryRequest.fetch).toHaveBeenCalledWith('user.dialog', { userId: 'usr_1' });
|
||||
expect(deps.selection.setSelectedUsers).toHaveBeenCalledWith('usr_1', expect.objectContaining({
|
||||
userId: 'usr_1',
|
||||
displayName: 'Alice'
|
||||
}));
|
||||
expect(queryRequest.fetch).toHaveBeenCalledWith('user.dialog', {
|
||||
userId: 'usr_1'
|
||||
});
|
||||
expect(deps.selection.setSelectedUsers).toHaveBeenCalledWith(
|
||||
'usr_1',
|
||||
expect.objectContaining({
|
||||
userId: 'usr_1',
|
||||
displayName: 'Alice'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -395,7 +436,8 @@ describe('useGroupModerationData', () => {
|
||||
const deps = createDeps();
|
||||
deps.tables.members.data = [{ userId: 'usr_1' }];
|
||||
|
||||
const { groupMembersSearch, memberSearch, isGroupMembersLoading } = useGroupModerationData(deps);
|
||||
const { groupMembersSearch, memberSearch, isGroupMembersLoading } =
|
||||
useGroupModerationData(deps);
|
||||
memberSearch.value = 'ab';
|
||||
groupMembersSearch();
|
||||
|
||||
@@ -405,9 +447,13 @@ describe('useGroupModerationData', () => {
|
||||
|
||||
test('setGroupMemberSortOrder does nothing when sort is the same', async () => {
|
||||
const deps = createDeps();
|
||||
deps.groupRequest.getGroupMember.mockResolvedValue({ json: null, params: {} });
|
||||
deps.groupRequest.getGroupMember.mockResolvedValue({
|
||||
json: null,
|
||||
params: {}
|
||||
});
|
||||
|
||||
const { setGroupMemberSortOrder, memberSortOrder } = useGroupModerationData(deps);
|
||||
const { setGroupMemberSortOrder, memberSortOrder } =
|
||||
useGroupModerationData(deps);
|
||||
const currentSort = memberSortOrder.value;
|
||||
await setGroupMemberSortOrder(currentSort);
|
||||
|
||||
@@ -418,7 +464,8 @@ describe('useGroupModerationData', () => {
|
||||
test('setGroupMemberFilter does nothing when filter is the same', async () => {
|
||||
const deps = createDeps();
|
||||
|
||||
const { setGroupMemberFilter, memberFilter } = useGroupModerationData(deps);
|
||||
const { setGroupMemberFilter, memberFilter } =
|
||||
useGroupModerationData(deps);
|
||||
const currentFilter = memberFilter.value;
|
||||
await setGroupMemberFilter(currentFilter);
|
||||
|
||||
@@ -429,7 +476,8 @@ describe('useGroupModerationData', () => {
|
||||
describe('loadAllGroupMembers', () => {
|
||||
test('does nothing when already loading', async () => {
|
||||
const deps = createDeps();
|
||||
const { loadAllGroupMembers, isGroupMembersLoading } = useGroupModerationData(deps);
|
||||
const { loadAllGroupMembers, isGroupMembersLoading } =
|
||||
useGroupModerationData(deps);
|
||||
isGroupMembersLoading.value = true;
|
||||
|
||||
await loadAllGroupMembers();
|
||||
|
||||
@@ -174,11 +174,7 @@
|
||||
});
|
||||
};
|
||||
|
||||
addFriendGroup(
|
||||
'friendsInInstance',
|
||||
t('dialog.invite.friends_in_instance'),
|
||||
props.inviteDialog?.friendsInInstance
|
||||
);
|
||||
addFriendGroup('friendsInInstance', t('dialog.invite.friends_in_instance'), props.inviteDialog?.friendsInInstance);
|
||||
addFriendGroup('vip', t('side_panel.favorite'), vipFriends.value);
|
||||
addFriendGroup('online', t('side_panel.online'), onlineFriends.value);
|
||||
addFriendGroup('active', t('side_panel.active'), activeFriends.value);
|
||||
|
||||
@@ -47,13 +47,7 @@
|
||||
useUserStore,
|
||||
useVrcxStore
|
||||
} from '../../../stores';
|
||||
import {
|
||||
compareByCreatedAt,
|
||||
localeIncludes,
|
||||
parseLocation,
|
||||
removeFromArray,
|
||||
timeToText
|
||||
} from '../../../shared/utils';
|
||||
import { compareByCreatedAt, localeIncludes, parseLocation, removeFromArray, timeToText } from '../../../shared/utils';
|
||||
import { DataTableLayout } from '../../ui/data-table';
|
||||
import { createPreviousInstancesColumns } from './previousInstancesColumns.jsx';
|
||||
import { database } from '../../../services/database';
|
||||
@@ -176,9 +170,7 @@
|
||||
|
||||
function deleteGameLogInstancePrompt(row) {
|
||||
const description =
|
||||
props.variant === 'user'
|
||||
? 'Continue? Delete User From GameLog Instance'
|
||||
: 'Continue? Delete GameLog Instance';
|
||||
props.variant === 'user' ? 'Continue? Delete User From GameLog Instance' : 'Continue? Delete GameLog Instance';
|
||||
modalStore
|
||||
.confirm({
|
||||
description,
|
||||
|
||||
@@ -497,7 +497,7 @@
|
||||
useInstanceStore,
|
||||
useLocationStore,
|
||||
useModalStore,
|
||||
useUserStore,
|
||||
useUserStore
|
||||
} from '../../../stores';
|
||||
import { showWorldDialog } from '../../../coordinators/worldCoordinator';
|
||||
import { queryRequest, userRequest } from '../../../api';
|
||||
@@ -506,7 +506,6 @@
|
||||
import { showUserDialog } from '../../../coordinators/userCoordinator';
|
||||
import { showGroupDialog } from '../../../coordinators/groupCoordinator';
|
||||
|
||||
|
||||
const EditNoteAndMemoDialog = defineAsyncComponent(() => import('./EditNoteAndMemoDialog.vue'));
|
||||
|
||||
defineEmits(['showBioDialog']);
|
||||
|
||||
@@ -61,12 +61,7 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
compareByDisplayName,
|
||||
compareByFriendOrder,
|
||||
compareByLastActiveRef,
|
||||
userImage
|
||||
} from '../../../shared/utils';
|
||||
import { compareByDisplayName, compareByFriendOrder, compareByLastActiveRef, userImage } from '../../../shared/utils';
|
||||
import { database } from '../../../services/database';
|
||||
import { processBulk } from '../../../services/request';
|
||||
import { useOptionKeySelect } from '../../../composables/useOptionKeySelect';
|
||||
|
||||
@@ -249,13 +249,7 @@
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import {
|
||||
formatDateFilter,
|
||||
languageClass,
|
||||
openDiscordProfile,
|
||||
userImage,
|
||||
userStatusClass
|
||||
} from '../../../shared/utils';
|
||||
import { formatDateFilter, languageClass, openDiscordProfile, userImage, userStatusClass } from '../../../shared/utils';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';
|
||||
import { useGalleryStore, useUserStore } from '../../../stores';
|
||||
import { Badge } from '../../ui/badge';
|
||||
|
||||
@@ -2,20 +2,61 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const mocks = vi.hoisted(() => ({ saveUserMemo: vi.fn(), saveNote: vi.fn(async () => ({ json: { note: 'n1' }, params: { targetUserId: 'usr_1', note: 'n1' } })), getUser: vi.fn() }));
|
||||
const mocks = vi.hoisted(() => ({
|
||||
saveUserMemo: vi.fn(),
|
||||
saveNote: vi.fn(async () => ({
|
||||
json: { note: 'n1' },
|
||||
params: { targetUserId: 'usr_1', note: 'n1' }
|
||||
})),
|
||||
getUser: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useUserStore: () => ({ userDialog: ref({ id: 'usr_1', note: 'n1', memo: 'm1', ref: { id: 'usr_1', note: 'n1' } }), cachedUsers: new Map([['usr_1', { note: 'n1' }]]) }),
|
||||
useAppearanceSettingsStore: () => ({ hideUserNotes: ref(false), hideUserMemos: ref(false) })
|
||||
useUserStore: () => ({
|
||||
userDialog: ref({
|
||||
id: 'usr_1',
|
||||
note: 'n1',
|
||||
memo: 'm1',
|
||||
ref: { id: 'usr_1', note: 'n1' }
|
||||
}),
|
||||
cachedUsers: new Map([['usr_1', { note: 'n1' }]])
|
||||
}),
|
||||
useAppearanceSettingsStore: () => ({
|
||||
hideUserNotes: ref(false),
|
||||
hideUserMemos: ref(false)
|
||||
})
|
||||
}));
|
||||
vi.mock('../../../../api', () => ({
|
||||
miscRequest: { saveNote: (...a) => mocks.saveNote(...a) },
|
||||
userRequest: { getUser: (...a) => mocks.getUser(...a) }
|
||||
}));
|
||||
vi.mock('../../../../coordinators/memoCoordinator', () => ({
|
||||
saveUserMemo: (...a) => mocks.saveUserMemo(...a)
|
||||
}));
|
||||
vi.mock('../../../../api', () => ({ miscRequest: { saveNote: (...a) => mocks.saveNote(...a) }, userRequest: { getUser: (...a) => mocks.getUser(...a) } }));
|
||||
vi.mock('../../../../coordinators/memoCoordinator', () => ({ saveUserMemo: (...a) => mocks.saveUserMemo(...a) }));
|
||||
vi.mock('../../../../shared/utils', () => ({ replaceBioSymbols: (s) => s }));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/input-group', () => ({ InputGroupTextareaField: { props: ['modelValue'], emits: ['update:modelValue'], template: '<textarea />' } }));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/input-group', () => ({
|
||||
InputGroupTextareaField: {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
template: '<textarea />'
|
||||
}
|
||||
}));
|
||||
|
||||
import EditNoteAndMemoDialog from '../EditNoteAndMemoDialog.vue';
|
||||
|
||||
@@ -25,7 +66,9 @@ describe('EditNoteAndMemoDialog.vue', () => {
|
||||
});
|
||||
|
||||
it('emits close and saves memo on confirm', async () => {
|
||||
const wrapper = mount(EditNoteAndMemoDialog, { props: { visible: false } });
|
||||
const wrapper = mount(EditNoteAndMemoDialog, {
|
||||
props: { visible: false }
|
||||
});
|
||||
await wrapper.setProps({ visible: true });
|
||||
const buttons = wrapper.findAll('[data-testid="btn"]');
|
||||
await buttons[1].trigger('click');
|
||||
|
||||
@@ -5,14 +5,49 @@ import { ref } from 'vue';
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useUserStore: () => ({ userDialog: ref({ ref: { id: 'usr_2', $isModerator: false }, isFriend: false, isFavorite: false, incomingRequest: false, outgoingRequest: false, isBlock: false, isMute: false, isMuteChat: false, isInteractOff: false, isHideAvatar: false, isShowAvatar: false }), currentUser: ref({ id: 'usr_1', isBoopingEnabled: true }) }),
|
||||
useUserStore: () => ({
|
||||
userDialog: ref({
|
||||
ref: { id: 'usr_2', $isModerator: false },
|
||||
isFriend: false,
|
||||
isFavorite: false,
|
||||
incomingRequest: false,
|
||||
outgoingRequest: false,
|
||||
isBlock: false,
|
||||
isMute: false,
|
||||
isMuteChat: false,
|
||||
isInteractOff: false,
|
||||
isHideAvatar: false,
|
||||
isShowAvatar: false
|
||||
}),
|
||||
currentUser: ref({ id: 'usr_1', isBoopingEnabled: true })
|
||||
}),
|
||||
useGameStore: () => ({ isGameRunning: ref(false) }),
|
||||
useLocationStore: () => ({ lastLocation: ref({ location: 'wrld_1:1' }) })
|
||||
}));
|
||||
vi.mock('../../../../composables/useInviteChecks', () => ({ useInviteChecks: () => ({ checkCanInvite: () => true }) }));
|
||||
vi.mock('../../../ui/dropdown-menu', () => ({ DropdownMenu: { template: '<div><slot /></div>' }, DropdownMenuTrigger: { template: '<div><slot /></div>' }, DropdownMenuContent: { template: '<div><slot /></div>' }, DropdownMenuSeparator: { template: '<hr />' }, DropdownMenuItem: { emits: ['click'], template: '<button data-testid="dd-item" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('../../../ui/tooltip', () => ({ TooltipWrapper: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('../../../../composables/useInviteChecks', () => ({
|
||||
useInviteChecks: () => ({ checkCanInvite: () => true })
|
||||
}));
|
||||
vi.mock('../../../ui/dropdown-menu', () => ({
|
||||
DropdownMenu: { template: '<div><slot /></div>' },
|
||||
DropdownMenuTrigger: { template: '<div><slot /></div>' },
|
||||
DropdownMenuContent: { template: '<div><slot /></div>' },
|
||||
DropdownMenuSeparator: { template: '<hr />' },
|
||||
DropdownMenuItem: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="dd-item" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('../../../ui/tooltip', () => ({
|
||||
TooltipWrapper: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('lucide-vue-next', () => ({
|
||||
Check: { template: '<i />' },
|
||||
CheckCircle: { template: '<i />' },
|
||||
@@ -42,7 +77,9 @@ import UserActionDropdown from '../UserActionDropdown.vue';
|
||||
describe('UserActionDropdown.vue', () => {
|
||||
it('forwards command callback from dropdown item', async () => {
|
||||
const userDialogCommand = vi.fn();
|
||||
const wrapper = mount(UserActionDropdown, { props: { userDialogCommand } });
|
||||
const wrapper = mount(UserActionDropdown, {
|
||||
props: { userDialogCommand }
|
||||
});
|
||||
|
||||
await wrapper.findAll('[data-testid="dd-item"]')[0].trigger('click');
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => {
|
||||
const { ref } = require('vue');
|
||||
return {
|
||||
t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key),
|
||||
t: (key, params) =>
|
||||
params ? `${key}:${JSON.stringify(params)}` : key,
|
||||
locale: ref('en')
|
||||
};
|
||||
},
|
||||
@@ -242,7 +243,9 @@ describe('UserDialogInfoTab.vue', () => {
|
||||
test('renders imported InstanceActionBar and Spinner components when conditions are met', () => {
|
||||
const wrapper = mountComponent();
|
||||
|
||||
expect(wrapper.find('instance-action-bar-stub').exists()).toBe(true);
|
||||
expect(wrapper.find('instance-action-bar-stub').exists()).toBe(
|
||||
true
|
||||
);
|
||||
expect(wrapper.find('spinner-stub').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ vi.mock('vue-i18n', () => ({
|
||||
locale: require('vue').ref('en')
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { t: (key) => key , locale: require('vue').ref('en') },
|
||||
global: { t: (key) => key, locale: require('vue').ref('en') },
|
||||
install: vi.fn()
|
||||
})
|
||||
}));
|
||||
|
||||
@@ -6,15 +6,34 @@ const mocks = vi.hoisted(() => ({
|
||||
addFavorite: vi.fn(() => Promise.resolve()),
|
||||
deleteFavoriteNoConfirm: vi.fn(),
|
||||
toastSuccess: vi.fn(),
|
||||
favoriteDialog: { __v_isRef: true, value: { visible: true, type: 'friend', objectId: 'usr_1', currentGroup: null } }
|
||||
favoriteDialog: {
|
||||
__v_isRef: true,
|
||||
value: {
|
||||
visible: true,
|
||||
type: 'friend',
|
||||
objectId: 'usr_1',
|
||||
currentGroup: null
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('vue-sonner', () => ({ toast: { success: (...a) => mocks.toastSuccess(...a) } }));
|
||||
vi.mock('vue-sonner', () => ({
|
||||
toast: { success: (...a) => mocks.toastSuccess(...a) }
|
||||
}));
|
||||
vi.mock('../../../stores', () => ({
|
||||
useFavoriteStore: () => ({
|
||||
favoriteFriendGroups: ref([{ key: 'group_1', type: 'friend', name: 'group_1', displayName: 'G1', count: 0, capacity: 100 }]),
|
||||
favoriteFriendGroups: ref([
|
||||
{
|
||||
key: 'group_1',
|
||||
type: 'friend',
|
||||
name: 'group_1',
|
||||
displayName: 'G1',
|
||||
count: 0,
|
||||
capacity: 100
|
||||
}
|
||||
]),
|
||||
favoriteAvatarGroups: ref([]),
|
||||
favoriteWorldGroups: ref([]),
|
||||
favoriteDialog: mocks.favoriteDialog,
|
||||
@@ -31,9 +50,22 @@ vi.mock('../../../stores', () => ({
|
||||
}),
|
||||
useUserStore: () => ({ isLocalUserVrcPlusSupporter: ref(true) })
|
||||
}));
|
||||
vi.mock('../../../api', () => ({ favoriteRequest: { addFavorite: (...a) => mocks.addFavorite(...a) } }));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('../../../api', () => ({
|
||||
favoriteRequest: { addFavorite: (...a) => mocks.addFavorite(...a) }
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('lucide-vue-next', () => ({ Check: { template: '<i />' } }));
|
||||
|
||||
import ChooseFavoriteGroupDialog from '../ChooseFavoriteGroupDialog.vue';
|
||||
@@ -42,7 +74,12 @@ describe('ChooseFavoriteGroupDialog.vue', () => {
|
||||
beforeEach(() => {
|
||||
mocks.addFavorite.mockClear();
|
||||
mocks.toastSuccess.mockClear();
|
||||
mocks.favoriteDialog.value = { visible: true, type: 'friend', objectId: 'usr_1', currentGroup: null };
|
||||
mocks.favoriteDialog.value = {
|
||||
visible: true,
|
||||
type: 'friend',
|
||||
objectId: 'usr_1',
|
||||
currentGroup: null
|
||||
};
|
||||
});
|
||||
|
||||
it('runs delete action for current group', async () => {
|
||||
@@ -50,7 +87,12 @@ describe('ChooseFavoriteGroupDialog.vue', () => {
|
||||
visible: true,
|
||||
type: 'friend',
|
||||
objectId: 'usr_1',
|
||||
currentGroup: { key: 'group_1', displayName: 'G1', count: 0, capacity: 100 }
|
||||
currentGroup: {
|
||||
key: 'group_1',
|
||||
displayName: 'G1',
|
||||
count: 0,
|
||||
capacity: 100
|
||||
}
|
||||
};
|
||||
const wrapper = mount(ChooseFavoriteGroupDialog);
|
||||
await wrapper.get('[data-testid="btn"]').trigger('click');
|
||||
|
||||
@@ -5,8 +5,16 @@ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('@/shared/utils/common', () => ({ openExternalLink: vi.fn() }));
|
||||
vi.mock('../../../stores', () => ({
|
||||
useDashboardStore: () => ({
|
||||
createDashboard: vi.fn(async () => ({ id: 'dashboard-1', name: 'Dashboard', icon: 'ri-dashboard-line' })),
|
||||
getDashboard: vi.fn(() => ({ id: 'dashboard-1', name: 'Dashboard', icon: 'ri-dashboard-line' })),
|
||||
createDashboard: vi.fn(async () => ({
|
||||
id: 'dashboard-1',
|
||||
name: 'Dashboard',
|
||||
icon: 'ri-dashboard-line'
|
||||
})),
|
||||
getDashboard: vi.fn(() => ({
|
||||
id: 'dashboard-1',
|
||||
name: 'Dashboard',
|
||||
icon: 'ri-dashboard-line'
|
||||
})),
|
||||
updateDashboard: vi.fn(async () => {}),
|
||||
deleteDashboard: vi.fn(async () => {}),
|
||||
setEditingDashboardId: vi.fn()
|
||||
@@ -25,7 +33,8 @@ vi.mock('@/components/ui/dialog', () => ({
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/hover-card', () => ({
|
||||
@@ -37,17 +46,26 @@ vi.mock('@/components/ui/input-group', () => ({
|
||||
InputGroupButton: { template: '<button><slot /></button>' },
|
||||
InputGroupField: { template: '<input />' }
|
||||
}));
|
||||
vi.mock('@/components/ui/separator', () => ({ Separator: { template: '<hr />' } }));
|
||||
vi.mock('@/components/ui/separator', () => ({
|
||||
Separator: { template: '<hr />' }
|
||||
}));
|
||||
vi.mock('@/components/ui/tree', () => ({
|
||||
Tree: {
|
||||
props: ['items'],
|
||||
template: '<div><slot :flatten-items="[]" /></div>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@dnd-kit/vue', () => ({ DragDropProvider: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@dnd-kit/vue', () => ({
|
||||
DragDropProvider: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@dnd-kit/vue/sortable', () => ({ isSortable: () => false }));
|
||||
vi.mock('lucide-vue-next', () => new Proxy({}, { get: () => ({ template: '<i />' }) }));
|
||||
vi.mock('../SortableTreeNode.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock(
|
||||
'lucide-vue-next',
|
||||
() => new Proxy({}, { get: () => ({ template: '<i />' }) })
|
||||
);
|
||||
vi.mock('../SortableTreeNode.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
|
||||
import CustomNavDialog from '../CustomNavDialog.vue';
|
||||
|
||||
@@ -74,8 +92,12 @@ describe('CustomNavDialog.vue', () => {
|
||||
});
|
||||
|
||||
const buttons = wrapper.findAll('[data-testid="btn"]');
|
||||
const resetButton = buttons.find((button) => button.text().includes('nav_menu.custom_nav.restore_default'));
|
||||
const saveButton = buttons.find((button) => button.text().includes('common.actions.confirm'));
|
||||
const resetButton = buttons.find((button) =>
|
||||
button.text().includes('nav_menu.custom_nav.restore_default')
|
||||
);
|
||||
const saveButton = buttons.find((button) =>
|
||||
button.text().includes('common.actions.confirm')
|
||||
);
|
||||
|
||||
await resetButton.trigger('click');
|
||||
await saveButton.trigger('click');
|
||||
|
||||
@@ -19,13 +19,36 @@ vi.mock('../../composables/useImageCropper', () => ({
|
||||
getCroppedBlob: (...a) => mocks.getCroppedBlob(...a)
|
||||
})
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/slider', () => ({ Slider: { emits: ['value-commit'], template: '<div />' } }));
|
||||
vi.mock('@/components/ui/spinner', () => ({ Spinner: { template: '<div />' } }));
|
||||
vi.mock('@/components/ui/tooltip/TooltipWrapper.vue', () => ({ default: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('vue-advanced-cropper', () => ({ Cropper: { emits: ['change'], template: '<div />' } }));
|
||||
vi.mock('lucide-vue-next', () => new Proxy({}, { get: () => ({ template: '<i />' }) }));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/slider', () => ({
|
||||
Slider: { emits: ['value-commit'], template: '<div />' }
|
||||
}));
|
||||
vi.mock('@/components/ui/spinner', () => ({
|
||||
Spinner: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('@/components/ui/tooltip/TooltipWrapper.vue', () => ({
|
||||
default: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('vue-advanced-cropper', () => ({
|
||||
Cropper: { emits: ['change'], template: '<div />' }
|
||||
}));
|
||||
vi.mock(
|
||||
'lucide-vue-next',
|
||||
() => new Proxy({}, { get: () => ({ template: '<i />' }) })
|
||||
);
|
||||
|
||||
import ImageCropDialog from '../ImageCropDialog.vue';
|
||||
|
||||
|
||||
@@ -10,24 +10,71 @@ const mocks = vi.hoisted(() => ({
|
||||
setString: vi.fn(),
|
||||
getString: vi.fn(async () => ''),
|
||||
applyGroup: vi.fn((g) => g),
|
||||
inviteDialog: { __v_isRef: true, value: { visible: true, loading: false, groupId: 'grp_1', userId: '', userIds: ['usr_1'], groupName: '', userObject: null } }
|
||||
inviteDialog: {
|
||||
__v_isRef: true,
|
||||
value: {
|
||||
visible: true,
|
||||
loading: false,
|
||||
groupId: 'grp_1',
|
||||
userId: '',
|
||||
userIds: ['usr_1'],
|
||||
groupName: '',
|
||||
userObject: null
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('vue-sonner', () => ({ toast: { error: vi.fn() } }));
|
||||
vi.mock('../../../shared/utils', () => ({ hasGroupPermission: () => true }));
|
||||
vi.mock('../../../composables/useUserDisplay', () => ({ useUserDisplay: () => ({ userImage: () => '', userStatusClass: () => '' }) }));
|
||||
vi.mock('../../../composables/useUserDisplay', () => ({
|
||||
useUserDisplay: () => ({ userImage: () => '', userStatusClass: () => '' })
|
||||
}));
|
||||
vi.mock('../../../stores', () => ({
|
||||
useFriendStore: () => ({ vipFriends: ref([]), onlineFriends: ref([]), activeFriends: ref([]), offlineFriends: ref([]) }),
|
||||
useGroupStore: () => ({ currentUserGroups: ref(new Map()), inviteGroupDialog: mocks.inviteDialog, applyGroup: (...a) => mocks.applyGroup(...a) }),
|
||||
useFriendStore: () => ({
|
||||
vipFriends: ref([]),
|
||||
onlineFriends: ref([]),
|
||||
activeFriends: ref([]),
|
||||
offlineFriends: ref([])
|
||||
}),
|
||||
useGroupStore: () => ({
|
||||
currentUserGroups: ref(new Map()),
|
||||
inviteGroupDialog: mocks.inviteDialog,
|
||||
applyGroup: (...a) => mocks.applyGroup(...a)
|
||||
}),
|
||||
useModalStore: () => ({ confirm: (...a) => mocks.confirm(...a) })
|
||||
}));
|
||||
vi.mock('../../../api', () => ({ groupRequest: { sendGroupInvite: (...a) => mocks.sendGroupInvite(...a), getGroup: (...a) => mocks.getGroup(...a) }, queryRequest: { fetch: (...a) => mocks.fetch(...a) } }));
|
||||
vi.mock('../../../services/config', () => ({ default: { getString: (...a) => mocks.getString(...a), setString: (...a) => mocks.setString(...a) } }));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('../../ui/virtual-combobox', () => ({ VirtualCombobox: { template: '<div />' } }));
|
||||
vi.mock('../../../api', () => ({
|
||||
groupRequest: {
|
||||
sendGroupInvite: (...a) => mocks.sendGroupInvite(...a),
|
||||
getGroup: (...a) => mocks.getGroup(...a)
|
||||
},
|
||||
queryRequest: { fetch: (...a) => mocks.fetch(...a) }
|
||||
}));
|
||||
vi.mock('../../../services/config', () => ({
|
||||
default: {
|
||||
getString: (...a) => mocks.getString(...a),
|
||||
setString: (...a) => mocks.setString(...a)
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('../../ui/virtual-combobox', () => ({
|
||||
VirtualCombobox: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('lucide-vue-next', () => ({ Check: { template: '<i />' } }));
|
||||
|
||||
import InviteGroupDialog from '../InviteGroupDialog.vue';
|
||||
|
||||
@@ -6,10 +6,19 @@ const mocks = vi.hoisted(() => ({
|
||||
selfInvite: vi.fn(async () => ({})),
|
||||
writeText: vi.fn(),
|
||||
getBool: vi.fn(async () => false),
|
||||
launchDialogData: { value: { visible: true, loading: true, tag: 'wrld_1:123', shortName: 'abc' } }
|
||||
launchDialogData: {
|
||||
value: {
|
||||
visible: true,
|
||||
loading: true,
|
||||
tag: 'wrld_1:123',
|
||||
shortName: 'abc'
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Object.assign(globalThis, { navigator: { clipboard: { writeText: (...a) => mocks.writeText(...a) } } });
|
||||
Object.assign(globalThis, {
|
||||
navigator: { clipboard: { writeText: (...a) => mocks.writeText(...a) } }
|
||||
});
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
@@ -18,27 +27,81 @@ vi.mock('../../../stores', () => ({
|
||||
useFriendStore: () => ({ friends: ref(new Map()) }),
|
||||
useGameStore: () => ({ isGameRunning: ref(false) }),
|
||||
useInviteStore: () => ({ canOpenInstanceInGame: ref(false) }),
|
||||
useLaunchStore: () => ({ launchDialogData: mocks.launchDialogData, launchGame: vi.fn(), tryOpenInstanceInVrc: vi.fn() }),
|
||||
useLaunchStore: () => ({
|
||||
launchDialogData: mocks.launchDialogData,
|
||||
launchGame: vi.fn(),
|
||||
tryOpenInstanceInVrc: vi.fn()
|
||||
}),
|
||||
useLocationStore: () => ({ lastLocation: ref({ friendList: new Map() }) }),
|
||||
useModalStore: () => ({ confirm: vi.fn() })
|
||||
}));
|
||||
vi.mock('../../../shared/utils', () => ({
|
||||
getLaunchURL: () => 'vrchat://launch',
|
||||
isRealInstance: () => true,
|
||||
parseLocation: () => ({ isRealInstance: true, worldId: 'wrld_1', instanceId: '123', tag: 'wrld_1:123' })
|
||||
parseLocation: () => ({
|
||||
isRealInstance: true,
|
||||
worldId: 'wrld_1',
|
||||
instanceId: '123',
|
||||
tag: 'wrld_1:123'
|
||||
})
|
||||
}));
|
||||
vi.mock('../../../composables/useInviteChecks', () => ({
|
||||
useInviteChecks: () => ({ checkCanInvite: () => true })
|
||||
}));
|
||||
vi.mock('../../../api', () => ({
|
||||
instanceRequest: {
|
||||
selfInvite: (...a) => mocks.selfInvite(...a),
|
||||
getInstanceShortName: vi.fn()
|
||||
},
|
||||
queryRequest: { fetch: vi.fn() }
|
||||
}));
|
||||
vi.mock('../../../services/config', () => ({
|
||||
default: { getBool: (...a) => mocks.getBool(...a), setBool: vi.fn() }
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogDescription: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/dropdown-menu', () => ({
|
||||
DropdownMenu: { template: '<div><slot /></div>' },
|
||||
DropdownMenuTrigger: { template: '<div><slot /></div>' },
|
||||
DropdownMenuContent: { template: '<div><slot /></div>' },
|
||||
DropdownMenuItem: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/field', () => ({
|
||||
Field: { template: '<div><slot /></div>' },
|
||||
FieldGroup: { template: '<div><slot /></div>' },
|
||||
FieldLabel: { template: '<div><slot /></div>' },
|
||||
FieldContent: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/button-group', () => ({
|
||||
ButtonGroup: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/input-group', () => ({
|
||||
InputGroupField: { template: '<input />' }
|
||||
}));
|
||||
vi.mock('@/components/ui/tooltip', () => ({
|
||||
TooltipWrapper: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('../InviteDialog/InviteDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('lucide-vue-next', () => ({
|
||||
Copy: { template: '<i />' },
|
||||
Info: { template: '<i />' },
|
||||
MoreHorizontal: { template: '<i />' }
|
||||
}));
|
||||
vi.mock('../../../composables/useInviteChecks', () => ({ useInviteChecks: () => ({ checkCanInvite: () => true }) }));
|
||||
vi.mock('../../../api', () => ({ instanceRequest: { selfInvite: (...a) => mocks.selfInvite(...a), getInstanceShortName: vi.fn() }, queryRequest: { fetch: vi.fn() } }));
|
||||
vi.mock('../../../services/config', () => ({ default: { getBool: (...a) => mocks.getBool(...a), setBool: vi.fn() } }));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogDescription: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/dropdown-menu', () => ({ DropdownMenu: { template: '<div><slot /></div>' }, DropdownMenuTrigger: { template: '<div><slot /></div>' }, DropdownMenuContent: { template: '<div><slot /></div>' }, DropdownMenuItem: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/field', () => ({ Field: { template: '<div><slot /></div>' }, FieldGroup: { template: '<div><slot /></div>' }, FieldLabel: { template: '<div><slot /></div>' }, FieldContent: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/button-group', () => ({ ButtonGroup: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/input-group', () => ({ InputGroupField: { template: '<input />' } }));
|
||||
vi.mock('@/components/ui/tooltip', () => ({ TooltipWrapper: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('../InviteDialog/InviteDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('lucide-vue-next', () => ({ Copy: { template: '<i />' }, Info: { template: '<i />' }, MoreHorizontal: { template: '<i />' } }));
|
||||
|
||||
import LaunchDialog from '../LaunchDialog.vue';
|
||||
|
||||
|
||||
@@ -5,31 +5,83 @@ import { ref } from 'vue';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
closeMainDialog: vi.fn(),
|
||||
handleBreadcrumbClick: vi.fn(),
|
||||
dialogCrumbs: { value: [{ type: 'user', id: 'u1', label: 'User' }, { type: 'world', id: 'w1', label: 'World' }] },
|
||||
dialogCrumbs: {
|
||||
value: [
|
||||
{ type: 'user', id: 'u1', label: 'User' },
|
||||
{ type: 'world', id: 'w1', label: 'World' }
|
||||
]
|
||||
},
|
||||
userVisible: { value: true }
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('@/stores', () => ({
|
||||
useUiStore: () => ({ dialogCrumbs: mocks.dialogCrumbs.value, closeMainDialog: (...a) => mocks.closeMainDialog(...a), handleBreadcrumbClick: (...a) => mocks.handleBreadcrumbClick(...a) }),
|
||||
useUiStore: () => ({
|
||||
dialogCrumbs: mocks.dialogCrumbs.value,
|
||||
closeMainDialog: (...a) => mocks.closeMainDialog(...a),
|
||||
handleBreadcrumbClick: (...a) => mocks.handleBreadcrumbClick(...a)
|
||||
}),
|
||||
useUserStore: () => ({ userDialog: { visible: mocks.userVisible.value } }),
|
||||
useWorldStore: () => ({ worldDialog: { visible: false } }),
|
||||
useAvatarStore: () => ({ avatarDialog: { visible: false } }),
|
||||
useGroupStore: () => ({ groupDialog: { visible: false } }),
|
||||
useInstanceStore: () => ({ previousInstancesInfoDialog: ref({ visible: false }), previousInstancesListDialog: ref({ visible: false, variant: 'user' }) })
|
||||
useInstanceStore: () => ({
|
||||
previousInstancesInfoDialog: ref({ visible: false }),
|
||||
previousInstancesListDialog: ref({ visible: false, variant: 'user' })
|
||||
})
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/breadcrumb', () => ({
|
||||
Breadcrumb: { template: '<div><slot /></div>' },
|
||||
BreadcrumbList: { template: '<div><slot /></div>' },
|
||||
BreadcrumbItem: { template: '<div><slot /></div>' },
|
||||
BreadcrumbLink: { template: '<div><slot /></div>' },
|
||||
BreadcrumbSeparator: { template: '<span>/</span>' },
|
||||
BreadcrumbPage: { template: '<span><slot /></span>' },
|
||||
BreadcrumbEllipsis: { template: '<span>...</span>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/dropdown-menu', () => ({
|
||||
DropdownMenu: { template: '<div><slot /></div>' },
|
||||
DropdownMenuTrigger: { template: '<div><slot /></div>' },
|
||||
DropdownMenuContent: { template: '<div><slot /></div>' },
|
||||
DropdownMenuItem: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="crumb-dd" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/tooltip', () => ({
|
||||
TooltipWrapper: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/breadcrumb', () => ({ Breadcrumb: { template: '<div><slot /></div>' }, BreadcrumbList: { template: '<div><slot /></div>' }, BreadcrumbItem: { template: '<div><slot /></div>' }, BreadcrumbLink: { template: '<div><slot /></div>' }, BreadcrumbSeparator: { template: '<span>/</span>' }, BreadcrumbPage: { template: '<span><slot /></span>' }, BreadcrumbEllipsis: { template: '<span>...</span>' } }));
|
||||
vi.mock('@/components/ui/dropdown-menu', () => ({ DropdownMenu: { template: '<div><slot /></div>' }, DropdownMenuTrigger: { template: '<div><slot /></div>' }, DropdownMenuContent: { template: '<div><slot /></div>' }, DropdownMenuItem: { emits: ['click'], template: '<button data-testid="crumb-dd" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/tooltip', () => ({ TooltipWrapper: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('lucide-vue-next', () => ({ ArrowLeft: { template: '<i />' } }));
|
||||
vi.mock('../AvatarDialog/AvatarDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('../GroupDialog/GroupDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('../PreviousInstancesDialog/PreviousInstancesInfoDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('../PreviousInstancesDialog/PreviousInstancesListDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('../UserDialog/UserDialog.vue', () => ({ default: { template: '<div data-testid="user-dialog" />' } }));
|
||||
vi.mock('../WorldDialog/WorldDialog.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('../AvatarDialog/AvatarDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('../GroupDialog/GroupDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('../PreviousInstancesDialog/PreviousInstancesInfoDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('../PreviousInstancesDialog/PreviousInstancesListDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('../UserDialog/UserDialog.vue', () => ({
|
||||
default: { template: '<div data-testid="user-dialog" />' }
|
||||
}));
|
||||
vi.mock('../WorldDialog/WorldDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
|
||||
import MainDialogContainer from '../MainDialogContainer.vue';
|
||||
|
||||
|
||||
@@ -9,16 +9,47 @@ const mocks = vi.hoisted(() => ({
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (k) => k }) }));
|
||||
vi.mock('../../../api', () => ({ miscRequest: { sendBoop: (...a) => mocks.sendBoop(...a) }, notificationRequest: { hideNotificationV2: vi.fn() }, queryRequest: { fetch: (...a) => mocks.fetch(...a) } }));
|
||||
vi.mock('../../../stores', () => ({
|
||||
useUserStore: () => ({ sendBoopDialog: mocks.boopDialog, isLocalUserVrcPlusSupporter: { value: false } }),
|
||||
useNotificationStore: () => ({ notificationTable: { value: { data: [] } }, isNotificationExpired: () => false, handleNotificationV2Hide: vi.fn() }),
|
||||
useGalleryStore: () => ({ showGalleryPage: vi.fn(), refreshEmojiTable: vi.fn(), emojiTable: { value: [] } })
|
||||
vi.mock('../../../api', () => ({
|
||||
miscRequest: { sendBoop: (...a) => mocks.sendBoop(...a) },
|
||||
notificationRequest: { hideNotificationV2: vi.fn() },
|
||||
queryRequest: { fetch: (...a) => mocks.fetch(...a) }
|
||||
}));
|
||||
vi.mock('../../../stores', () => ({
|
||||
useUserStore: () => ({
|
||||
sendBoopDialog: mocks.boopDialog,
|
||||
isLocalUserVrcPlusSupporter: { value: false }
|
||||
}),
|
||||
useNotificationStore: () => ({
|
||||
notificationTable: { value: { data: [] } },
|
||||
isNotificationExpired: () => false,
|
||||
handleNotificationV2Hide: vi.fn()
|
||||
}),
|
||||
useGalleryStore: () => ({
|
||||
showGalleryPage: vi.fn(),
|
||||
refreshEmojiTable: vi.fn(),
|
||||
emojiTable: { value: [] }
|
||||
})
|
||||
}));
|
||||
vi.mock('../../../shared/constants/photon.js', () => ({
|
||||
photonEmojis: ['Wave']
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('../../ui/virtual-combobox', () => ({
|
||||
VirtualCombobox: { template: '<div />' }
|
||||
}));
|
||||
vi.mock('../../../shared/constants/photon.js', () => ({ photonEmojis: ['Wave'] }));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('../../ui/virtual-combobox', () => ({ VirtualCombobox: { template: '<div />' } }));
|
||||
vi.mock('../../Emoji.vue', () => ({ default: { template: '<div />' } }));
|
||||
vi.mock('lucide-vue-next', () => ({ Check: { template: '<i />' } }));
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import { mount } from '@vue/test-utils';
|
||||
const mocks = vi.hoisted(() => ({
|
||||
close: vi.fn(),
|
||||
save: vi.fn(),
|
||||
dialog: { value: { visible: true, maxTableSize: '1000', searchLimit: '100' } }
|
||||
dialog: {
|
||||
value: { visible: true, maxTableSize: '1000', searchLimit: '100' }
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (i) => ({ ...(await i()), storeToRefs: (s) => s }));
|
||||
@@ -20,10 +22,30 @@ vi.mock('../../../stores', () => ({
|
||||
SEARCH_LIMIT_MAX: 1000
|
||||
})
|
||||
}));
|
||||
vi.mock('@/components/ui/dialog', () => ({ Dialog: { template: '<div><slot /></div>' }, DialogContent: { template: '<div><slot /></div>' }, DialogHeader: { template: '<div><slot /></div>' }, DialogTitle: { template: '<div><slot /></div>' }, DialogDescription: { template: '<div><slot /></div>' }, DialogFooter: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/field', () => ({ Field: { template: '<div><slot /></div>' }, FieldGroup: { template: '<div><slot /></div>' }, FieldLabel: { template: '<div><slot /></div>' }, FieldContent: { template: '<div><slot /></div>' } }));
|
||||
vi.mock('@/components/ui/button', () => ({ Button: { emits: ['click'], template: '<button data-testid="btn" :disabled="$attrs.disabled" @click="$emit(\'click\')"><slot /></button>' } }));
|
||||
vi.mock('@/components/ui/input-group', () => ({ InputGroupField: { template: '<input />' } }));
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: { template: '<div><slot /></div>' },
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' },
|
||||
DialogDescription: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/field', () => ({
|
||||
Field: { template: '<div><slot /></div>' },
|
||||
FieldGroup: { template: '<div><slot /></div>' },
|
||||
FieldLabel: { template: '<div><slot /></div>' },
|
||||
FieldContent: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="btn" :disabled="$attrs.disabled" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
vi.mock('@/components/ui/input-group', () => ({
|
||||
InputGroupField: { template: '<input />' }
|
||||
}));
|
||||
|
||||
import TableLimitsDialog from '../TableLimitsDialog.vue';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user