diff --git a/package-lock.json b/package-lock.json index c522ebb..13fd8cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "file-type": "^16.5.4", "image-size": "^1.0.0", "moment": "^2.29.1", + "nyc-dark": "^3.0.3", "pg": "^8.7.1", "react": "^18.2.0", "react-contenteditable": "^3.3.6", @@ -5740,6 +5741,15 @@ "set-blocking": "^2.0.0" } }, + "node_modules/nyc-dark": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/nyc-dark/-/nyc-dark-3.0.3.tgz", + "integrity": "sha512-jcb5VU7F9zrikF6BW+tPdTNEl7PRL1H4rwYqcqjAxLnVCH1nKqgSBngMv/D336SS/Dn2CNzM6JzN6NcGyDdbHA==", + "engines": { + "node": ">= 10.12.0", + "npm": ">= 1.4.x" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12254,6 +12264,11 @@ "set-blocking": "^2.0.0" } }, + "nyc-dark": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/nyc-dark/-/nyc-dark-3.0.3.tgz", + "integrity": "sha512-jcb5VU7F9zrikF6BW+tPdTNEl7PRL1H4rwYqcqjAxLnVCH1nKqgSBngMv/D336SS/Dn2CNzM6JzN6NcGyDdbHA==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", diff --git a/package.json b/package.json index f56a971..bfda255 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "file-type": "^16.5.4", "image-size": "^1.0.0", "moment": "^2.29.1", + "nyc-dark": "^3.0.3", "pg": "^8.7.1", "react": "^18.2.0", "react-contenteditable": "^3.3.6", diff --git a/src/client/tests/webapp/auto-verifier.test.ts b/src/client/tests/webapp/auto-verifier.test.ts index 57137c9..5e4e593 100644 --- a/src/client/tests/webapp/auto-verifier.test.ts +++ b/src/client/tests/webapp/auto-verifier.test.ts @@ -222,11 +222,7 @@ describe('fetchAndVerifyIfNeeded tests', () => { await Util.sleep(0); } - /* test('nothing before, primary null, then trusted with value', async () => { */ - /* expect(false).toBe(true); */ - /* }); */ - - test('nothing before, primary with value, then trusted with value', async () => { + test('primary null, then trusted with value - cache miss, return from server', async () => { const { nextPrimary, nextTrusted, nextEnsureTrustedFuncReady, nextVerify, primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc @@ -238,24 +234,25 @@ describe('fetchAndVerifyIfNeeded tests', () => { const verify = nextVerify(); const av = new AutoVerifier(primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc); - const result = av.fetchAndVerifyIfNeeded(); + 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(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(0); - primary.resolve(new BasicWE(2)); + primary.resolve(null); await disjoint(); - expect(result).resolves.toEqual(new BasicWE(2)); + expect(ensureTrustedFuncReadyFunc).toHaveBeenCalled(); expect(av.primaryPromise).toBe(null); expect(av.trustedPromise).toBe(trusted.promise); expect(av.trustedStatus).toBe('verifying'); - expect(ensureTrustedFuncReadyFunc).toHaveBeenCalled(); ensureTrustedFuncReady.resolve(); await disjoint(); @@ -263,21 +260,20 @@ describe('fetchAndVerifyIfNeeded tests', () => { expect(av.trustedPromise).toBe(trusted.promise); expect(av.trustedStatus).toBe('verifying'); - expect(trustedFunc).toHaveBeenCalled(); expect(verifyFunc).toHaveBeenCalledTimes(0); trusted.resolve(new BasicWE(2)); await disjoint(); - expect(trustedFunc).toHaveBeenCalled(); + expect(verifyFunc).toHaveBeenCalledWith(null, new BasicWE(2)); expect(av.primaryPromise).toBe(null); expect(av.trustedPromise).toBe(trusted.promise); expect(av.trustedStatus).toBe('verifying'); - expect(verifyFunc).toHaveBeenCalled(); + expect(result).toBeUndefined(); verify.resolve(true); await disjoint(); - - expect(verifyFunc).toHaveBeenCalledWith(new BasicWE(2), new BasicWE(2)); + + expect(result).toEqual(new BasicWE(2)); expect(av.primaryPromise).toBe(null); expect(av.trustedPromise).toBe(trusted.promise); expect(av.trustedStatus).toBe('verified'); @@ -288,7 +284,73 @@ describe('fetchAndVerifyIfNeeded tests', () => { expect(verifyFunc).toHaveBeenCalledTimes(1); }); - /* test('nothing before, primary with value, then trusted with null', async () => { */ + test('primary with value, then trusted with value - cache hit, verify with server', async () => { + const { + nextPrimary, nextTrusted, nextEnsureTrustedFuncReady, nextVerify, + primaryFunc, trustedFunc, ensureTrustedFuncReadyFunc, verifyFunc + } = getManualsAndMocks(); + + const primary = nextPrimary(); + const trusted = nextTrusted(); + const ensureTrustedFuncReady = nextEnsureTrustedFuncReady(); + const verify = nextVerify(); + + 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'); + + expect(verifyFunc).toHaveBeenCalledTimes(0); + trusted.resolve(new BasicWE(2)); + await disjoint(); + + expect(verifyFunc).toHaveBeenCalledWith(new BasicWE(2), new BasicWE(2)); + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verifying'); + + verify.resolve(true); + await disjoint(); + + expect(av.primaryPromise).toBe(null); + expect(av.trustedPromise).toBe(trusted.promise); + expect(av.trustedStatus).toBe('verified'); + + expect(primaryFunc).toHaveBeenCalledTimes(1); + expect(trustedFunc).toHaveBeenCalledTimes(1); + expect(ensureTrustedFuncReadyFunc).toHaveBeenCalledTimes(1); + expect(verifyFunc).toHaveBeenCalledTimes(1); + }); + + /* test('primary null, then trusted with null - cache miss, server confirms miss', async () => { */ + /* expect(false).toBe(true); */ + /* }); */ + + /* test('primary with value, then trusted with null - cache hit, server deleted', async () => { */ /* expect(false).toBe(true); */ /* }); */ // Make sure to do try/catch errors