servers/execution/runner/test/integration/app.controller.spec.ts
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
import { Test } from '@nestjs/testing';
import AppModule from 'src/app.module';
import AppController from 'src/app.controller';
import { HttpStatus, INestApplication } from '@nestjs/common';
import { Response } from 'express';
import { ExecuteCommandDto } from 'src/dto/command.dto';
import { Manager } from 'src/interfaces/command.interface';
import ExecaManager from 'src/execa-manager.service';
import Keyv from 'keyv';
import Config from 'src/config/configuration.service';
type ResponseBody = {
status: string;
};
let mockBlackhole: jest.Mock;
describe('Test AppController', () => {
let app: INestApplication;
let controller: AppController;
let manager: Manager;
const CLIOptions: Keyv = new Keyv();
let config: Config;
async function newCommandTest(
executeCommandDto: ExecuteCommandDto,
httpStatus: HttpStatus,
resBody: ResponseBody,
) {
mockBlackhole = jest.fn();
const res: Response = {} as Response;
res.status = function status(): Response {
mockBlackhole(httpStatus);
return res;
};
res.send = function send(body: ResponseBody): Response {
mockBlackhole(body);
return res;
};
const resStatus = jest.spyOn(res, 'status');
const resSend = jest.spyOn(res, 'send');
const spyManager = jest.spyOn(manager, 'newCommand');
await controller.newCommand(executeCommandDto, res);
expect(spyManager).toHaveBeenCalledWith(executeCommandDto.name);
expect(resStatus).toHaveBeenCalledWith(httpStatus);
expect(resSend).toHaveBeenCalledWith(resBody);
}
beforeAll(async () => {
await CLIOptions.set('configFile', 'runner.test.yaml');
});
beforeEach(async () => {
const moduleFixture = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
controller = app.get<AppController>(AppController);
manager = app.get<ExecaManager>(ExecaManager);
config = app.get<Config>(Config);
config.loadConfig(CLIOptions);
});
afterEach(() => jest.resetAllMocks());
it('Should start with empty command history', () => {
expect(controller.getHistory()).toEqual([]);
});
it('should execute an available command', async () => {
await newCommandTest({ name: 'create' }, HttpStatus.OK, {
status: 'success',
});
});
it('should not execute an unavailable command', async () => {
await newCommandTest({ name: 'test' }, HttpStatus.BAD_REQUEST, {
status: 'invalid command',
});
});
it('Should have correct command history', async () => {
await newCommandTest({ name: 'create' }, HttpStatus.OK, {
status: 'success',
});
await newCommandTest({ name: 'test' }, HttpStatus.BAD_REQUEST, {
status: 'invalid command',
});
expect(controller.getHistory()).toEqual([
{
name: 'create',
},
{ name: 'test' },
]);
});
it('Should return correct command status after valid command execution followed by invalid command execution', async () => {
await newCommandTest({ name: 'create' }, HttpStatus.OK, {
status: 'success',
});
const successStatus = await controller.cmdStatus();
await newCommandTest({ name: 'test' }, HttpStatus.BAD_REQUEST, {
status: 'invalid command',
});
const unsuccessStatus = await controller.cmdStatus();
expect(successStatus).toEqual({
name: 'create',
status: 'valid',
logs: {
stdout: 'hello world',
stderr: '',
},
});
expect(unsuccessStatus).toEqual({
name: 'test',
status: 'invalid',
logs: {
stdout: '',
stderr: '',
},
});
});
it('Should return correct command status without any prior command execution', async () => {
const unsuccessStatus = await controller.cmdStatus();
expect(unsuccessStatus).toEqual({
name: 'none',
status: 'invalid',
logs: {
stdout: '',
stderr: '',
},
});
});
});