mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-20 07:13:51 +02:00
split user dialog
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { mount } from '@vue/test-utils';
|
||||
|
||||
// ─── Mocks ───────────────────────────────────────────────────────────
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key)
|
||||
}),
|
||||
createI18n: () => ({
|
||||
global: { t: (key) => key },
|
||||
install: vi.fn()
|
||||
})
|
||||
}));
|
||||
|
||||
vi.mock('../../../../plugin/router', () => {
|
||||
const { ref } = require('vue');
|
||||
return {
|
||||
router: {
|
||||
beforeEach: vi.fn(),
|
||||
push: vi.fn(),
|
||||
replace: vi.fn(),
|
||||
currentRoute: ref({ path: '/', name: '', meta: {} }),
|
||||
isReady: vi.fn().mockResolvedValue(true)
|
||||
},
|
||||
initRouter: vi.fn()
|
||||
};
|
||||
});
|
||||
vi.mock('vue-router', async (importOriginal) => {
|
||||
const actual = await importOriginal();
|
||||
const { ref } = require('vue');
|
||||
return {
|
||||
...actual,
|
||||
useRouter: vi.fn(() => ({
|
||||
push: vi.fn(),
|
||||
replace: vi.fn(),
|
||||
currentRoute: ref({ path: '/', name: '', meta: {} })
|
||||
}))
|
||||
};
|
||||
});
|
||||
vi.mock('../../../../plugin/interopApi', () => ({ initInteropApi: vi.fn() }));
|
||||
vi.mock('../../../../service/database', () => ({
|
||||
database: new Proxy(
|
||||
{},
|
||||
{
|
||||
get: (_target, prop) => {
|
||||
if (prop === '__esModule') return false;
|
||||
return vi.fn().mockResolvedValue(null);
|
||||
}
|
||||
}
|
||||
)
|
||||
}));
|
||||
vi.mock('../../../../service/config', () => ({
|
||||
default: {
|
||||
init: vi.fn(),
|
||||
getString: vi.fn().mockImplementation((_k, d) => d ?? '{}'),
|
||||
setString: vi.fn(),
|
||||
getBool: vi.fn().mockImplementation((_k, d) => d ?? false),
|
||||
setBool: vi.fn(),
|
||||
getInt: vi.fn().mockImplementation((_k, d) => d ?? 0),
|
||||
setInt: vi.fn(),
|
||||
getFloat: vi.fn().mockImplementation((_k, d) => d ?? 0),
|
||||
setFloat: vi.fn(),
|
||||
getObject: vi.fn().mockReturnValue(null),
|
||||
setObject: vi.fn(),
|
||||
getArray: vi.fn().mockReturnValue([]),
|
||||
setArray: vi.fn(),
|
||||
remove: vi.fn()
|
||||
}
|
||||
}));
|
||||
vi.mock('../../../../service/jsonStorage', () => ({ default: vi.fn() }));
|
||||
vi.mock('../../../../service/watchState', () => ({
|
||||
watchState: { isLoggedIn: false }
|
||||
}));
|
||||
vi.mock('../../../../service/request', () => ({
|
||||
request: vi.fn().mockResolvedValue({ json: {} }),
|
||||
processBulk: vi.fn(),
|
||||
buildRequestInit: vi.fn(),
|
||||
parseResponse: vi.fn(),
|
||||
shouldIgnoreError: vi.fn(),
|
||||
$throw: vi.fn(),
|
||||
failedGetRequests: new Map()
|
||||
}));
|
||||
|
||||
import UserDialogMutualFriendsTab from '../UserDialogMutualFriendsTab.vue';
|
||||
import { useUserStore } from '../../../../stores';
|
||||
import { userDialogMutualFriendSortingOptions } from '../../../../shared/constants';
|
||||
|
||||
// ─── Helpers ─────────────────────────────────────────────────────────
|
||||
|
||||
const MOCK_MUTUAL_FRIENDS = [
|
||||
{
|
||||
id: 'usr_1',
|
||||
displayName: 'Charlie',
|
||||
$userColour: '#ff0000',
|
||||
currentAvatarThumbnailImageUrl: 'https://img/charlie.png'
|
||||
},
|
||||
{
|
||||
id: 'usr_2',
|
||||
displayName: 'Alice',
|
||||
$userColour: '#00ff00',
|
||||
currentAvatarThumbnailImageUrl: 'https://img/alice.png'
|
||||
},
|
||||
{
|
||||
id: 'usr_3',
|
||||
displayName: 'Bob',
|
||||
$userColour: '#0000ff',
|
||||
currentAvatarThumbnailImageUrl: 'https://img/bob.png'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param overrides
|
||||
*/
|
||||
function mountComponent(overrides = {}) {
|
||||
const pinia = createTestingPinia({
|
||||
stubActions: false
|
||||
});
|
||||
|
||||
const userStore = useUserStore(pinia);
|
||||
userStore.userDialog = {
|
||||
id: 'usr_target',
|
||||
ref: { id: 'usr_target' },
|
||||
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
|
||||
mutualFriendSorting: userDialogMutualFriendSortingOptions.alphabetical,
|
||||
isMutualFriendsLoading: false,
|
||||
...overrides
|
||||
};
|
||||
userStore.currentUser = {
|
||||
id: 'usr_me',
|
||||
hasSharedConnectionsOptOut: false,
|
||||
...overrides.currentUser
|
||||
};
|
||||
|
||||
return mount(UserDialogMutualFriendsTab, {
|
||||
global: {
|
||||
plugins: [pinia],
|
||||
stubs: {
|
||||
RefreshCw: { template: '<svg class="refresh-icon" />' }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Tests ───────────────────────────────────────────────────────────
|
||||
|
||||
describe('UserDialogMutualFriendsTab.vue', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('rendering', () => {
|
||||
test('renders mutual friend count', () => {
|
||||
const wrapper = mountComponent();
|
||||
expect(wrapper.text()).toContain('3');
|
||||
});
|
||||
|
||||
test('renders all mutual friends', () => {
|
||||
const wrapper = mountComponent();
|
||||
const items = wrapper.findAll('li');
|
||||
expect(items).toHaveLength(3);
|
||||
});
|
||||
|
||||
test('renders friend display names', () => {
|
||||
const wrapper = mountComponent();
|
||||
expect(wrapper.text()).toContain('Charlie');
|
||||
expect(wrapper.text()).toContain('Alice');
|
||||
expect(wrapper.text()).toContain('Bob');
|
||||
});
|
||||
|
||||
test('renders friend avatar images', () => {
|
||||
const wrapper = mountComponent();
|
||||
const images = wrapper.findAll('img');
|
||||
expect(images).toHaveLength(3);
|
||||
});
|
||||
|
||||
test('applies user colour to display name', () => {
|
||||
const wrapper = mountComponent();
|
||||
const nameSpan = wrapper.find('span[style*="color"]');
|
||||
expect(nameSpan.exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('renders empty list when no mutual friends', () => {
|
||||
const wrapper = mountComponent({ mutualFriends: [] });
|
||||
const items = wrapper.findAll('li');
|
||||
expect(items).toHaveLength(0);
|
||||
expect(wrapper.text()).toContain('0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('loading state', () => {
|
||||
test('disables refresh button when loading', () => {
|
||||
const wrapper = mountComponent({ isMutualFriendsLoading: true });
|
||||
const button = wrapper.find('button');
|
||||
expect(button.attributes('disabled')).toBeDefined();
|
||||
});
|
||||
|
||||
test('refresh button is enabled when not loading', () => {
|
||||
const wrapper = mountComponent({ isMutualFriendsLoading: false });
|
||||
const button = wrapper.find('button');
|
||||
expect(button.attributes('disabled')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('click interactions', () => {
|
||||
test('calls showUserDialog when a friend is clicked', async () => {
|
||||
const pinia = createTestingPinia({ stubActions: false });
|
||||
const userStore = useUserStore(pinia);
|
||||
userStore.userDialog = {
|
||||
id: 'usr_target',
|
||||
ref: { id: 'usr_target' },
|
||||
mutualFriends: [...MOCK_MUTUAL_FRIENDS],
|
||||
mutualFriendSorting:
|
||||
userDialogMutualFriendSortingOptions.alphabetical,
|
||||
isMutualFriendsLoading: false
|
||||
};
|
||||
userStore.currentUser = { id: 'usr_me' };
|
||||
const showUserDialogSpy = vi
|
||||
.spyOn(userStore, 'showUserDialog')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const wrapper = mount(UserDialogMutualFriendsTab, {
|
||||
global: {
|
||||
plugins: [pinia],
|
||||
stubs: {
|
||||
RefreshCw: { template: '<svg class="refresh-icon" />' }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const firstItem = wrapper.findAll('li')[0];
|
||||
await firstItem.trigger('click');
|
||||
expect(showUserDialogSpy).toHaveBeenCalledWith('usr_1');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user