mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
fix style
This commit is contained in:
@@ -781,7 +781,7 @@
|
||||
* @param row
|
||||
*/
|
||||
function handleRowClick(row) {
|
||||
handleWearAvatar(row.original.id);
|
||||
handleShowAvatarDialog(row.original.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../shared/constants', () => ({
|
||||
TAG_COLORS: [
|
||||
{
|
||||
name: 'blue',
|
||||
label: 'Blue',
|
||||
bg: 'hsl(210 100% 50% / 0.2)',
|
||||
text: 'hsl(210 100% 40%)'
|
||||
}
|
||||
],
|
||||
getTagColor: () => ({
|
||||
name: 'blue',
|
||||
bg: 'hsl(210 100% 50% / 0.2)',
|
||||
text: 'hsl(210 100% 40%)'
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/dialog', () => ({
|
||||
Dialog: {
|
||||
props: ['open'],
|
||||
emits: ['update:open'],
|
||||
template: '<div><slot /></div>'
|
||||
},
|
||||
DialogContent: { template: '<div><slot /></div>' },
|
||||
DialogDescription: { template: '<div><slot /></div>' },
|
||||
DialogFooter: { template: '<div><slot /></div>' },
|
||||
DialogHeader: { template: '<div><slot /></div>' },
|
||||
DialogTitle: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/popover', () => ({
|
||||
Popover: { template: '<div><slot /></div>' },
|
||||
PopoverContent: { template: '<div><slot /></div>' },
|
||||
PopoverTrigger: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template: '<button data-testid="button" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/tags-input', () => ({
|
||||
TagsInput: {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
template: '<div><slot /></div>'
|
||||
},
|
||||
TagsInputInput: {
|
||||
template: '<input data-testid="tags-input" />'
|
||||
},
|
||||
TagsInputItem: {
|
||||
props: ['value'],
|
||||
template: '<span data-testid="tag-item"><slot />{{ value }}</span>'
|
||||
},
|
||||
TagsInputItemDelete: { template: '<span>x</span>' },
|
||||
TagsInputItemText: { template: '<span />' }
|
||||
}));
|
||||
|
||||
import ManageTagsDialog from '../ManageTagsDialog.vue';
|
||||
|
||||
function mountDialog(props = {}) {
|
||||
return mount(ManageTagsDialog, {
|
||||
props: {
|
||||
open: false,
|
||||
avatarName: 'Test Avatar',
|
||||
avatarId: 'avtr_1',
|
||||
initialTags: [],
|
||||
...props
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('ManageTagsDialog.vue', () => {
|
||||
test('loads initial tags when dialog opens', async () => {
|
||||
const wrapper = mountDialog({
|
||||
initialTags: [{ tag: 'cute', color: null }]
|
||||
});
|
||||
|
||||
await wrapper.setProps({ open: true });
|
||||
await nextTick();
|
||||
|
||||
const tags = wrapper.findAll('[data-testid="tag-item"]');
|
||||
expect(tags).toHaveLength(1);
|
||||
expect(tags[0].text()).toContain('cute');
|
||||
});
|
||||
|
||||
test('emits save payload and closes dialog', async () => {
|
||||
const wrapper = mountDialog({
|
||||
initialTags: [{ tag: 'cute', color: null }]
|
||||
});
|
||||
|
||||
await wrapper.setProps({ open: true });
|
||||
await nextTick();
|
||||
|
||||
const okButton = wrapper
|
||||
.findAll('[data-testid="button"]')
|
||||
.find((node) => node.text().includes('prompt.rename_avatar.ok'));
|
||||
|
||||
expect(okButton).toBeTruthy();
|
||||
await okButton.trigger('click');
|
||||
|
||||
expect(wrapper.emitted('save')).toBeTruthy();
|
||||
expect(wrapper.emitted('save')[0][0]).toEqual({
|
||||
avatarId: 'avtr_1',
|
||||
tags: [{ tag: 'cute', color: null }]
|
||||
});
|
||||
expect(wrapper.emitted('update:open')).toBeTruthy();
|
||||
expect(wrapper.emitted('update:open').at(-1)).toEqual([false]);
|
||||
});
|
||||
|
||||
test('cancel button closes dialog without save', async () => {
|
||||
const wrapper = mountDialog();
|
||||
|
||||
const cancelButton = wrapper
|
||||
.findAll('[data-testid="button"]')
|
||||
.find((node) => node.text().includes('prompt.rename_avatar.cancel'));
|
||||
|
||||
expect(cancelButton).toBeTruthy();
|
||||
await cancelButton.trigger('click');
|
||||
|
||||
expect(wrapper.emitted('save')).toBeFalsy();
|
||||
expect(wrapper.emitted('update:open')).toBeTruthy();
|
||||
expect(wrapper.emitted('update:open').at(-1)).toEqual([false]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,341 @@
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { nextTick, ref } from 'vue';
|
||||
import { flushPromises, mount } from '@vue/test-utils';
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
currentUser: { value: { currentAvatar: 'avtr_current', $previousAvatarSwapTime: 0 }, __v_isRef: true },
|
||||
modalConfirm: vi.fn(),
|
||||
configGetString: vi.fn(),
|
||||
configSetString: vi.fn(),
|
||||
processBulk: vi.fn(),
|
||||
applyAvatar: vi.fn((json) => ({ ...json })),
|
||||
selectAvatarWithoutConfirmation: vi.fn(),
|
||||
showAvatarDialog: vi.fn(),
|
||||
getAllAvatarTags: vi.fn(),
|
||||
getAvatarTimeSpent: vi.fn(),
|
||||
virtualMeasure: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('pinia', async (importOriginal) => {
|
||||
const actual = await importOriginal();
|
||||
return {
|
||||
...actual,
|
||||
storeToRefs: (store) => store
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('vue-sonner', () => ({
|
||||
toast: {
|
||||
success: vi.fn(),
|
||||
error: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../../../plugins/router', () => ({
|
||||
router: {
|
||||
push: vi.fn(),
|
||||
replace: vi.fn(),
|
||||
beforeEach: vi.fn(),
|
||||
currentRoute: ref({ path: '/', name: '' }),
|
||||
isReady: vi.fn().mockResolvedValue(true)
|
||||
},
|
||||
initRouter: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('@tanstack/vue-virtual', () => ({
|
||||
useVirtualizer: () => ({
|
||||
value: {
|
||||
getVirtualItems: () => [{ key: 0, index: 0, start: 0 }],
|
||||
getTotalSize: () => 100,
|
||||
measure: (...args) => mocks.virtualMeasure(...args),
|
||||
measureElement: vi.fn()
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../stores', () => ({
|
||||
useAppearanceSettingsStore: () => ({
|
||||
tablePageSizes: [10, 25, 50],
|
||||
tablePageSize: 25
|
||||
}),
|
||||
useAvatarStore: () => ({}),
|
||||
useModalStore: () => ({
|
||||
confirm: (...args) => mocks.modalConfirm(...args),
|
||||
prompt: vi.fn()
|
||||
}),
|
||||
useUserStore: () => ({
|
||||
currentUser: mocks.currentUser
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../coordinators/avatarCoordinator', () => ({
|
||||
applyAvatar: (...args) => mocks.applyAvatar(...args),
|
||||
selectAvatarWithoutConfirmation: (...args) => mocks.selectAvatarWithoutConfirmation(...args),
|
||||
showAvatarDialog: (...args) => mocks.showAvatarDialog(...args)
|
||||
}));
|
||||
|
||||
vi.mock('../../../coordinators/imageUploadCoordinator', () => ({
|
||||
handleImageUploadInput: () => ({ file: null, clearInput: vi.fn() }),
|
||||
resizeImageToFitLimits: vi.fn(),
|
||||
uploadImageLegacy: vi.fn()
|
||||
}));
|
||||
|
||||
vi.mock('../../../shared/utils/imageUpload', () => ({
|
||||
readFileAsBase64: vi.fn(),
|
||||
withUploadTimeout: async (promise) => promise
|
||||
}));
|
||||
|
||||
vi.mock('../../../api', () => ({
|
||||
avatarRequest: {
|
||||
getAvatars: vi.fn(),
|
||||
saveAvatar: vi.fn(),
|
||||
createImposter: vi.fn(),
|
||||
uploadAvatarImage: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../../../services/database', () => ({
|
||||
database: {
|
||||
getAllAvatarTags: (...args) => mocks.getAllAvatarTags(...args),
|
||||
getAvatarTimeSpent: (...args) => mocks.getAvatarTimeSpent(...args),
|
||||
addAvatarTag: vi.fn(),
|
||||
removeAvatarTag: vi.fn(),
|
||||
updateAvatarTagColor: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../columns.jsx', () => ({
|
||||
getColumns: () => []
|
||||
}));
|
||||
|
||||
vi.mock('../../../shared/utils/avatar', () => ({
|
||||
getPlatformInfo: () => ({})
|
||||
}));
|
||||
|
||||
vi.mock('../../../shared/constants', () => ({
|
||||
getTagColor: () => ({ bg: '#000', text: '#fff' })
|
||||
}));
|
||||
|
||||
vi.mock('../../../services/request', () => ({
|
||||
processBulk: (...args) => mocks.processBulk(...args)
|
||||
}));
|
||||
|
||||
vi.mock('../composables/useAvatarCardGrid.js', () => ({
|
||||
useAvatarCardGrid: () => ({
|
||||
cardScale: ref(0.6),
|
||||
cardSpacing: ref(1),
|
||||
cardScalePercent: ref(60),
|
||||
cardSpacingPercent: ref(100),
|
||||
cardScaleValue: ref([0.6]),
|
||||
cardSpacingValue: ref([1]),
|
||||
scaleSlider: { min: 0.3, max: 0.9, step: 0.05 },
|
||||
spacingSlider: { min: 0.5, max: 1.5, step: 0.05 },
|
||||
gridContainerRef: ref(null),
|
||||
gridStyle: ref(() => ({ '--avatar-grid-columns': '1' })),
|
||||
chunkIntoRows: (items, prefix = 'row') =>
|
||||
Array.isArray(items)
|
||||
? items.map((item, index) => ({ key: `${prefix}:${index}`, items: [item] }))
|
||||
: [],
|
||||
estimateRowHeight: () => 80,
|
||||
updateContainerWidth: vi.fn()
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../composables/useDataTableScrollHeight', () => ({
|
||||
useDataTableScrollHeight: () => ({
|
||||
tableStyle: {}
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../lib/table/useVrcxVueTable', () => ({
|
||||
useVrcxVueTable: () => ({
|
||||
table: {},
|
||||
pagination: ref({ pageIndex: 0, pageSize: 25 })
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../services/config.js', () => ({
|
||||
default: {
|
||||
getString: (...args) => mocks.configGetString(...args),
|
||||
setString: (...args) => mocks.configSetString(...args)
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/context-menu', () => ({
|
||||
ContextMenuContent: { template: '<div><slot /></div>' },
|
||||
ContextMenuItem: { template: '<button><slot /></button>' },
|
||||
ContextMenuSeparator: { template: '<hr />' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/dropdown-menu', () => ({
|
||||
DropdownMenu: { template: '<div><slot /></div>' },
|
||||
DropdownMenuContent: { template: '<div><slot /></div>' },
|
||||
DropdownMenuTrigger: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/field', () => ({
|
||||
Field: { template: '<div><slot /></div>' },
|
||||
FieldContent: { template: '<div><slot /></div>' },
|
||||
FieldLabel: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/popover', () => ({
|
||||
Popover: { template: '<div><slot /></div>' },
|
||||
PopoverContent: { template: '<div><slot /></div>' },
|
||||
PopoverTrigger: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/data-table', () => ({
|
||||
DataTableEmpty: { template: '<div data-testid="empty">empty</div>' },
|
||||
DataTableLayout: { template: '<div data-testid="table-layout">table</div>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/toggle-group', () => ({
|
||||
ToggleGroup: {
|
||||
emits: ['update:model-value'],
|
||||
template:
|
||||
'<div data-testid="toggle-group">' +
|
||||
'<button data-testid="set-table" @click="$emit(\'update:model-value\', \'table\')">table</button>' +
|
||||
'<slot />' +
|
||||
'</div>'
|
||||
},
|
||||
ToggleGroupItem: { template: '<button><slot /></button>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/badge', () => ({
|
||||
Badge: { template: '<span><slot /></span>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template: '<button data-testid="button" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/input', () => ({
|
||||
Input: {
|
||||
props: ['modelValue'],
|
||||
emits: ['update:modelValue'],
|
||||
template:
|
||||
'<input data-testid="search-input" :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/slider', () => ({
|
||||
Slider: { template: '<div />' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/ui/tooltip', () => ({
|
||||
TooltipWrapper: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('../../../components/dialogs/ImageCropDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
|
||||
vi.mock('../ManageTagsDialog.vue', () => ({
|
||||
default: { template: '<div />' }
|
||||
}));
|
||||
|
||||
vi.mock('../components/MyAvatarCard.vue', () => ({
|
||||
default: {
|
||||
props: ['avatar'],
|
||||
emits: ['click', 'context-action'],
|
||||
template: '<button data-testid="avatar-card" @click="$emit(\'click\')">{{ avatar.name }}</button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('lucide-vue-next', () => ({
|
||||
Check: { template: '<i />' },
|
||||
Eye: { template: '<i />' },
|
||||
Image: { template: '<i />' },
|
||||
LayoutGrid: { template: '<i />' },
|
||||
List: { template: '<i />' },
|
||||
ListFilter: { template: '<i />' },
|
||||
Pencil: { template: '<i />' },
|
||||
RefreshCw: { template: '<i />' },
|
||||
Settings: { template: '<i />' },
|
||||
Tag: { template: '<i />' },
|
||||
User: { template: '<i />' }
|
||||
}));
|
||||
|
||||
import MyAvatars from '../MyAvatars.vue';
|
||||
|
||||
async function flushAll() {
|
||||
await flushPromises();
|
||||
await nextTick();
|
||||
await nextTick();
|
||||
}
|
||||
|
||||
describe('MyAvatars.vue', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
mocks.currentUser.value = { currentAvatar: 'avtr_current', $previousAvatarSwapTime: 0 };
|
||||
mocks.modalConfirm.mockResolvedValue({ ok: true });
|
||||
mocks.configGetString.mockImplementation((key, defaultValue) => {
|
||||
if (key === 'VRCX_MyAvatarsViewMode') {
|
||||
return Promise.resolve('grid');
|
||||
}
|
||||
return Promise.resolve(defaultValue ?? '');
|
||||
});
|
||||
mocks.getAllAvatarTags.mockResolvedValue(new Map([['avtr_1', [{ tag: 'fun', color: null }]]]));
|
||||
mocks.getAvatarTimeSpent.mockResolvedValue({ timeSpent: 1000 });
|
||||
mocks.processBulk.mockImplementation(async ({ handle, done }) => {
|
||||
handle({
|
||||
json: [
|
||||
{
|
||||
id: 'avtr_1',
|
||||
name: 'Avatar One',
|
||||
releaseStatus: 'public',
|
||||
unityPackages: [],
|
||||
updated_at: '2025-01-01T00:00:00.000Z',
|
||||
created_at: '2024-01-01T00:00:00.000Z'
|
||||
}
|
||||
]
|
||||
});
|
||||
await done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loads table view mode from config', async () => {
|
||||
mocks.configGetString.mockImplementation((key, defaultValue) => {
|
||||
if (key === 'VRCX_MyAvatarsViewMode') {
|
||||
return Promise.resolve('table');
|
||||
}
|
||||
return Promise.resolve(defaultValue ?? '');
|
||||
});
|
||||
|
||||
const wrapper = mount(MyAvatars);
|
||||
await flushAll();
|
||||
|
||||
expect(wrapper.find('[data-testid="table-layout"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('persists view mode when toggled', async () => {
|
||||
const wrapper = mount(MyAvatars);
|
||||
await flushAll();
|
||||
|
||||
await wrapper.get('[data-testid="set-table"]').trigger('click');
|
||||
|
||||
expect(mocks.configSetString).toHaveBeenCalledWith('VRCX_MyAvatarsViewMode', 'table');
|
||||
});
|
||||
|
||||
test('confirms and selects avatar when grid card is clicked', async () => {
|
||||
const wrapper = mount(MyAvatars);
|
||||
await flushAll();
|
||||
|
||||
await wrapper.get('[data-testid="avatar-card"]').trigger('click');
|
||||
await flushAll();
|
||||
|
||||
expect(mocks.modalConfirm).toHaveBeenCalled();
|
||||
expect(mocks.selectAvatarWithoutConfirmation).toHaveBeenCalledWith('avtr_1');
|
||||
});
|
||||
});
|
||||
@@ -76,7 +76,7 @@ export function getColumns({
|
||||
'h-4 w-4',
|
||||
isActive
|
||||
? 'text-primary'
|
||||
: 'text-muted-foreground/0 group-hover/row:text-muted-foreground'
|
||||
: 'text-muted-foreground/0'
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../../shared/utils', () => ({
|
||||
formatDateFilter: () => 'formatted-date',
|
||||
getAvailablePlatforms: () => ({ isPC: true, isQuest: true, isIos: false }),
|
||||
getPlatformInfo: () => ({
|
||||
pc: { performanceRating: 'Good' },
|
||||
android: { performanceRating: 'Medium' },
|
||||
ios: { performanceRating: '' }
|
||||
}),
|
||||
timeToText: () => '1h'
|
||||
}));
|
||||
|
||||
vi.mock('../../../../shared/constants', () => ({
|
||||
getTagColor: () => ({
|
||||
name: 'blue',
|
||||
bg: 'hsl(210 100% 50% / 0.2)',
|
||||
text: 'hsl(210 100% 40%)'
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/context-menu', () => ({
|
||||
ContextMenu: { template: '<div><slot /></div>' },
|
||||
ContextMenuTrigger: { template: '<div><slot /></div>' },
|
||||
ContextMenuContent: { template: '<div><slot /></div>' },
|
||||
ContextMenuSeparator: { template: '<hr />' },
|
||||
ContextMenuItem: {
|
||||
props: ['disabled'],
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="ctx-item" :disabled="disabled" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/hover-card', () => ({
|
||||
HoverCard: {
|
||||
props: ['open'],
|
||||
emits: ['update:open'],
|
||||
template: '<div><slot /></div>'
|
||||
},
|
||||
HoverCardTrigger: { template: '<div><slot /></div>' },
|
||||
HoverCardContent: { template: '<div><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/badge', () => ({
|
||||
Badge: { template: '<span data-testid="badge"><slot /></span>' }
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template: '<button data-testid="button" @click="$emit(\'click\')"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/card', () => ({
|
||||
Card: { template: '<div data-testid="card"><slot /></div>' }
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/separator', () => ({
|
||||
Separator: { template: '<hr />' }
|
||||
}));
|
||||
|
||||
vi.mock('lucide-vue-next', () => ({
|
||||
Apple: { template: '<i />' },
|
||||
Check: { template: '<i />' },
|
||||
ExternalLink: { template: '<i />' },
|
||||
Eye: { template: '<i />' },
|
||||
Image: { template: '<i />' },
|
||||
Monitor: { template: '<i />' },
|
||||
Pencil: { template: '<i />' },
|
||||
RefreshCw: { template: '<i />' },
|
||||
Smartphone: { template: '<i />' },
|
||||
Tag: { template: '<i />' },
|
||||
User: { template: '<i />' }
|
||||
}));
|
||||
|
||||
import MyAvatarCard from '../MyAvatarCard.vue';
|
||||
|
||||
function mountCard(props = {}) {
|
||||
return mount(MyAvatarCard, {
|
||||
props: {
|
||||
avatar: {
|
||||
id: 'avtr_1',
|
||||
name: 'Avatar One',
|
||||
thumbnailImageUrl: 'https://example.com/a.jpg',
|
||||
releaseStatus: 'public',
|
||||
unityPackages: [],
|
||||
$tags: [{ tag: 'fun' }],
|
||||
updated_at: '2025-01-01T00:00:00.000Z',
|
||||
created_at: '2024-01-01T00:00:00.000Z',
|
||||
version: 1,
|
||||
...props.avatar
|
||||
},
|
||||
currentAvatarId: '',
|
||||
cardScale: 0.6,
|
||||
...props
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('MyAvatarCard.vue', () => {
|
||||
test('renders avatar name and tags', () => {
|
||||
const wrapper = mountCard();
|
||||
|
||||
expect(wrapper.text()).toContain('Avatar One');
|
||||
expect(wrapper.text()).toContain('fun');
|
||||
});
|
||||
|
||||
test('emits click when card wrapper is clicked', async () => {
|
||||
const wrapper = mountCard();
|
||||
|
||||
await wrapper.find('.avatar-card-wrapper').trigger('click');
|
||||
|
||||
expect(wrapper.emitted('click')).toBeTruthy();
|
||||
expect(wrapper.emitted('click')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test('emits context action from menu item', async () => {
|
||||
const wrapper = mountCard();
|
||||
const detailsItem = wrapper
|
||||
.findAll('[data-testid="ctx-item"]')
|
||||
.find((node) => node.text().includes('dialog.avatar.actions.view_details'));
|
||||
|
||||
expect(detailsItem).toBeTruthy();
|
||||
await detailsItem.trigger('click');
|
||||
|
||||
expect(wrapper.emitted('context-action')).toBeTruthy();
|
||||
expect(wrapper.emitted('context-action')[0]).toEqual([
|
||||
'details',
|
||||
expect.objectContaining({ id: 'avtr_1' })
|
||||
]);
|
||||
});
|
||||
|
||||
test('disables wear action when avatar is active', () => {
|
||||
const wrapper = mountCard({ currentAvatarId: 'avtr_1' });
|
||||
const wearItem = wrapper
|
||||
.findAll('[data-testid="ctx-item"]')
|
||||
.find((node) => node.text().includes('view.favorite.select_avatar_tooltip'));
|
||||
|
||||
expect(wearItem.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user