import { expectedDeliveryMonitoringSteps, expectKafkaTopicMessagesCount, } from "../../mocks/kafka.mock"; import { IntegrationTestContext } from "../utils/integration-test-context"; import * as helper from "../../../src/utils/helper"; import { MockedFeatureConfig } from "@ogury/feature-config-sdk"; import { FeatureConfigService } from "../../../src/services/FeatureConfig.service"; import { bid } from "../../../src/beeswax-protos/beeswax"; import { FakeBeeswaxRequestBuilder } from "../../unit/utils/fakeBeeswaxRequestBuilder"; import { assert, expect } from "chai"; import Long from "long"; import util from "util"; const EXTERNAL_PATH = "/context"; let campaigns: string[]; let featureConfigService: FeatureConfigService; let mockedFeatureConf: MockedFeatureConfig; describe("External - integration", () => { let testContext: IntegrationTestContext; before(async () => { testContext = new IntegrationTestContext( EXTERNAL_PATH, "test/integration/data/campaigns", "test/integration/data/s3", { "3": 10.1 }, // domain courbis.fr -> hash: 0x104AF593AB1AAA3C ["104AF593AB1AAA3C"], "0", "0" ); await testContext.init(); featureConfigService = FeatureConfigService.getInstance(); mockedFeatureConf = new MockedFeatureConfig(); campaigns = ["1", "3", "5", "7", "9"]; }); afterEach(() => { mockedFeatureConf.clearParams(); testContext.afterEachRestore(); }); after(() => { testContext.afterRestore(); }); describe("Request validation", () => { beforeEach(() => { mockedFeatureConf.setParam("ms-choices.validation-mode-external", "enabled"); featureConfigService.setFeatureConfig(mockedFeatureConf); }); after(() => { mockedFeatureConf.clearParams(); }); it("not valid: no campaign provided", async () => { const body: bid.IBidAgentRequest = new FakeBeeswaxRequestBuilder().withCampaigns().build(); const res: bid.IBidAgentResponse = await testContext.sendHttpProtobuf(body, 200); res.bids?.forEach((bid) => expect(bid.bid_price_micros?.toString()).to.eql("0")); }); it("not valid: no imp provided", async () => { const body: bid.IBidAgentRequest = new FakeBeeswaxRequestBuilder() .withCampaigns(...campaigns) .withImp() .build(); const res = await testContext.sendHttpProtobuf(body, 200); res.bids?.forEach((bid) => expect(bid.bid_price_micros?.toString()).to.eql("0")); }); }); // in all following tests, prog campaign should automatically be excluded because programmatic is not supported for external inventory it("all campaign are stopped because request if fraud", async () => { const body: bid.IBidAgentRequest = new FakeBeeswaxRequestBuilder() .withCampaigns(...campaigns) .build(); const res: bid.IBidAgentResponse = await testContext.sendHttpProtobuf(body); await helper.waitImmediate(); if (res.bids?.length) { expect(res.bids?.length).to.eql(campaigns.length); checkBid(res?.bids[0], 1, 1, 0); checkBid(res?.bids[1], 3, 3, 0); checkBid(res?.bids[2], 5, 5, 0); checkBid(res?.bids[3], 7, 7, 0); checkBid(res?.bids[4], 9, 9, 0); } else { assert.fail(`No bid in response`); } expectKafkaTopicMessagesCount(testContext.getKafkaSpy(), "choices", 1); expectedDeliveryMonitoringSteps(testContext.getKafkaSpy(), { dv_fraud: [], }); }); it("all campaign are stopped they are programmatic (programmatic is not supported by external)", async () => { const body: bid.IBidAgentRequest = new FakeBeeswaxRequestBuilder() .withCampaigns("2", "4", "6", "8", "10") .build(); const res: bid.IBidAgentResponse = await testContext.sendHttpProtobuf(body); await helper.waitImmediate(); if (res.bids?.length) { expect(res.bids?.length).to.eql(campaigns.length); checkBid(res?.bids[0], 2, 2, 0); checkBid(res?.bids[1], 4, 4, 0); checkBid(res?.bids[2], 6, 6, 0); checkBid(res?.bids[3], 8, 8, 0); checkBid(res?.bids[4], 10, 10, 0); } else { assert.fail(`No bid in response`); } expectKafkaTopicMessagesCount(testContext.getKafkaSpy(), "choices", 1); expectedDeliveryMonitoringSteps(testContext.getKafkaSpy(), { allowed_campaign_groups: [], }); }); it("bid on campaign", async () => { const body: bid.IBidAgentRequest = new FakeBeeswaxRequestBuilder() .withIp("1.2.3.4") .withBidfloor(5) .withCampaigns(...campaigns) .build(); const res: any = await testContext.sendHttpProtobuf(body); await helper.waitImmediate(); if (res.bids?.length) { expect(res.bids?.length).to.eql(campaigns.length); checkBid(res?.bids[0], 1, 1, 0); checkBid(res?.bids[1], 3, 3, 0); checkBid(res?.bids[2], 5, 5, 0); checkBid(res?.bids[3], 7, 7, 28000); checkBid(res?.bids[4], 9, 9, 0); } else { assert.fail(`No bid in response`); } expectKafkaTopicMessagesCount(testContext.getKafkaSpy(), "choices", 1); expectedDeliveryMonitoringSteps(testContext.getKafkaSpy(), { dv_fraud: [1, 3, 5, 7, 9], device_fraud: [1, 3, 5, 7, 9], publisher_fraud: [1, 3, 5, 7, 9], brand_safety_dv: [1, 3, 5, 7, 9], brand_safety_ias: [1, 3, 5, 7, 9], brand_suitability_ias: [1, 3, 5, 7, 9], external_blacklist: [1, 3, 7, 9], bidfloor: [3, 7, 9], speed_threshold: [7, 9], campaign_size: [7], }); }); }); function checkBid( bid: bid.BidAgentResponse.IBid, expectedLineItemId: number, expectedCreativeId: number, expectedBidPriceMicros: number ): void { // @ts-ignore expect(bid.line_item_id).to.eql(Long.fromNumber(expectedLineItemId, true)); // @ts-ignore expect(bid.creative.id).to.eql(Long.fromNumber(expectedCreativeId, true)); // @ts-ignore expect(bid.bid_price_micros.toNumber()).to.eql(expectedBidPriceMicros); }