tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PersistentCache.test.js (4290B)


      1 import { GlobalOverrider } from "test/unit/utils";
      2 import { PersistentCache } from "lib/PersistentCache.sys.mjs";
      3 
      4 describe("PersistentCache", () => {
      5  let fakeIOUtils;
      6  let fakePathUtils;
      7  let cache;
      8  let filename = "cache.json";
      9  let consoleErrorStub;
     10  let globals;
     11  let sandbox;
     12 
     13  beforeEach(() => {
     14    globals = new GlobalOverrider();
     15    sandbox = sinon.createSandbox();
     16    fakeIOUtils = {
     17      writeJSON: sinon.stub().resolves(0),
     18      readJSON: sinon.stub().resolves({}),
     19    };
     20    fakePathUtils = {
     21      join: sinon.stub().returns(filename),
     22      localProfileDir: "/",
     23    };
     24    consoleErrorStub = sandbox.stub();
     25    globals.set("console", { error: consoleErrorStub });
     26    globals.set("IOUtils", fakeIOUtils);
     27    globals.set("PathUtils", fakePathUtils);
     28 
     29    cache = new PersistentCache(filename);
     30  });
     31  afterEach(() => {
     32    globals.restore();
     33    sandbox.restore();
     34  });
     35 
     36  describe("#get", () => {
     37    it("tries to read the file", async () => {
     38      await cache.get("foo");
     39      assert.calledOnce(fakeIOUtils.readJSON);
     40    });
     41    it("doesnt try to read the file if it was already loaded", async () => {
     42      await cache._load();
     43      fakeIOUtils.readJSON.resetHistory();
     44      await cache.get("foo");
     45      assert.notCalled(fakeIOUtils.readJSON);
     46    });
     47    it("should catch and report errors", async () => {
     48      fakeIOUtils.readJSON.rejects(new SyntaxError("Failed to parse JSON"));
     49      await cache._load();
     50      assert.calledOnce(consoleErrorStub);
     51 
     52      cache._cache = undefined;
     53      consoleErrorStub.resetHistory();
     54 
     55      fakeIOUtils.readJSON.rejects(
     56        new DOMException("IOUtils shutting down", "AbortError")
     57      );
     58      await cache._load();
     59      assert.calledOnce(consoleErrorStub);
     60 
     61      cache._cache = undefined;
     62      consoleErrorStub.resetHistory();
     63 
     64      fakeIOUtils.readJSON.rejects(
     65        new DOMException("File not found", "NotFoundError")
     66      );
     67      await cache._load();
     68      assert.notCalled(consoleErrorStub);
     69    });
     70    it("returns data for a given cache key", async () => {
     71      fakeIOUtils.readJSON.resolves({ foo: "bar" });
     72      let value = await cache.get("foo");
     73      assert.equal(value, "bar");
     74    });
     75    it("returns undefined for a cache key that doesn't exist", async () => {
     76      let value = await cache.get("baz");
     77      assert.equal(value, undefined);
     78    });
     79    it("returns all the data if no cache key is specified", async () => {
     80      fakeIOUtils.readJSON.resolves({ foo: "bar" });
     81      let value = await cache.get();
     82      assert.deepEqual(value, { foo: "bar" });
     83    });
     84  });
     85 
     86  describe("#set", () => {
     87    it("tries to read the file on the first set", async () => {
     88      await cache.set("foo", { x: 42 });
     89      assert.calledOnce(fakeIOUtils.readJSON);
     90    });
     91    it("doesnt try to read the file if it was already loaded", async () => {
     92      cache = new PersistentCache(filename, true);
     93      await cache._load();
     94      fakeIOUtils.readJSON.resetHistory();
     95      await cache.set("foo", { x: 42 });
     96      assert.notCalled(fakeIOUtils.readJSON);
     97    });
     98    it("sets a string value", async () => {
     99      const key = "testkey";
    100      const value = "testvalue";
    101      await cache.set(key, value);
    102      const cachedValue = await cache.get(key);
    103      assert.equal(cachedValue, value);
    104    });
    105    it("sets an object value", async () => {
    106      const key = "testkey";
    107      const value = { x: 1, y: 2, z: 3 };
    108      await cache.set(key, value);
    109      const cachedValue = await cache.get(key);
    110      assert.deepEqual(cachedValue, value);
    111    });
    112    it("writes the data to file", async () => {
    113      const key = "testkey";
    114      const value = { x: 1, y: 2, z: 3 };
    115 
    116      await cache.set(key, value);
    117      assert.calledOnce(fakeIOUtils.writeJSON);
    118      assert.calledWith(
    119        fakeIOUtils.writeJSON,
    120        filename,
    121        { [[key]]: value },
    122        { tmpPath: `${filename}.tmp` }
    123      );
    124    });
    125    it("throws when failing to get file path", async () => {
    126      Object.defineProperty(fakePathUtils, "localProfileDir", {
    127        get() {
    128          throw new Error();
    129        },
    130      });
    131 
    132      let rejected = false;
    133      try {
    134        await cache.set("key", "val");
    135      } catch (error) {
    136        rejected = true;
    137      }
    138 
    139      assert(rejected);
    140    });
    141  });
    142 });