@mediarithmics/plugins-nodejs-sdk
Version:
This is the mediarithmics nodejs to help plugin developers bootstrapping their plugin without having to deal with most of the plugin boilerplate
178 lines (159 loc) • 6.2 kB
text/typescript
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unused-vars */
import 'mocha';
import { expect } from 'chai';
import sinon from 'sinon';
import { core, extra } from '../';
import { PropertiesWrapper } from '../mediarithmics/index';
const PLUGIN_AUTHENTICATION_TOKEN = 'Manny';
const PLUGIN_WORKER_ID = 'Calavera';
// set by the plugin runner in production
process.env.PLUGIN_AUTHENTICATION_TOKEN = PLUGIN_AUTHENTICATION_TOKEN;
process.env.PLUGIN_WORKER_ID = PLUGIN_WORKER_ID;
describe('Fetch recommendation API', () => {
class MyDummyHandlebarsAdRenderer extends core.AdRendererRecoTemplatePlugin {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
engineBuilder = new extra.HandlebarsEngine();
constructor(enableThrottling = false) {
super(false);
}
protected async onAdContents(
adRenderRequest: core.AdRendererRequest,
instanceContext: core.AdRendererRecoTemplateInstanceContext,
): Promise<core.AdRendererPluginResponse> {
return Promise.resolve({
html: `This is Spart.... Oups, HTML I mean`,
});
}
}
const fakeRecommenderResponse: core.DataResponse<core.RecommendationsWrapper> = {
status: 'ok',
data: {
ts: 1496939189652,
proposals: [
{
$type: 'ITEM_PROPOSAL',
$item_id: '8',
$id: '8',
$catalog_id: '16',
$name: 'Résidence Les Terrasses de Veret***',
$brand: 'Madame Vacance',
$url: 'https://www.madamevacances.com/locations/france/alpes-du-nord/flaine/residence-les-terrasses-de-veret/',
$image_url:
'http://hbs.madamevacances.com/photos/etab/87/235x130/residence_les_terrasses_de_veret_piscine.jpg',
$price: 160.3,
$sale_price: undefined,
city: 'Flaine',
country: 'France',
region: 'Alpes du Nord',
zip_code: '74300',
},
{
$type: 'ITEM_PROPOSAL',
$item_id: '7',
$id: '7',
$catalog_id: '16',
$name: 'Le Chalet Altitude*****',
$brand: 'Madame Vacance',
$url: 'https://www.madamevacances.com/locations/france/alpes-du-nord/val-thorens/le-chalet-altitude/',
$image_url: 'http://hbs.madamevacances.com/photos/etab/335/235x130/chalet_altitude_exterieure_2.jpg',
$price: undefined,
$sale_price: undefined,
city: 'Val Thorens',
country: 'France',
region: 'Alpes du Nord',
zip_code: '73440',
},
{
$type: 'ITEM_PROPOSAL',
$item_id: '6',
$id: '6',
$catalog_id: '16',
$name: 'Les Chalets du Thabor***',
$brand: 'Madame Vacance',
$url: 'https://www.madamevacances.com/locations/france/alpes-du-nord/valfrejus/les-chalets-du-thabor/',
$image_url: 'http://hbs.madamevacances.com/photos/etab/65/235x130/valfrejus_chalet_thabor_exterieure_2.jpg',
$price: 143.2,
$sale_price: undefined,
city: 'Valfréjus',
country: 'France',
region: 'Alpes du Nord',
zip_code: '73500',
},
],
},
};
const fakeCreative: core.DisplayAd = {
type: 'DISPLAY_AD',
id: '7168',
organisation_id: '1126',
name: 'Toto',
technical_name: 'hello',
archived: false,
editor_version_id: '5',
editor_version_value: '1.0.0',
editor_group_id: 'com.mediarithmics.creative.display',
editor_artifact_id: 'default-editor',
editor_plugin_id: '5',
renderer_version_id: '1054',
renderer_version_value: '1.0.0',
renderer_group_id: 'com.trololo.creative.display',
renderer_artifact_id: 'multi-advertisers-display-ad-renderer',
renderer_plugin_id: '1041',
creation_date: 1492785056278,
subtype: 'BANNER',
format: '300x250',
};
const fakeCreativeProperty: core.StringProperty = {
technical_name: 'hello_world',
value: {
value: 'Yay',
},
property_type: 'STRING',
origin: 'PLUGIN',
writable: true,
deletable: false,
};
const fakeInstanceContext: core.AdRendererRecoTemplateInstanceContext = {
recommender_id: '74',
width: '300',
height: '250',
creative_click_url: 'http://yolo.com',
displayAd: fakeCreative,
properties: new PropertiesWrapper([fakeCreativeProperty]),
};
const fakeUserAgentId = 'vec:888888';
const rpMockup: sinon.SinonStub = sinon.stub();
rpMockup
.withArgs(sinon.match.has('uri', sinon.match(/\/v1\/recommenders\/(.){1,10}\/recommendations/)))
.returns(fakeRecommenderResponse);
it('Check that recommenderId and userAgentId are passed correctly in fetchRecommendations', function (done) {
const plugin = new MyDummyHandlebarsAdRenderer(false);
const runner = new core.TestingPluginRunner(plugin, rpMockup);
// We try a call to the Gateway
void (runner.plugin as MyDummyHandlebarsAdRenderer)
.fetchRecommendations(fakeInstanceContext, fakeUserAgentId)
.then(() => {
expect(rpMockup.args[0][0].uri).to.be.eq(
`${plugin.outboundPlatformUrl}/v1/recommenders/${fakeInstanceContext.recommender_id}/recommendations`,
);
expect(rpMockup.args[0][0].body.input_data.user_agent_id).to.be.eq(fakeUserAgentId);
done();
});
});
it('Check that fetched itemProposal are the same as sent by the recommender', function (done) {
const plugin = new MyDummyHandlebarsAdRenderer(false);
const runner = new core.TestingPluginRunner(plugin, rpMockup);
// We try a call to the Gateway
void (runner.plugin as MyDummyHandlebarsAdRenderer)
.fetchRecommendations(fakeInstanceContext, fakeUserAgentId)
.then((proposals: Array<core.ItemProposal>) => {
expect(proposals[0]).to.deep.eq(fakeRecommenderResponse.data.proposals[0]);
expect(proposals[1]).to.deep.eq(fakeRecommenderResponse.data.proposals[1]);
expect(proposals[2]).to.deep.eq(fakeRecommenderResponse.data.proposals[2]);
done();
});
});
});