diff --git a/src/client/tests/webapp/auto-verifier.test.ts b/src/client/tests/webapp/auto-verifier.test.ts index 23efe40..4046339 100644 --- a/src/client/tests/webapp/auto-verifier.test.ts +++ b/src/client/tests/webapp/auto-verifier.test.ts @@ -272,6 +272,82 @@ describe('fetchAndVerifyIfNeeded tests', () => { expect(verifyFunc).toHaveBeenCalledTimes(1); }); + test('primary null, then trusted with value, then refetch, primary with value - primary use case', async () => { + // the main use case! + const { + nextPrimary, nextTrusted, nextVerify, + primaryFunc, trustedFunc, verifyFunc + } = getManualsAndMocks(); + + const primary1 = nextPrimary(); + const trusted = nextTrusted(); + const verify = nextVerify(); + + const av = new AutoVerifier(primaryFunc, trustedFunc, verifyFunc); + + const result1Promise = av.fetchAndVerifyIfNeeded(); + let result1: BasicWE | null | undefined = undefined; + result1Promise.then(value => { result1 = value; }); + + expect(av.primaryPromise).toBe(primary1.promise); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('fetching'); + expect(primaryFunc).toHaveBeenCalled(); + expect(trustedFunc).toHaveBeenCalled(); + + primary1.resolve(null); + await disjoint(); + + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verifying'); + + expect(verifyFunc).toHaveBeenCalledTimes(0); + trusted.resolve(new BasicWE(2)); + await disjoint(); + + expect(verifyFunc).toHaveBeenCalledWith(null, new BasicWE(2)); + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verifying'); + + expect(result1).toBeUndefined(); + verify.resolve(true); + await disjoint(); + + expect(result1).toEqual(new BasicWE(2)); + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verified'); + + const primary2 = nextPrimary(); + + const result2Promise = av.fetchAndVerifyIfNeeded(); + let result2: BasicWE | null | undefined = undefined; + result2Promise.then(value => { result2 = value; }); + + expect(av.primaryPromise).toBe(primary2.promise); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verified'); + expect(primaryFunc).toHaveBeenCalledTimes(2); + + expect(result2).toBeUndefined(); + primary2.resolve(new BasicWE(2)); + await disjoint(); + + expect(result2).toEqual(new BasicWE(2)); + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verified'); + + await disjoint(); // sanity check + + expect(primaryFunc).toHaveBeenCalledTimes(2); + expect(trustedFunc).toHaveBeenCalledTimes(1); + expect(verifyFunc).toHaveBeenCalledTimes(1); + + }); + test('primary with value, then trusted with value - cache hit, verify with server', async () => { const { nextPrimary, nextTrusted, nextVerify, @@ -1149,8 +1225,6 @@ describe('fetchAndVerifyIfNeeded tests', () => { // can't because of primary promise early resolution // Make sure to do try/catch errors/rejections, verification failures, unverifies in the middle - // Multiple tryResolveTrustedPromises - multiple fetchAndVerifyIfNeeded at the same time - // Trusted resolves *BEFORE* ensureTrustedFuncReady // Fetching after verified doesn't re-fetch trusted // Unverify during verify w/ dedups });