mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-11 16:39:15 +08:00
fix: typecheck/test:lint/format:check
feat: add data related test
This commit is contained in:
parent
8353f331f1
commit
d397a43806
@ -98,4 +98,4 @@ const ErrorContainer = styled.div`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export { ErrorBoundaryCustomized as ErrorBoundary }
|
export { ErrorBoundaryCustomized as ErrorBoundary }
|
||||||
export type { ErrorBoundaryCustomizedProps, CustomFallbackProps }
|
export type { CustomFallbackProps, ErrorBoundaryCustomizedProps }
|
||||||
|
|||||||
@ -5,4 +5,4 @@ export function formatErrorMessage(error: Error): string {
|
|||||||
return error.message
|
return error.message
|
||||||
}
|
}
|
||||||
return error.toString()
|
return error.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,11 @@ import React from 'react'
|
|||||||
|
|
||||||
// 创建一个 Icon 工厂函数
|
// 创建一个 Icon 工厂函数
|
||||||
export function createIcon(IconComponent: LucideIcon, defaultSize: string | number = '1rem') {
|
export function createIcon(IconComponent: LucideIcon, defaultSize: string | number = '1rem') {
|
||||||
const Icon = React.forwardRef<SVGSVGElement, React.ComponentProps<typeof IconComponent>>(
|
const Icon = ({
|
||||||
(props, ref) => <IconComponent ref={ref} size={defaultSize} {...props} />
|
ref,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof IconComponent> & { ref?: React.RefObject<SVGSVGElement | null> }) => (
|
||||||
|
<IconComponent ref={ref} size={defaultSize} {...props} />
|
||||||
)
|
)
|
||||||
Icon.displayName = `Icon(${IconComponent.displayName || IconComponent.name})`
|
Icon.displayName = `Icon(${IconComponent.displayName || IconComponent.name})`
|
||||||
return Icon
|
return Icon
|
||||||
|
|||||||
@ -4,12 +4,12 @@ export { default as CustomCollapse } from './base/CustomCollapse'
|
|||||||
export { default as CustomTag } from './base/CustomTag'
|
export { default as CustomTag } from './base/CustomTag'
|
||||||
export { default as DividerWithText } from './base/DividerWithText'
|
export { default as DividerWithText } from './base/DividerWithText'
|
||||||
export { default as EmojiIcon } from './base/EmojiIcon'
|
export { default as EmojiIcon } from './base/EmojiIcon'
|
||||||
|
export type { CustomFallbackProps, ErrorBoundaryCustomizedProps } from './base/ErrorBoundary'
|
||||||
export { ErrorBoundary } from './base/ErrorBoundary'
|
export { ErrorBoundary } from './base/ErrorBoundary'
|
||||||
export type { ErrorBoundaryCustomizedProps, CustomFallbackProps } from './base/ErrorBoundary'
|
|
||||||
export { default as IndicatorLight } from './base/IndicatorLight'
|
export { default as IndicatorLight } from './base/IndicatorLight'
|
||||||
export { default as Spinner } from './base/Spinner'
|
export { default as Spinner } from './base/Spinner'
|
||||||
export { StatusTag, ErrorTag, SuccessTag, WarnTag, InfoTag } from './base/StatusTag'
|
export type { StatusTagProps, StatusType } from './base/StatusTag'
|
||||||
export type { StatusType, StatusTagProps } from './base/StatusTag'
|
export { ErrorTag, InfoTag, StatusTag, SuccessTag, WarnTag } from './base/StatusTag'
|
||||||
export { default as TextBadge } from './base/TextBadge'
|
export { default as TextBadge } from './base/TextBadge'
|
||||||
|
|
||||||
// Display Components
|
// Display Components
|
||||||
@ -26,22 +26,22 @@ export { default as HorizontalScrollContainer } from './layout/HorizontalScrollC
|
|||||||
export { default as Scrollbar } from './layout/Scrollbar'
|
export { default as Scrollbar } from './layout/Scrollbar'
|
||||||
|
|
||||||
// Icon Components
|
// Icon Components
|
||||||
|
export { FilePngIcon, FileSvgIcon } from './icons/FileIcons'
|
||||||
|
export type { LucideIcon, LucideProps } from './icons/Icon'
|
||||||
export {
|
export {
|
||||||
createIcon,
|
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
|
createIcon,
|
||||||
DeleteIcon,
|
DeleteIcon,
|
||||||
EditIcon,
|
EditIcon,
|
||||||
|
OcrIcon,
|
||||||
RefreshIcon,
|
RefreshIcon,
|
||||||
ResetIcon,
|
ResetIcon,
|
||||||
ToolIcon,
|
ToolIcon,
|
||||||
|
UnWrapIcon,
|
||||||
VisionIcon,
|
VisionIcon,
|
||||||
WebSearchIcon,
|
WebSearchIcon,
|
||||||
WrapIcon,
|
WrapIcon
|
||||||
UnWrapIcon,
|
|
||||||
OcrIcon
|
|
||||||
} from './icons/Icon'
|
} from './icons/Icon'
|
||||||
export type { LucideIcon, LucideProps } from './icons/Icon'
|
|
||||||
export { FilePngIcon, FileSvgIcon } from './icons/FileIcons'
|
|
||||||
export { default as ReasoningIcon } from './icons/ReasoningIcon'
|
export { default as ReasoningIcon } from './icons/ReasoningIcon'
|
||||||
export { default as SvgSpinners180Ring } from './icons/SvgSpinners180Ring'
|
export { default as SvgSpinners180Ring } from './icons/SvgSpinners180Ring'
|
||||||
export { default as ToolsCallingIcon } from './icons/ToolsCallingIcon'
|
export { default as ToolsCallingIcon } from './icons/ToolsCallingIcon'
|
||||||
|
|||||||
@ -1,35 +1,19 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react'
|
import type { Meta, StoryObj } from '@storybook/react'
|
||||||
import {
|
import { ChevronRight, Download, Settings, Upload } from 'lucide-react'
|
||||||
Copy,
|
|
||||||
Trash,
|
|
||||||
Pencil,
|
|
||||||
RefreshCw,
|
|
||||||
RotateCcw,
|
|
||||||
Wrench,
|
|
||||||
Eye,
|
|
||||||
Search,
|
|
||||||
WrapText,
|
|
||||||
AlignLeft,
|
|
||||||
ScanLine,
|
|
||||||
Settings,
|
|
||||||
Download,
|
|
||||||
Upload,
|
|
||||||
ChevronRight
|
|
||||||
} from 'lucide-react'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createIcon,
|
|
||||||
CopyIcon,
|
CopyIcon,
|
||||||
|
createIcon,
|
||||||
DeleteIcon,
|
DeleteIcon,
|
||||||
EditIcon,
|
EditIcon,
|
||||||
|
OcrIcon,
|
||||||
RefreshIcon,
|
RefreshIcon,
|
||||||
ResetIcon,
|
ResetIcon,
|
||||||
ToolIcon,
|
ToolIcon,
|
||||||
|
UnWrapIcon,
|
||||||
VisionIcon,
|
VisionIcon,
|
||||||
WebSearchIcon,
|
WebSearchIcon,
|
||||||
WrapIcon,
|
WrapIcon
|
||||||
UnWrapIcon,
|
|
||||||
OcrIcon
|
|
||||||
} from '../../../src/components/icons/Icon'
|
} from '../../../src/components/icons/Icon'
|
||||||
|
|
||||||
// Create a dummy component for the story
|
// Create a dummy component for the story
|
||||||
@ -278,8 +262,7 @@ export const IconGrid: Story = {
|
|||||||
{AllIcons.map(({ Icon, name }) => (
|
{AllIcons.map(({ Icon, name }) => (
|
||||||
<div
|
<div
|
||||||
key={name}
|
key={name}
|
||||||
className="flex flex-col items-center gap-2 rounded-lg border border-gray-200 p-4 hover:border-blue-500"
|
className="flex flex-col items-center gap-2 rounded-lg border border-gray-200 p-4 hover:border-blue-500">
|
||||||
>
|
|
||||||
<Icon size={24} />
|
<Icon size={24} />
|
||||||
<span className="text-xs">{name}</span>
|
<span className="text-xs">{name}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -287,4 +270,4 @@ export const IconGrid: Story = {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,7 +100,8 @@ vi.mock('@renderer/utils', () => ({
|
|||||||
|
|
||||||
vi.mock('@shared/config/prompts', () => ({
|
vi.mock('@shared/config/prompts', () => ({
|
||||||
WEB_SEARCH_PROMPT_FOR_OPENROUTER: 'mock-prompt',
|
WEB_SEARCH_PROMPT_FOR_OPENROUTER: 'mock-prompt',
|
||||||
TRANSLATE_PROMPT: 'You are a translation expert. Your only task is to translate text enclosed with <translate_input> from input language to {{target_language}}, provide the translation result directly without any explanation, without `TRANSLATE` and keep original format.'
|
TRANSLATE_PROMPT:
|
||||||
|
'You are a translation expert. Your only task is to translate text enclosed with <translate_input> from input language to {{target_language}}, provide the translation result directly without any explanation, without `TRANSLATE` and keep original format.'
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@renderer/config/systemModels', () => ({
|
vi.mock('@renderer/config/systemModels', () => ({
|
||||||
|
|||||||
@ -7,9 +7,9 @@ import { includeKeywords, matchKeywordsInModel, matchKeywordsInProvider, matchKe
|
|||||||
vi.mock('@renderer/i18n/label', () => ({
|
vi.mock('@renderer/i18n/label', () => ({
|
||||||
getProviderLabel: vi.fn((id: string) => {
|
getProviderLabel: vi.fn((id: string) => {
|
||||||
const labelMap: Record<string, string> = {
|
const labelMap: Record<string, string> = {
|
||||||
'dashscope': 'Alibaba Cloud',
|
dashscope: 'Alibaba Cloud',
|
||||||
'openai': 'OpenAI',
|
openai: 'OpenAI',
|
||||||
'anthropic': 'Anthropic'
|
anthropic: 'Anthropic'
|
||||||
}
|
}
|
||||||
return labelMap[id] || id
|
return labelMap[id] || id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,9 +5,9 @@ import { describe, expect, it, vi } from 'vitest'
|
|||||||
vi.mock('@renderer/i18n/label', () => ({
|
vi.mock('@renderer/i18n/label', () => ({
|
||||||
getProviderLabel: vi.fn((id: string) => {
|
getProviderLabel: vi.fn((id: string) => {
|
||||||
const labelMap: Record<string, string> = {
|
const labelMap: Record<string, string> = {
|
||||||
'dashscope': 'Alibaba Cloud',
|
dashscope: 'Alibaba Cloud',
|
||||||
'openai': 'OpenAI',
|
openai: 'OpenAI',
|
||||||
'anthropic': 'Anthropic'
|
anthropic: 'Anthropic'
|
||||||
}
|
}
|
||||||
return labelMap[id] || id
|
return labelMap[id] || id
|
||||||
})
|
})
|
||||||
|
|||||||
@ -79,13 +79,7 @@ export class MockMainCacheService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Private methods exposed for testing
|
// Private methods exposed for testing
|
||||||
private broadcastSync = vi.fn((message: CacheSyncMessage, senderWindowId?: number): void => {
|
// These methods are mocked but not exposed to avoid TypeScript unused warnings
|
||||||
mockBroadcastCalls.push({ message, senderWindowId })
|
|
||||||
})
|
|
||||||
|
|
||||||
private setupIpcHandlers = vi.fn((): void => {
|
|
||||||
// Mock IPC handler setup
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mock singleton instance
|
// Mock singleton instance
|
||||||
@ -108,7 +102,7 @@ export const MockMainCacheServiceUtils = {
|
|||||||
*/
|
*/
|
||||||
resetMocks: () => {
|
resetMocks: () => {
|
||||||
// Reset all method mocks
|
// Reset all method mocks
|
||||||
Object.values(mockInstance).forEach(method => {
|
Object.values(mockInstance).forEach((method) => {
|
||||||
if (vi.isMockFunction(method)) {
|
if (vi.isMockFunction(method)) {
|
||||||
method.mockClear()
|
method.mockClear()
|
||||||
}
|
}
|
||||||
@ -234,4 +228,4 @@ export const MockMainCacheServiceUtils = {
|
|||||||
delete: mockInstance.delete.mock.calls.length,
|
delete: mockInstance.delete.mock.calls.length,
|
||||||
cleanup: mockInstance.cleanup.mock.calls.length
|
cleanup: mockInstance.cleanup.mock.calls.length
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,11 +35,11 @@ export class MockMainDataApiService {
|
|||||||
private static instance: MockMainDataApiService
|
private static instance: MockMainDataApiService
|
||||||
private initialized = false
|
private initialized = false
|
||||||
private apiServer: MockApiServer
|
private apiServer: MockApiServer
|
||||||
private ipcAdapter: MockIpcAdapter
|
private _ipcAdapter: MockIpcAdapter // Used for mock setup (referenced in constructor)
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
this.apiServer = new MockApiServer()
|
this.apiServer = new MockApiServer()
|
||||||
this.ipcAdapter = new MockIpcAdapter()
|
this._ipcAdapter = new MockIpcAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getInstance(): MockMainDataApiService {
|
public static getInstance(): MockMainDataApiService {
|
||||||
@ -82,6 +82,11 @@ export class MockMainDataApiService {
|
|||||||
public shutdown = vi.fn(async (): Promise<void> => {
|
public shutdown = vi.fn(async (): Promise<void> => {
|
||||||
this.initialized = false
|
this.initialized = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Getter for testing purposes
|
||||||
|
public get ipcAdapter() {
|
||||||
|
return this._ipcAdapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mock singleton instance
|
// Mock singleton instance
|
||||||
@ -112,7 +117,7 @@ export const MockMainDataApiServiceUtils = {
|
|||||||
*/
|
*/
|
||||||
resetMocks: () => {
|
resetMocks: () => {
|
||||||
// Reset all method mocks
|
// Reset all method mocks
|
||||||
Object.values(mockInstance).forEach(method => {
|
Object.values(mockInstance).forEach((method) => {
|
||||||
if (vi.isMockFunction(method)) {
|
if (vi.isMockFunction(method)) {
|
||||||
method.mockClear()
|
method.mockClear()
|
||||||
}
|
}
|
||||||
@ -139,7 +144,7 @@ export const MockMainDataApiServiceUtils = {
|
|||||||
/**
|
/**
|
||||||
* Mock system info for testing
|
* Mock system info for testing
|
||||||
*/
|
*/
|
||||||
mockSystemInfo: (info: Record<string, any>) => {
|
mockSystemInfo: (info: { server: string; version: string; handlers: string[]; middlewares: string[] }) => {
|
||||||
mockInstance.getApiServer().getSystemInfo.mockReturnValue(info)
|
mockInstance.getApiServer().getSystemInfo.mockReturnValue(info)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -166,4 +171,4 @@ export const MockMainDataApiServiceUtils = {
|
|||||||
getSystemStatus: mockInstance.getSystemStatus.mock.calls.length,
|
getSystemStatus: mockInstance.getSystemStatus.mock.calls.length,
|
||||||
getApiServer: mockInstance.getApiServer.mock.calls.length
|
getApiServer: mockInstance.getApiServer.mock.calls.length
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
import type {
|
|
||||||
PreferenceDefaultScopeType,
|
|
||||||
PreferenceKeyType
|
|
||||||
} from '@shared/data/preference/preferenceTypes'
|
|
||||||
import { DefaultPreferences } from '@shared/data/preference/preferenceSchemas'
|
import { DefaultPreferences } from '@shared/data/preference/preferenceSchemas'
|
||||||
|
import type { PreferenceDefaultScopeType, PreferenceKeyType } from '@shared/data/preference/preferenceTypes'
|
||||||
import { vi } from 'vitest'
|
import { vi } from 'vitest'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +23,7 @@ const mockMainSubscribers = new Map<string, Set<(newValue: any, oldValue?: any)
|
|||||||
const notifyMainSubscribers = (key: string, newValue: any, oldValue?: any) => {
|
const notifyMainSubscribers = (key: string, newValue: any, oldValue?: any) => {
|
||||||
const subscribers = mockMainSubscribers.get(key)
|
const subscribers = mockMainSubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.forEach(callback => {
|
subscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback(newValue, oldValue)
|
callback(newValue, oldValue)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -41,7 +38,7 @@ const notifyMainSubscribers = (key: string, newValue: any, oldValue?: any) => {
|
|||||||
*/
|
*/
|
||||||
export class MockMainPreferenceService {
|
export class MockMainPreferenceService {
|
||||||
private static instance: MockMainPreferenceService
|
private static instance: MockMainPreferenceService
|
||||||
private initialized = false
|
private _initialized = false // Used in initialize method
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
@ -54,7 +51,7 @@ export class MockMainPreferenceService {
|
|||||||
|
|
||||||
// Mock initialization
|
// Mock initialization
|
||||||
public initialize = vi.fn(async (): Promise<void> => {
|
public initialize = vi.fn(async (): Promise<void> => {
|
||||||
this.initialized = true
|
this._initialized = true
|
||||||
})
|
})
|
||||||
|
|
||||||
// Mock get method
|
// Mock get method
|
||||||
@ -63,19 +60,18 @@ export class MockMainPreferenceService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Mock set method
|
// Mock set method
|
||||||
public set = vi.fn(async <K extends PreferenceKeyType>(
|
public set = vi.fn(
|
||||||
key: K,
|
async <K extends PreferenceKeyType>(key: K, value: PreferenceDefaultScopeType[K]): Promise<void> => {
|
||||||
value: PreferenceDefaultScopeType[K]
|
const oldValue = mockPreferenceState.get(key)
|
||||||
): Promise<void> => {
|
mockPreferenceState.set(key, value)
|
||||||
const oldValue = mockPreferenceState.get(key)
|
notifyMainSubscribers(key, value, oldValue)
|
||||||
mockPreferenceState.set(key, value)
|
}
|
||||||
notifyMainSubscribers(key, value, oldValue)
|
)
|
||||||
})
|
|
||||||
|
|
||||||
// Mock getMultiple method
|
// Mock getMultiple method
|
||||||
public getMultiple = vi.fn(<K extends PreferenceKeyType>(keys: K[]) => {
|
public getMultiple = vi.fn(<K extends PreferenceKeyType>(keys: K[]) => {
|
||||||
const result: any = {}
|
const result: any = {}
|
||||||
keys.forEach(key => {
|
keys.forEach((key) => {
|
||||||
result[key] = mockPreferenceState.get(key) ?? DefaultPreferences.default[key]
|
result[key] = mockPreferenceState.get(key) ?? DefaultPreferences.default[key]
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
@ -98,7 +94,7 @@ export class MockMainPreferenceService {
|
|||||||
mockSubscriptions.set(windowId, new Set())
|
mockSubscriptions.set(windowId, new Set())
|
||||||
}
|
}
|
||||||
const windowKeys = mockSubscriptions.get(windowId)!
|
const windowKeys = mockSubscriptions.get(windowId)!
|
||||||
keys.forEach(key => windowKeys.add(key))
|
keys.forEach((key) => windowKeys.add(key))
|
||||||
})
|
})
|
||||||
|
|
||||||
public unsubscribeForWindow = vi.fn((windowId: number): void => {
|
public unsubscribeForWindow = vi.fn((windowId: number): void => {
|
||||||
@ -106,45 +102,50 @@ export class MockMainPreferenceService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Mock main process subscription methods
|
// Mock main process subscription methods
|
||||||
public subscribeChange = vi.fn(<K extends PreferenceKeyType>(
|
public subscribeChange = vi.fn(
|
||||||
key: K,
|
<K extends PreferenceKeyType>(
|
||||||
callback: (newValue: PreferenceDefaultScopeType[K], oldValue?: PreferenceDefaultScopeType[K]) => void
|
key: K,
|
||||||
): (() => void) => {
|
callback: (newValue: PreferenceDefaultScopeType[K], oldValue?: PreferenceDefaultScopeType[K]) => void
|
||||||
if (!mockMainSubscribers.has(key)) {
|
): (() => void) => {
|
||||||
mockMainSubscribers.set(key, new Set())
|
if (!mockMainSubscribers.has(key)) {
|
||||||
}
|
mockMainSubscribers.set(key, new Set())
|
||||||
mockMainSubscribers.get(key)!.add(callback)
|
}
|
||||||
|
mockMainSubscribers.get(key)!.add(callback)
|
||||||
|
|
||||||
// Return unsubscribe function
|
// Return unsubscribe function
|
||||||
return () => {
|
return () => {
|
||||||
const subscribers = mockMainSubscribers.get(key)
|
const subscribers = mockMainSubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.delete(callback)
|
subscribers.delete(callback)
|
||||||
if (subscribers.size === 0) {
|
if (subscribers.size === 0) {
|
||||||
mockMainSubscribers.delete(key)
|
mockMainSubscribers.delete(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
public subscribeMultipleChanges = vi.fn((
|
public subscribeMultipleChanges = vi.fn(
|
||||||
keys: PreferenceKeyType[],
|
(
|
||||||
callback: (key: PreferenceKeyType, newValue: any, oldValue: any) => void
|
keys: PreferenceKeyType[],
|
||||||
): (() => void) => {
|
callback: (key: PreferenceKeyType, newValue: any, oldValue: any) => void
|
||||||
const unsubscribeFunctions = keys.map(key =>
|
): (() => void) => {
|
||||||
this.subscribeChange(key, (newValue, oldValue) => callback(key, newValue, oldValue))
|
const unsubscribeFunctions = keys.map((key) =>
|
||||||
)
|
this.subscribeChange(key, (newValue, oldValue) => callback(key, newValue, oldValue))
|
||||||
|
)
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribeFunctions.forEach(unsubscribe => unsubscribe())
|
unsubscribeFunctions.forEach((unsubscribe) => unsubscribe())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
// Mock utility methods
|
// Mock utility methods
|
||||||
public getAll = vi.fn((): PreferenceDefaultScopeType => {
|
public getAll = vi.fn((): PreferenceDefaultScopeType => {
|
||||||
const result: any = {}
|
const result: any = {}
|
||||||
Object.keys(DefaultPreferences.default).forEach(key => {
|
Object.keys(DefaultPreferences.default).forEach((key) => {
|
||||||
result[key] = mockPreferenceState.get(key as PreferenceKeyType) ?? DefaultPreferences.default[key as PreferenceKeyType]
|
result[key] =
|
||||||
|
mockPreferenceState.get(key as PreferenceKeyType) ?? DefaultPreferences.default[key as PreferenceKeyType]
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
@ -157,7 +158,7 @@ export class MockMainPreferenceService {
|
|||||||
|
|
||||||
public getChangeListenerCount = vi.fn((): number => {
|
public getChangeListenerCount = vi.fn((): number => {
|
||||||
let total = 0
|
let total = 0
|
||||||
mockMainSubscribers.forEach(subscribers => {
|
mockMainSubscribers.forEach((subscribers) => {
|
||||||
total += subscribers.size
|
total += subscribers.size
|
||||||
})
|
})
|
||||||
return total
|
return total
|
||||||
@ -179,6 +180,11 @@ export class MockMainPreferenceService {
|
|||||||
return stats
|
return stats
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Getter for testing purposes
|
||||||
|
public get isInitialized() {
|
||||||
|
return this._initialized
|
||||||
|
}
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
public static registerIpcHandler = vi.fn((): void => {
|
public static registerIpcHandler = vi.fn((): void => {
|
||||||
// Mock IPC handler registration
|
// Mock IPC handler registration
|
||||||
@ -205,7 +211,7 @@ export const MockMainPreferenceServiceUtils = {
|
|||||||
*/
|
*/
|
||||||
resetMocks: () => {
|
resetMocks: () => {
|
||||||
// Reset all method mocks
|
// Reset all method mocks
|
||||||
Object.values(mockInstance).forEach(method => {
|
Object.values(mockInstance).forEach((method) => {
|
||||||
if (vi.isMockFunction(method)) {
|
if (vi.isMockFunction(method)) {
|
||||||
method.mockClear()
|
method.mockClear()
|
||||||
}
|
}
|
||||||
@ -283,4 +289,4 @@ export const MockMainPreferenceServiceUtils = {
|
|||||||
windows: Array.from(mockSubscriptions.entries()).map(([windowId, keys]) => [windowId, keys.size]),
|
windows: Array.from(mockSubscriptions.entries()).map(([windowId, keys]) => [windowId, keys.size]),
|
||||||
mainSubscribers: Array.from(mockMainSubscribers.entries()).map(([key, subs]) => [key, subs.size])
|
mainSubscribers: Array.from(mockMainSubscribers.entries()).map(([key, subs]) => [key, subs.size])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,7 @@ import type {
|
|||||||
RendererPersistCacheKey,
|
RendererPersistCacheKey,
|
||||||
RendererPersistCacheSchema,
|
RendererPersistCacheSchema,
|
||||||
UseCacheKey,
|
UseCacheKey,
|
||||||
UseCacheSchema,
|
UseSharedCacheKey
|
||||||
UseSharedCacheKey,
|
|
||||||
UseSharedCacheSchema
|
|
||||||
} from '@shared/data/cache/cacheSchemas'
|
} from '@shared/data/cache/cacheSchemas'
|
||||||
import { DefaultRendererPersistCache, DefaultUseCache, DefaultUseSharedCache } from '@shared/data/cache/cacheSchemas'
|
import { DefaultRendererPersistCache, DefaultUseCache, DefaultUseSharedCache } from '@shared/data/cache/cacheSchemas'
|
||||||
import type { CacheSubscriber } from '@shared/data/cache/cacheTypes'
|
import type { CacheSubscriber } from '@shared/data/cache/cacheTypes'
|
||||||
@ -18,11 +16,13 @@ import { vi } from 'vitest'
|
|||||||
/**
|
/**
|
||||||
* Create a mock CacheService with realistic behavior
|
* Create a mock CacheService with realistic behavior
|
||||||
*/
|
*/
|
||||||
export const createMockCacheService = (options: {
|
export const createMockCacheService = (
|
||||||
initialMemoryCache?: Map<string, any>
|
options: {
|
||||||
initialSharedCache?: Map<string, any>
|
initialMemoryCache?: Map<string, any>
|
||||||
initialPersistCache?: Map<RendererPersistCacheKey, any>
|
initialSharedCache?: Map<string, any>
|
||||||
} = {}) => {
|
initialPersistCache?: Map<RendererPersistCacheKey, any>
|
||||||
|
} = {}
|
||||||
|
) => {
|
||||||
// Mock cache storage
|
// Mock cache storage
|
||||||
const memoryCache = new Map<string, any>(options.initialMemoryCache || [])
|
const memoryCache = new Map<string, any>(options.initialMemoryCache || [])
|
||||||
const sharedCache = new Map<string, any>(options.initialSharedCache || [])
|
const sharedCache = new Map<string, any>(options.initialSharedCache || [])
|
||||||
@ -32,10 +32,10 @@ export const createMockCacheService = (options: {
|
|||||||
const subscribers = new Map<string, Set<CacheSubscriber>>()
|
const subscribers = new Map<string, Set<CacheSubscriber>>()
|
||||||
|
|
||||||
// Helper function to notify subscribers
|
// Helper function to notify subscribers
|
||||||
const notifySubscribers = (key: string, value: any) => {
|
const notifySubscribers = (key: string) => {
|
||||||
const keySubscribers = subscribers.get(key)
|
const keySubscribers = subscribers.get(key)
|
||||||
if (keySubscribers) {
|
if (keySubscribers) {
|
||||||
keySubscribers.forEach(callback => {
|
keySubscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -56,11 +56,11 @@ export const createMockCacheService = (options: {
|
|||||||
return defaultValue !== undefined ? defaultValue : null
|
return defaultValue !== undefined ? defaultValue : null
|
||||||
}),
|
}),
|
||||||
|
|
||||||
set: vi.fn(<T>(key: string, value: T, ttl?: number): void => {
|
set: vi.fn(<T>(key: string, value: T): void => {
|
||||||
const oldValue = memoryCache.get(key)
|
const oldValue = memoryCache.get(key)
|
||||||
memoryCache.set(key, value)
|
memoryCache.set(key, value)
|
||||||
if (oldValue !== value) {
|
if (oldValue !== value) {
|
||||||
notifySubscribers(key, value)
|
notifySubscribers(key)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ export const createMockCacheService = (options: {
|
|||||||
const existed = memoryCache.has(key)
|
const existed = memoryCache.has(key)
|
||||||
memoryCache.delete(key)
|
memoryCache.delete(key)
|
||||||
if (existed) {
|
if (existed) {
|
||||||
notifySubscribers(key, null)
|
notifySubscribers(key)
|
||||||
}
|
}
|
||||||
return existed
|
return existed
|
||||||
}),
|
}),
|
||||||
@ -76,7 +76,7 @@ export const createMockCacheService = (options: {
|
|||||||
clear: vi.fn((): void => {
|
clear: vi.fn((): void => {
|
||||||
const keys = Array.from(memoryCache.keys())
|
const keys = Array.from(memoryCache.keys())
|
||||||
memoryCache.clear()
|
memoryCache.clear()
|
||||||
keys.forEach(key => notifySubscribers(key, null))
|
keys.forEach((key) => notifySubscribers(key))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
has: vi.fn((key: string): boolean => {
|
has: vi.fn((key: string): boolean => {
|
||||||
@ -96,11 +96,11 @@ export const createMockCacheService = (options: {
|
|||||||
return defaultValue !== undefined ? defaultValue : null
|
return defaultValue !== undefined ? defaultValue : null
|
||||||
}),
|
}),
|
||||||
|
|
||||||
setShared: vi.fn(<T>(key: string, value: T, ttl?: number): void => {
|
setShared: vi.fn(<T>(key: string, value: T): void => {
|
||||||
const oldValue = sharedCache.get(key)
|
const oldValue = sharedCache.get(key)
|
||||||
sharedCache.set(key, value)
|
sharedCache.set(key, value)
|
||||||
if (oldValue !== value) {
|
if (oldValue !== value) {
|
||||||
notifySubscribers(`shared:${key}`, value)
|
notifySubscribers(`shared:${key}`)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ export const createMockCacheService = (options: {
|
|||||||
const existed = sharedCache.has(key)
|
const existed = sharedCache.has(key)
|
||||||
sharedCache.delete(key)
|
sharedCache.delete(key)
|
||||||
if (existed) {
|
if (existed) {
|
||||||
notifySubscribers(`shared:${key}`, null)
|
notifySubscribers(`shared:${key}`)
|
||||||
}
|
}
|
||||||
return existed
|
return existed
|
||||||
}),
|
}),
|
||||||
@ -116,7 +116,7 @@ export const createMockCacheService = (options: {
|
|||||||
clearShared: vi.fn((): void => {
|
clearShared: vi.fn((): void => {
|
||||||
const keys = Array.from(sharedCache.keys())
|
const keys = Array.from(sharedCache.keys())
|
||||||
sharedCache.clear()
|
sharedCache.clear()
|
||||||
keys.forEach(key => notifySubscribers(`shared:${key}`, null))
|
keys.forEach((key) => notifySubscribers(`shared:${key}`))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Persist cache methods
|
// Persist cache methods
|
||||||
@ -131,7 +131,7 @@ export const createMockCacheService = (options: {
|
|||||||
const oldValue = persistCache.get(key)
|
const oldValue = persistCache.get(key)
|
||||||
persistCache.set(key, value)
|
persistCache.set(key, value)
|
||||||
if (oldValue !== value) {
|
if (oldValue !== value) {
|
||||||
notifySubscribers(`persist:${key}`, value)
|
notifySubscribers(`persist:${key}`)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ export const createMockCacheService = (options: {
|
|||||||
const existed = persistCache.has(key)
|
const existed = persistCache.has(key)
|
||||||
persistCache.delete(key)
|
persistCache.delete(key)
|
||||||
if (existed) {
|
if (existed) {
|
||||||
notifySubscribers(`persist:${key}`, DefaultRendererPersistCache[key])
|
notifySubscribers(`persist:${key}`)
|
||||||
}
|
}
|
||||||
return existed
|
return existed
|
||||||
}),
|
}),
|
||||||
@ -147,7 +147,7 @@ export const createMockCacheService = (options: {
|
|||||||
clearPersist: vi.fn((): void => {
|
clearPersist: vi.fn((): void => {
|
||||||
const keys = Array.from(persistCache.keys()) as RendererPersistCacheKey[]
|
const keys = Array.from(persistCache.keys()) as RendererPersistCacheKey[]
|
||||||
persistCache.clear()
|
persistCache.clear()
|
||||||
keys.forEach(key => notifySubscribers(`persist:${key}`, DefaultRendererPersistCache[key]))
|
keys.forEach((key) => notifySubscribers(`persist:${key}`))
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Subscription methods
|
// Subscription methods
|
||||||
@ -184,11 +184,11 @@ export const createMockCacheService = (options: {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
// Hook reference tracking (for advanced cache management)
|
// Hook reference tracking (for advanced cache management)
|
||||||
addHookReference: vi.fn((key: string): void => {
|
addHookReference: vi.fn((): void => {
|
||||||
// Mock implementation - in real service this prevents cache cleanup
|
// Mock implementation - in real service this prevents cache cleanup
|
||||||
}),
|
}),
|
||||||
|
|
||||||
removeHookReference: vi.fn((key: string): void => {
|
removeHookReference: vi.fn((): void => {
|
||||||
// Mock implementation
|
// Mock implementation
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -253,11 +253,11 @@ export const MockCacheService = {
|
|||||||
|
|
||||||
// Delegate all methods to the mock
|
// Delegate all methods to the mock
|
||||||
get<T>(key: string): T | null {
|
get<T>(key: string): T | null {
|
||||||
return mockCacheService.get<T>(key)
|
return mockCacheService.get(key) as T | null
|
||||||
}
|
}
|
||||||
|
|
||||||
set<T>(key: string, value: T, ttl?: number): void {
|
set<T>(key: string, value: T): void {
|
||||||
return mockCacheService.set(key, value, ttl)
|
return mockCacheService.set(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(key: string): boolean {
|
delete(key: string): boolean {
|
||||||
@ -277,11 +277,11 @@ export const MockCacheService = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getShared<T>(key: string): T | null {
|
getShared<T>(key: string): T | null {
|
||||||
return mockCacheService.getShared<T>(key)
|
return mockCacheService.getShared(key) as T | null
|
||||||
}
|
}
|
||||||
|
|
||||||
setShared<T>(key: string, value: T, ttl?: number): void {
|
setShared<T>(key: string, value: T): void {
|
||||||
return mockCacheService.setShared(key, value, ttl)
|
return mockCacheService.setShared(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteShared(key: string): boolean {
|
deleteShared(key: string): boolean {
|
||||||
@ -316,12 +316,12 @@ export const MockCacheService = {
|
|||||||
return mockCacheService.unsubscribe(key, callback)
|
return mockCacheService.unsubscribe(key, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
addHookReference(key: string): void {
|
addHookReference(): void {
|
||||||
return mockCacheService.addHookReference(key)
|
return mockCacheService.addHookReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
removeHookReference(key: string): void {
|
removeHookReference(): void {
|
||||||
return mockCacheService.removeHookReference(key)
|
return mockCacheService.removeHookReference()
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllKeys(): string[] {
|
getAllKeys(): string[] {
|
||||||
@ -343,7 +343,7 @@ export const MockCacheUtils = {
|
|||||||
* Reset all mock function call counts and state
|
* Reset all mock function call counts and state
|
||||||
*/
|
*/
|
||||||
resetMocks: () => {
|
resetMocks: () => {
|
||||||
Object.values(mockCacheService).forEach(method => {
|
Object.values(mockCacheService).forEach((method) => {
|
||||||
if (vi.isMockFunction(method)) {
|
if (vi.isMockFunction(method)) {
|
||||||
method.mockClear()
|
method.mockClear()
|
||||||
}
|
}
|
||||||
@ -386,4 +386,4 @@ export const MockCacheUtils = {
|
|||||||
triggerCacheChange: (key: string, value: any) => {
|
triggerCacheChange: (key: string, value: any) => {
|
||||||
mockCacheService.set(key, value)
|
mockCacheService.set(key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,5 @@
|
|||||||
import type { ConcreteApiPaths } from '@shared/data/api/apiSchemas'
|
import type { ApiClient, ConcreteApiPaths } from '@shared/data/api/apiSchemas'
|
||||||
import type {
|
import type { DataResponse } from '@shared/data/api/apiTypes'
|
||||||
ApiClient,
|
|
||||||
BatchRequest,
|
|
||||||
BatchResponse,
|
|
||||||
DataRequest,
|
|
||||||
DataResponse,
|
|
||||||
SubscriptionCallback,
|
|
||||||
SubscriptionOptions,
|
|
||||||
TransactionRequest
|
|
||||||
} from '@shared/data/api/apiTypes'
|
|
||||||
import { vi } from 'vitest'
|
import { vi } from 'vitest'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,20 +9,21 @@ import { vi } from 'vitest'
|
|||||||
|
|
||||||
// Mock response utilities
|
// Mock response utilities
|
||||||
const createMockResponse = <T>(data: T, success = true): DataResponse<T> => ({
|
const createMockResponse = <T>(data: T, success = true): DataResponse<T> => ({
|
||||||
success,
|
id: 'mock-id',
|
||||||
|
status: success ? 200 : 500,
|
||||||
data,
|
data,
|
||||||
timestamp: new Date().toISOString(),
|
...(success ? {} : { error: { code: 'MOCK_ERROR', message: 'Mock error', details: {}, status: 500 } })
|
||||||
...(success ? {} : { error: { code: 'MOCK_ERROR', message: 'Mock error', details: {} } })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const createMockError = (message: string): DataResponse<never> => ({
|
const createMockError = (message: string): DataResponse<never> => ({
|
||||||
success: false,
|
id: 'mock-error-id',
|
||||||
|
status: 500,
|
||||||
error: {
|
error: {
|
||||||
code: 'MOCK_ERROR',
|
code: 'MOCK_ERROR',
|
||||||
message,
|
message,
|
||||||
details: {}
|
details: {},
|
||||||
},
|
status: 500
|
||||||
timestamp: new Date().toISOString()
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,80 +32,25 @@ const createMockError = (message: string): DataResponse<never> => ({
|
|||||||
export const createMockDataApiService = (customBehavior: Partial<ApiClient> = {}): ApiClient => {
|
export const createMockDataApiService = (customBehavior: Partial<ApiClient> = {}): ApiClient => {
|
||||||
const mockService: ApiClient = {
|
const mockService: ApiClient = {
|
||||||
// HTTP Methods
|
// HTTP Methods
|
||||||
get: vi.fn(async (path: ConcreteApiPaths, options?: any) => {
|
get: vi.fn(async (path: ConcreteApiPaths) => {
|
||||||
// Default mock behavior - return empty data based on path
|
// Default mock behavior - return raw data based on path
|
||||||
const mockData = getMockDataForPath(path, 'GET')
|
return getMockDataForPath(path, 'GET') as any
|
||||||
return createMockResponse(mockData)
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
post: vi.fn(async (path: ConcreteApiPaths, options?: any) => {
|
post: vi.fn(async (path: ConcreteApiPaths) => {
|
||||||
const mockData = getMockDataForPath(path, 'POST')
|
return getMockDataForPath(path, 'POST') as any
|
||||||
return createMockResponse(mockData)
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
put: vi.fn(async (path: ConcreteApiPaths, options?: any) => {
|
put: vi.fn(async (path: ConcreteApiPaths) => {
|
||||||
const mockData = getMockDataForPath(path, 'PUT')
|
return getMockDataForPath(path, 'PUT') as any
|
||||||
return createMockResponse(mockData)
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
patch: vi.fn(async (path: ConcreteApiPaths, options?: any) => {
|
patch: vi.fn(async (path: ConcreteApiPaths) => {
|
||||||
const mockData = getMockDataForPath(path, 'PATCH')
|
return getMockDataForPath(path, 'PATCH') as any
|
||||||
return createMockResponse(mockData)
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
delete: vi.fn(async (path: ConcreteApiPaths, options?: any) => {
|
delete: vi.fn(async () => {
|
||||||
return createMockResponse({ deleted: true })
|
return { deleted: true } as any
|
||||||
}),
|
|
||||||
|
|
||||||
// Batch operations
|
|
||||||
batch: vi.fn(async (requests: BatchRequest[]): Promise<BatchResponse> => {
|
|
||||||
const responses = requests.map((request, index) => ({
|
|
||||||
id: request.id || `batch_${index}`,
|
|
||||||
success: true,
|
|
||||||
data: getMockDataForPath(request.path as ConcreteApiPaths, request.method),
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
}))
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
responses,
|
|
||||||
timestamp: new Date().toISOString()
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Transaction support
|
|
||||||
transaction: vi.fn(async (operations: TransactionRequest[]): Promise<DataResponse<any[]>> => {
|
|
||||||
const results = operations.map((op, index) => ({
|
|
||||||
operation: op.operation,
|
|
||||||
result: getMockDataForPath(op.path as ConcreteApiPaths, 'POST'),
|
|
||||||
success: true
|
|
||||||
}))
|
|
||||||
|
|
||||||
return createMockResponse(results)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Subscription methods
|
|
||||||
subscribe: vi.fn((path: ConcreteApiPaths, callback: SubscriptionCallback, options?: SubscriptionOptions) => {
|
|
||||||
// Return a mock unsubscribe function
|
|
||||||
return vi.fn()
|
|
||||||
}),
|
|
||||||
|
|
||||||
unsubscribe: vi.fn((path: ConcreteApiPaths) => {
|
|
||||||
// Mock unsubscribe
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Connection management
|
|
||||||
connect: vi.fn(async () => {
|
|
||||||
return createMockResponse({ connected: true })
|
|
||||||
}),
|
|
||||||
|
|
||||||
disconnect: vi.fn(async () => {
|
|
||||||
return createMockResponse({ disconnected: true })
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Health check
|
|
||||||
ping: vi.fn(async () => {
|
|
||||||
return createMockResponse({ pong: true, timestamp: new Date().toISOString() })
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Apply custom behavior overrides
|
// Apply custom behavior overrides
|
||||||
@ -229,34 +166,6 @@ export const MockDataApiService = {
|
|||||||
async delete(path: ConcreteApiPaths, options?: any) {
|
async delete(path: ConcreteApiPaths, options?: any) {
|
||||||
return mockDataApiService.delete(path, options)
|
return mockDataApiService.delete(path, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
async batch(requests: BatchRequest[]) {
|
|
||||||
return mockDataApiService.batch(requests)
|
|
||||||
}
|
|
||||||
|
|
||||||
async transaction(operations: TransactionRequest[]) {
|
|
||||||
return mockDataApiService.transaction(operations)
|
|
||||||
}
|
|
||||||
|
|
||||||
subscribe(path: ConcreteApiPaths, callback: SubscriptionCallback, options?: SubscriptionOptions) {
|
|
||||||
return mockDataApiService.subscribe(path, callback, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsubscribe(path: ConcreteApiPaths) {
|
|
||||||
return mockDataApiService.unsubscribe(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
async connect() {
|
|
||||||
return mockDataApiService.connect()
|
|
||||||
}
|
|
||||||
|
|
||||||
async disconnect() {
|
|
||||||
return mockDataApiService.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
async ping() {
|
|
||||||
return mockDataApiService.ping()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
dataApiService: mockDataApiService
|
dataApiService: mockDataApiService
|
||||||
}
|
}
|
||||||
@ -269,7 +178,7 @@ export const MockDataApiUtils = {
|
|||||||
* Reset all mock function call counts and implementations
|
* Reset all mock function call counts and implementations
|
||||||
*/
|
*/
|
||||||
resetMocks: () => {
|
resetMocks: () => {
|
||||||
Object.values(mockDataApiService).forEach(method => {
|
Object.values(mockDataApiService).forEach((method) => {
|
||||||
if (vi.isMockFunction(method)) {
|
if (vi.isMockFunction(method)) {
|
||||||
method.mockClear()
|
method.mockClear()
|
||||||
}
|
}
|
||||||
@ -282,7 +191,7 @@ export const MockDataApiUtils = {
|
|||||||
setCustomResponse: (path: ConcreteApiPaths, method: string, response: any) => {
|
setCustomResponse: (path: ConcreteApiPaths, method: string, response: any) => {
|
||||||
const methodFn = mockDataApiService[method.toLowerCase() as keyof ApiClient] as any
|
const methodFn = mockDataApiService[method.toLowerCase() as keyof ApiClient] as any
|
||||||
if (vi.isMockFunction(methodFn)) {
|
if (vi.isMockFunction(methodFn)) {
|
||||||
methodFn.mockImplementation(async (requestPath: string, options?: any) => {
|
methodFn.mockImplementation(async (requestPath: string) => {
|
||||||
if (requestPath === path) {
|
if (requestPath === path) {
|
||||||
return createMockResponse(response)
|
return createMockResponse(response)
|
||||||
}
|
}
|
||||||
@ -298,7 +207,7 @@ export const MockDataApiUtils = {
|
|||||||
setErrorResponse: (path: ConcreteApiPaths, method: string, errorMessage: string) => {
|
setErrorResponse: (path: ConcreteApiPaths, method: string, errorMessage: string) => {
|
||||||
const methodFn = mockDataApiService[method.toLowerCase() as keyof ApiClient] as any
|
const methodFn = mockDataApiService[method.toLowerCase() as keyof ApiClient] as any
|
||||||
if (vi.isMockFunction(methodFn)) {
|
if (vi.isMockFunction(methodFn)) {
|
||||||
methodFn.mockImplementation(async (requestPath: string, options?: any) => {
|
methodFn.mockImplementation(async (requestPath: string) => {
|
||||||
if (requestPath === path) {
|
if (requestPath === path) {
|
||||||
return createMockError(errorMessage)
|
return createMockError(errorMessage)
|
||||||
}
|
}
|
||||||
@ -323,4 +232,4 @@ export const MockDataApiUtils = {
|
|||||||
const methodFn = mockDataApiService[method] as any
|
const methodFn = mockDataApiService[method] as any
|
||||||
return vi.isMockFunction(methodFn) ? methodFn.mock.calls : []
|
return vi.isMockFunction(methodFn) ? methodFn.mock.calls : []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export const mockPreferenceDefaults: Record<string, any> = {
|
|||||||
|
|
||||||
// App preferences
|
// App preferences
|
||||||
'app.user.name': 'MockUser',
|
'app.user.name': 'MockUser',
|
||||||
'app.language': 'zh-CN',
|
'app.language': 'zh-CN'
|
||||||
|
|
||||||
// Add more defaults as needed
|
// Add more defaults as needed
|
||||||
}
|
}
|
||||||
@ -76,14 +76,14 @@ export const createMockPreferenceService = (customDefaults: Record<string, any>
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
clear: vi.fn(() => {
|
clear: vi.fn(() => {
|
||||||
Object.keys(mergedDefaults).forEach(key => delete mergedDefaults[key])
|
Object.keys(mergedDefaults).forEach((key) => delete mergedDefaults[key])
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Internal state access for testing
|
// Internal state access for testing
|
||||||
_getMockState: () => ({ ...mergedDefaults }),
|
_getMockState: () => ({ ...mergedDefaults }),
|
||||||
_resetMockState: () => {
|
_resetMockState: () => {
|
||||||
Object.keys(mergedDefaults).forEach(key => delete mergedDefaults[key])
|
Object.keys(mergedDefaults).forEach((key) => delete mergedDefaults[key])
|
||||||
Object.assign(mergedDefaults, mockPreferenceDefaults, customDefaults)
|
Object.assign(mergedDefaults, mockPreferenceDefaults, customDefaults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,4 +95,4 @@ export const mockPreferenceService = createMockPreferenceService()
|
|||||||
// Export for easy mocking in individual tests
|
// Export for easy mocking in individual tests
|
||||||
export const MockPreferenceService = {
|
export const MockPreferenceService = {
|
||||||
preferenceService: mockPreferenceService
|
preferenceService: mockPreferenceService
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ const mockPersistSubscribers = new Map<RendererPersistCacheKey, Set<() => void>>
|
|||||||
const notifyMemorySubscribers = (key: UseCacheKey) => {
|
const notifyMemorySubscribers = (key: UseCacheKey) => {
|
||||||
const subscribers = mockMemorySubscribers.get(key)
|
const subscribers = mockMemorySubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.forEach(callback => {
|
subscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -54,7 +54,7 @@ const notifyMemorySubscribers = (key: UseCacheKey) => {
|
|||||||
const notifySharedSubscribers = (key: UseSharedCacheKey) => {
|
const notifySharedSubscribers = (key: UseSharedCacheKey) => {
|
||||||
const subscribers = mockSharedSubscribers.get(key)
|
const subscribers = mockSharedSubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.forEach(callback => {
|
subscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -67,7 +67,7 @@ const notifySharedSubscribers = (key: UseSharedCacheKey) => {
|
|||||||
const notifyPersistSubscribers = (key: RendererPersistCacheKey) => {
|
const notifyPersistSubscribers = (key: RendererPersistCacheKey) => {
|
||||||
const subscribers = mockPersistSubscribers.get(key)
|
const subscribers = mockPersistSubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.forEach(callback => {
|
subscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -80,77 +80,83 @@ const notifyPersistSubscribers = (key: RendererPersistCacheKey) => {
|
|||||||
/**
|
/**
|
||||||
* Mock useCache hook (memory cache)
|
* Mock useCache hook (memory cache)
|
||||||
*/
|
*/
|
||||||
export const mockUseCache = vi.fn(<K extends UseCacheKey>(
|
export const mockUseCache = vi.fn(
|
||||||
key: K,
|
<K extends UseCacheKey>(
|
||||||
initValue?: UseCacheSchema[K]
|
key: K,
|
||||||
): [UseCacheSchema[K], (value: UseCacheSchema[K]) => void] => {
|
initValue?: UseCacheSchema[K]
|
||||||
// Get current value
|
): [UseCacheSchema[K], (value: UseCacheSchema[K]) => void] => {
|
||||||
let currentValue = mockMemoryCache.get(key)
|
// Get current value
|
||||||
if (currentValue === undefined) {
|
let currentValue = mockMemoryCache.get(key)
|
||||||
currentValue = initValue ?? DefaultUseCache[key]
|
if (currentValue === undefined) {
|
||||||
if (currentValue !== undefined) {
|
currentValue = initValue ?? DefaultUseCache[key]
|
||||||
mockMemoryCache.set(key, currentValue)
|
if (currentValue !== undefined) {
|
||||||
|
mockMemoryCache.set(key, currentValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mock setValue function
|
||||||
|
const setValue = vi.fn((value: UseCacheSchema[K]) => {
|
||||||
|
mockMemoryCache.set(key, value)
|
||||||
|
notifyMemorySubscribers(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
return [currentValue, setValue]
|
||||||
}
|
}
|
||||||
|
)
|
||||||
// Mock setValue function
|
|
||||||
const setValue = vi.fn((value: UseCacheSchema[K]) => {
|
|
||||||
mockMemoryCache.set(key, value)
|
|
||||||
notifyMemorySubscribers(key)
|
|
||||||
})
|
|
||||||
|
|
||||||
return [currentValue, setValue]
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock useSharedCache hook (shared cache)
|
* Mock useSharedCache hook (shared cache)
|
||||||
*/
|
*/
|
||||||
export const mockUseSharedCache = vi.fn(<K extends UseSharedCacheKey>(
|
export const mockUseSharedCache = vi.fn(
|
||||||
key: K,
|
<K extends UseSharedCacheKey>(
|
||||||
initValue?: UseSharedCacheSchema[K]
|
key: K,
|
||||||
): [UseSharedCacheSchema[K], (value: UseSharedCacheSchema[K]) => void] => {
|
initValue?: UseSharedCacheSchema[K]
|
||||||
// Get current value
|
): [UseSharedCacheSchema[K], (value: UseSharedCacheSchema[K]) => void] => {
|
||||||
let currentValue = mockSharedCache.get(key)
|
// Get current value
|
||||||
if (currentValue === undefined) {
|
let currentValue = mockSharedCache.get(key)
|
||||||
currentValue = initValue ?? DefaultUseSharedCache[key]
|
if (currentValue === undefined) {
|
||||||
if (currentValue !== undefined) {
|
currentValue = initValue ?? DefaultUseSharedCache[key]
|
||||||
mockSharedCache.set(key, currentValue)
|
if (currentValue !== undefined) {
|
||||||
|
mockSharedCache.set(key, currentValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mock setValue function
|
||||||
|
const setValue = vi.fn((value: UseSharedCacheSchema[K]) => {
|
||||||
|
mockSharedCache.set(key, value)
|
||||||
|
notifySharedSubscribers(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
return [currentValue, setValue]
|
||||||
}
|
}
|
||||||
|
)
|
||||||
// Mock setValue function
|
|
||||||
const setValue = vi.fn((value: UseSharedCacheSchema[K]) => {
|
|
||||||
mockSharedCache.set(key, value)
|
|
||||||
notifySharedSubscribers(key)
|
|
||||||
})
|
|
||||||
|
|
||||||
return [currentValue, setValue]
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock usePersistCache hook (persistent cache)
|
* Mock usePersistCache hook (persistent cache)
|
||||||
*/
|
*/
|
||||||
export const mockUsePersistCache = vi.fn(<K extends RendererPersistCacheKey>(
|
export const mockUsePersistCache = vi.fn(
|
||||||
key: K,
|
<K extends RendererPersistCacheKey>(
|
||||||
initValue?: RendererPersistCacheSchema[K]
|
key: K,
|
||||||
): [RendererPersistCacheSchema[K], (value: RendererPersistCacheSchema[K]) => void] => {
|
initValue?: RendererPersistCacheSchema[K]
|
||||||
// Get current value
|
): [RendererPersistCacheSchema[K], (value: RendererPersistCacheSchema[K]) => void] => {
|
||||||
let currentValue = mockPersistCache.get(key)
|
// Get current value
|
||||||
if (currentValue === undefined) {
|
let currentValue = mockPersistCache.get(key)
|
||||||
currentValue = initValue ?? DefaultRendererPersistCache[key]
|
if (currentValue === undefined) {
|
||||||
if (currentValue !== undefined) {
|
currentValue = initValue ?? DefaultRendererPersistCache[key]
|
||||||
mockPersistCache.set(key, currentValue)
|
if (currentValue !== undefined) {
|
||||||
|
mockPersistCache.set(key, currentValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mock setValue function
|
||||||
|
const setValue = vi.fn((value: RendererPersistCacheSchema[K]) => {
|
||||||
|
mockPersistCache.set(key, value)
|
||||||
|
notifyPersistSubscribers(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
return [currentValue, setValue]
|
||||||
}
|
}
|
||||||
|
)
|
||||||
// Mock setValue function
|
|
||||||
const setValue = vi.fn((value: RendererPersistCacheSchema[K]) => {
|
|
||||||
mockPersistCache.set(key, value)
|
|
||||||
notifyPersistSubscribers(key)
|
|
||||||
})
|
|
||||||
|
|
||||||
return [currentValue, setValue]
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export all mocks as a unified module
|
* Export all mocks as a unified module
|
||||||
@ -292,18 +298,12 @@ export const MockUseCacheUtils = {
|
|||||||
) => {
|
) => {
|
||||||
mockUseCache.mockImplementation((cacheKey, initValue) => {
|
mockUseCache.mockImplementation((cacheKey, initValue) => {
|
||||||
if (cacheKey === key) {
|
if (cacheKey === key) {
|
||||||
return [
|
return [value, setValue || vi.fn()]
|
||||||
value,
|
|
||||||
setValue || vi.fn()
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior for other keys
|
// Default behavior for other keys
|
||||||
const defaultValue = mockMemoryCache.get(cacheKey) ?? initValue ?? DefaultUseCache[cacheKey]
|
const defaultValue = mockMemoryCache.get(cacheKey) ?? initValue ?? DefaultUseCache[cacheKey]
|
||||||
return [
|
return [defaultValue, vi.fn()]
|
||||||
defaultValue,
|
|
||||||
vi.fn()
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -317,18 +317,12 @@ export const MockUseCacheUtils = {
|
|||||||
) => {
|
) => {
|
||||||
mockUseSharedCache.mockImplementation((cacheKey, initValue) => {
|
mockUseSharedCache.mockImplementation((cacheKey, initValue) => {
|
||||||
if (cacheKey === key) {
|
if (cacheKey === key) {
|
||||||
return [
|
return [value, setValue || vi.fn()]
|
||||||
value,
|
|
||||||
setValue || vi.fn()
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior for other keys
|
// Default behavior for other keys
|
||||||
const defaultValue = mockSharedCache.get(cacheKey) ?? initValue ?? DefaultUseSharedCache[cacheKey]
|
const defaultValue = mockSharedCache.get(cacheKey) ?? initValue ?? DefaultUseSharedCache[cacheKey]
|
||||||
return [
|
return [defaultValue, vi.fn()]
|
||||||
defaultValue,
|
|
||||||
vi.fn()
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -342,18 +336,12 @@ export const MockUseCacheUtils = {
|
|||||||
) => {
|
) => {
|
||||||
mockUsePersistCache.mockImplementation((cacheKey, initValue) => {
|
mockUsePersistCache.mockImplementation((cacheKey, initValue) => {
|
||||||
if (cacheKey === key) {
|
if (cacheKey === key) {
|
||||||
return [
|
return [value, setValue || vi.fn()]
|
||||||
value,
|
|
||||||
setValue || vi.fn()
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior for other keys
|
// Default behavior for other keys
|
||||||
const defaultValue = mockPersistCache.get(cacheKey) ?? initValue ?? DefaultRendererPersistCache[cacheKey]
|
const defaultValue = mockPersistCache.get(cacheKey) ?? initValue ?? DefaultRendererPersistCache[cacheKey]
|
||||||
return [
|
return [defaultValue, vi.fn()]
|
||||||
defaultValue,
|
|
||||||
vi.fn()
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -425,4 +413,4 @@ export const MockUseCacheUtils = {
|
|||||||
shared: Array.from(mockSharedSubscribers.entries()).map(([key, subs]) => [key, subs.size]),
|
shared: Array.from(mockSharedSubscribers.entries()).map(([key, subs]) => [key, subs.size]),
|
||||||
persist: Array.from(mockPersistSubscribers.entries()).map(([key, subs]) => [key, subs.size])
|
persist: Array.from(mockPersistSubscribers.entries()).map(([key, subs]) => [key, subs.size])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,133 +71,134 @@ function createMockDataForPath(path: ConcreteApiPaths): any {
|
|||||||
/**
|
/**
|
||||||
* Mock useQuery hook
|
* Mock useQuery hook
|
||||||
*/
|
*/
|
||||||
export const mockUseQuery = vi.fn(<TPath extends ConcreteApiPaths>(
|
export const mockUseQuery = vi.fn(
|
||||||
path: TPath | null,
|
<TPath extends ConcreteApiPaths>(path: TPath | null, _query?: any, options?: any): MockSWRResponse<any> => {
|
||||||
query?: any,
|
const isLoading = options?.initialLoading ?? false
|
||||||
options?: any
|
const hasError = options?.shouldError ?? false
|
||||||
): MockSWRResponse<any> => {
|
|
||||||
const isLoading = options?.initialLoading ?? false
|
if (hasError) {
|
||||||
const hasError = options?.shouldError ?? false
|
return {
|
||||||
|
data: undefined,
|
||||||
|
error: new Error(`Mock error for ${path}`),
|
||||||
|
isLoading: false,
|
||||||
|
isValidating: false,
|
||||||
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockData = path ? createMockDataForPath(path) : undefined
|
||||||
|
|
||||||
if (hasError) {
|
|
||||||
return {
|
return {
|
||||||
data: undefined,
|
data: mockData,
|
||||||
error: new Error(`Mock error for ${path}`),
|
error: undefined,
|
||||||
isLoading: false,
|
isLoading,
|
||||||
isValidating: false,
|
isValidating: false,
|
||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
mutate: vi.fn().mockResolvedValue(mockData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
const mockData = path ? createMockDataForPath(path) : undefined
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: mockData,
|
|
||||||
error: undefined,
|
|
||||||
isLoading,
|
|
||||||
isValidating: false,
|
|
||||||
mutate: vi.fn().mockResolvedValue(mockData)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock useMutation hook
|
* Mock useMutation hook
|
||||||
*/
|
*/
|
||||||
export const mockUseMutation = vi.fn(<TPath extends ConcreteApiPaths, TMethod extends 'POST' | 'PUT' | 'DELETE' | 'PATCH'>(
|
export const mockUseMutation = vi.fn(
|
||||||
path: TPath,
|
<TPath extends ConcreteApiPaths, TMethod extends 'POST' | 'PUT' | 'DELETE' | 'PATCH'>(
|
||||||
method: TMethod,
|
path: TPath,
|
||||||
options?: any
|
method: TMethod,
|
||||||
): MockMutationResponse<any> => {
|
options?: any
|
||||||
const isMutating = options?.initialMutating ?? false
|
): MockMutationResponse<any> => {
|
||||||
const hasError = options?.shouldError ?? false
|
const isMutating = options?.initialMutating ?? false
|
||||||
|
const hasError = options?.shouldError ?? false
|
||||||
|
|
||||||
const mockTrigger = vi.fn(async (...args: any[]) => {
|
const mockTrigger = vi.fn(async (...args: any[]) => {
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
throw new Error(`Mock mutation error for ${method} ${path}`)
|
throw new Error(`Mock mutation error for ${method} ${path}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate different responses based on method
|
||||||
|
switch (method) {
|
||||||
|
case 'POST':
|
||||||
|
return { id: 'new_item', created: true, ...args[0] }
|
||||||
|
case 'PUT':
|
||||||
|
case 'PATCH':
|
||||||
|
return { id: 'updated_item', updated: true, ...args[0] }
|
||||||
|
case 'DELETE':
|
||||||
|
return { deleted: true }
|
||||||
|
default:
|
||||||
|
return { success: true }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: undefined,
|
||||||
|
error: undefined,
|
||||||
|
isMutating,
|
||||||
|
trigger: mockTrigger,
|
||||||
|
reset: vi.fn()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate different responses based on method
|
|
||||||
switch (method) {
|
|
||||||
case 'POST':
|
|
||||||
return { id: 'new_item', created: true, ...args[0] }
|
|
||||||
case 'PUT':
|
|
||||||
case 'PATCH':
|
|
||||||
return { id: 'updated_item', updated: true, ...args[0] }
|
|
||||||
case 'DELETE':
|
|
||||||
return { deleted: true }
|
|
||||||
default:
|
|
||||||
return { success: true }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: undefined,
|
|
||||||
error: undefined,
|
|
||||||
isMutating,
|
|
||||||
trigger: mockTrigger,
|
|
||||||
reset: vi.fn()
|
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock usePaginatedQuery hook
|
* Mock usePaginatedQuery hook
|
||||||
*/
|
*/
|
||||||
export const mockUsePaginatedQuery = vi.fn(<TPath extends ConcreteApiPaths>(
|
export const mockUsePaginatedQuery = vi.fn(
|
||||||
path: TPath | null,
|
<TPath extends ConcreteApiPaths>(path: TPath | null, _query?: any, options?: any): MockPaginatedResponse<any> => {
|
||||||
query?: any,
|
const isLoading = options?.initialLoading ?? false
|
||||||
options?: any
|
const isLoadingMore = options?.initialLoadingMore ?? false
|
||||||
): MockPaginatedResponse<any> => {
|
const hasError = options?.shouldError ?? false
|
||||||
const isLoading = options?.initialLoading ?? false
|
|
||||||
const isLoadingMore = options?.initialLoadingMore ?? false
|
if (hasError) {
|
||||||
const hasError = options?.shouldError ?? false
|
return {
|
||||||
|
data: undefined,
|
||||||
|
error: new Error(`Mock paginated error for ${path}`),
|
||||||
|
isLoading: false,
|
||||||
|
isValidating: false,
|
||||||
|
mutate: vi.fn().mockResolvedValue(undefined),
|
||||||
|
loadMore: vi.fn(),
|
||||||
|
isLoadingMore: false,
|
||||||
|
hasMore: false,
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockItems = path
|
||||||
|
? [
|
||||||
|
{ id: 'item1', name: 'Mock Item 1' },
|
||||||
|
{ id: 'item2', name: 'Mock Item 2' },
|
||||||
|
{ id: 'item3', name: 'Mock Item 3' }
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
|
||||||
|
const mockData: PaginatedResponse<any> = {
|
||||||
|
items: mockItems,
|
||||||
|
total: mockItems.length,
|
||||||
|
page: 1,
|
||||||
|
pageCount: 1,
|
||||||
|
hasNext: false,
|
||||||
|
hasPrev: false
|
||||||
|
}
|
||||||
|
|
||||||
if (hasError) {
|
|
||||||
return {
|
return {
|
||||||
data: undefined,
|
data: mockData,
|
||||||
error: new Error(`Mock paginated error for ${path}`),
|
error: undefined,
|
||||||
isLoading: false,
|
isLoading,
|
||||||
isValidating: false,
|
isValidating: false,
|
||||||
mutate: vi.fn().mockResolvedValue(undefined),
|
mutate: vi.fn().mockResolvedValue(mockData),
|
||||||
loadMore: vi.fn(),
|
loadMore: vi.fn(),
|
||||||
isLoadingMore: false,
|
isLoadingMore,
|
||||||
hasMore: false,
|
hasMore: mockData.hasNext,
|
||||||
items: []
|
items: mockItems
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
const mockItems = path ? [
|
|
||||||
{ id: 'item1', name: 'Mock Item 1' },
|
|
||||||
{ id: 'item2', name: 'Mock Item 2' },
|
|
||||||
{ id: 'item3', name: 'Mock Item 3' }
|
|
||||||
] : []
|
|
||||||
|
|
||||||
const mockData: PaginatedResponse<any> = {
|
|
||||||
items: mockItems,
|
|
||||||
total: mockItems.length,
|
|
||||||
page: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
hasMore: false
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
data: mockData,
|
|
||||||
error: undefined,
|
|
||||||
isLoading,
|
|
||||||
isValidating: false,
|
|
||||||
mutate: vi.fn().mockResolvedValue(mockData),
|
|
||||||
loadMore: vi.fn(),
|
|
||||||
isLoadingMore,
|
|
||||||
hasMore: mockData.hasMore,
|
|
||||||
items: mockItems
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock useInvalidateCache hook
|
* Mock useInvalidateCache hook
|
||||||
*/
|
*/
|
||||||
export const mockUseInvalidateCache = vi.fn(() => {
|
export const mockUseInvalidateCache = vi.fn(() => {
|
||||||
return {
|
return {
|
||||||
invalidate: vi.fn(async (path?: ConcreteApiPaths) => {
|
invalidate: vi.fn(async () => {
|
||||||
// Mock cache invalidation
|
// Mock cache invalidation
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}),
|
}),
|
||||||
@ -211,13 +212,9 @@ export const mockUseInvalidateCache = vi.fn(() => {
|
|||||||
/**
|
/**
|
||||||
* Mock prefetch function
|
* Mock prefetch function
|
||||||
*/
|
*/
|
||||||
export const mockPrefetch = vi.fn(async <TPath extends ConcreteApiPaths>(
|
export const mockPrefetch = vi.fn(async <TPath extends ConcreteApiPaths>(_path: TPath): Promise<any> => {
|
||||||
path: TPath,
|
|
||||||
query?: any,
|
|
||||||
options?: any
|
|
||||||
): Promise<any> => {
|
|
||||||
// Mock prefetch - return mock data
|
// Mock prefetch - return mock data
|
||||||
return createMockDataForPath(path)
|
return createMockDataForPath(_path)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,13 +258,15 @@ export const MockUseDataApiUtils = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Default behavior for other paths
|
// Default behavior for other paths
|
||||||
return mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
return (
|
||||||
data: undefined,
|
mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
||||||
error: undefined,
|
data: undefined,
|
||||||
isLoading: false,
|
error: undefined,
|
||||||
isValidating: false,
|
isLoading: false,
|
||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
isValidating: false,
|
||||||
}
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -285,13 +284,15 @@ export const MockUseDataApiUtils = {
|
|||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
return (
|
||||||
data: undefined,
|
mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
||||||
error: undefined,
|
data: undefined,
|
||||||
isLoading: false,
|
error: undefined,
|
||||||
isValidating: false,
|
isLoading: false,
|
||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
isValidating: false,
|
||||||
}
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -309,13 +310,15 @@ export const MockUseDataApiUtils = {
|
|||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
return (
|
||||||
data: undefined,
|
mockUseQuery.getMockImplementation()?.(queryPath, query, options) || {
|
||||||
error: undefined,
|
data: undefined,
|
||||||
isLoading: false,
|
error: undefined,
|
||||||
isValidating: false,
|
isLoading: false,
|
||||||
mutate: vi.fn().mockResolvedValue(undefined)
|
isValidating: false,
|
||||||
}
|
mutate: vi.fn().mockResolvedValue(undefined)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -333,13 +336,15 @@ export const MockUseDataApiUtils = {
|
|||||||
reset: vi.fn()
|
reset: vi.fn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mockUseMutation.getMockImplementation()?.(mutationPath, mutationMethod, options) || {
|
return (
|
||||||
data: undefined,
|
mockUseMutation.getMockImplementation()?.(mutationPath, mutationMethod, options) || {
|
||||||
error: undefined,
|
data: undefined,
|
||||||
isMutating: false,
|
error: undefined,
|
||||||
trigger: vi.fn().mockResolvedValue({}),
|
isMutating: false,
|
||||||
reset: vi.fn()
|
trigger: vi.fn().mockResolvedValue({}),
|
||||||
}
|
reset: vi.fn()
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -357,13 +362,15 @@ export const MockUseDataApiUtils = {
|
|||||||
reset: vi.fn()
|
reset: vi.fn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mockUseMutation.getMockImplementation()?.(mutationPath, mutationMethod, options) || {
|
return (
|
||||||
data: undefined,
|
mockUseMutation.getMockImplementation()?.(mutationPath, mutationMethod, options) || {
|
||||||
error: undefined,
|
data: undefined,
|
||||||
isMutating: false,
|
error: undefined,
|
||||||
trigger: vi.fn().mockResolvedValue({}),
|
isMutating: false,
|
||||||
reset: vi.fn()
|
trigger: vi.fn().mockResolvedValue({}),
|
||||||
}
|
reset: vi.fn()
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
import type {
|
import type { PreferenceKeyType, PreferenceUpdateOptions } from '@shared/data/preference/preferenceTypes'
|
||||||
PreferenceKeyType,
|
|
||||||
PreferenceUpdateOptions,
|
|
||||||
PreferenceValueType
|
|
||||||
} from '@shared/data/preference/preferenceTypes'
|
|
||||||
import { vi } from 'vitest'
|
import { vi } from 'vitest'
|
||||||
|
|
||||||
import { mockPreferenceDefaults } from './PreferenceService'
|
import { mockPreferenceDefaults } from './PreferenceService'
|
||||||
@ -27,7 +23,7 @@ const mockPreferenceSubscribers = new Map<PreferenceKeyType, Set<() => void>>()
|
|||||||
const notifyPreferenceSubscribers = (key: PreferenceKeyType) => {
|
const notifyPreferenceSubscribers = (key: PreferenceKeyType) => {
|
||||||
const subscribers = mockPreferenceSubscribers.get(key)
|
const subscribers = mockPreferenceSubscribers.get(key)
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
subscribers.forEach(callback => {
|
subscribers.forEach((callback) => {
|
||||||
try {
|
try {
|
||||||
callback()
|
callback()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -40,111 +36,109 @@ const notifyPreferenceSubscribers = (key: PreferenceKeyType) => {
|
|||||||
/**
|
/**
|
||||||
* Mock usePreference hook
|
* Mock usePreference hook
|
||||||
*/
|
*/
|
||||||
export const mockUsePreference = vi.fn(<K extends PreferenceKeyType>(
|
export const mockUsePreference = vi.fn(
|
||||||
key: K,
|
<K extends PreferenceKeyType>(key: K, options?: PreferenceUpdateOptions): [any, (value: any) => Promise<void>] => {
|
||||||
options?: PreferenceUpdateOptions
|
// Get current value
|
||||||
): [PreferenceValueType<K>, (value: PreferenceValueType<K>) => Promise<void>] => {
|
const currentValue = mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
||||||
// Get current value
|
|
||||||
const currentValue = mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
|
||||||
|
|
||||||
// Mock setValue function
|
// Mock setValue function
|
||||||
const setValue = vi.fn(async (value: PreferenceValueType<K>) => {
|
const setValue = vi.fn(async (value: any) => {
|
||||||
const oldValue = mockPreferenceState.get(key)
|
const oldValue = mockPreferenceState.get(key)
|
||||||
|
|
||||||
// Simulate optimistic updates (default behavior)
|
// Simulate optimistic updates (default behavior)
|
||||||
if (options?.optimistic !== false) {
|
if (options?.optimistic !== false) {
|
||||||
mockPreferenceState.set(key, value)
|
mockPreferenceState.set(key, value)
|
||||||
notifyPreferenceSubscribers(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate async update delay
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 10))
|
|
||||||
|
|
||||||
// For pessimistic updates, update after delay
|
|
||||||
if (options?.optimistic === false) {
|
|
||||||
mockPreferenceState.set(key, value)
|
|
||||||
notifyPreferenceSubscribers(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate error scenarios if configured
|
|
||||||
if (options?.shouldError) {
|
|
||||||
// Rollback optimistic update on error
|
|
||||||
if (options.optimistic !== false) {
|
|
||||||
mockPreferenceState.set(key, oldValue)
|
|
||||||
notifyPreferenceSubscribers(key)
|
notifyPreferenceSubscribers(key)
|
||||||
}
|
}
|
||||||
throw new Error(`Mock preference error for key: ${key}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return [currentValue, setValue]
|
// Simulate async update delay
|
||||||
})
|
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||||
|
|
||||||
|
// For pessimistic updates, update after delay
|
||||||
|
if (options?.optimistic === false) {
|
||||||
|
mockPreferenceState.set(key, value)
|
||||||
|
notifyPreferenceSubscribers(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate error scenarios if configured
|
||||||
|
if ((options as any)?.shouldError) {
|
||||||
|
// Rollback optimistic update on error
|
||||||
|
if (options?.optimistic !== false) {
|
||||||
|
mockPreferenceState.set(key, oldValue)
|
||||||
|
notifyPreferenceSubscribers(key)
|
||||||
|
}
|
||||||
|
throw new Error(`Mock preference error for key: ${key}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return [currentValue, setValue]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock useMultiplePreferences hook
|
* Mock useMultiplePreferences hook
|
||||||
*/
|
*/
|
||||||
export const mockUseMultiplePreferences = vi.fn(<T extends Record<string, PreferenceKeyType>>(
|
export const mockUseMultiplePreferences = vi.fn(
|
||||||
keys: T,
|
<T extends Record<string, PreferenceKeyType>>(
|
||||||
options?: PreferenceUpdateOptions
|
keys: T,
|
||||||
): [
|
options?: PreferenceUpdateOptions
|
||||||
{ [K in keyof T]: PreferenceValueType<T[K]> },
|
): [{ [K in keyof T]: any }, (values: Partial<{ [K in keyof T]: any }>) => Promise<void>] => {
|
||||||
(values: Partial<{ [K in keyof T]: PreferenceValueType<T[K]> }>) => Promise<void>
|
// Get current values for all keys
|
||||||
] => {
|
const currentValues = {} as { [K in keyof T]: any }
|
||||||
// Get current values for all keys
|
Object.entries(keys).forEach(([alias, key]) => {
|
||||||
const currentValues = {} as { [K in keyof T]: PreferenceValueType<T[K]> }
|
currentValues[alias as keyof T] =
|
||||||
Object.entries(keys).forEach(([alias, key]) => {
|
mockPreferenceState.get(key as PreferenceKeyType) ?? mockPreferenceDefaults[key as string] ?? null
|
||||||
currentValues[alias as keyof T] = mockPreferenceState.get(key as PreferenceKeyType) ??
|
})
|
||||||
mockPreferenceDefaults[key as string] ?? null
|
|
||||||
})
|
|
||||||
|
|
||||||
// Mock setValues function
|
// Mock setValues function
|
||||||
const setValues = vi.fn(async (values: Partial<{ [K in keyof T]: PreferenceValueType<T[K]> }>) => {
|
const setValues = vi.fn(async (values: Partial<{ [K in keyof T]: any }>) => {
|
||||||
const oldValues = { ...currentValues }
|
const oldValues = { ...currentValues }
|
||||||
|
|
||||||
// Simulate optimistic updates
|
// Simulate optimistic updates
|
||||||
if (options?.optimistic !== false) {
|
if (options?.optimistic !== false) {
|
||||||
Object.entries(values).forEach(([alias, value]) => {
|
Object.entries(values).forEach(([alias, value]) => {
|
||||||
const key = keys[alias as keyof T] as PreferenceKeyType
|
|
||||||
if (value !== undefined) {
|
|
||||||
mockPreferenceState.set(key, value)
|
|
||||||
currentValues[alias as keyof T] = value as any
|
|
||||||
notifyPreferenceSubscribers(key)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate async update delay
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 10))
|
|
||||||
|
|
||||||
// For pessimistic updates, update after delay
|
|
||||||
if (options?.optimistic === false) {
|
|
||||||
Object.entries(values).forEach(([alias, value]) => {
|
|
||||||
const key = keys[alias as keyof T] as PreferenceKeyType
|
|
||||||
if (value !== undefined) {
|
|
||||||
mockPreferenceState.set(key, value)
|
|
||||||
currentValues[alias as keyof T] = value as any
|
|
||||||
notifyPreferenceSubscribers(key)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate error scenarios
|
|
||||||
if (options?.shouldError) {
|
|
||||||
// Rollback optimistic updates on error
|
|
||||||
if (options.optimistic !== false) {
|
|
||||||
Object.entries(oldValues).forEach(([alias, value]) => {
|
|
||||||
const key = keys[alias as keyof T] as PreferenceKeyType
|
const key = keys[alias as keyof T] as PreferenceKeyType
|
||||||
mockPreferenceState.set(key, value)
|
if (value !== undefined) {
|
||||||
currentValues[alias as keyof T] = value
|
mockPreferenceState.set(key, value)
|
||||||
notifyPreferenceSubscribers(key)
|
currentValues[alias as keyof T] = value as any
|
||||||
|
notifyPreferenceSubscribers(key)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
throw new Error('Mock multiple preferences error')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return [currentValues, setValues]
|
// Simulate async update delay
|
||||||
})
|
await new Promise((resolve) => setTimeout(resolve, 10))
|
||||||
|
|
||||||
|
// For pessimistic updates, update after delay
|
||||||
|
if (options?.optimistic === false) {
|
||||||
|
Object.entries(values).forEach(([alias, value]) => {
|
||||||
|
const key = keys[alias as keyof T] as PreferenceKeyType
|
||||||
|
if (value !== undefined) {
|
||||||
|
mockPreferenceState.set(key, value)
|
||||||
|
currentValues[alias as keyof T] = value as any
|
||||||
|
notifyPreferenceSubscribers(key)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate error scenarios
|
||||||
|
if ((options as any)?.shouldError) {
|
||||||
|
// Rollback optimistic updates on error
|
||||||
|
if (options?.optimistic !== false) {
|
||||||
|
Object.entries(oldValues).forEach(([alias, value]) => {
|
||||||
|
const key = keys[alias as keyof T] as PreferenceKeyType
|
||||||
|
mockPreferenceState.set(key, value)
|
||||||
|
currentValues[alias as keyof T] = value
|
||||||
|
notifyPreferenceSubscribers(key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
throw new Error('Mock multiple preferences error')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return [currentValues, setValues]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export all mocks as a unified module
|
* Export all mocks as a unified module
|
||||||
@ -178,7 +172,7 @@ export const MockUsePreferenceUtils = {
|
|||||||
/**
|
/**
|
||||||
* Set a preference value for testing
|
* Set a preference value for testing
|
||||||
*/
|
*/
|
||||||
setPreferenceValue: <K extends PreferenceKeyType>(key: K, value: PreferenceValueType<K>) => {
|
setPreferenceValue: <K extends PreferenceKeyType>(key: K, value: any) => {
|
||||||
mockPreferenceState.set(key, value)
|
mockPreferenceState.set(key, value)
|
||||||
notifyPreferenceSubscribers(key)
|
notifyPreferenceSubscribers(key)
|
||||||
},
|
},
|
||||||
@ -186,7 +180,7 @@ export const MockUsePreferenceUtils = {
|
|||||||
/**
|
/**
|
||||||
* Get current preference value
|
* Get current preference value
|
||||||
*/
|
*/
|
||||||
getPreferenceValue: <K extends PreferenceKeyType>(key: K): PreferenceValueType<K> => {
|
getPreferenceValue: <K extends PreferenceKeyType>(key: K): any => {
|
||||||
return mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
return mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -214,7 +208,7 @@ export const MockUsePreferenceUtils = {
|
|||||||
/**
|
/**
|
||||||
* Simulate preference change from external source
|
* Simulate preference change from external source
|
||||||
*/
|
*/
|
||||||
simulateExternalPreferenceChange: <K extends PreferenceKeyType>(key: K, value: PreferenceValueType<K>) => {
|
simulateExternalPreferenceChange: <K extends PreferenceKeyType>(key: K, value: any) => {
|
||||||
mockPreferenceState.set(key, value)
|
mockPreferenceState.set(key, value)
|
||||||
notifyPreferenceSubscribers(key)
|
notifyPreferenceSubscribers(key)
|
||||||
},
|
},
|
||||||
@ -222,26 +216,15 @@ export const MockUsePreferenceUtils = {
|
|||||||
/**
|
/**
|
||||||
* Mock preference hook to return specific value for a key
|
* Mock preference hook to return specific value for a key
|
||||||
*/
|
*/
|
||||||
mockPreferenceReturn: <K extends PreferenceKeyType>(
|
mockPreferenceReturn: <K extends PreferenceKeyType>(key: K, value: any, setValue?: (value: any) => Promise<void>) => {
|
||||||
key: K,
|
mockUsePreference.mockImplementation((preferenceKey) => {
|
||||||
value: PreferenceValueType<K>,
|
|
||||||
setValue?: (value: PreferenceValueType<K>) => Promise<void>
|
|
||||||
) => {
|
|
||||||
mockUsePreference.mockImplementation((preferenceKey, options) => {
|
|
||||||
if (preferenceKey === key) {
|
if (preferenceKey === key) {
|
||||||
return [
|
return [value, setValue || vi.fn().mockResolvedValue(undefined)]
|
||||||
value,
|
|
||||||
setValue || vi.fn().mockResolvedValue(undefined)
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior for other keys
|
// Default behavior for other keys
|
||||||
const defaultValue = mockPreferenceState.get(preferenceKey) ??
|
const defaultValue = mockPreferenceState.get(preferenceKey) ?? mockPreferenceDefaults[preferenceKey] ?? null
|
||||||
mockPreferenceDefaults[preferenceKey] ?? null
|
return [defaultValue, vi.fn().mockResolvedValue(undefined)]
|
||||||
return [
|
|
||||||
defaultValue,
|
|
||||||
vi.fn().mockResolvedValue(undefined)
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -249,7 +232,7 @@ export const MockUsePreferenceUtils = {
|
|||||||
* Mock preference hook to simulate error for a key
|
* Mock preference hook to simulate error for a key
|
||||||
*/
|
*/
|
||||||
mockPreferenceError: <K extends PreferenceKeyType>(key: K, error: Error) => {
|
mockPreferenceError: <K extends PreferenceKeyType>(key: K, error: Error) => {
|
||||||
mockUsePreference.mockImplementation((preferenceKey, options) => {
|
mockUsePreference.mockImplementation((preferenceKey) => {
|
||||||
if (preferenceKey === key) {
|
if (preferenceKey === key) {
|
||||||
const setValue = vi.fn().mockRejectedValue(error)
|
const setValue = vi.fn().mockRejectedValue(error)
|
||||||
const currentValue = mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
const currentValue = mockPreferenceState.get(key) ?? mockPreferenceDefaults[key] ?? null
|
||||||
@ -257,12 +240,8 @@ export const MockUsePreferenceUtils = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Default behavior for other keys
|
// Default behavior for other keys
|
||||||
const defaultValue = mockPreferenceState.get(preferenceKey) ??
|
const defaultValue = mockPreferenceState.get(preferenceKey) ?? mockPreferenceDefaults[preferenceKey] ?? null
|
||||||
mockPreferenceDefaults[preferenceKey] ?? null
|
return [defaultValue, vi.fn().mockResolvedValue(undefined)]
|
||||||
return [
|
|
||||||
defaultValue,
|
|
||||||
vi.fn().mockResolvedValue(undefined)
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -293,4 +272,4 @@ export const MockUsePreferenceUtils = {
|
|||||||
getSubscriberCount: (key: PreferenceKeyType): number => {
|
getSubscriberCount: (key: PreferenceKeyType): number => {
|
||||||
return mockPreferenceSubscribers.get(key)?.size ?? 0
|
return mockPreferenceSubscribers.get(key)?.size ?? 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user