mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-22 00:03:51 +02:00
add test
This commit is contained in:
170
src/views/Sidebar/components/__tests__/FriendItem.test.js
Normal file
170
src/views/Sidebar/components/__tests__/FriendItem.test.js
Normal file
@@ -0,0 +1,170 @@
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
appearanceStore: {
|
||||
hideNicknames: false
|
||||
},
|
||||
friendStore: {
|
||||
isRefreshFriendsLoading: false,
|
||||
allFavoriteFriendIds: new Set(),
|
||||
confirmDeleteFriend: vi.fn()
|
||||
},
|
||||
userStore: {
|
||||
showUserDialog: vi.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('pinia', () => ({
|
||||
storeToRefs: (store) => store
|
||||
}));
|
||||
|
||||
vi.mock('../../../../stores', () => ({
|
||||
useAppearanceSettingsStore: () => mocks.appearanceStore,
|
||||
useFriendStore: () => mocks.friendStore,
|
||||
useUserStore: () => mocks.userStore
|
||||
}));
|
||||
|
||||
vi.mock('../../../../shared/utils', () => ({
|
||||
userImage: vi.fn(() => 'https://example.com/avatar.png'),
|
||||
userStatusClass: vi.fn(() => 'status-online')
|
||||
}));
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key) => key
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/avatar', () => ({
|
||||
Avatar: {
|
||||
template: '<div data-testid="avatar"><slot /></div>'
|
||||
},
|
||||
AvatarImage: {
|
||||
props: ['src'],
|
||||
template: '<img data-testid="avatar-image" :src="src" />'
|
||||
},
|
||||
AvatarFallback: {
|
||||
template: '<span data-testid="avatar-fallback"><slot /></span>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/button', () => ({
|
||||
Button: {
|
||||
emits: ['click'],
|
||||
template:
|
||||
'<button data-testid="delete-button" @click="$emit(\'click\', $event)"><slot /></button>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/spinner', () => ({
|
||||
Spinner: {
|
||||
template: '<span data-testid="spinner" />'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/Location.vue', () => ({
|
||||
default: {
|
||||
props: ['location', 'traveling', 'link'],
|
||||
template:
|
||||
'<span data-testid="location">{{ location }}|{{ traveling }}</span>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('@/components/Timer.vue', () => ({
|
||||
default: {
|
||||
props: ['epoch'],
|
||||
template: '<span data-testid="timer">{{ epoch }}</span>'
|
||||
}
|
||||
}));
|
||||
|
||||
vi.mock('lucide-vue-next', () => ({
|
||||
User: {
|
||||
template: '<span data-testid="icon-user" />'
|
||||
},
|
||||
Trash2: {
|
||||
template: '<span data-testid="icon-trash" />'
|
||||
}
|
||||
}));
|
||||
|
||||
import FriendItem from '../FriendItem.vue';
|
||||
|
||||
function makeFriend(overrides = {}) {
|
||||
return {
|
||||
id: 'usr_1',
|
||||
name: 'Alice',
|
||||
state: 'active',
|
||||
pendingOffline: false,
|
||||
$nickName: 'Ali',
|
||||
ref: {
|
||||
displayName: 'Alice',
|
||||
$userColour: '#fff',
|
||||
statusDescription: 'Online',
|
||||
location: 'wrld_abc:123',
|
||||
travelingToLocation: '',
|
||||
$location_at: 123
|
||||
},
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
function mountItem(props = {}) {
|
||||
return mount(FriendItem, {
|
||||
props: {
|
||||
friend: makeFriend(),
|
||||
isGroupByInstance: false,
|
||||
...props
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
describe('FriendItem.vue', () => {
|
||||
beforeEach(() => {
|
||||
mocks.appearanceStore.hideNicknames = false;
|
||||
mocks.friendStore.isRefreshFriendsLoading = false;
|
||||
mocks.friendStore.allFavoriteFriendIds = new Set();
|
||||
mocks.friendStore.confirmDeleteFriend.mockReset();
|
||||
mocks.userStore.showUserDialog.mockReset();
|
||||
});
|
||||
|
||||
test('renders nickname when hideNicknames is false', () => {
|
||||
const wrapper = mountItem();
|
||||
expect(wrapper.text()).toContain('Alice (Ali)');
|
||||
});
|
||||
|
||||
test('renders favorite star when grouped by instance and friend is favorite', () => {
|
||||
mocks.appearanceStore.hideNicknames = true;
|
||||
mocks.friendStore.allFavoriteFriendIds = new Set(['usr_1']);
|
||||
|
||||
const wrapper = mountItem({
|
||||
friend: makeFriend({ $nickName: '' }),
|
||||
isGroupByInstance: true
|
||||
});
|
||||
|
||||
expect(wrapper.text()).toContain('Alice ⭐');
|
||||
});
|
||||
|
||||
test('clicking row opens user dialog', async () => {
|
||||
const wrapper = mountItem();
|
||||
await wrapper.get('div').trigger('click');
|
||||
expect(mocks.userStore.showUserDialog).toHaveBeenCalledWith('usr_1');
|
||||
});
|
||||
|
||||
test('renders delete action for orphan friend and triggers confirmDeleteFriend', async () => {
|
||||
const wrapper = mountItem({
|
||||
friend: makeFriend({
|
||||
id: 'usr_orphan',
|
||||
name: 'Ghost',
|
||||
ref: null
|
||||
})
|
||||
});
|
||||
|
||||
expect(wrapper.text()).toContain('Ghost');
|
||||
const button = wrapper.get('[data-testid="delete-button"]');
|
||||
await button.trigger('click');
|
||||
expect(mocks.friendStore.confirmDeleteFriend).toHaveBeenCalledWith(
|
||||
'usr_orphan'
|
||||
);
|
||||
expect(mocks.userStore.showUserDialog).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user