mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
committed by
Nino Righi
parent
5f74c6ddf8
commit
40c9d51dfc
@@ -9,6 +9,7 @@ describe('InFlight Decorators', () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
describe('InFlight', () => {
|
||||
@@ -75,17 +76,27 @@ describe('InFlight Decorators', () => {
|
||||
const promise1 = service.fetchWithError();
|
||||
const promise2 = service.fetchWithError();
|
||||
|
||||
// Handle the promises immediately to avoid unhandled rejections
|
||||
const resultsPromise = Promise.allSettled([promise1, promise2]);
|
||||
|
||||
await vi.runAllTimersAsync();
|
||||
|
||||
// Both should reject with the same error
|
||||
await expect(promise1).rejects.toThrow('Test error');
|
||||
await expect(promise2).rejects.toThrow('Test error');
|
||||
const results = await resultsPromise;
|
||||
expect(results[0].status).toBe('rejected');
|
||||
expect(results[1].status).toBe('rejected');
|
||||
expect((results[0] as PromiseRejectedResult).reason.message).toBe('Test error');
|
||||
expect((results[1] as PromiseRejectedResult).reason.message).toBe('Test error');
|
||||
expect(service.callCount).toBe(1);
|
||||
|
||||
// Should allow new call after error
|
||||
const promise3 = service.fetchWithError();
|
||||
const promise3Result = Promise.allSettled([promise3]);
|
||||
await vi.runAllTimersAsync();
|
||||
await expect(promise3).rejects.toThrow('Test error');
|
||||
|
||||
const [result3] = await promise3Result;
|
||||
expect(result3.status).toBe('rejected');
|
||||
expect((result3 as PromiseRejectedResult).reason.message).toBe('Test error');
|
||||
expect(service.callCount).toBe(2);
|
||||
});
|
||||
|
||||
@@ -307,14 +318,20 @@ describe('InFlight Decorators', () => {
|
||||
|
||||
// First call that errors
|
||||
const promise1 = service.fetchWithError();
|
||||
const promise1Result = Promise.allSettled([promise1]);
|
||||
await vi.runAllTimersAsync();
|
||||
await expect(promise1).rejects.toThrow('API Error');
|
||||
const result1 = await promise1Result;
|
||||
expect(result1[0].status).toBe('rejected');
|
||||
expect((result1[0] as PromiseRejectedResult).reason.message).toBe('API Error');
|
||||
expect(service.callCount).toBe(1);
|
||||
|
||||
// Second call should not use cache (errors aren't cached)
|
||||
const promise2 = service.fetchWithError();
|
||||
const promise2Result = Promise.allSettled([promise2]);
|
||||
await vi.runAllTimersAsync();
|
||||
await expect(promise2).rejects.toThrow('API Error');
|
||||
const result2 = await promise2Result;
|
||||
expect(result2[0].status).toBe('rejected');
|
||||
expect((result2[0] as PromiseRejectedResult).reason.message).toBe('API Error');
|
||||
expect(service.callCount).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,8 +20,8 @@ export function InFlight<
|
||||
const inFlightMap = new WeakMap<object, Promise<any>>();
|
||||
|
||||
return function (
|
||||
target: any,
|
||||
propertyKey: string | symbol,
|
||||
_target: any,
|
||||
_propertyKey: string | symbol,
|
||||
descriptor: PropertyDescriptor,
|
||||
): PropertyDescriptor {
|
||||
const originalMethod = descriptor.value;
|
||||
@@ -39,15 +39,9 @@ export function InFlight<
|
||||
// Create new request and store it
|
||||
const promise = originalMethod
|
||||
.apply(this, args)
|
||||
.then((result: any) => {
|
||||
// Clean up after successful completion
|
||||
.finally(() => {
|
||||
// Always clean up in-flight request
|
||||
inFlightMap.delete(this);
|
||||
return result;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
// Clean up after error
|
||||
inFlightMap.delete(this);
|
||||
throw error;
|
||||
});
|
||||
|
||||
inFlightMap.set(this, promise);
|
||||
@@ -92,8 +86,8 @@ export function InFlightWithKey<T extends (...args: any[]) => Promise<any>>(
|
||||
const inFlightMap = new WeakMap<object, Map<string, Promise<any>>>();
|
||||
|
||||
return function (
|
||||
target: any,
|
||||
propertyKey: string | symbol,
|
||||
_target: any,
|
||||
_propertyKey: string | symbol,
|
||||
descriptor: PropertyDescriptor,
|
||||
): PropertyDescriptor {
|
||||
const originalMethod = descriptor.value;
|
||||
@@ -106,7 +100,7 @@ export function InFlightWithKey<T extends (...args: any[]) => Promise<any>>(
|
||||
if (!inFlightMap.has(this)) {
|
||||
inFlightMap.set(this, new Map());
|
||||
}
|
||||
const instanceMap = inFlightMap.get(this)!;
|
||||
const instanceMap = inFlightMap.get(this) as Map<string, Promise<any>>;
|
||||
|
||||
// Generate cache key
|
||||
const key = options.keyGenerator
|
||||
@@ -122,15 +116,9 @@ export function InFlightWithKey<T extends (...args: any[]) => Promise<any>>(
|
||||
// Create new request and store it
|
||||
const promise = originalMethod
|
||||
.apply(this, args)
|
||||
.then((result: any) => {
|
||||
// Clean up after successful completion
|
||||
.finally(() => {
|
||||
// Always clean up in-flight request
|
||||
instanceMap.delete(key);
|
||||
return result;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
// Clean up after error
|
||||
instanceMap.delete(key);
|
||||
throw error;
|
||||
});
|
||||
|
||||
instanceMap.set(key, promise);
|
||||
@@ -183,8 +171,8 @@ export function InFlightWithCache<T extends (...args: any[]) => Promise<any>>(
|
||||
>();
|
||||
|
||||
return function (
|
||||
target: any,
|
||||
propertyKey: string | symbol,
|
||||
_target: any,
|
||||
_propertyKey: string | symbol,
|
||||
descriptor: PropertyDescriptor,
|
||||
): PropertyDescriptor {
|
||||
const originalMethod = descriptor.value;
|
||||
@@ -198,8 +186,8 @@ export function InFlightWithCache<T extends (...args: any[]) => Promise<any>>(
|
||||
inFlightMap.set(this, new Map());
|
||||
cacheMap.set(this, new Map());
|
||||
}
|
||||
const instanceInFlight = inFlightMap.get(this)!;
|
||||
const instanceCache = cacheMap.get(this)!;
|
||||
const instanceInFlight = inFlightMap.get(this) as Map<string, Promise<any>>;
|
||||
const instanceCache = cacheMap.get(this) as Map<string, { result: any; expiry: number }>;
|
||||
|
||||
// Generate cache key
|
||||
const key = options.keyGenerator
|
||||
|
||||
Reference in New Issue
Block a user