Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MobianRtdModule: Add more signals from API endpoint to first-party data #11999

41 changes: 38 additions & 3 deletions modules/mobianRtdProvider.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
/**
* This module adds the Mobian RTD provider to the real time data module
* The {@link module:modules/realTimeData} module is required
* @module modules/anonymisedRtdProvider
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you from idward / anonymised? do you mean to import their type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no -- that's embarrassing. I've had trouble getting the build to include the real time data module without including it explicitly, and hoped that typing would help. Will remove...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add yourself to .submodules.js

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"medianetRtdProvider",

* @requires module:modules/realTimeData
*/
import { submodule } from '../src/hook.js';
import { ajaxBuilder } from '../src/ajax.js';
import { deepSetValue } from '../src/utils.js';

/**
* @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule
*/

export const MOBIAN_URL = 'https://impact-api-prod.themobian.com/brand_safety';

/** @type {RtdSubmodule} */
export const mobianBrandSafetySubmodule = {
name: 'mobianBrandSafety',
gvlid: null,
init: init,
getBidRequestData: getBidRequestData
};

function init() {
return true;
}

function getBidRequestData(bidReqConfig, callback, config) {
const { site: ortb2Site } = bidReqConfig.ortb2Fragments.global;
const pageUrl = encodeURIComponent(getPageUrl());
Expand All @@ -32,14 +45,36 @@ function getBidRequestData(bidReqConfig, callback, config) {
break;
}
}

// Get GARM content categories
const garmCategories = Object.keys(response)
.filter(key => key.startsWith('garm_content_category_') && response[key])
.map(key => key.replace('garm_content_category_', ''));

// Get sentiment
const sentiment = Object.keys(response)
.find(key => key.startsWith('sentiment_') && response[key])
?.replace('sentiment_', '') || 'unknown';

// Get emotions
const emotions = Object.keys(response)
.filter(key => key.startsWith('emotion_') && response[key])
.map(key => key.replace('emotion_', ''));

const risk = {
'mobianGarmRisk': mobianGarmRisk
'mobianGarmRisk': mobianGarmRisk,
'garmContentCategories': garmCategories,
'sentiment': sentiment,
'emotions': emotions
};

resolve(risk);
ortb2Site.ext.data['mobian'] = risk
deepSetValue(ortb2Site.ext, 'data.mobian', risk);
callback()
},
error: function () {
resolve({});
callback()
}
});
});
Expand Down
92 changes: 88 additions & 4 deletions test/spec/modules/mobianRtdProvider_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ describe('Mobian RTD Submodule', function () {
ortb2Fragments: {
global: {
site: {
ext: {
data: {}
}
ext: {}
}
}
}
Expand Down Expand Up @@ -42,7 +40,7 @@ describe('Mobian RTD Submodule', function () {
});
});

it('should return low_risk when server responds with garm_no_risk', function () {
it('should return low_risk when server responds with garm_low_risk', function () {
ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) {
callbacks.success({
garm_no_risk: false,
Expand Down Expand Up @@ -104,4 +102,90 @@ describe('Mobian RTD Submodule', function () {
expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk);
});
});

// New tests for GARM content categories, sentiment, and emotions
it('should return correct GARM content categories', function () {
ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) {
callbacks.success({
garm_content_category_adult: false,
garm_content_category_arms: true,
garm_content_category_crime: true,
garm_content_category_death_injury: false,
});
});

return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => {
expect(risk).to.have.property('garmContentCategories');
expect(risk['garmContentCategories']).to.deep.equal(['arms', 'crime']);
expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk);
});
});

it('should return correct sentiment', function () {
ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) {
callbacks.success({
sentiment_positive: false,
sentiment_negative: true,
sentiment_neutral: false,
});
});

return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => {
expect(risk).to.have.property('sentiment');
expect(risk['sentiment']).to.equal('negative');
expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk);
});
});

it('should return correct emotions', function () {
ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) {
callbacks.success({
emotion_love: false,
emotion_joy: true,
emotion_anger: false,
emotion_surprise: true,
emotion_sadness: false,
emotion_fear: true,
});
});

return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => {
expect(risk).to.have.property('emotions');
expect(risk['emotions']).to.deep.equal(['joy', 'surprise', 'fear']);
expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk);
});
});

it('should handle all new properties correctly', function () {
ajaxStub = sinon.stub(ajax, 'ajaxBuilder').returns(function(url, callbacks) {
callbacks.success({
garm_no_risk: false,
garm_low_risk: true,
garm_medium_risk: false,
garm_high_risk: false,
garm_content_category_adult: false,
garm_content_category_arms: true,
garm_content_category_crime: false,
sentiment_positive: false,
sentiment_negative: false,
sentiment_neutral: true,
emotion_love: false,
emotion_joy: true,
emotion_anger: false,
emotion_surprise: false,
});
});

return mobianBrandSafetySubmodule.getBidRequestData(bidReqConfig, {}, {}).then((risk) => {
expect(risk).to.have.property('mobianGarmRisk');
expect(risk['mobianGarmRisk']).to.equal('low_risk');
expect(risk).to.have.property('garmContentCategories');
expect(risk['garmContentCategories']).to.deep.equal(['arms']);
expect(risk).to.have.property('sentiment');
expect(risk['sentiment']).to.equal('neutral');
expect(risk).to.have.property('emotions');
expect(risk['emotions']).to.deep.equal(['joy']);
expect(bidReqConfig.ortb2Fragments.global.site.ext.data.mobian).to.deep.equal(risk);
});
});
});