From 5463ab02936572cb5c30ae6aa4a43660da82d7eb Mon Sep 17 00:00:00 2001 From: Alexander Martinz Date: Wed, 7 Sep 2022 15:03:07 +0200 Subject: [PATCH] plugins: core: catch and rethrow error when unpacking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unpacking actually expects the callback to always be provided, either as second or third argument. Change-Id: If81661d806ea58304c91d38a168535575ece8afd Co-developed-by: Maciej SopyƂo Signed-off-by: Alexander Martinz --- src/core/plugins/core/plugin.js | 23 +++++++--- src/core/plugins/core/plugin.spec.js | 64 +++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/core/plugins/core/plugin.js b/src/core/plugins/core/plugin.js index 885404c3..97f0b3ef 100644 --- a/src/core/plugins/core/plugin.js +++ b/src/core/plugins/core/plugin.js @@ -200,14 +200,23 @@ class CorePlugin extends Plugin { }) .then(basepath => Promise.all( - files.map(file => - unpack( - path.join(basepath, file.archive), - path.join(basepath, file.dir) - ) - ) + files.map(file => { + const archive = path.join(basepath, file.archive); + const directory = path.join(basepath, file.dir || "."); + this.log.debug("Unpacking " + archive + " to: " + directory); + return new Promise(function (resolve, reject) { + unpack(archive, directory, err => { + if (err) { + reject(Error("Failed to unpack: " + err)); + } else { + resolve(); + } + }); + }); + }) ) - ); + ) + .then(() => Promise.resolve()); } /** diff --git a/src/core/plugins/core/plugin.spec.js b/src/core/plugins/core/plugin.spec.js index 4354fe6a..8fe207b2 100644 --- a/src/core/plugins/core/plugin.spec.js +++ b/src/core/plugins/core/plugin.spec.js @@ -1,13 +1,18 @@ process.argv = [null, null, "-vv"]; const mainEvent = { emit: jest.fn() }; const log = { error: jest.fn(), debug: jest.fn(), info: jest.fn() }; +const asarLibs = require("../../helpers/asarLibs.js"); +jest.mock("../../helpers/asarLibs.js"); beforeEach(() => { mainEvent.emit.mockReset(); log.error.mockReset(); log.debug.mockReset(); log.info.mockReset(); + asarLibs.unpack.mockClear(); }); +const path = require("path"); + const { download, checkFile } = require("progressive-downloader"); const { writeFile } = require("fs-extra"); const core = new (require("./plugin.js"))( @@ -209,11 +214,60 @@ describe("core plugin", () => { }); describe("action__unpack()", () => { - it("should unpack", () => - core.action__unpack({ - group: "firmware", - files: [{ archive: "a.zip", dir: "a" }] - })); // TODO add assertions + it("should unpack to a child directory called 'unpacked'", () => { + jest + .spyOn(mainEvent, "emit") + .mockImplementation((e, f, g, cb) => (cb ? cb() : null)); + return core + .action__unpack({ + group: "firmware", + files: [{ archive: "a.zip", dir: "unpacked" }] + }) + .then(() => { + expect(asarLibs.unpack).toHaveBeenCalledTimes(1); + expect(asarLibs.unpack).toHaveBeenCalledWith( + path.join("a/yggdrasil/firmware", "a.zip"), + path.join("a/yggdrasil/firmware", "unpacked"), + expect.any(Function) + ); + expect(mainEvent.emit).toHaveBeenCalledTimes(3); + }); + }); + it("should unpack to directory where archive is located", () => { + jest + .spyOn(mainEvent, "emit") + .mockImplementation((e, f, g, cb) => (cb ? cb() : null)); + return core + .action__unpack({ + group: "firmware", + files: [{ archive: "a.zip" }] + }) + .then(() => { + expect(asarLibs.unpack).toHaveBeenCalledTimes(1); + expect(asarLibs.unpack).toHaveBeenCalledWith( + path.join("a/yggdrasil/firmware", "a.zip"), + path.join("a/yggdrasil/firmware", "."), + expect.any(Function) + ); + expect(mainEvent.emit).toHaveBeenCalledTimes(3); + }); + }); + it("should reject on unpack errors", () => { + jest + .spyOn(mainEvent, "emit") + .mockImplementation((e, f, g, cb) => (cb ? cb() : null)); + asarLibs.unpack.mockImplementation((e, f, cb) => + cb(new Error("test error")) + ); + return core + .action__unpack({ + group: "firmware", + files: [{ archive: "a.zip" }] + }) + .catch(e => { + expect(e.message).toEqual("Failed to unpack: Error: test error"); + }); + }); }); describe("action__manual_download()", () => {