lion/packages-node/providence-analytics/test-node/dashboard/dashboard-server.test.js
2023-11-09 11:38:39 +01:00

121 lines
4.4 KiB
JavaScript

/* eslint-disable import/no-extraneous-dependencies */
import fs from 'fs';
import pathLib from 'path';
import sinon from 'sinon';
import { fileURLToPath, pathToFileURL } from 'url';
import { expect } from 'chai';
import { it } from 'mocha';
import fetch from 'node-fetch';
import { createTestServer } from '@web/dev-server-core/test-helpers';
import { createDashboardServerConfig } from '../../src/dashboard/server.js';
import { ReportService } from '../../src/program/core/ReportService.js';
import { providenceConfUtil } from '../../src/program/utils/providence-conf-util.js';
/**
* @typedef {import('@web/dev-server-core').DevServer} DevServer
*/
const __dirname = pathLib.dirname(fileURLToPath(import.meta.url));
const { outputPath: reportServiceOutputPathOriginal } = ReportService;
const fixturesPath = pathLib.join(__dirname, 'fixtures');
const mockedResponsesPath = pathLib.join(__dirname, 'fixtures/dashboard-responses');
const mockedOutputPath = pathLib.join(__dirname, 'fixtures/providence-output');
/**
* @param {string} url
*/
async function getConf(url) {
const { href } = pathToFileURL(url);
const { default: providenceConf } = await import(href);
const providenceConfRaw = fs.readFileSync(url, 'utf8');
return { providenceConf, providenceConfRaw };
}
describe('Dashboard Server', () => {
/** @type {string} */
let host;
/** @type {DevServer} */
let server;
/** @type {sinon.SinonStub} */
let providenceConfStub;
before(() => {
// N.B. don't use mock-fs, since it doesn't correctly handle dynamic imports and fs.promises
ReportService.outputPath = mockedOutputPath;
});
after(() => {
ReportService.outputPath = reportServiceOutputPathOriginal;
});
describe('Happy flow', () => {
beforeEach(async () => {
const conf = await getConf(`${fixturesPath}/providence.conf.mjs`);
providenceConfStub = sinon.stub(providenceConfUtil, 'getConf').resolves(conf);
({ host, server } = await createTestServer(await createDashboardServerConfig()));
});
afterEach(() => {
providenceConfStub.restore();
server.stop();
});
describe('Index', () => {
it(`returns an index on '/'`, async () => {
const response = await fetch(`${host}/src/dashboard`);
const responseText = await response.text();
expect(response.status).to.equal(200);
expect(responseText).to.include('<title>Providence dashboard</title>');
});
});
describe('App assets', () => {
it(`returns (static) js assets via app/*`, async () => {
const response = await fetch(`${host}/src/dashboard/app/p-board.js`);
expect(response.status).to.equal(200);
});
});
describe('Menu data', () => {
it(`returns json object based on output`, async () => {
const response = await fetch(`${host}/menu-data.json`);
expect(response.status).to.equal(200);
const responseJSON = await response.json();
const expectedResult = fs.readFileSync(`${mockedResponsesPath}/menu-data.json`, 'utf8');
expect(responseJSON).to.eql(JSON.parse(expectedResult));
});
});
describe('Results', () => {
it(`returns json object based on output`, async () => {
const response = await fetch(`${host}/results.json`);
expect(response.status).to.equal(200);
const responseJson = await response.json();
const expectedResult = fs.readFileSync(`${mockedResponsesPath}/results.json`, 'utf8');
expect(responseJson).to.eql(JSON.parse(expectedResult));
});
});
describe('Config file "providence.conf.(m)js"', () => {
it(`returns providence.conf.mjs found in cwd`, async () => {
const response = await fetch(`${host}/providence-conf.js`);
expect(response.status).to.equal(200);
const responseText = await response.text();
const { providenceConfRaw } = await getConf(`${fixturesPath}/providence.conf.mjs`);
expect(responseText).to.equal(providenceConfRaw);
});
// Since we cannot mock dynamic imports: skip for now...
it.skip(`returns providence.conf.js found in cwd`, async () => {});
});
});
describe('Unhappy flow', () => {
// Since we cannot mock dynamic imports: skip for now...
describe.skip('Config file "providence.conf.(m)js"', () => {
it(`throws when no providence.conf.(m)js found`, async () => {});
it(`throws when providence.conf.(m)js is not an esm module`, async () => {});
});
});
});