@codecovevienna/gittt-cli
Version:
Tracking time with CLI into a git repository
1,586 lines (1,228 loc) • 211 kB
text/typescript
import { assert, expect } from "chai";
import commander, { Command, CommanderStatic } from "commander";
import proxyquire from "proxyquire";
import sinon from "sinon";
import { App } from "../../app";
import { LogHelper } from "../../helper/index";
import { IJiraLink, IJiraPublishResult, IProject, IRecord, IMultipieInputLink, IMultipiePublishResult, IMultipieStoreLink } from "../../interfaces";
import { RECORD_TYPES } from "../../types";
import { emptyHelper } from "../helper";
import { DefaultLogFields } from "simple-git";
LogHelper.DEBUG = true;
LogHelper.silence = false;
// TODO this needs a complete refactoring due to
// massive changes in commander 8
describe.skip("App", function () {
before(function () {
proxyquire.noCallThru();
});
describe("General", function () {
it("should create instance", async function () {
const app: App = new App();
expect(app).to.be.instanceOf(App);
});
it("should start app", async function () {
const parseStub = sinon.spy();
const proxy: any = proxyquire("../../app", {
commander: {
parse: parseStub,
},
});
process.argv = [
"ts-node",
"app.ts",
"list",
];
const app: App = new proxy.App();
app.start();
assert.isTrue(parseStub.calledOnce);
});
it("should start app and show help [unknown command]", async function () {
const helpStub = sinon.spy();
const proxy: any = proxyquire("../../app", {
commander: {
help: helpStub,
},
});
process.argv = [
"mocked",
"unknownCommand",
];
const app: App = new proxy.App();
app.start();
assert.isTrue(helpStub.calledOnce);
});
it("should exit without error", async function () {
const exitStub = sinon.stub(process, "exit");
const warnStub = sinon.stub(LogHelper, "warn");
const proxy: any = proxyquire("../../app", {});
const app: App = new proxy.App();
app.exit("Mock", 0);
assert.isTrue(exitStub.calledWith(0));
assert.isTrue(warnStub.calledWith("Mock"));
exitStub.restore();
warnStub.restore();
});
it("should exit with error", async function () {
const exitStub = sinon.stub(process, "exit");
const errorStub = sinon.stub(LogHelper, "error");
const proxy: any = proxyquire("../../app", {});
const app: App = new proxy.App();
app.exit("Mock", 1337);
assert.isTrue(exitStub.calledWith(1337));
assert.isTrue(errorStub.calledWith("Mock"));
exitStub.restore();
errorStub.restore();
});
});
describe("Setup", function () {
it("should setup app", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper
});
const app: App = new proxy.App();
sinon.stub(app, "initCommander").resolves();
await app.setup();
});
it("should setup app without config directory", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(false);
}
mockedHelper.QuestionHelper = class {
public static confirmSetup = sinon.stub().resolves(true)
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
sinon.stub(app, "initCommander").resolves();
const initConfigDirStub = sinon.stub(app, "initConfigDir").resolves();
await app.setup();
assert.isTrue(initConfigDirStub.calledOnce);
});
it("should exit app due to no setup config directory", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const exitStub = sinon.stub(process, "exit");
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(false);
}
mockedHelper.QuestionHelper = class {
public static confirmSetup = sinon.stub().resolves(false)
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
sinon.stub(app, "initCommander").resolves();
await app.setup();
assert.isTrue(exitStub.calledWith(0));
exitStub.restore();
});
it("should pull repo due to already set up config directory", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const pullStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public configDirExists = sinon.stub().resolves(true);
public isConfigFileValid = sinon.stub().resolves(true);
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.QuestionHelper = class {
public static confirmSetup = sinon.stub().resolves(false)
}
mockedHelper.GitHelper = class {
public pullRepo = pullStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
// Has to be called to have all helper instantiated
await app.setup();
await app.initConfigDir();
assert.isTrue(pullStub.calledOnce);
});
it("should exit app due to invalid config file", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const exitStub = sinon.stub(process, "exit");
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public configDirExists = sinon.stub().resolves(true)
public isConfigFileValid = sinon.stub().resolves(false)
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
// Has to be called to have all helper instantiated
await app.setup();
await app.initConfigDir();
assert.isTrue(exitStub.calledWith(1));
exitStub.restore();
});
it("should initialize config directory from scratch", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const initRepoStub = sinon.stub().resolves();
const pullRepoStub = sinon.stub().resolves();
const createDirStub = sinon.stub().resolves();
const initConfigFileStub = sinon.stub().resolves();
const commitChangesStub = sinon.stub().resolves();
const pushChangesStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public configDirExists = sinon.stub().resolves(false)
public isConfigFileValid = sinon.stub().resolves(false)
public createConfigDir = createDirStub
public initConfigFile = initConfigFileStub
}
mockedHelper.GitHelper = class {
public commitChanges = commitChangesStub
public initRepo = initRepoStub
public pullRepo = pullRepoStub
public pushChanges = pushChangesStub
}
mockedHelper.QuestionHelper = class {
public static askGitUrl = sinon.stub().resolves("ssh://git@mocked.git.com/mock/test.git")
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
// Has to be called to have all helper instantiated
await app.setup();
await app.initConfigDir();
assert.isTrue(createDirStub.calledOnce);
assert.isTrue(initRepoStub.calledOnce);
assert.isTrue(pullRepoStub.calledOnce);
assert.isTrue(initConfigFileStub.calledOnce);
assert.isTrue(commitChangesStub.calledOnce);
assert.isTrue(pushChangesStub.calledOnce);
});
it("should initialize config directory and pull", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const pullStub = sinon.stub().resolves();
const createDirStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public configDirExists = sinon.stub().resolves(false)
public isConfigFileValid = sinon.stub().resolves(true);
public createConfigDir = createDirStub
}
mockedHelper.GitHelper = class {
public pullRepo = pullStub
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const app: App = new proxy.App();
// Has to be called to have all helper instantiated
await app.setup();
await app.initConfigDir();
assert.isTrue(createDirStub.calledOnce);
assert.isTrue(pullStub.calledOnce);
});
});
describe("Init", function () {
it("should init current git repository", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const initProjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ProjectHelper = class {
public initProject = initProjectStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.QuestionHelper = class {
public static confirmInit = sinon.stub().resolves(true)
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
await mockedApp.initAction();
assert.isTrue(initProjectStub.calledOnce);
})
it("should fail to init current git repository [canceled]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const initProjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public initProject = initProjectStub;
}
mockedHelper.QuestionHelper = class {
public static confirmInit = sinon.stub().resolves(false)
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit");
await mockedApp.setup();
await mockedApp.initAction();
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
})
it("should fail to init current git repository [initProject throws]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const initProjectStub = sinon.stub().throws(new Error("mocked"));
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public initProject = initProjectStub;
}
mockedHelper.QuestionHelper = class {
public static confirmInit = sinon.stub().resolves(true)
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit");
await mockedApp.setup();
await mockedApp.initAction();
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
})
})
describe("Edit records", function () {
it("should edit specific record", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getOrAskForProjectFromGitStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
requiresRoles: true,
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
requiresRoles: true,
records: mockedRecords,
} as IProject);
const commitChangesStub = sinon.stub().resolves();
const saveProjectObjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
public saveProjectObject = saveProjectObjectStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.RecordHelper = class {
public static filterRecordsByYear = sinon.stub().resolves(mockedRecords)
public static filterRecordsByMonth = sinon.stub().resolves(mockedRecords)
public static filterRecordsByDay = sinon.stub().resolves(mockedRecords)
}
mockedHelper.GitHelper = class {
public commitChanges = commitChangesStub;
}
mockedHelper.ProjectHelper = class {
public getOrAskForProjectFromGit = getOrAskForProjectFromGitStub;
}
mockedHelper.QuestionHelper = class {
public static askAmount = sinon.stub().resolves(69);
public static askDay = sinon.stub().resolves(24);
public static askHour = sinon.stub().resolves(13);
public static askMessage = sinon.stub().resolves("Mocked message");
public static askMinute = sinon.stub().resolves(37);
public static askMonth = sinon.stub().resolves(24);
public static askYear = sinon.stub().resolves(2019);
public static chooseRecord = sinon.stub().resolves(mockedRecords[0]);
public static chooseType = sinon.stub().resolves("Time");
public static chooseRole = sinon.stub().resolves("?");
}
mockedHelper.MultipieHelper = class {
public getValidRoles = sinon.stub().resolves([{ name: '?', value: '?' }]);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to enable interactive mode
process.argv = ["1", "2", "3"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getOrAskForProjectFromGitStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(saveProjectObjectStub.calledOnce);
expect(saveProjectObjectStub.args[0][0].records[0].amount).to.eq(69);
expect(saveProjectObjectStub.args[0][0].records[0].role).to.eq('?');
expect(saveProjectObjectStub.args[0][0].records[0].message).to.eq("Mocked message");
expect(saveProjectObjectStub.args[0][0].records[0].type).to.eq("Time");
assert.isTrue(commitChangesStub.calledOnce);
});
it("should fail to edit specific record [unable to get project from git]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getProjectByNameStub = sinon.stub().resolves(undefined);
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit").returns();
await mockedApp.setup();
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(new Command());
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should fail to edit specific record [unable to get project from filesystem]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves(undefined);
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit").returns();
await mockedApp.setup();
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(new Command());
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should fail to edit specific record [no records]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: [],
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
public getProjectFromGit = getProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit").returns();
await mockedApp.setup();
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(new Command());
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should edit specific record with arguments", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
const commitChangesStub = sinon.stub().resolves();
const saveProjectObjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
public saveProjectObject = saveProjectObjectStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.GitHelper = class {
public commitChanges = commitChangesStub;
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
mockedHelper.ValidationHelper = class {
public static validateNumber = sinon.stub().returns(true);
}
mockedHelper.MultipieHelper = class {
public getValidRoles = sinon.stub().resolves([{ name: '?', value: '?' }]);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const mockedCommand = new Command();
sinon.stub(mockedCommand, "opts").returns({
amount: 69,
guid: "mocked-guid",
message: "mocked-message",
type: RECORD_TYPES.Time,
role: '?',
});
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
const opts = mockedCommand.opts()
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(saveProjectObjectStub.calledOnce);
expect(saveProjectObjectStub.args[0][0].records[0].amount).to.eq(opts.amount);
expect(saveProjectObjectStub.args[0][0].records[0].role).to.eq(opts.role);
expect(saveProjectObjectStub.args[0][0].records[0].type).to.eq(opts.type);
expect(saveProjectObjectStub.args[0][0].records[0].guid).to.eq(opts.guid);
expect(saveProjectObjectStub.args[0][0].records[0].message).to.eq(opts.message);
assert.isTrue(commitChangesStub.calledOnce);
});
it("should fail to edit specific record with arguments [unknown guid]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit").resolves();
await mockedApp.setup();
const mockedCommand = new Command();
sinon.stub(mockedCommand, "opts").returns({
amount: 69,
guid: "unknown-guid",
type: RECORD_TYPES.Time,
});
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should fail to edit specific record with arguments [no guid]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.amount = 3;
mockedCommand.type = RECORD_TYPES.Time;
const helpStub = sinon.stub(mockedCommand, "help");
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(helpStub.calledOnce);
});
it("should fail to edit specific record with arguments [no amount]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
mockedHelper.ValidationHelper = class {
public static validateNumber = sinon.stub().returns(false);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.guid = "mocked-guid";
mockedCommand.type = RECORD_TYPES.Time;
const helpStub = sinon.stub(mockedCommand, "help");
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(helpStub.calledOnce);
});
it("should fail to edit specific record with arguments [no type]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.amount = 420;
mockedCommand.guid = "mocked-guid";
const helpStub = sinon.stub(mockedCommand, "help");
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(helpStub.calledOnce);
});
it("should fail to edit specific record with arguments [no role]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
requiresRoles: true,
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ValidationHelper = class {
public static validateNumber = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.amount = 420;
mockedCommand.guid = "mocked-guid";
mockedCommand.type = "Time";
const helpStub = sinon.stub(mockedCommand, "help");
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(helpStub.calledOnce);
});
it("should fail to edit specific record with arguments [wrong role]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
requiresRoles: true,
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ValidationHelper = class {
public static validateNumber = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
mockedHelper.MultipieHelper = class {
public getValidRoles = sinon.stub().resolves([{ name: '?', value: '?' }]);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.amount = 420;
mockedCommand.guid = "mocked-guid";
mockedCommand.type = "Time";
mockedCommand.role = "Not found";
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
const exitStub = sinon.stub(process, "exit");
await mockedApp.editAction(mockedCommand);
exitStub.restore();
});
it("should fail to edit specific record with arguments [throws]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getProjectByNameStub = sinon.stub().throws(new Error("Mocked"));
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit").resolves();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to disable interactive mode
process.argv = ["1", "2", "3", "4"];
await mockedApp.editAction(mockedCommand);
assert.isTrue(exitStub.calledOnce);
});
});
describe("Remove records", function () {
it("should remove specific record", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getOrAskForProjectFromGitStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
const commitChangesStub = sinon.stub().resolves();
const saveProjectObjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
public saveProjectObject = saveProjectObjectStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.RecordHelper = class {
public static filterRecordsByYear = sinon.stub().resolves(mockedRecords)
public static filterRecordsByMonth = sinon.stub().resolves(mockedRecords)
public static filterRecordsByDay = sinon.stub().resolves(mockedRecords)
}
mockedHelper.GitHelper = class {
public commitChanges = commitChangesStub;
}
mockedHelper.ProjectHelper = class {
public getOrAskForProjectFromGit = getOrAskForProjectFromGitStub;
}
mockedHelper.QuestionHelper = class {
public static chooseRecord = sinon.stub().resolves(mockedRecords[0]);
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to enable interactive mode
process.argv = ["1", "2", "3"];
await mockedApp.removeAction(mockedCommand);
assert.isTrue(getOrAskForProjectFromGitStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(saveProjectObjectStub.calledOnce);
expect(saveProjectObjectStub.args[0][0].records.length).to.eq(0);
assert.isTrue(commitChangesStub.calledOnce);
});
it("should fail to remove specific record [unable to get project from git]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getOrAskForProjectFromGitStub = sinon.stub().throws(new Error("Mocked Error"));
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getOrAskForProjectFromGit = getOrAskForProjectFromGitStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit");
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to enable interactive mode
process.argv = ["1", "2", "3"];
await mockedApp.removeAction(mockedCommand);
assert.isTrue(getOrAskForProjectFromGitStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should fail to remove specific record [unable to get project from filesystem]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const getOrAskForProjectFromGitStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves(undefined);
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getOrAskForProjectFromGit = getOrAskForProjectFromGitStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit");
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to enable interactive mode
process.argv = ["1", "2", "3"];
await mockedApp.removeAction(mockedCommand);
assert.isTrue(getOrAskForProjectFromGitStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should fail to remove specific record [no records]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [];
const getOrAskForProjectFromGitStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.ProjectHelper = class {
public getOrAskForProjectFromGit = getOrAskForProjectFromGitStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
const exitStub = sinon.stub(mockedApp, "exit");
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
// Mock arguments array to enable interactive mode
process.argv = ["1", "2", "3"];
await mockedApp.removeAction(mockedCommand);
assert.isTrue(getOrAskForProjectFromGitStub.calledOnce);
assert.isTrue(exitStub.calledOnce);
exitStub.restore();
});
it("should remove specific record with arguments", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,
];
const getProjectByNameStub = sinon.stub().returns({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
} as IProject);
const findProjectByNameStub = sinon.stub().resolves({
meta: {
host: "test.git.com",
port: 443,
},
name: "mocked",
records: mockedRecords,
});
const commitChangesStub = sinon.stub().resolves();
const saveProjectObjectStub = sinon.stub().resolves();
mockedHelper.FileHelper = class {
public static getHomeDir = sinon.stub().returns("/home/test");
public findProjectByName = findProjectByNameStub;
public saveProjectObject = saveProjectObjectStub;
}
mockedHelper.ConfigHelper = class {
public static instance: any;
public static getInstance(): any { if (!this.instance) { this.instance = new this() } return this.instance }
public isInitialized = sinon.stub().resolves(true);
}
mockedHelper.GitHelper = class {
public commitChanges = commitChangesStub;
}
mockedHelper.ProjectHelper = class {
public getProjectByName = getProjectByNameStub;
}
const proxy: any = proxyquire("../../app", {
"./helper": mockedHelper,
});
const mockedApp: App = new proxy.App();
await mockedApp.setup();
const program = new commander.Command();
const mockedCommand: commander.Command = program.createCommand();
mockedCommand.guid = "mocked-guid";
// Mock arguments array to be greater than 3
process.argv = ["1", "2", "3", "4"];
await mockedApp.removeAction(mockedCommand);
assert.isTrue(getProjectByNameStub.calledOnce);
assert.isTrue(findProjectByNameStub.calledOnce);
assert.isTrue(saveProjectObjectStub.calledOnce);
expect(saveProjectObjectStub.args[0][0].records.length).to.eq(0);
assert.isTrue(commitChangesStub.calledOnce);
});
it("should fail to remove specific record with arguments [no guid]", async function () {
const mockedHelper: any = Object.assign({}, emptyHelper);
const mockedRecords: IRecord[] = [
{
amount: 1337,
created: 1234,
guid: "mocked-guid",
type: RECORD_TYPES.Time,
} as IRecord,