__tests__/backend.processFile.mocked.spec.ts
import { beforeAll, afterAll, afterEach, beforeEach, describe, it, expect, vi } from 'vitest';
import { readFileContents } from '../src/backend/processFile';
import { CliOptions, ExecResult } from '../src/backend';
import fetcher from '@jestaubach/fetcher-axios';
import cloner from '@jestaubach/cloner-git';
import fsHelpers from '@jestaubach/fs-helpers';
const useFsHelpers = fsHelpers.use(fsHelpers.mock, [
`__tests__/testFiles/terrafile.test.json`,
`./__tests__/modules/test-module/main.tf`,
`terrafile.sample.json`,
]);
const { getAbsolutePath, createDir, touchFile, rimrafDirs, checkIfFileExists } = useFsHelpers;
const { readFile } = fsHelpers.use(fsHelpers.default);
const useFetcher = fetcher.use(fetcher.mock);
const useCloner = cloner.use(cloner.mock(useFsHelpers) as (_: string[], __?: string) => Promise<ExecResult>);
const testDirs = [`err_vendor1`, `err_vendor2`, `err_vendor3`, `err_vendor4`, `err_vendor_lerror`, `err_vendor_2x`];
describe(`read file contents should read specified json file and validate its contents`, async () => {
beforeAll(async () => {
await rimrafDirs(testDirs);
});
beforeEach(async () => {
vi.resetAllMocks();
});
afterAll(async () => {
await rimrafDirs(testDirs);
});
// expected result when provide bad file path
async function expectFileIssue(options: CliOptions): Promise<void> {
const retVals = await readFileContents(options);
expect(retVals.success).toBe(false);
}
it(`should successfully read a valid terrafile when provided a relative path`, async () => {
const configFile = `__tests__/testFiles/terrafile.test.json`;
const retVals = await readFileContents({
directory: `err_vendor1/modules`,
file: configFile,
fetcher: useFetcher,
cloner: useCloner,
fsHelpers: useFsHelpers,
});
expect(retVals.error).toBe(null);
expect(retVals.success).toBe(true);
expect(retVals.contents).not.toEqual(null);
const testJson = await JSON.parse(readFile(getAbsolutePath(configFile).value).value);
expect(Object.keys(testJson).length).toBe(31);
for (const modName of Object.keys(testJson)) {
expect(checkIfFileExists(getAbsolutePath(`err_vendor1/modules/${modName}/main.tf`).value).value).toEqual(true);
}
});
it(`should successfully read a valid terrafile when provided an absolute path`, async () => {
const configFile = getAbsolutePath(`__tests__/testFiles/terrafile.test.json`).value;
const retVals = await readFileContents({
directory: `err_vendor2/modules`,
file: configFile,
fetcher: useFetcher,
cloner: useCloner,
fsHelpers: useFsHelpers,
});
expect(retVals.success).toBe(true);
expect(retVals.contents).not.toEqual(null);
const testJson = await JSON.parse(readFile(getAbsolutePath(configFile).value).value);
expect(Object.keys(testJson).length).toBe(31);
for (const modName of Object.keys(testJson)) {
expect(checkIfFileExists(getAbsolutePath(`err_vendor2/modules/${modName}/main.tf`).value).value).toEqual(true);
}
});
it(`ensure our sample file passes tests`, async () => {
const configFile = `terrafile.sample.json`;
const destination = `err_vendor3/modules`;
const retVals = await readFileContents({
directory: destination,
file: configFile,
fetcher: useFetcher,
cloner: useCloner,
fsHelpers: useFsHelpers,
});
expect(retVals.error).toBe(null);
expect(retVals.success).toBe(true);
expect(retVals.contents).not.toEqual(null);
const testJson = await JSON.parse(readFile(getAbsolutePath(configFile).value).value);
expect(Object.keys(testJson).length).toBe(7);
for (const modName of Object.keys(testJson)) {
expect(checkIfFileExists(getAbsolutePath(`${destination}/${modName}/main.tf`).value).value).toEqual(true);
}
});
it(`should err on lack read access to file`, async () => {
const configFile = `err_vendor4/no_access_file`;
createDir(getAbsolutePath(`${configFile}/..`).value);
touchFile(getAbsolutePath(configFile).value, 0);
await expectFileIssue({ file: configFile, fsHelpers: useFsHelpers });
});
// test various bad paths and files
it.each([
undefined, // options no provided - no module definition location
{}, // no file option provided for a module definition
{ file: `` }, // no path provided to a module defintion file
{ file: getAbsolutePath(`.`).value }, // a directory provided as a module defintion file
{ file: `does_not_exist` }, // path to module definition file does not exist
{ file: `__tests__/testFiles/invalid.txt` }, // module definitions are not json
{ file: `__tests__/testFiles/invalid.json` }, // json - but doesn't provide valid module definitions
{ file: `__tests__/testFiles/invalid2.json` }, // local module definition includes invalid field
{ file: `__tests__/testFiles/invalid3.json` }, // gitHttps module definition includes invalid field
{ file: `__tests__/testFiles/invalid4.json` }, // terraform module definition includes invalid field
{ file: `__tests__/testFiles/invalid5.json` }, // gitSSH module definition includes invalid field
])(`should err when bad file provided: %s`, async (badFileOption) => {
await expectFileIssue({ ...badFileOption, fsHelpers: useFsHelpers });
});
// valid local module definition - but location of module does not exist
it(`should err on bad local dir`, async () => {
const configFile = `__tests__/testFiles/localError.json`;
await expectFileIssue({
directory: `err_vendor_lerror/testFiles/modules`,
file: configFile,
fetcher: useFetcher,
cloner: useCloner,
fsHelpers: useFsHelpers,
});
});
// two modules with same name and location collision
it(`should err on copy 2x`, async () => {
const configFile = `__tests__/testFiles/local2xError.json`;
const options = {
directory: `err_vendor_2x/modules`,
file: configFile,
fetcher: useFetcher,
cloner: useCloner,
fsHelpers: useFsHelpers,
};
await readFileContents(options); // 1st call to readFileContents
await expectFileIssue(options); // 2nd call to readFileContents, tries to copy module to same location
});
});