From ff492811230e7e8b39fd4da70951d2babcb27108 Mon Sep 17 00:00:00 2001 From: Lukasz Ostrowski Date: Mon, 24 Oct 2022 16:11:15 +0200 Subject: [PATCH] Change behavior when FileAPL reads file that doesnt exist to fallback value (#96) --- src/APL/file-apl.test.ts | 25 ++++++++----------------- src/APL/file-apl.ts | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/APL/file-apl.test.ts b/src/APL/file-apl.test.ts index 70eee80..9a02659 100644 --- a/src/APL/file-apl.test.ts +++ b/src/APL/file-apl.test.ts @@ -15,18 +15,14 @@ describe("APL", () => { describe("FileAPL", () => { describe("get", () => { - it("Should throw error when JSON parse fails", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); + it("Should fallback to 'undefined' if parsing fail fails", async () => { vi.spyOn(fsPromises, "readFile").mockResolvedValue("Not a valid JSON"); const apl = new FileAPL(); - await expect(apl.get(stubAuthData.domain)).rejects.toThrow( - "File APL could not read auth data from the .saleor-app-auth.json file" - ); + await expect(apl.get(stubAuthData.domain)).resolves.toBe(undefined); }); it("Returns auth data for existing domain", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue(JSON.stringify(stubAuthData)); const apl = new FileAPL(); @@ -35,7 +31,6 @@ describe("APL", () => { }); it("Returns undefined for unknown domain", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue(JSON.stringify(stubAuthData)); const apl = new FileAPL(); @@ -57,21 +52,20 @@ describe("APL", () => { ); expect(spyWriteFile).toBeCalledWith(".saleor-app-auth.json", JSON.stringify(stubAuthData)); }); - }); - it("Successfully save to file", async () => { - const spyWriteFile = vi.spyOn(fsPromises, "writeFile").mockResolvedValue(); + it("Successfully save to file", async () => { + const spyWriteFile = vi.spyOn(fsPromises, "writeFile").mockResolvedValue(); - const apl = new FileAPL(); + const apl = new FileAPL(); - await expect(apl.set(stubAuthData)); + await expect(apl.set(stubAuthData)); - expect(spyWriteFile).toBeCalledWith(".saleor-app-auth.json", JSON.stringify(stubAuthData)); + expect(spyWriteFile).toBeCalledWith(".saleor-app-auth.json", JSON.stringify(stubAuthData)); + }); }); describe("delete", () => { it("Should override file when called with known domain", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue(JSON.stringify(stubAuthData)); const spyWriteFile = vi.spyOn(fsPromises, "writeFile").mockResolvedValue(); @@ -83,7 +77,6 @@ describe("APL", () => { }); it("Should not delete data when called with unknown domain", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue(JSON.stringify(stubAuthData)); const spyWriteFile = vi.spyOn(fsPromises, "writeFile").mockResolvedValue(); @@ -98,7 +91,6 @@ describe("APL", () => { describe("getAll", () => { it("Should return list with one item when auth data are existing", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue(JSON.stringify(stubAuthData)); const apl = new FileAPL(); @@ -107,7 +99,6 @@ describe("APL", () => { }); it("Should return empty list when auth data are empty", async () => { - vi.spyOn(fsPromises, "access").mockResolvedValue(); vi.spyOn(fsPromises, "readFile").mockResolvedValue("{}"); const apl = new FileAPL(); diff --git a/src/APL/file-apl.ts b/src/APL/file-apl.ts index f6f5220..75b452a 100644 --- a/src/APL/file-apl.ts +++ b/src/APL/file-apl.ts @@ -31,38 +31,46 @@ export class FileAPL implements APL { /** * Load auth data from a file and return it as AuthData format. * In case of incomplete or invalid data, return `undefined`. - * - * @param {string} fileName */ private async loadDataFromFile(): Promise { - debug(`Load auth data from the ${this.fileName} file`); + debug(`Will try to load auth data from the ${this.fileName} file`); let parsedData: Record = {}; + try { - await fsPromises.access(this.fileName); parsedData = JSON.parse(await fsPromises.readFile(this.fileName, "utf-8")); + debug("%s read successfully", this.fileName); } catch (err) { debug(`Could not read auth data from the ${this.fileName} file`, err); - throw new Error(`File APL could not read auth data from the ${this.fileName} file`); + debug( + "Maybe apl.get() was called before app was registered. Returning empty, fallback data (undefined)" + ); + + return undefined; } + const { token, domain } = parsedData; + if (token && domain) { + debug("Token and domain found, returning values: %s, %s", domain, `${token[0]}***`); return { token, domain }; } + return undefined; } /** * Save auth data to file. * When `authData` argument is empty, will overwrite file with empty values. - * - * @param {string} fileName - * @param {AuthData} [authData] */ private async saveDataToFile(authData?: AuthData) { - debug(`Save auth data to the ${this.fileName} file`); + debug(`Trying to save auth data to the ${this.fileName} file`); + const newData = authData ? JSON.stringify(authData) : "{}"; + try { await fsPromises.writeFile(this.fileName, newData); + + debug("Successfully written file %", this.fileName); } catch (err) { debug(`Could not save auth data to the ${this.fileName} file`, err); throw new Error("File APL was unable to save auth data");