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

feat(data-collector): add data collector utility #166

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {

Check failure on line 1 in jest.config.js

View workflow job for this annotation

GitHub Actions / main

Flow file annotation is missing

Check failure on line 1 in jest.config.js

View workflow job for this annotation

GitHub Actions / main

Expected "export" or "export default"
testEnvironment: "jsdom",
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"license": "Apache-2.0",
"readmeFilename": "README.md",
"dependencies": {
"@krakenjs/beaver-logger": "^5.0.0",
"@krakenjs/beaver-logger": "^5.5.0",
"@krakenjs/belter": "^2.0.0",
"@krakenjs/cross-domain-utils": "^3.0.2",
"@krakenjs/jsx-pragmatic": "^3.0.0",
Expand Down
57 changes: 57 additions & 0 deletions src/data-collector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* @flow */

// import { ENV } from '@paypal/sdk-constants/src';

export const FRAUDNET_FNCLS = "fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99";
export const FRAUDNET_APP_NAME = "SMART_PAYMENT_BUTTONS";

// const FRAUDNET_URL = {
// [ENV.LOCAL]: "https://www.msmaster.qa.paypal.com/en_US/m/fb-raw.js",
// [ENV.STAGE]: "https://stage2mb044.qa.paypal.com/fraudnetjsnodeweb/automate/develop/stage_raw.js",
// [ENV.SANDBOX]: "https://c.paypal.com/da/r/fb.js",
// [ENV.PRODUCTION]: "https://c.paypal.com/da/r/fb.js",
// [ENV.TEST]: "https://c.paypal.com/da/r/fb.js",
// };

export const loadDataCollector = async ({
cspNonce = "",
clientMetadataID,
env,
}) => {

Check failure on line 20 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

Async arrow function has no 'await' expression
// TODO: Ensure these functions return zalgo promises accordingly. reference fraudnet.js in SPB for pattern
createConfigScript({ cspNonce, clientMetadataID });

Check failure on line 22 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

'createConfigScript' was used before it was defined
createFraudnetScript({ cspNonce, env });

Check failure on line 23 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

'createFraudnetScript' was used before it was defined

// TODO: test and implement the window.fallback/timeout logic (see fraudnet.js in SPB)
};

export const createConfigScript = ({ cspNonce = "", clientMetadataID }) => {
const fraudnetConfig = {
f: clientMetadataID,
s: FRAUDNET_APP_NAME,
cb1: "fnCallback",
};

const configScript = document.createElement("script");

configScript.setAttribute("nonce", cspNonce);
configScript.setAttribute("type", "application/json");
configScript.setAttribute("id", "fconfig");
configScript.setAttribute("fncls", FRAUDNET_FNCLS);
configScript.textContent = JSON.stringify(fraudnetConfig);

document.body.appendChild(configScript);

Check failure on line 43 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

document.body() is not supported in Firefox 30
};

export const createFraudnetScript = ({ cspNonce, env }) => {

Check failure on line 46 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

'env' is defined but never used
const fraudnetScript = document.createElement("script");

// const fraudnetUrl = FRAUDNET_URL[env]
fraudnetScript.setAttribute("nonce", cspNonce);
// fraudnetScript.setAttribute('src', fraudnetUrl)
fraudnetScript.addEventListener("error", () => {
/* We'll want to resolve here Zalgo style */
});

document.body.appendChild(fraudnetScript);

Check failure on line 56 in src/data-collector.js

View workflow job for this annotation

GitHub Actions / main

document.body() is not supported in Firefox 30
};
89 changes: 89 additions & 0 deletions test/server/data-collector.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* @jest-environment jsdom
*/
import {

Check failure on line 4 in test/server/data-collector.test.js

View workflow job for this annotation

GitHub Actions / main

Flow file annotation is missing
loadDataCollector,
createConfigScript,
createFraudnetScript,
FRAUDNET_FNCLS,
FRAUDNET_APP_NAME,
} from "../../src/data-collector";

describe.only("data-collector.js", () => {
beforeEach(() => {
jest.clearAllMocks();

Check failure on line 14 in test/server/data-collector.test.js

View workflow job for this annotation

GitHub Actions / main

'jest' is not defined
});

const testInputs = {
clientMetadataID: "some-cmid",
fraudnetAppName: "spb-test-name",
env: "unit-tests",
cspNonce: "not-sure-what-this-is-yet-csp-nonce",
queryStringParams: {
/* TBD */
},
};

test("creates both scripts", async () => {
const mockAppendChild = jest.fn();
document.body.appendChild = mockAppendChild;

await loadDataCollector(testInputs);

expect(mockAppendChild).toHaveBeenCalledTimes(2);
});

test("it create and append the config element", async () => {
const mockSetAttribute = jest.fn();
const mockAppendChild = jest.fn();
const mockReturnedElement = {
setAttribute: mockSetAttribute,
};
document.createElement = jest.fn(() => {
return mockReturnedElement;
});
document.body.appendChild = mockAppendChild;

const expectedScriptConfig = {
f: testInputs.clientMetadataID,
s: FRAUDNET_APP_NAME,
//u: <NOT SURE THIS IS RELEVANT! Does it currently default in spb?>
cb1: "fnCallback",
};
await createConfigScript(testInputs);

expect(document.createElement).toHaveBeenNthCalledWith(1, "script");
expect(mockSetAttribute).toBeCalledWith("nonce", testInputs.cspNonce);
expect(mockSetAttribute).toBeCalledWith("type", "application/json");
expect(mockSetAttribute).toBeCalledWith("id", "fconfig");
expect(mockSetAttribute).toBeCalledWith("fncls", FRAUDNET_FNCLS);
expect(mockReturnedElement.textContent).toEqual(
JSON.stringify(expectedScriptConfig)
);
expect(mockAppendChild).toBeCalledWith(mockReturnedElement);
});

test("creates fraudnet script with config", async () => {
const mockAppendChild = jest.fn();
const mockListener = jest.fn();
const mockSetAttribute = jest.fn();
const mockReturnedElement = {
setAttribute: mockSetAttribute,
addEventListener: mockListener,
};
document.body.appendChild = mockAppendChild;

document.createElement = jest.fn(() => {
return mockReturnedElement;
});

await createFraudnetScript(testInputs);

expect(document.createElement).toHaveBeenCalledWith("script");
expect(mockSetAttribute).toHaveBeenCalledWith("nonce", testInputs.cspNonce);
// TODO: Update the test and implementation to address the need for the SRC attribute and various env urls
// expect(mockSetAttribute).toHaveBeenCalledWith("src", expect.stringContaining("fb.js"))
expect(mockListener).toHaveBeenCalledWith("error", expect.any(Function));
expect(mockAppendChild).toBeCalledWith(mockReturnedElement);
});
});