Skip to content

Commit

Permalink
Updates fraud detection endpoint consumer
Browse files Browse the repository at this point in the history
- uses /js/v1/risk/info endpoint
  • Loading branch information
chrissrogers committed Jan 30, 2020
1 parent 38a9bf7 commit f164761
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 160 deletions.
50 changes: 36 additions & 14 deletions lib/recurly/fraud.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import each from 'component-each';
import find from 'component-find';
import Emitter from 'component-emitter';
import dom from '../util/dom';
Expand Down Expand Up @@ -62,22 +61,45 @@ export class Fraud extends Emitter {
this.dataCollectorInitiated = true;

this.recurly.request.get({
route: '/fraud_data_collector',
route: '/risk/info',
done: (error, response) => {
debug('response from recurly data collector', error, response);
debug('risk info', error, response);

if (error) {
const requestFailedError = errors('fraud-data-collector-request-failed', { error });
this.emit('error', requestFailedError);
} else if (response.content) {
const form = dom.element(this.recurly.config.fraud.kount.form) || this.getHostedFieldParentForm();
const tempContainer = document.createElement('div');
tempContainer.innerHTML = response.content;
each(tempContainer.childNodes, node => {
this.attachedNodes.push(node);
form.appendChild(node);
});
this.emit('ready');
return this.emit('error', errors('fraud-data-collector-request-failed', { error }));
}

const { profiles } = response;

profiles.forEach(profile => {
const { processor, params } = profile;
if (processor === 'kount') {
const configuredForm = this.recurly.config.fraud.kount.form;
const scriptElement = document.createElement('script');
const initializerElement = document.createElement('div');
const sessionIdInputElement = dom.createHiddenInput({
'data-recurly': 'fraud_session_id',
'value': params.session_id
});
const initialize = () => {
// eslint-disable-next-line no-undef
const client = new ka.ClientSDK();
client.autoLoadEvents();
};

scriptElement.setAttribute('src', params.script_url);
scriptElement.onload = initialize;

initializerElement.className = 'kaxsdc';
initializerElement.setAttribute('data-event', 'load');

const form = dom.element(configuredForm) || this.getHostedFieldParentForm();
form.appendChild(sessionIdInputElement);
form.appendChild(scriptElement);
form.appendChild(initializerElement);
this.emit('ready');
}
});
}
});
}
Expand Down
143 changes: 0 additions & 143 deletions test/fraud.test.js
Original file line number Diff line number Diff line change
@@ -1,143 +0,0 @@
import assert from 'assert';
import clone from 'component-clone';
import {Recurly} from '../lib/recurly';
import {fixture} from './support/fixtures';
import {initRecurly} from './support/helpers';

describe('Fraud', () => {
describe('params', () => {
var litleSessionId = '98as6d09df907asd';
var fraudSessionId = 'a0s89d09adfsadsgf34';
var data = { fraud_session_id: fraudSessionId }
var recurly;

function initializeRecurlyWithConfig(config) {
recurly = initRecurly(config);
sinon.stub(recurly, 'request');
recurly.emit('ready');
return recurly;
}

// beforeEach(() => {
// fixture('minimal');
// });

// it('inserts both fraud processor session ids when configured', () => {
// let fraudParams = initializeRecurlyWithConfig({ fraud: {
// kount: { dataCollector: true },
// litle: { sessionId: litleSessionId }
// }}).fraud.params(data);
// assert(fraudParams.length == 2);
// assert(fraudParams[0].processor == 'kount');
// assert(fraudParams[0].session_id == fraudSessionId);
// assert(fraudParams[1].processor == 'litle_threat_metrix');
// assert(fraudParams[1].session_id == litleSessionId);
// });

// it('inserts only kount processor when litle not configured', () => {
// let fraudParams = initializeRecurlyWithConfig({ fraud: {
// kount: { dataCollector: true }
// }}).fraud.params(data);
// assert(fraudParams.length == 1);
// assert(fraudParams[0].processor == 'kount');
// assert(fraudParams[0].session_id == fraudSessionId);
// });

// it('inserts only litle processor when only litle and not kount configured', () => {
// let fraudParams = initializeRecurlyWithConfig({ fraud: {
// litle: { sessionId: litleSessionId }
// }}).fraud.params(data);
// assert(fraudParams.length == 1);
// assert(fraudParams[0].processor == 'litle_threat_metrix');
// assert(fraudParams[0].session_id == litleSessionId);
// });

// it('returns empty array when both processors are not configured or ran', () => {
// let fraudParams = initializeRecurlyWithConfig({ fraud: {} }).fraud.params(data);
// assert(fraudParams.length == 0);
// });
});


describe('dataCollector', () => {
const defaultConfig = {
fraud: {
kount: { dataCollector: true },
litle: { sessionId: '98as6d09df907asd' }
}
};
let testId = 'testDataCollector';
const fixtures = {
successfulResponse: {
err: null, res: { content: `<div id='${testId}'>response from server<div>` }
},
serverError: {
err: 'server error', res: null
}
}
var recurly;
var config;

function initializeRecurlyWith(responseType) {
recurly = initRecurly(config);
sinon.stub(recurly, 'request', (function () {
return function(method, url, callback) {
callback(fixtures[responseType].err, fixtures[responseType].res);
}
})());
recurly.emit('ready');
}

// beforeEach(() => {
// fixture('minimal');
// config = clone(defaultConfig);
// });

// it("doesn't run unless set to true in config", () => {
// config.fraud.kount.dataCollector = false;
// initializeRecurlyWith('serverError');
// assert(!recurly.request.calledOnce);
// });

// it('throws general data collector error when receiving error from server', () => {
// let errorCaught = false;

// try {
// initializeRecurlyWith('serverError');
// } catch (e) {
// errorCaught = true;
// assert(e.name == 'fraud-data-collector-request-failed');
// }

// assert(recurly.request.calledOnce);
// assert(errorCaught === true);
// });

// it('throws error if no form found to inject new fields into', () => {
// fixture();
// let errorCaught = false;

// try {
// initializeRecurlyWith('successfulResponse');
// } catch (e) {
// errorCaught = true;
// assert(e.name == 'fraud-data-collector-missing-form');
// }

// assert(recurly.request.calledOnce);
// assert(errorCaught === true);
// });

// it('injects successfully received content from server', () => {
// let testId = 'testDataCollector';
// let content = `<div id='${testId}'>response from server<div>`;

// assert(window.document.getElementById(testId) === null);

// initializeRecurlyWith('successfulResponse');

// assert(recurly.request.calledOnce);
// assert(window.document.getElementById(testId) != null);
// });
});
});
3 changes: 0 additions & 3 deletions test/server/fixtures/fraud_data_collector.json

This file was deleted.

11 changes: 11 additions & 0 deletions test/server/fixtures/risk/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"profiles": [
{
"processor": "kount",
"params": {
"session_id": "9a87s6dfaso978ljk",
"script_url": "/api/mock-200"
}
}
]
}
2 changes: 2 additions & 0 deletions test/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ app.use(route.get('/gift_cards/:id', json));
app.use(route.get('/items/:id', json));
app.use(route.get('/plans/:plan_id', json));
app.use(route.get('/plans/:plan_id/coupons/:id', json));
app.use(route.get('/risk/info', json));
app.use(route.get('/risk/preflights', json));
app.use(route.get('/tax', json));
app.use(route.get('/token', json));
Expand All @@ -49,6 +50,7 @@ app.use(route.get('/relay', html('relay')));
app.use(route.get('/field.html', html('field')));

app.use(route.get('/mock-404'), ctx => ctx.status = 404);
app.use(route.get('/mock-200'), ok);

app.listen(port, () => {
fs.writeFileSync(`${__dirname}/pid.txt`, process.pid, 'utf-8');
Expand Down

0 comments on commit f164761

Please sign in to comment.