primary with value, trusted rejects test

This commit is contained in:
Michael Peters 2022-10-05 22:44:50 -07:00
parent 61f57875f9
commit 24d796ba5c
2 changed files with 62 additions and 2 deletions

View File

@ -635,7 +635,6 @@ describe('fetchAndVerifyIfNeeded tests', () => {
expect(av.trustedStatus).toBe('verifying');
expect(rejection).toBeUndefined();
jest.spyOn(console, 'warn').mockImplementationOnce(() => {}); // suppress the warning
trusted.reject(new Error());
await disjoint();
@ -652,6 +651,64 @@ describe('fetchAndVerifyIfNeeded tests', () => {
expect(verifyFunc).toHaveBeenCalledTimes(0);
});
test('primary with value, trusted rejects - cache hit, failed to ping server', async () => {
// expect the promise to reject, but the verify function to never be called
const {
nextPrimary, nextTrusted, nextEnsureTrustedFuncReady,
primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc
} = getManualsAndMocks();
const primary = nextPrimary();
const trusted = nextTrusted();
const ensureTrustedFuncReady = nextEnsureTrustedFuncReady();
const av = new AutoVerifier(primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc);
const resultPromise = av.fetchAndVerifyIfNeeded();
let result: BasicWE | null | undefined = undefined;
resultPromise.then(value => { result = value; });
expect(av.primaryPromise).toBe(primary.promise);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('fetching');
expect(primaryFunc).toHaveBeenCalled();
expect(trustedFunc).toHaveBeenCalled();
expect(result).toBeUndefined();
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(0);
primary.resolve(new BasicWE(2));
await disjoint();
expect(result).toEqual(new BasicWE(2));
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalled();
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verifying');
ensureTrustedFuncReady.resolve();
await disjoint();
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(trusted.promise);
expect(av.trustedStatus).toBe('verifying');
// suppress the warning about trusted rejecting after primary hit
const cwSpy = jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
trusted.reject(new Error());
await disjoint();
expect(cwSpy).toHaveBeenCalled();
expect(av.primaryPromise).toBe(null);
expect(av.trustedPromise).toBe(null);
expect(av.trustedStatus).toBe('none');
await disjoint(); // sanity check
expect(primaryFunc).toHaveBeenCalledTimes(1);
expect(trustedFunc).toHaveBeenCalledTimes(1); // notably, this server response will be thrown out
expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1);
expect(verifyFunc).toHaveBeenCalledTimes(0);
});
// Make sure to do try/catch errors/rejections, verification failures, unverifies in the middle
// Multiple tryResolveTrustedPromises
// Multiple fetchAndVerifyIfNeeded at the same time

View File

@ -357,14 +357,17 @@ export class AutoVerifier<T> {
};
await tryResolveTrustedPromise();
} catch (e: unknown) {
this.unverify();
if (!resolved) {
this.trustedPromise = null; // suppress warnings
this.primaryPromise = null; // suppress warnings
this.unverify();
/* istanbul ignore next */
if (debug) LOG.debug(fetchId + ': error during fetch', e);
// eslint-disable-next-line prefer-promise-reject-errors
reject(e as Error);
resolved = true;
} else {
this.unverify()
/* istanbul ignore next */
if (debug)
LOG.debug(