From 4f8c180c0f38e3f6950b9f1bfb40d4d0dbb03c6e Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Thu, 5 Sep 2019 15:36:39 +0200 Subject: [PATCH] [FIX] Resolve absolute paths (webapp / src / test) Fixes: https://github.com/SAP/karma-ui5/issues/91 --- lib/errors.js | 23 +++++++ lib/framework.js | 31 +++++++++ test/framework.test.js | 141 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) diff --git a/lib/errors.js b/lib/errors.js index 5cb1d4ae..c2770ea1 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -225,6 +225,29 @@ But entry ${JSON.stringify(urlParameter)} is of type "${typeof urlParameter}".`, Every urlParameters configuration entry must have properties "key" and "value": ${JSON.stringify(urlParameter)} `, + + pathNotWithinBasePath: ({pathName, pathValue, absolutePathValue, basePath}) => `error 18: +Configured "${pathName}" folder must be within configured "basePath" folder. + +${absolutePathValue} +not within +${basePath} + +Please check if the configured paths are correct: + +module.exports = function(config) { + config.set({ + + ui5: { + paths: { + ${pathName}: "${pathValue}" \t<-- + } + } + + }); +}; +`, + failure: () => "ui5.framework failed. See error message above" } diff --git a/lib/framework.js b/lib/framework.js index ae1ab45c..9dca677e 100644 --- a/lib/framework.js +++ b/lib/framework.js @@ -179,6 +179,37 @@ class Framework { test: "test" }; + ["webapp", "src", "test"].forEach((pathName) => { + let pathValue = this.config.ui5.paths[pathName]; + if (!pathValue) { + return; + } + + let absolutePathValue; + const absoluteBasePath = path.resolve(this.config.basePath); + + // Make sure paths are relative to the basePath + if (path.isAbsolute(pathValue)) { + absolutePathValue = pathValue; + pathValue = path.relative(this.config.basePath, pathValue); + } else { + absolutePathValue = path.resolve(this.config.basePath, pathValue); + } + + // Paths must be within basePath + if (!absolutePathValue.startsWith(absoluteBasePath)) { + this.logger.log("error", ErrorMessage.pathNotWithinBasePath({ + pathName, + pathValue: this.config.ui5.paths[pathName], // use value given in config here + absolutePathValue, + basePath: absoluteBasePath + })); + throw new Error(ErrorMessage.failure()); + } + + this.config.ui5.paths[pathName] = pathValue; + }); + this.autoDetectType(); if (this.config.ui5.mode === "script") { diff --git a/test/framework.test.js b/test/framework.test.js index 061aaf02..9ede8431 100644 --- a/test/framework.test.js +++ b/test/framework.test.js @@ -1,4 +1,5 @@ const Framework = require("../lib/framework"); +const path = require("path"); const fs = require("fs"); const {ErrorMessage} = require("../lib/errors"); @@ -191,6 +192,146 @@ describe("UI5 Middleware / Proxy configuration", () => { }); }); +describe("ui5.paths handling", () => { + it("application: Should resolve relative path relative to basePath", () => { + const framework = new Framework(); + const config = { + ui5: { + url: "http://localhost", + type: "application", + paths: { + webapp: "webapp-path" + } + } + }; + + framework.exists = (filePath) => { + return filePath === "webapp-path"; + }; + + framework.init({config, logger}); + + expect(config.ui5.paths).toStrictEqual({ + webapp: "webapp-path" + }); + }); + it("application: Should resolve absolute path relative to basePath", () => { + const framework = new Framework(); + const config = { + ui5: { + url: "http://localhost", + type: "application", + paths: { + webapp: path.resolve("webapp-path") + } + } + }; + + framework.exists = (filePath) => { + return filePath === "webapp-path"; + }; + + framework.init({config, logger}); + + expect(config.ui5.paths).toStrictEqual({ + webapp: "webapp-path" + }); + }); + + it("library: Should resolve relative paths relative to basePath", () => { + const framework = new Framework(); + const config = { + ui5: { + url: "http://localhost", + type: "library", + paths: { + src: "src-path", + test: "test-path" + } + } + }; + + framework.exists = (filePath) => { + return filePath === "src-path" || filePath === "test-path"; + }; + + framework.init({config, logger}); + + expect(config.ui5.paths).toStrictEqual({ + src: "src-path", + test: "test-path" + }); + }); + it("library: Should resolve absolute paths relative to basePath", () => { + const framework = new Framework(); + const config = { + ui5: { + url: "http://localhost", + type: "library", + paths: { + src: path.resolve("src-path"), + test: path.resolve("test-path") + } + } + }; + + framework.exists = (filePath) => { + return filePath === "src-path" || filePath === "test-path"; + }; + + framework.init({config, logger}); + + expect(config.ui5.paths).toStrictEqual({ + src: "src-path", + test: "test-path" + }); + }); + + it("application: Should throw error when absolute path is not within basePath", () => { + const framework = new Framework(); + const config = { + basePath: "/test/bar", + ui5: { + url: "http://localhost", + type: "application", + paths: { + webapp: "/test/foo/webapp-path" + } + } + }; + + expect(() => framework.init({config, logger})).toThrow(); + + expect(framework.logger.message).toBe(ErrorMessage.pathNotWithinBasePath({ + pathName: "webapp", + pathValue: "/test/foo/webapp-path", + absolutePathValue: "/test/foo/webapp-path", + basePath: "/test/bar" + })); + }); + it("application: Should throw error when relative path is not within basePath", () => { + const framework = new Framework(); + const config = { + basePath: "/test/bar", + ui5: { + url: "http://localhost", + type: "application", + paths: { + webapp: "../foo/webapp-path" + } + } + }; + + expect(() => framework.init({config, logger})).toThrow(); + + expect(framework.logger.message).toBe(ErrorMessage.pathNotWithinBasePath({ + pathName: "webapp", + pathValue: "../foo/webapp-path", + absolutePathValue: "/test/foo/webapp-path", + basePath: "/test/bar" + })); + }); +}); describe("Utility functions", () => { const framework = new Framework();