Skip to content

Commit

Permalink
Merge branch 'develop' into chore.addmetricsForReqSize
Browse files Browse the repository at this point in the history
  • Loading branch information
Jayachand authored Mar 15, 2024
2 parents 7beb4ce + f51e6b9 commit 21c8b48
Show file tree
Hide file tree
Showing 31 changed files with 5,854 additions and 7,232 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"rudder-transformer-cdk": "^1.4.11",
"set-value": "^4.1.0",
"sha256": "^0.2.0",
"sqlstring": "^2.3.3",
"stacktrace-parser": "^0.1.10",
"statsd-client": "^0.4.7",
"truncate-utf8-bytes": "^1.0.2",
Expand Down
28 changes: 28 additions & 0 deletions src/v0/destinations/facebook_pixel/transform.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ const getTestMessage = () => {
return message;
};

const getTestMessageWithoutProductIdAndCategory = () => {
let message = {
properties: {
currency: 'CAD',
quantity: 1,
price: 24.75,
value: 30,
name: 'my product 1',
testDimension: true,
testMetric: true,
position: 4.5,
query: 'HDMI Cable',
},
};
return message;
};

const getTestCategoryToContent = () => {
let categoryToContent = [
{
Expand Down Expand Up @@ -52,6 +69,17 @@ describe('Unit test cases for facebook_pixel handle search', () => {
expect(handleSearch(getTestMessage())).toEqual(expectedOutput);
});

it('should return content with content_ids and content fields as empty array', async () => {
const expectedOutput = {
content_ids: [],
content_category: '',
value: 30,
search_string: 'HDMI Cable',
contents: [],
};
expect(handleSearch(getTestMessageWithoutProductIdAndCategory())).toEqual(expectedOutput);
});

it("mapping 'product_id' with contentId", async () => {
let message = getTestMessage();
message.properties.product_id = 'prd-123';
Expand Down
154 changes: 154 additions & 0 deletions src/v0/destinations/facebook_pixel/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
const { InstrumentationError } = require('@rudderstack/integrations-lib');
const { getActionSource, formatRevenue, getCategoryFromEvent } = require('./utils');
const { CONFIG_CATEGORIES, OTHER_STANDARD_EVENTS } = require('./config');

describe('Test Facebook Pixel Utils', () => {
describe('getActionSource', () => {
// Returns 'other' if payload.action_source is not defined and channel is neither 'web' nor 'mobile'
it('should return "other" when payload.action_source is not defined and channel is neither "web" nor "mobile"', () => {
const payload = {};
const channel = 'email';
const result = getActionSource(payload, channel);
expect(result).toBe('other');
});

// Returns payload.action_source if it is defined and is a valid value from ACTION_SOURCES_VALUES
it('should return payload.action_source when it is defined and is a valid value from ACTION_SOURCES_VALUES', () => {
const payload = { action_source: 'website' };
const channel = 'email';
const result = getActionSource(payload, channel);
expect(result).toBe('website');
});

// Returns 'website' if channel is 'web' and payload.action_source is not defined
it('should return "website" when channel is "web" and payload.action_source is not defined', () => {
const payload = {};
const channel = 'web';
const result = getActionSource(payload, channel);
expect(result).toBe('website');
});

// Throws an InstrumentationError if payload.action_source is defined but not a valid value from ACTION_SOURCES_VALUES
it('should throw an InstrumentationError when payload.action_source is defined but not a valid value from ACTION_SOURCES_VALUES', () => {
const payload = { action_source: 'invalid' };
const channel = 'email';
expect(() => {
getActionSource(payload, channel);
}).toThrow(InstrumentationError);
});
});

describe('formatRevenue', () => {
// Returns a number with two decimal places when passed a valid revenue value.
it('should return a number with two decimal places when passed a valid revenue value', () => {
const revenue = '100.50';
const formattedRevenue = formatRevenue(revenue);
expect(formattedRevenue).toBe(100.5);
});

// Returns 0 when passed a null revenue value.
it('should return 0 when passed a null revenue value', () => {
const revenue = null;
const formattedRevenue = formatRevenue(revenue);
expect(formattedRevenue).toBe(0);
});

// Returns 0 when passed an undefined revenue value.
it('should return 0 when passed an undefined revenue value', () => {
const revenue = undefined;
const formattedRevenue = formatRevenue(revenue);
expect(formattedRevenue).toBe(0);
});

// Throws an InstrumentationError when passed a non-numeric string revenue value.
it('should throw an InstrumentationError when passed a non-numeric string revenue value', () => {
const revenue = 'abc';
expect(() => {
formatRevenue(revenue);
}).toThrow(InstrumentationError);
});

// Returns a number with two decimal places when passed a numeric string revenue value with more than two decimal places.
it('should return a number with two decimal places when passed a numeric string revenue value with more than two decimal places', () => {
const revenue = '100.555';
const formattedRevenue = formatRevenue(revenue);
expect(formattedRevenue).toBe(100.56);
});

// Returns a number with two decimal places when passed a numeric value with more than two decimal places.
it('should return a number with two decimal places when passed a numeric value with more than two decimal places', () => {
const revenue = 100.555;
const formattedRevenue = formatRevenue(revenue);
expect(formattedRevenue).toBe(100.56);
});
});

describe('getCategoryFromEvent', () => {
// The function correctly maps the eventName to its corresponding category.
it('should correctly map the eventName to its corresponding category', () => {
const eventName = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type;
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED);
});

// The function returns the correct category for a given eventName.
it('should return the correct category for a given eventName', () => {
const eventName = CONFIG_CATEGORIES.PRODUCT_VIEWED.type;
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.PRODUCT_VIEWED);
});

// The function returns the default category if the eventName is not recognized.
it('should return the default category if the eventName is not recognized', () => {
const eventName = 'unknownEvent';
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK);
});

// The function handles null or undefined eventName inputs.
it('should handle null or undefined eventName inputs', () => {
const eventName = null;
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK);
});

// The function handles empty string eventName inputs.
it('should handle empty string eventName inputs', () => {
const eventName = '';
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK);
});

// The function handles eventName inputs that are not strings.
it('should handle eventName inputs that are not strings', () => {
const eventName = 123;
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK);
});

// The function handles multiple eventNames that map to the same category.
it('should correctly map multiple eventNames to the same category', () => {
const eventName1 = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.type;
const eventName2 = CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED.eventName;
const result1 = getCategoryFromEvent(eventName1);
const result2 = getCategoryFromEvent(eventName2);
expect(result1).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED);
expect(result2).toEqual(CONFIG_CATEGORIES.PRODUCT_LIST_VIEWED);
});

// The function handles eventNames that are included in the OTHER_STANDARD_EVENTS list.
it('should correctly handle eventNames included in the OTHER_STANDARD_EVENTS list', () => {
const eventName = OTHER_STANDARD_EVENTS[0];
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.OTHER_STANDARD);
expect(result.eventName).toEqual(eventName);
});

// The function handles eventNames that are not recognized and not in the OTHER_STANDARD_EVENTS list.
it('should correctly handle unrecognized eventNames', () => {
const eventName = 'unrecognizedEvent';
const result = getCategoryFromEvent(eventName);
expect(result).toEqual(CONFIG_CATEGORIES.SIMPLE_TRACK);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { get, set } = require('lodash');
const sha256 = require('sha256');
const { NetworkError, NetworkInstrumentationError } = require('@rudderstack/integrations-lib');
const SqlString = require('sqlstring');
const { prepareProxyRequest, handleHttpRequest } = require('../../../adapters/network');
const { isHttpStatusSuccess, getAuthErrCategoryFromStCode } = require('../../util/index');
const { CONVERSION_ACTION_ID_CACHE_TTL } = require('./config');
Expand Down Expand Up @@ -29,8 +30,12 @@ const ERROR_MSG_PATH = 'response[0].error.message';
const getConversionActionId = async (method, headers, params) => {
const conversionActionIdKey = sha256(params.event + params.customerId).toString();
return conversionActionIdCache.get(conversionActionIdKey, async () => {
const queryString = SqlString.format(
'SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = ?',
[params.event],
);
const data = {
query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = '${params.event}'`,
query: queryString,
};
const requestBody = {
url: `${BASE_ENDPOINT}/${params.customerId}/googleAds:searchStream`,
Expand Down Expand Up @@ -117,7 +122,7 @@ const responseHandler = (responseParams) => {
// Ref - https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
if (partialFailureError && partialFailureError.code !== 0) {
throw new NetworkError(
`[Google Ads Offline Conversions]:: partialFailureError - ${JSON.stringify(
`[Google Adwords Enhanced Conversions]:: partialFailureError - ${JSON.stringify(
partialFailureError,
)}`,
400,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const sha256 = require('sha256');
const SqlString = require('sqlstring');
const { get, set, cloneDeep } = require('lodash');
const {
AbortedError,
Expand Down Expand Up @@ -53,8 +54,12 @@ const validateDestinationConfig = ({ Config }) => {
const getConversionActionId = async (headers, params) => {
const conversionActionIdKey = sha256(params.event + params.customerId).toString();
return conversionActionIdCache.get(conversionActionIdKey, async () => {
const queryString = SqlString.format(
'SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = ?',
[params.event],
);
const data = {
query: `SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = '${params.event}'`,
query: queryString,
};
const endpoint = SEARCH_STREAM.replace(':customerId', params.customerId);
const requestOptions = {
Expand Down
13 changes: 13 additions & 0 deletions src/v0/destinations/pardot/networkHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ const getStatus = (code) => {
const pardotRespHandler = (destResponse, stageMsg) => {
const { status, response } = destResponse;
const respAttributes = response['@attributes'];

// to handle errors like service unavilable, wrong url, no response
if (!respAttributes) {
throw new NetworkError(
`${JSON.stringify(response)} ${stageMsg}`,
status,
{
[tags.TAG_NAMES.ERROR_TYPE]: getDynamicErrorType(status),
},
response,
);
}

const { stat, err_code: errorCode } = respAttributes;

if (isHttpStatusSuccess(status) && stat !== 'fail') {
Expand Down
1 change: 1 addition & 0 deletions src/v0/util/facebookUtils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,5 @@ module.exports = {
transformedPayloadData,
formingFinalResponse,
fetchUserData,
deduceFbcParam,
};
Loading

0 comments on commit 21c8b48

Please sign in to comment.