diff options
Diffstat (limited to '')
-rw-r--r-- | browser/components/newtab/test/unit/lib/PersistentCache.test.js | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/browser/components/newtab/test/unit/lib/PersistentCache.test.js b/browser/components/newtab/test/unit/lib/PersistentCache.test.js new file mode 100644 index 0000000000..e645b8d398 --- /dev/null +++ b/browser/components/newtab/test/unit/lib/PersistentCache.test.js @@ -0,0 +1,142 @@ +import { GlobalOverrider } from "test/unit/utils"; +import { PersistentCache } from "lib/PersistentCache.sys.mjs"; + +describe("PersistentCache", () => { + let fakeIOUtils; + let fakePathUtils; + let cache; + let filename = "cache.json"; + let consoleErrorStub; + let globals; + let sandbox; + + beforeEach(() => { + globals = new GlobalOverrider(); + sandbox = sinon.createSandbox(); + fakeIOUtils = { + writeJSON: sinon.stub().resolves(0), + readJSON: sinon.stub().resolves({}), + }; + fakePathUtils = { + join: sinon.stub().returns(filename), + localProfileDir: "/", + }; + consoleErrorStub = sandbox.stub(); + globals.set("console", { error: consoleErrorStub }); + globals.set("IOUtils", fakeIOUtils); + globals.set("PathUtils", fakePathUtils); + + cache = new PersistentCache(filename); + }); + afterEach(() => { + globals.restore(); + sandbox.restore(); + }); + + describe("#get", () => { + it("tries to read the file", async () => { + await cache.get("foo"); + assert.calledOnce(fakeIOUtils.readJSON); + }); + it("doesnt try to read the file if it was already loaded", async () => { + await cache._load(); + fakeIOUtils.readJSON.resetHistory(); + await cache.get("foo"); + assert.notCalled(fakeIOUtils.readJSON); + }); + it("should catch and report errors", async () => { + fakeIOUtils.readJSON.rejects(new SyntaxError("Failed to parse JSON")); + await cache._load(); + assert.calledOnce(consoleErrorStub); + + cache._cache = undefined; + consoleErrorStub.resetHistory(); + + fakeIOUtils.readJSON.rejects( + new DOMException("IOUtils shutting down", "AbortError") + ); + await cache._load(); + assert.calledOnce(consoleErrorStub); + + cache._cache = undefined; + consoleErrorStub.resetHistory(); + + fakeIOUtils.readJSON.rejects( + new DOMException("File not found", "NotFoundError") + ); + await cache._load(); + assert.notCalled(consoleErrorStub); + }); + it("returns data for a given cache key", async () => { + fakeIOUtils.readJSON.resolves({ foo: "bar" }); + let value = await cache.get("foo"); + assert.equal(value, "bar"); + }); + it("returns undefined for a cache key that doesn't exist", async () => { + let value = await cache.get("baz"); + assert.equal(value, undefined); + }); + it("returns all the data if no cache key is specified", async () => { + fakeIOUtils.readJSON.resolves({ foo: "bar" }); + let value = await cache.get(); + assert.deepEqual(value, { foo: "bar" }); + }); + }); + + describe("#set", () => { + it("tries to read the file on the first set", async () => { + await cache.set("foo", { x: 42 }); + assert.calledOnce(fakeIOUtils.readJSON); + }); + it("doesnt try to read the file if it was already loaded", async () => { + cache = new PersistentCache(filename, true); + await cache._load(); + fakeIOUtils.readJSON.resetHistory(); + await cache.set("foo", { x: 42 }); + assert.notCalled(fakeIOUtils.readJSON); + }); + it("sets a string value", async () => { + const key = "testkey"; + const value = "testvalue"; + await cache.set(key, value); + const cachedValue = await cache.get(key); + assert.equal(cachedValue, value); + }); + it("sets an object value", async () => { + const key = "testkey"; + const value = { x: 1, y: 2, z: 3 }; + await cache.set(key, value); + const cachedValue = await cache.get(key); + assert.deepEqual(cachedValue, value); + }); + it("writes the data to file", async () => { + const key = "testkey"; + const value = { x: 1, y: 2, z: 3 }; + + await cache.set(key, value); + assert.calledOnce(fakeIOUtils.writeJSON); + assert.calledWith( + fakeIOUtils.writeJSON, + filename, + { [[key]]: value }, + { tmpPath: `${filename}.tmp` } + ); + }); + it("throws when failing to get file path", async () => { + Object.defineProperty(fakePathUtils, "localProfileDir", { + get() { + throw new Error(); + }, + }); + + let rejected = false; + try { + await cache.set("key", "val"); + } catch (error) { + rejected = true; + } + + assert(rejected); + }); + }); +}); |