Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"prepublishOnly": "rimraf ./dist && npm run build && pkg-ok",
"build": "node ./esbuild.config.js",
"test": "npm run test-only && npm run lint",
"test-only": "glob -c \"node --loader=esmock --no-warnings --test-concurrency 1 --test\" \"test/**/*.test.js\"",
"test-only": "glob -c \"node --no-warnings --test-concurrency 1 --test\" \"test/**/*.test.js\"",
"coverage": "c8 --reporter=lcov npm run test",
"clear:cache": "node ./scripts/clear-cache.js"
},
Expand Down Expand Up @@ -72,7 +72,6 @@
"cross-env": "^7.0.3",
"esbuild": "^0.25.0",
"eslint-plugin-jsdoc": "^50.6.2",
"esmock": "^2.6.7",
"http-server": "^14.1.1",
"pkg-ok": "^3.0.0",
"pretty-bytes": "^7.0.0",
Expand Down
4 changes: 2 additions & 2 deletions src/http-server/endpoints/flags.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Import Node.js Dependencies
import { pipeline } from "node:stream";
import stream from "node:stream";

// Import Third-party Dependencies
import send from "@polka/send-type";
Expand All @@ -19,7 +19,7 @@ export function get(req, res) {

res.writeHead(200, { "Content-Type": "text/html" });

return pipeline(lazyFetchFlagFile(req.params.title), res, (err) => {
return stream.pipeline(lazyFetchFlagFile(req.params.title), res, (err) => {
if (err) {
console.error(err);
}
Expand Down
7 changes: 6 additions & 1 deletion src/http-server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import * as middlewares from "./middlewares/index.js";
import { appCache } from "../cache.js";
import { WebSocketServerInstanciator } from "./websocket/index.js";

// CONSTANTS
export const BROWSER = {
open
};

export function buildServer(dataFilePath, options = {}) {
const httpConfigPort = typeof options.port === "number" ? options.port : 0;
const openLink = typeof options.openLink === "boolean" ? options.openLink : true;
Expand Down Expand Up @@ -68,7 +73,7 @@ export function buildServer(dataFilePath, options = {}) {
console.log(kleur.magenta().bold(await i18n.getToken("cli.http_server_started")), kleur.cyan().bold(link));

if (openLink) {
open(link);
BROWSER.open(link);
}
});

Expand Down
30 changes: 12 additions & 18 deletions test/commands/scorecard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { fileURLToPath } from "node:url";
import path from "node:path";
import { test } from "node:test";
import assert from "node:assert";
import fs from "node:fs";

// Import Third-party Dependencies
import esmock from "esmock";
import { API_URL } from "@nodesecure/ossf-scorecard-sdk";
import { Ok } from "@openally/result";

// Import Internal Dependencies
import { runProcess } from "../helpers/cliCommandRunner.js";
import { arrayFromAsync, getExpectedScorecardLines } from "../helpers/utils.js";
import { getCurrentRepository } from "../../src/commands/scorecard.js";

// CONSTANTS
const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -97,26 +98,19 @@ test("should not display scorecard for unknown repository", async() => {
assert.deepEqual(givenLines, expectedLines, `lines should be ${expectedLines}`);
});

test("should retrieve repository whithin git config", async() => {
const testingModule = await esmock("../../src/commands/scorecard.js", {
fs: {
readFileSync: () => [
"[remote \"origin\"]",
"\turl = git@github.com:myawesome/repository.git"
].join("\n")
}
});
test("should retrieve repository within git config", async(ctx) => {
const readFileResult = [
"[remote \"origin\"]",
"\turl = git@github.com:myawesome/repository.git"
].join("\n");
ctx.mock.method(fs, "readFileSync", () => readFileResult);

assert.deepEqual(testingModule.getCurrentRepository(), Ok(["myawesome/repository", "github"]));
assert.deepEqual(getCurrentRepository(), Ok(["myawesome/repository", "github"]));
});

test("should not find origin remote", async() => {
const testingModule = await esmock("../../src/commands/scorecard.js", {
fs: {
readFileSync: () => "just one line"
}
});
const result = testingModule.getCurrentRepository();
test("should not find origin remote", async(ctx) => {
ctx.mock.method(fs, "readFileSync", () => "just one line");
const result = getCurrentRepository();

assert.equal(result.err, true);
assert.equal(result.val, "Cannot find origin remote.");
Expand Down
77 changes: 41 additions & 36 deletions test/httpServer.test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
// Import Node.js Dependencies
import fs from "node:fs";
import { fileURLToPath } from "node:url";
import { after, before, describe, test } from "node:test";
import { after, before, describe, test, mock } from "node:test";
import { once } from "node:events";
import path from "node:path";
import assert from "node:assert";
import stream from "node:stream";

// Import Third-party Dependencies
import { get, post, MockAgent, getGlobalDispatcher, setGlobalDispatcher } from "@myunisoft/httpie";
import * as i18n from "@nodesecure/i18n";
import * as flags from "@nodesecure/flags";
import enableDestroy from "server-destroy";
import esmock from "esmock";
import cacache from "cacache";

// Import Internal Dependencies
import { buildServer } from "../src/http-server/index.js";
import { buildServer, BROWSER } from "../src/http-server/index.js";
import { CACHE_PATH } from "../src/cache.js";
import * as rootEndpoint from "../src/http-server/endpoints/root.js";
import * as flagsEndpoint from "../src/http-server/endpoints/flags.js";

// CONSTANTS
const kHttpPort = 17049;
Expand Down Expand Up @@ -69,20 +71,35 @@ describe("httpServer", { concurrency: 1 }, () => {
assert.equal(result.headers["content-type"], "text/html");
});

test("'/' should fail", async() => {
const errors = [];
const module = await esmock("../src/http-server/endpoints/root.js", {
"@polka/send-type": {
default: (_res, _status, { error }) => errors.push(error)
test("'/' should fail", async(ctx) => {
class Response {
constructor() {
this.body = "";
this.headers = {};
this.statusCode = 200;
}
});

await module.get({}, ({
writeHead: () => {
throw new Error("fake error");
end(str) {
this.body = str;
}
writeHead(int) {
this.statusCode = int;
}
getHeader(key) {
return this.headers[key];
}
}));
assert.deepEqual(errors, ["fake error"]);
}

const fakeError = "fake error";
function toThrow() {
throw new Error(fakeError);
}
ctx.mock.method(Response.prototype, "writeHead", toThrow, { times: 1 });

const response = new Response();
await rootEndpoint.get({}, response);

assert.strictEqual(response.body, JSON.stringify({ error: fakeError }));
assert.strictEqual(response.statusCode, 500);
});

test("'/flags' should return the flags list as JSON", async() => {
Expand Down Expand Up @@ -111,19 +128,12 @@ describe("httpServer", { concurrency: 1 }, () => {
});
});

test("'/flags/description/:title' should fail", async() => {
const module = await esmock("../src/http-server/endpoints/flags.js", {
stream: {
pipeline: (_stream, _res, err) => err("fake error")
},
fs: {
createReadStream: () => "foo"
}
});
test("'/flags/description/:title' should fail", async(ctx) => {
ctx.mock.method(stream, "pipeline", (_stream, _res, err) => err("fake error"));
const logs = [];
console.error = (data) => logs.push(data);

await module.get({ params: { title: "hasWarnings" } }, ({ writeHead: () => true }));
await flagsEndpoint.get({ params: { title: "hasWarnings" } }, ({ writeHead: () => true }));
assert.deepEqual(logs, ["fake error"]);
});

Expand Down Expand Up @@ -312,30 +322,25 @@ describe("httpServer", { concurrency: 1 }, () => {

describe("httpServer without options", () => {
let httpServer;
let opened = false;
let spawnOpen;
// We want to disable WS
process.env.NODE_ENV = "test";

before(async() => {
const module = await esmock("../src/http-server/index.js", {
open: () => (opened = true)
});

httpServer = module.buildServer(JSON_PATH);
spawnOpen = mock.method(BROWSER, "open", () => void 0);
httpServer = buildServer(JSON_PATH);
await once(httpServer.server, "listening");
enableDestroy(httpServer.server);
});

after(async() => {
httpServer.server.destroy();
spawnOpen.mock.restore();
});

test("should listen on random port", () => {
test("should listen on random port and call childProcess.spawn method ('open' pkg) to open link", async() => {
assert.ok(httpServer.server.address().port > 0);
});

test("should have openLink to true", () => {
assert.equal(opened, true);
assert.strictEqual(spawnOpen.mock.callCount(), 1);
});
});

Expand Down