import { expect } from "chai"; import { ChoiceRequest } from "../../../src/models"; import { FakeRequestBuilder } from "../fakeRequestBuilder"; import { StepBuilder } from "../../../src/steps/stepBuilder"; import { StepResult } from "../../../src/steps/stepResult"; import { AbstractStep } from "../../../src/steps/abstractStep"; import { FakeCampaign } from "../fake/Campaign"; import { config } from "../../../src/utils/config"; describe("AbstractStep", () => { describe("applyFiltering", () => { it("chained filtering", async () => { let step = new StepBuilder(new FilteringFakeStep(2)).build(); const campaigns = [ new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4"), ]; const request: ChoiceRequest = new FakeRequestBuilder().withCampaigns(...campaigns).build(); // filtering 1 await step.execute(request); expect(request.campaigns).to.have.length(2); expect(request.campaigns.find((campaign) => campaign.id === "2")).to.not.be.undefined; expect(request.campaigns.find((campaign) => campaign.id === "4")).to.not.be.undefined; request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus["pass_test_step_2"]).to.be.equal("true") ); expect(request.excluded).to.have.length(2); expect(request.excluded!.find((campaign) => campaign.id === "1")).to.not.be.undefined; expect(request.excluded!.find((campaign) => campaign.id === "3")).to.not.be.undefined; request.excluded!.forEach((campaign) => expect(campaign.stepsPassedStatus["pass_test_step_2"]).to.be.equal("false") ); step = new StepBuilder(new FilteringFakeStep(4)).build(); await step.execute(request); expect(request.campaigns).to.have.length(1); expect(request.campaigns.find((campaign) => campaign.id === "4")).to.not.be.undefined; request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus["pass_test_step_2"]).to.be.equal("true") ); request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus["pass_test_step_4"]).to.be.equal("true") ); expect(request.excluded).to.have.length(3); expect(request.excluded!.find((campaign) => campaign.id === "1")).to.not.be.undefined; expect(request.excluded!.find((campaign) => campaign.id === "2")).to.not.be.undefined; expect(request.excluded!.find((campaign) => campaign.id === "3")).to.not.be.undefined; expect( request.excluded!.find((campaign) => campaign.id === "2")!.stepsPassedStatus[ "pass_test_step_2" ] ).to.be.equal("true"); expect( request.excluded!.find((campaign) => campaign.id === "2")!.stepsPassedStatus[ "pass_test_step_4" ] ).to.be.equal("false"); expect( request.excluded!.find((campaign) => campaign.id === "1")!.stepsPassedStatus[ "pass_test_step_2" ] ).to.be.equal("false"); expect( request.excluded!.find((campaign) => campaign.id === "3")!.stepsPassedStatus[ "pass_test_step_2" ] ).to.be.equal("false"); }); }); describe("run a step", () => { it("filtering step", async () => { const step = new StepBuilder(new FilteringFakeStep(2)).build(); const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("3"), new FakeCampaign("2"), new FakeCampaign("6"), new FakeCampaign("8"), new FakeCampaign("5"), new FakeCampaign("4"), new FakeCampaign("7") ) .build(); const res = await step.execute(request); expect(res.passedCampaigns).to.have.lengthOf(4); expect(res.passedCampaigns[0].id).to.equal("2"); expect(res.passedCampaigns[1].id).to.equal("6"); expect(res.passedCampaigns[2].id).to.equal("8"); expect(res.passedCampaigns[3].id).to.equal("4"); res.passedCampaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_2).to.be.equal("true") ); expect(request.campaigns).to.have.lengthOf(4); expect(request.campaigns[0].id).to.equal("2"); expect(request.campaigns[1].id).to.equal("6"); expect(request.campaigns[2].id).to.equal("8"); expect(request.campaigns[3].id).to.equal("4"); request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_2).to.be.equal("true") ); expect(request.excluded).to.have.lengthOf(4); expect(request.excluded![0].id).to.equal("1"); expect(request.excluded![1].id).to.equal("3"); expect(request.excluded![2].id).to.equal("5"); expect(request.excluded![3].id).to.equal("7"); request.excluded!.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_2).to.be.equal("false") ); }); it("chained filtering step", async () => { const step2 = new StepBuilder(new FilteringFakeStep(2)).build(); const step4 = new StepBuilder(new FilteringFakeStep(4)).build(); const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("3"), new FakeCampaign("2"), new FakeCampaign("6"), new FakeCampaign("8"), new FakeCampaign("5"), new FakeCampaign("4"), new FakeCampaign("7") ) .build(); await step2.execute(request); const res = await step4.execute(request); expect(res.passedCampaigns).to.have.lengthOf(2); expect(res.passedCampaigns[0].id).to.equal("8"); expect(res.passedCampaigns[1].id).to.equal("4"); res.passedCampaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_2).to.be.equal("true") ); res.passedCampaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_4).to.be.equal("true") ); expect(request.campaigns).to.have.lengthOf(2); expect(request.campaigns[0].id).to.equal("8"); expect(request.campaigns[1].id).to.equal("4"); request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_2).to.be.equal("true") ); request.campaigns.forEach((campaign) => expect(campaign.stepsPassedStatus.pass_test_step_4).to.be.equal("true") ); expect(request.excluded).to.have.lengthOf(6); expect(request.excluded![0].id).to.equal("2"); expect(request.excluded![1].id).to.equal("6"); expect(request.excluded![2].id).to.equal("1"); expect(request.excluded![3].id).to.equal("3"); expect(request.excluded![4].id).to.equal("5"); expect(request.excluded![5].id).to.equal("7"); expect(request.excluded![0].stepsPassedStatus.pass_test_step_2).to.be.equal("true"); expect(request.excluded![0].stepsPassedStatus.pass_test_step_4).to.be.equal("false"); expect(request.excluded![1].stepsPassedStatus.pass_test_step_2).to.be.equal("true"); expect(request.excluded![1].stepsPassedStatus.pass_test_step_4).to.be.equal("false"); expect(request.excluded![2].stepsPassedStatus.pass_test_step_2).to.be.equal("false"); expect(request.excluded![2].stepsPassedStatus.pass_test_step_4).to.be.undefined; expect(request.excluded![3].stepsPassedStatus.pass_test_step_2).to.be.equal("false"); expect(request.excluded![3].stepsPassedStatus.pass_test_step_4).to.be.undefined; expect(request.excluded![4].stepsPassedStatus.pass_test_step_2).to.be.equal("false"); expect(request.excluded![4].stepsPassedStatus.pass_test_step_4).to.be.undefined; expect(request.excluded![5].stepsPassedStatus.pass_test_step_2).to.be.equal("false"); expect(request.excluded![5].stepsPassedStatus.pass_test_step_4).to.be.undefined; }); }); describe("conditionalRun", () => { it("no conditional step should run", async () => { const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(2); expect(innerStep.numberOfRuns).to.be.equal(1); }); it("with conditional step step should not run", async () => { const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).conditionalRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(0); }); it("with conditional step and activate config to false then step should not run", async () => { config.STEP_ACTIVATE_test_step_2 = "false"; const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).conditionalRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(0); delete config.STEP_ACTIVATE_test_step_21000; }); it("with conditional step and activate config to true then step should run", async () => { config.STEP_ACTIVATE_test_step_2 = "true"; const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).conditionalRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(2); expect(innerStep.numberOfRuns).to.be.equal(1); delete config.STEP_ACTIVATE_test_step_2; }); it("with conditional step and dryrun step should not run", async () => { const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).conditionalRun().dryRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(0); }); it("without conditional step and dryrun then step should dry run", async () => { const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).dryRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(1); }); it("without conditional step and dryrun and decorator then step should dry run", async () => { const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).metrics().dryRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(1); }); it("with conditional step and activate config to true and dryrun then step should dry run", async () => { config.STEP_ACTIVATE_test_step_2 = "true"; const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).dryRun().conditionalRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(1); delete config.STEP_ACTIVATE_test_step_2; }); it("with conditional step and activate config to dry then step should dry run", async () => { config.STEP_ACTIVATE_test_step_2 = "dry"; const request: ChoiceRequest = new FakeRequestBuilder() .withCampaigns( new FakeCampaign("1"), new FakeCampaign("2"), new FakeCampaign("3"), new FakeCampaign("4") ) .build(); const innerStep = new FilteringFakeStep(2); const fullStep = new StepBuilder(innerStep).conditionalRun().build(); await fullStep.execute(request); expect(request.campaigns).to.have.length(4); expect(innerStep.numberOfRuns).to.be.equal(1); delete config.STEP_ACTIVATE_test_step_2; }); }); /** * Fake step that filters campaigns with ID % param === 0. */ class FilteringFakeStep extends AbstractStep { private readonly param: number; public numberOfRuns = 0; constructor(param: number) { super("test_step_" + param); this.param = param; } async run(request: ChoiceRequest): Promise { const result = new StepResult(); result.passCampaigns( ...request.campaigns.filter((campaign) => parseInt(campaign.id) % this.param === 0) ); this.numberOfRuns++; return result; } } });