From d2d3dc8f1377a0134f76e5f7a464350679702f4e Mon Sep 17 00:00:00 2001 From: pa Date: Mon, 9 Mar 2026 14:24:00 +0900 Subject: [PATCH] refactor --- src/components/__tests__/StatusBar.test.js | 4 +- .../__tests__/GroupDialogPhotosTab.test.js | 5 +- .../__tests__/GroupDialogPostsTab.test.js | 23 +- .../GroupModerationBulkActions.test.js | 6 +- .../__tests__/useGroupMembers.test.js | 6 +- .../__tests__/useGroupModerationData.test.js | 6 +- .../dialogs/UserDialog/UserDialog.vue | 722 +----------------- .../dialogs/UserDialog/UserDialogInfoTab.vue | 712 +++++++++++++++++ .../__tests__/UserDialogAvatarsTab.test.js | 23 +- .../__tests__/UserDialogInfoTab.test.js | 241 ++++++ .../UserDialogMutualFriendsTab.test.js | 5 +- .../__tests__/UserDialogWorldsTab.test.js | 23 +- .../__tests__/useImageCropper.test.js | 4 +- src/stores/__tests__/vrcStatus.test.js | 4 +- src/stores/__tests__/vrcxUpdater.test.js | 4 +- src/stores/favorite.js | 65 +- .../__tests__/FavoritesWorldItem.test.js | 4 +- .../FriendList/__tests__/FriendList.test.js | 3 +- .../FriendLog/__tests__/FriendLog.test.js | 4 +- .../__tests__/FriendsLocations.test.js | 3 +- .../__tests__/LoginSettingsDialog.test.js | 4 +- .../Moderation/__tests__/Moderation.test.js | 4 +- .../PlayerList/__tests__/PlayerList.test.js | 4 +- .../dialogs/__tests__/ChangelogDialog.test.js | 4 +- .../__tests__/LaunchOptionsDialog.test.js | 4 +- .../__tests__/TranslationApiDialog.test.js | 3 +- .../__tests__/VRChatConfigDialog.test.js | 3 +- .../components/__tests__/FriendItem.test.js | 4 +- .../__tests__/FriendsSidebar.test.js | 3 +- .../__tests__/NotificationCenterSheet.test.js | 4 +- .../__tests__/NotificationItem.test.js | 21 +- .../__tests__/NotificationList.test.js | 4 +- 32 files changed, 1128 insertions(+), 801 deletions(-) create mode 100644 src/components/dialogs/UserDialog/UserDialogInfoTab.vue create mode 100644 src/components/dialogs/UserDialog/__tests__/UserDialogInfoTab.test.js diff --git a/src/components/__tests__/StatusBar.test.js b/src/components/__tests__/StatusBar.test.js index 349c9402..016f136c 100644 --- a/src/components/__tests__/StatusBar.test.js +++ b/src/components/__tests__/StatusBar.test.js @@ -226,9 +226,7 @@ describe('StatusBar.vue - Servers indicator', () => { test('shows Servers indicator with green dot when no issues', () => { const wrapper = mountStatusBar(); expect(wrapper.text()).toContain('Servers'); - const serversDots = wrapper.findAll( - '.bg-\\[var\\(--status-online\\)\\]' - ); + const serversDots = wrapper.findAll('.bg-status-online'); expect(serversDots.length).toBeGreaterThan(0); expect(wrapper.find('.bg-\\[\\#e6a23c\\]').exists()).toBe(false); }); diff --git a/src/components/dialogs/GroupDialog/__tests__/GroupDialogPhotosTab.test.js b/src/components/dialogs/GroupDialog/__tests__/GroupDialogPhotosTab.test.js index d70b9241..fb6740da 100644 --- a/src/components/dialogs/GroupDialog/__tests__/GroupDialogPhotosTab.test.js +++ b/src/components/dialogs/GroupDialog/__tests__/GroupDialogPhotosTab.test.js @@ -6,10 +6,11 @@ import { mount } from '@vue/test-utils'; vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key) + t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key), + locale: require('vue').ref('en') }), createI18n: () => ({ - global: { t: (key) => key }, + global: { t: (key) => key , locale: require('vue').ref('en') }, install: vi.fn() }) })); diff --git a/src/components/dialogs/GroupDialog/__tests__/GroupDialogPostsTab.test.js b/src/components/dialogs/GroupDialog/__tests__/GroupDialogPostsTab.test.js index 47445fb6..21946a0e 100644 --- a/src/components/dialogs/GroupDialog/__tests__/GroupDialogPostsTab.test.js +++ b/src/components/dialogs/GroupDialog/__tests__/GroupDialogPostsTab.test.js @@ -4,15 +4,20 @@ 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('vue-i18n', () => { + const { ref } = require('vue'); + return { + useI18n: () => ({ + t: (key, params) => + params ? `${key}:${JSON.stringify(params)}` : key, + locale: ref('en') + }), + createI18n: () => ({ + global: { t: (key) => key, locale: ref('en') }, + install: vi.fn() + }) + }; +}); vi.mock('../../../../plugin/router', () => { const { ref } = require('vue'); diff --git a/src/components/dialogs/GroupDialog/__tests__/GroupModerationBulkActions.test.js b/src/components/dialogs/GroupDialog/__tests__/GroupModerationBulkActions.test.js index 00406a41..a4ab902f 100644 --- a/src/components/dialogs/GroupDialog/__tests__/GroupModerationBulkActions.test.js +++ b/src/components/dialogs/GroupDialog/__tests__/GroupModerationBulkActions.test.js @@ -4,9 +4,11 @@ import { mount } from '@vue/test-utils'; vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }), + , + locale: require('vue').ref('en') + }), createI18n: () => ({ - global: { t: (key) => key }, + global: { t: (key) => key , locale: require('vue').ref('en') }, install: vi.fn() }) })); diff --git a/src/components/dialogs/GroupDialog/__tests__/useGroupMembers.test.js b/src/components/dialogs/GroupDialog/__tests__/useGroupMembers.test.js index 2fa9594f..b935d5af 100644 --- a/src/components/dialogs/GroupDialog/__tests__/useGroupMembers.test.js +++ b/src/components/dialogs/GroupDialog/__tests__/useGroupMembers.test.js @@ -80,9 +80,11 @@ vi.mock('../../../../service/request', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }), + , + locale: require('vue').ref('en') + }), createI18n: () => ({ - global: { t: (key) => key }, + global: { t: (key) => key , locale: require('vue').ref('en') }, install: vi.fn() }) })); diff --git a/src/components/dialogs/GroupDialog/__tests__/useGroupModerationData.test.js b/src/components/dialogs/GroupDialog/__tests__/useGroupModerationData.test.js index 354e477b..d9e9d8b9 100644 --- a/src/components/dialogs/GroupDialog/__tests__/useGroupModerationData.test.js +++ b/src/components/dialogs/GroupDialog/__tests__/useGroupModerationData.test.js @@ -5,9 +5,11 @@ vi.mock('vue-sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } })); vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }), + , + locale: require('vue').ref('en') + }), createI18n: () => ({ - global: { t: (key) => key }, + global: { t: (key) => key , locale: require('vue').ref('en') }, install: vi.fn() }) })); diff --git a/src/components/dialogs/UserDialog/UserDialog.vue b/src/components/dialogs/UserDialog/UserDialog.vue index 4462cac1..428fb404 100644 --- a/src/components/dialogs/UserDialog/UserDialog.vue +++ b/src/components/dialogs/UserDialog/UserDialog.vue @@ -19,538 +19,7 @@ :unmount-on-hide="false" @update:modelValue="userDialogTabClick"> diff --git a/src/components/dialogs/UserDialog/UserDialogInfoTab.vue b/src/components/dialogs/UserDialog/UserDialogInfoTab.vue new file mode 100644 index 00000000..a1d89948 --- /dev/null +++ b/src/components/dialogs/UserDialog/UserDialogInfoTab.vue @@ -0,0 +1,712 @@ + + + diff --git a/src/components/dialogs/UserDialog/__tests__/UserDialogAvatarsTab.test.js b/src/components/dialogs/UserDialog/__tests__/UserDialogAvatarsTab.test.js index f722ad2a..9e555e39 100644 --- a/src/components/dialogs/UserDialog/__tests__/UserDialogAvatarsTab.test.js +++ b/src/components/dialogs/UserDialog/__tests__/UserDialogAvatarsTab.test.js @@ -4,15 +4,20 @@ import { mount } from '@vue/test-utils'; // ─── Mocks (must be before any imports that use them) ──────────────── -vi.mock('vue-i18n', () => ({ - useI18n: () => ({ - t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key) - }), - createI18n: () => ({ - global: { t: (key) => key }, - install: vi.fn() - }) -})); +vi.mock('vue-i18n', () => { + const { ref } = require('vue'); + return { + useI18n: () => ({ + t: (key, params) => + params ? `${key}:${JSON.stringify(params)}` : key, + locale: ref('en') + }), + createI18n: () => ({ + global: { t: (key) => key, locale: ref('en') }, + install: vi.fn() + }) + }; +}); vi.mock('../../../../plugin/router', () => { const { ref } = require('vue'); diff --git a/src/components/dialogs/UserDialog/__tests__/UserDialogInfoTab.test.js b/src/components/dialogs/UserDialog/__tests__/UserDialogInfoTab.test.js new file mode 100644 index 00000000..33adde3d --- /dev/null +++ b/src/components/dialogs/UserDialog/__tests__/UserDialogInfoTab.test.js @@ -0,0 +1,241 @@ +import { beforeEach, describe, expect, test, vi } from 'vitest'; +import { createTestingPinia } from '@pinia/testing'; +import { flushPromises, shallowMount } from '@vue/test-utils'; + +vi.mock('vue-i18n', () => ({ + useI18n: () => { + const { ref } = require('vue'); + return { + t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key), + locale: ref('en') + }; + }, + 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 UserDialogInfoTab from '../UserDialogInfoTab.vue'; +import { miscRequest } from '../../../../api'; +import { + useAdvancedSettingsStore, + useAppearanceSettingsStore, + useLocationStore, + useModalStore, + useUserStore +} from '../../../../stores'; + +/** + * + * @param overrides + */ +function mountComponent(overrides = {}) { + const pinia = createTestingPinia({ + stubActions: true + }); + + const appearanceSettingsStore = useAppearanceSettingsStore(pinia); + appearanceSettingsStore.hideUserNotes = false; + appearanceSettingsStore.hideUserMemos = false; + + const advancedSettingsStore = useAdvancedSettingsStore(pinia); + advancedSettingsStore.bioLanguage = 'en'; + advancedSettingsStore.translationApi = ''; + advancedSettingsStore.translationApiType = 'google'; + advancedSettingsStore.translateText = vi.fn().mockResolvedValue(''); + + const userStore = useUserStore(pinia); + userStore.userDialog = { + id: 'usr_target', + friend: { + state: 'online', + ref: { + location: 'wrld_test:123' + } + }, + ref: { + id: 'usr_target', + location: 'wrld_test:123', + travelingToLocation: '', + profilePicOverride: '', + currentAvatarImageUrl: '', + currentAvatarTags: [], + bio: '', + bioLinks: [], + state: 'online', + $online_for: 1000, + last_login: '2025-01-01T00:00:00.000Z', + last_activity: '2025-01-01T00:00:00.000Z', + date_joined: '2020-01-01', + allowAvatarCopying: true, + displayName: 'Target' + }, + $location: { + tag: 'wrld_test:123', + shortName: 'Test', + userId: '', + user: null + }, + instance: { + ref: {}, + friendCount: 0 + }, + users: [ + { + id: 'usr_friend_1', + displayName: 'Friend A', + $userColour: '#ffffff', + location: 'traveling', + $travelingToTime: Date.now(), + $location_at: Date.now() + } + ], + note: '', + memo: '', + isRepresentedGroupLoading: false, + representedGroup: null, + lastSeen: '2025-01-01T00:00:00.000Z', + joinCount: 0, + timeSpent: 0, + dateFriendedInfo: [], + unFriended: false, + dateFriended: '2025-01-01T00:00:00.000Z', + $homeLocationName: '', + ...overrides.userDialog + }; + + userStore.currentUser = { + id: 'usr_me', + allowAvatarCopying: true, + isBoopingEnabled: true, + hasSharedConnectionsOptOut: false, + hasDiscordFriendsOptOut: false, + homeLocation: '', + ...overrides.currentUser + }; + + const locationStore = useLocationStore(pinia); + locationStore.lastLocation = { + location: 'wrld_test:123' + }; + + const modalStore = useModalStore(pinia); + modalStore.confirm = vi.fn().mockResolvedValue({ ok: false }); + + return shallowMount(UserDialogInfoTab, { + global: { + plugins: [pinia], + stubs: { + Location: true, + Timer: true, + TooltipWrapper: true, + AvatarInfo: true + } + } + }); +} + +describe('UserDialogInfoTab.vue', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('unit behavior', () => { + test('onTabActivated fetches VRChat credits only once after first success', async () => { + const creditsSpy = vi + .spyOn(miscRequest, 'getVRChatCredits') + .mockResolvedValue({ json: { balance: 42 } }); + const wrapper = mountComponent(); + + wrapper.vm.onTabActivated(); + await flushPromises(); + wrapper.vm.onTabActivated(); + await flushPromises(); + + expect(creditsSpy).toHaveBeenCalledTimes(1); + }); + }); + + describe('dom rendering', () => { + 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('spinner-stub').exists()).toBe(true); + }); + }); +}); diff --git a/src/components/dialogs/UserDialog/__tests__/UserDialogMutualFriendsTab.test.js b/src/components/dialogs/UserDialog/__tests__/UserDialogMutualFriendsTab.test.js index 318fdeaa..72652ec5 100644 --- a/src/components/dialogs/UserDialog/__tests__/UserDialogMutualFriendsTab.test.js +++ b/src/components/dialogs/UserDialog/__tests__/UserDialogMutualFriendsTab.test.js @@ -6,10 +6,11 @@ import { mount } from '@vue/test-utils'; vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key) + t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key), + locale: require('vue').ref('en') }), createI18n: () => ({ - global: { t: (key) => key }, + global: { t: (key) => key , locale: require('vue').ref('en') }, install: vi.fn() }) })); diff --git a/src/components/dialogs/UserDialog/__tests__/UserDialogWorldsTab.test.js b/src/components/dialogs/UserDialog/__tests__/UserDialogWorldsTab.test.js index 87db8584..bdf7ced9 100644 --- a/src/components/dialogs/UserDialog/__tests__/UserDialogWorldsTab.test.js +++ b/src/components/dialogs/UserDialog/__tests__/UserDialogWorldsTab.test.js @@ -4,15 +4,20 @@ 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('vue-i18n', () => { + const { ref } = require('vue'); + return { + useI18n: () => ({ + t: (key, params) => + params ? `${key}:${JSON.stringify(params)}` : key, + locale: ref('en') + }), + createI18n: () => ({ + global: { t: (key) => key, locale: ref('en') }, + install: vi.fn() + }) + }; +}); vi.mock('../../../../plugin/router', () => { const { ref } = require('vue'); diff --git a/src/composables/__tests__/useImageCropper.test.js b/src/composables/__tests__/useImageCropper.test.js index 5deb2d74..61d5aa93 100644 --- a/src/composables/__tests__/useImageCropper.test.js +++ b/src/composables/__tests__/useImageCropper.test.js @@ -5,7 +5,9 @@ vi.mock('vue-sonner', () => ({ })); vi.mock('vue-i18n', () => ({ - useI18n: () => ({ t: (key) => key }) + useI18n: () => ({ t: (key) => key , + locale: require('vue').ref('en') + }) })); import { diff --git a/src/stores/__tests__/vrcStatus.test.js b/src/stores/__tests__/vrcStatus.test.js index 85acfe2c..c7a26c24 100644 --- a/src/stores/__tests__/vrcStatus.test.js +++ b/src/stores/__tests__/vrcStatus.test.js @@ -39,7 +39,9 @@ vi.mock('../../shared/utils', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); /** diff --git a/src/stores/__tests__/vrcxUpdater.test.js b/src/stores/__tests__/vrcxUpdater.test.js index 1e0e13a7..ea4b05f7 100644 --- a/src/stores/__tests__/vrcxUpdater.test.js +++ b/src/stores/__tests__/vrcxUpdater.test.js @@ -29,7 +29,9 @@ vi.mock('vue-sonner', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); function flushPromises() { diff --git a/src/stores/favorite.js b/src/stores/favorite.js index c7acd405..0e6fc709 100644 --- a/src/stores/favorite.js +++ b/src/stores/favorite.js @@ -213,8 +213,9 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param list - * @param selectionRef + * @param {Array} list + * @param {object} selectionRef + * @returns {void} */ function syncFavoriteSelection(list, selectionRef) { if (!Array.isArray(list)) { @@ -263,7 +264,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { ); /** - * + * @returns {void} */ function getCachedFavoriteGroupsByTypeName() { const group = {}; @@ -286,7 +287,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param objectId + * @param {string} objectId + * @returns {object | undefined} */ function getCachedFavoritesByObjectId(objectId) { return cachedFavoritesByObjectId.get(objectId); @@ -294,7 +296,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args + * @returns {void} */ function handleFavoriteAdd(args) { handleFavorite({ @@ -330,7 +333,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args + * @returns {void} */ function handleFavorite(args) { args.ref = applyFavoriteCached(args.json); @@ -353,7 +357,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param objectId + * @param {string} objectId + * @returns {void} */ function handleFavoriteDelete(objectId) { const ref = getCachedFavoritesByObjectId(objectId); @@ -365,7 +370,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args + * @returns {void} */ function handleFavoriteGroup(args) { args.ref = applyFavoriteGroup(args.json); @@ -373,7 +379,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args + * @returns {void} */ function handleFavoriteGroupClear(args) { const key = `${args.params.type}:${args.params.group}`; @@ -387,7 +394,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args + * @returns {void} */ function handleFavoriteWorldList(args) { for (const json of args.json) { @@ -400,7 +408,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param args + * @param {object} args */ function handleFavoriteAvatarList(args) { for (const json of args.json) { @@ -413,7 +421,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param ref + * @param {object} ref + * @returns {void} */ function handleFavoriteAtDelete(ref) { const favorite = state.favoriteObjects.get(ref.favoriteId); @@ -583,7 +592,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { } /** - * + * @returns {void} */ function refreshFavoriteGroups() { if (isFavoriteGroupLoading.value) { @@ -813,8 +822,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param json - * @returns {any} + * @param {object} json + * @returns {object} */ function applyFavoriteGroup(json) { let ref = cachedFavoriteGroups.value[json.id]; @@ -829,8 +838,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param json - * @returns {any} + * @param {object} json + * @returns {object} */ function applyFavoriteCached(json) { let ref = cachedFavorites.get(json.id); @@ -866,7 +875,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param tag + * @param {string} tag + * @returns {void} */ async function refreshFavoriteAvatars(tag) { const params = { @@ -879,7 +889,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { } /** - * + * @returns {void} */ function refreshFavoriteItems() { const types = { @@ -929,21 +939,21 @@ export const useFavoriteStore = defineStore('Favorite', () => { } /** - * + * @returns {void} */ function showWorldImportDialog() { worldImportDialogVisible.value = true; } /** - * + * @returns {void} */ function showAvatarImportDialog() { avatarImportDialogVisible.value = true; } /** - * + * @returns {void} */ function showFriendImportDialog() { friendImportDialogVisible.value = true; @@ -1104,7 +1114,8 @@ export const useFavoriteStore = defineStore('Favorite', () => { /** * - * @param objectId + * @param {string} objectId + * @returns {void} */ function updateFavoriteDialog(objectId) { const D = favoriteDialog.value; @@ -1199,7 +1210,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { } /** - * + * @returns {void} */ function sortLocalAvatarFavorites() { if (!appearanceSettingsStore.sortFavorites) { @@ -1389,7 +1400,7 @@ export const useFavoriteStore = defineStore('Favorite', () => { } /** - * + * @returns {void} */ function sortLocalWorldFavorites() { if (!appearanceSettingsStore.sortFavorites) { @@ -1450,6 +1461,10 @@ export const useFavoriteStore = defineStore('Favorite', () => { }); await new Promise((resolve) => setTimeout(resolve, 500)); } catch (err) { + console.error( + `Failed to fetch avatar ${favorite.id}:`, + err + ); result.invalid++; result.invalidIds.push(favorite.id); } diff --git a/src/views/Favorites/components/__tests__/FavoritesWorldItem.test.js b/src/views/Favorites/components/__tests__/FavoritesWorldItem.test.js index b6bd52dd..1259ce8d 100644 --- a/src/views/Favorites/components/__tests__/FavoritesWorldItem.test.js +++ b/src/views/Favorites/components/__tests__/FavoritesWorldItem.test.js @@ -18,7 +18,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('@/components/ui/context-menu', () => ({ diff --git a/src/views/FriendList/__tests__/FriendList.test.js b/src/views/FriendList/__tests__/FriendList.test.js index 3c2e0338..ca7efd93 100644 --- a/src/views/FriendList/__tests__/FriendList.test.js +++ b/src/views/FriendList/__tests__/FriendList.test.js @@ -46,7 +46,8 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key) => key + t: (key) => key, + locale: require('vue').ref('en') }) })); diff --git a/src/views/FriendLog/__tests__/FriendLog.test.js b/src/views/FriendLog/__tests__/FriendLog.test.js index fb511563..c6d085de 100644 --- a/src/views/FriendLog/__tests__/FriendLog.test.js +++ b/src/views/FriendLog/__tests__/FriendLog.test.js @@ -34,7 +34,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../stores', () => ({ diff --git a/src/views/FriendsLocations/__tests__/FriendsLocations.test.js b/src/views/FriendsLocations/__tests__/FriendsLocations.test.js index f5ad3f40..ce3b8980 100644 --- a/src/views/FriendsLocations/__tests__/FriendsLocations.test.js +++ b/src/views/FriendsLocations/__tests__/FriendsLocations.test.js @@ -44,7 +44,8 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key) => key + t: (key) => key, + locale: require('vue').ref('en') }) })); diff --git a/src/views/Login/Dialog/__tests__/LoginSettingsDialog.test.js b/src/views/Login/Dialog/__tests__/LoginSettingsDialog.test.js index 75152ff7..9010766d 100644 --- a/src/views/Login/Dialog/__tests__/LoginSettingsDialog.test.js +++ b/src/views/Login/Dialog/__tests__/LoginSettingsDialog.test.js @@ -19,7 +19,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../../stores', () => ({ diff --git a/src/views/Moderation/__tests__/Moderation.test.js b/src/views/Moderation/__tests__/Moderation.test.js index 2246b954..4034e50c 100644 --- a/src/views/Moderation/__tests__/Moderation.test.js +++ b/src/views/Moderation/__tests__/Moderation.test.js @@ -32,7 +32,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../stores', () => ({ diff --git a/src/views/PlayerList/__tests__/PlayerList.test.js b/src/views/PlayerList/__tests__/PlayerList.test.js index 654b8d38..0b6c67de 100644 --- a/src/views/PlayerList/__tests__/PlayerList.test.js +++ b/src/views/PlayerList/__tests__/PlayerList.test.js @@ -28,7 +28,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../stores', () => ({ diff --git a/src/views/Settings/dialogs/__tests__/ChangelogDialog.test.js b/src/views/Settings/dialogs/__tests__/ChangelogDialog.test.js index 67525833..821ebe93 100644 --- a/src/views/Settings/dialogs/__tests__/ChangelogDialog.test.js +++ b/src/views/Settings/dialogs/__tests__/ChangelogDialog.test.js @@ -20,7 +20,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../../stores', () => ({ diff --git a/src/views/Settings/dialogs/__tests__/LaunchOptionsDialog.test.js b/src/views/Settings/dialogs/__tests__/LaunchOptionsDialog.test.js index 07b25017..3afcf84c 100644 --- a/src/views/Settings/dialogs/__tests__/LaunchOptionsDialog.test.js +++ b/src/views/Settings/dialogs/__tests__/LaunchOptionsDialog.test.js @@ -27,7 +27,9 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../../stores', () => ({ diff --git a/src/views/Settings/dialogs/__tests__/TranslationApiDialog.test.js b/src/views/Settings/dialogs/__tests__/TranslationApiDialog.test.js index a7c5c3da..a7bc1a29 100644 --- a/src/views/Settings/dialogs/__tests__/TranslationApiDialog.test.js +++ b/src/views/Settings/dialogs/__tests__/TranslationApiDialog.test.js @@ -42,7 +42,8 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key) + t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key), + locale: require('vue').ref('en') }) })); diff --git a/src/views/Settings/dialogs/__tests__/VRChatConfigDialog.test.js b/src/views/Settings/dialogs/__tests__/VRChatConfigDialog.test.js index c9c3681d..6de65b5b 100644 --- a/src/views/Settings/dialogs/__tests__/VRChatConfigDialog.test.js +++ b/src/views/Settings/dialogs/__tests__/VRChatConfigDialog.test.js @@ -49,7 +49,8 @@ vi.mock('pinia', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key) + t: (key, params) => (params ? `${key}:${JSON.stringify(params)}` : key), + locale: require('vue').ref('en') }) })); diff --git a/src/views/Sidebar/components/__tests__/FriendItem.test.js b/src/views/Sidebar/components/__tests__/FriendItem.test.js index 7ce18f0e..13b8779c 100644 --- a/src/views/Sidebar/components/__tests__/FriendItem.test.js +++ b/src/views/Sidebar/components/__tests__/FriendItem.test.js @@ -33,7 +33,9 @@ vi.mock('../../../../shared/utils', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('@/components/ui/avatar', () => ({ diff --git a/src/views/Sidebar/components/__tests__/FriendsSidebar.test.js b/src/views/Sidebar/components/__tests__/FriendsSidebar.test.js index 69739067..a3197678 100644 --- a/src/views/Sidebar/components/__tests__/FriendsSidebar.test.js +++ b/src/views/Sidebar/components/__tests__/FriendsSidebar.test.js @@ -150,7 +150,8 @@ vi.mock('vue-sonner', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ - t: (key) => key + t: (key) => key, + locale: require('vue').ref('en') }) })); diff --git a/src/views/Sidebar/components/__tests__/NotificationCenterSheet.test.js b/src/views/Sidebar/components/__tests__/NotificationCenterSheet.test.js index 31f8385a..9a17ff9e 100644 --- a/src/views/Sidebar/components/__tests__/NotificationCenterSheet.test.js +++ b/src/views/Sidebar/components/__tests__/NotificationCenterSheet.test.js @@ -26,7 +26,9 @@ vi.mock('vue-router', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('../../../../stores', () => ({ diff --git a/src/views/Sidebar/components/__tests__/NotificationItem.test.js b/src/views/Sidebar/components/__tests__/NotificationItem.test.js index 6137aab4..c260f193 100644 --- a/src/views/Sidebar/components/__tests__/NotificationItem.test.js +++ b/src/views/Sidebar/components/__tests__/NotificationItem.test.js @@ -52,7 +52,8 @@ vi.mock('../../../../shared/utils', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key, - te: () => false + te: () => false, + locale: require('vue').ref('en') }) })); @@ -72,13 +73,19 @@ vi.mock('@/components/ui/avatar', () => ({ props: ['src'], template: '' }, - AvatarFallback: { template: '' } + AvatarFallback: { + template: '' + } })); vi.mock('@/components/ui/hover-card', () => ({ HoverCard: { template: '
' }, - HoverCardTrigger: { template: '
' }, - HoverCardContent: { template: '
' } + HoverCardTrigger: { + template: '
' + }, + HoverCardContent: { + template: '
' + } })); vi.mock('@/components/ui/badge', () => ({ @@ -197,9 +204,9 @@ describe('NotificationItem.vue', () => { }); await wrapper.get('[data-icon="Link"]').trigger('click'); - expect(mocks.notificationStore.openNotificationLink).toHaveBeenCalledWith( - 'group:grp_123' - ); + expect( + mocks.notificationStore.openNotificationLink + ).toHaveBeenCalledWith('group:grp_123'); }); test('unmount queues mark-as-seen for unseen notification', () => { diff --git a/src/views/Sidebar/components/__tests__/NotificationList.test.js b/src/views/Sidebar/components/__tests__/NotificationList.test.js index 99cf44fd..dcde57a8 100644 --- a/src/views/Sidebar/components/__tests__/NotificationList.test.js +++ b/src/views/Sidebar/components/__tests__/NotificationList.test.js @@ -22,7 +22,9 @@ vi.mock('@tanstack/vue-virtual', () => ({ vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key) => key - }) + , + locale: require('vue').ref('en') + }) })); vi.mock('@/components/ui/button', () => ({