2026-04-15 12:19:25 +03:00
|
|
|
import { queryClient } from '$shared/api/queryClient';
|
|
|
|
|
import {
|
|
|
|
|
beforeEach,
|
|
|
|
|
describe,
|
|
|
|
|
expect,
|
|
|
|
|
it,
|
|
|
|
|
vi,
|
|
|
|
|
} from 'vitest';
|
|
|
|
|
import { BaseQueryStore } from './BaseQueryStore.svelte';
|
|
|
|
|
|
|
|
|
|
class TestStore extends BaseQueryStore<string> {
|
|
|
|
|
constructor(key = ['test'], fn = () => Promise.resolve('ok')) {
|
|
|
|
|
super({
|
|
|
|
|
queryKey: key,
|
|
|
|
|
queryFn: fn,
|
|
|
|
|
retry: false, // Disable retries for faster error testing
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
get data() {
|
|
|
|
|
return this.result.data;
|
|
|
|
|
}
|
|
|
|
|
get isLoading() {
|
|
|
|
|
return this.result.isLoading;
|
|
|
|
|
}
|
|
|
|
|
get isError() {
|
|
|
|
|
return this.result.isError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update(newKey: string[], newFn?: () => Promise<string>) {
|
|
|
|
|
this.updateOptions({
|
|
|
|
|
queryKey: newKey,
|
|
|
|
|
queryFn: newFn ?? (() => Promise.resolve('ok')),
|
|
|
|
|
retry: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
import * as tq from '@tanstack/query-core';
|
|
|
|
|
|
|
|
|
|
// ... (TestStore remains same)
|
|
|
|
|
|
|
|
|
|
describe('BaseQueryStore', () => {
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
queryClient.clear();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('Lifecycle & Fetching', () => {
|
|
|
|
|
it('should transition from loading to success', async () => {
|
|
|
|
|
const store = new TestStore();
|
|
|
|
|
expect(store.isLoading).toBe(true);
|
|
|
|
|
await vi.waitFor(() => expect(store.data).toBe('ok'), { timeout: 1000 });
|
|
|
|
|
expect(store.isLoading).toBe(false);
|
|
|
|
|
});
|
2026-04-15 15:59:01 +03:00
|
|
|
|
|
|
|
|
it('should have undefined data and no error in initial loading state', () => {
|
|
|
|
|
const store = new TestStore(['initial-state'], () => new Promise(r => setTimeout(() => r('late'), 500)));
|
|
|
|
|
expect(store.data).toBeUndefined();
|
|
|
|
|
expect(store.isError).toBe(false);
|
|
|
|
|
});
|
2026-04-15 12:19:25 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('Error Handling', () => {
|
|
|
|
|
it('should handle query failures', async () => {
|
|
|
|
|
const store = new TestStore(['fail'], () => Promise.reject(new Error('fail')));
|
|
|
|
|
await vi.waitFor(() => expect(store.isError).toBe(true), { timeout: 1000 });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('Reactivity', () => {
|
|
|
|
|
it('should refetch and update data when options change', async () => {
|
|
|
|
|
const store = new TestStore(['key1'], () => Promise.resolve('val1'));
|
|
|
|
|
await vi.waitFor(() => expect(store.data).toBe('val1'), { timeout: 1000 });
|
|
|
|
|
|
|
|
|
|
store.update(['key2'], () => Promise.resolve('val2'));
|
|
|
|
|
await vi.waitFor(() => expect(store.data).toBe('val2'), { timeout: 1000 });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('Cleanup', () => {
|
|
|
|
|
it('should unsubscribe observer on destroy', () => {
|
|
|
|
|
const unsubscribe = vi.fn();
|
|
|
|
|
const subscribeSpy = vi.spyOn(tq.QueryObserver.prototype, 'subscribe').mockReturnValue(unsubscribe);
|
|
|
|
|
|
|
|
|
|
const store = new TestStore();
|
|
|
|
|
store.destroy();
|
|
|
|
|
|
|
|
|
|
expect(unsubscribe).toHaveBeenCalled();
|
|
|
|
|
subscribeSpy.mockRestore();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|