Skip to content

Commit

Permalink
fix: addressed review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
shrouti1507 committed Feb 16, 2024
1 parent 0996df4 commit 6b86e73
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/cdk/v2/destinations/bluecore/procWorkflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ steps:
const newPayload = $.cloneDeep(payload);
newPayload.properties.distinct_id = $.populateAccurateDistinctId(newPayload, ^.message);
const temporaryProductArray = newPayload.properties.products ?? $.createProductForStandardEcommEvent(^.message, eventName);
newPayload.properties.products = $.addProductArray(temporaryProductArray);
newPayload.properties.products = $.normalizeProductArray(temporaryProductArray);
newPayload.event = eventName;
newPayload.token = ^.destination.Config.bluecoreNamespace;
$.verifyPayload(newPayload, ^.message);
Expand Down
32 changes: 26 additions & 6 deletions src/cdk/v2/destinations/bluecore/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,31 @@ const verifyPayload = (payload, message) => {
}
switch (payload.event) {
case 'search':
if (!payload.properties.search_term) {
if (!payload?.properties?.search_term) {
throw new InstrumentationError(
'[Bluecore] property:: search_query is required for search event',
);
}
break;
case 'purchase':
if (!payload.properties.order_id) {
if (!payload?.properties?.order_id) {
throw new InstrumentationError(
'[Bluecore] property:: order_id is required for purchase event',
);
}
if (!payload.properties.total) {
if (!payload?.properties?.total) {
throw new InstrumentationError(
'[Bluecore] property:: total is required for purchase event',
);
}
if (
!isDefinedAndNotNull(payload?.properties?.customer) ||
Object.keys(payload.properties.customer).length === 0

Check warning on line 59 in src/cdk/v2/destinations/bluecore/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/bluecore/utils.js#L59

Added line #L59 was not covered by tests
) {
throw new InstrumentationError(
`[Bluecore] property:: No relevant trait to populate customer information, which is required for ${payload.event} event`,
);
}
break;

Check warning on line 65 in src/cdk/v2/destinations/bluecore/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/bluecore/utils.js#L65

Added line #L65 was not covered by tests
case 'identify':
case 'optin':
Expand All @@ -63,6 +71,14 @@ const verifyPayload = (payload, message) => {
`[Bluecore] property:: email is required for ${payload.event} action`,
);
}
if (
!isDefinedAndNotNull(payload?.properties?.customer) ||
Object.keys(payload.properties.customer).length === 0
) {
throw new InstrumentationError(

Check warning on line 78 in src/cdk/v2/destinations/bluecore/utils.js

View check run for this annotation

Codecov / codecov/patch

src/cdk/v2/destinations/bluecore/utils.js#L78

Added line #L78 was not covered by tests
`[Bluecore] property:: No relevant trait to populate customer information, which is required for ${payload.event} action`,
);
}
break;
default:
break;
Expand Down Expand Up @@ -133,7 +149,7 @@ const isStandardBluecoreEvent = (eventName) => {
* @throws {InstrumentationError} - If the products array is not defined or null.
* @returns {array} - The updated product array.
*/
const addProductArray = (products) => {
const normalizeProductArray = (products) => {
let finalProductArray = null;
if (isDefinedAndNotNull(products)) {
const productArray = Array.isArray(products) ? products : [products];
Expand All @@ -145,6 +161,7 @@ const addProductArray = (products) => {
);
finalProductArray = mappedProductArray;
}
// if any custom event is not sent with product array, then it should be null
return finalProductArray;
};

Expand All @@ -171,7 +188,10 @@ const constructProperties = (message) => {
* @returns {Array|null} - An array containing the properties if the event is a standard Bluecore event and not 'search', otherwise null.
*/
const createProductForStandardEcommEvent = (message, eventName) => {
const { properties } = message;
const { event, properties } = message;
if (event.toLowerCase() === 'order completed' && eventName === 'purchase') {
throw new InstrumentationError('[Bluecore]:: products array is required for purchase event');
}
if (isStandardBluecoreEvent(eventName) && eventName !== 'search') {
return [properties];
}
Expand Down Expand Up @@ -220,7 +240,7 @@ const populateAccurateDistinctId = (payload, message) => {
module.exports = {
verifyPayload,
deduceTrackEventName,
addProductArray,
normalizeProductArray,
isStandardBluecoreEvent,
constructProperties,
createProductForStandardEcommEvent,
Expand Down
88 changes: 80 additions & 8 deletions src/cdk/v2/destinations/bluecore/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
const {
addProductArray,
normalizeProductArray,
verifyPayload,
isStandardBluecoreEvent,
deduceTrackEventName,
populateAccurateDistinctId,
createProductForStandardEcommEvent,
} = require('./utils');
const { InstrumentationError } = require('@rudderstack/integrations-lib');

describe('addProductArray', () => {
describe('normalizeProductArray', () => {
// Adds an array of products to a message when products array is defined and not null.
it('should add an array of products to a message when products array is defined and not null', () => {
const products = [
Expand All @@ -16,7 +17,7 @@ describe('addProductArray', () => {
];
const eventName = 'purchase';

const result = addProductArray(products, eventName);
const result = normalizeProductArray(products, eventName);

expect(result).toEqual([
{ id: 1, name: 'Product 1' },
Expand All @@ -29,7 +30,7 @@ describe('addProductArray', () => {
const product = { product_id: 1, name: 'Product 1' };
const eventName = 'add_to_cart';

const result = addProductArray(product, eventName);
const result = normalizeProductArray(product, eventName);
expect(result).toEqual([{ id: 1, name: 'Product 1' }]);
});

Expand All @@ -39,7 +40,7 @@ describe('addProductArray', () => {
const eventName = 'custom';

expect(() => {
addProductArray(message, products, eventName);
normalizeProductArray(message, products, eventName);
}).toBeNull;
});
});
Expand All @@ -57,22 +58,26 @@ describe('verifyPayload', () => {
});

// Verify payload for purchase event with order_id and total properties.
it('should verify payload for purchase event with order_id and total properties', () => {
it('should verify payload for purchase event with order_id and total and customer properties', () => {
const payload = {
event: 'purchase',
properties: {
order_id: '123',
total: 100,
},
};
expect(() => verifyPayload(payload, {})).not.toThrow();
expect(() => verifyPayload(payload, {})).toThrow(InstrumentationError);
});

// Verify payload for identify event with email property.
it('should verify payload for identify event with email property', () => {
const payload = {
event: 'identify',
properties: {},
properties: {
customer: {
first_name: 'John',
},
},
};
const message = {
traits: {
Expand Down Expand Up @@ -329,3 +334,70 @@ describe('populateAccurateDistinctId', () => {
expect(distinctId).toBe('54321');
});
});

describe('createProductForStandardEcommEvent', () => {
// Returns an array containing the properties if the event is a standard Bluecore event and not 'search'.
it("should return an array containing the properties when the event is a standard Bluecore event and not 'search'", () => {
const message = {
event: 'some event',
properties: { name: 'product 1' },
};
const eventName = 'some event';
const result = createProductForStandardEcommEvent(message, eventName);
expect(result).toEqual(null);
});

// Returns null if the event is 'search'.
it("should return null when the event is 'search'", () => {
const message = {
event: 'search',
properties: { name: 'product 1' },
};
const eventName = 'search';
const result = createProductForStandardEcommEvent(message, eventName);
expect(result).toBeNull();
});

// Throws an InstrumentationError if the event is 'order completed' and the eventName is 'purchase'.
it("should throw an InstrumentationError when the event is 'order completed' and the eventName is 'purchase'", () => {
const message = {
event: 'order completed',
properties: { name: 'product 1' },
};
const eventName = 'purchase';
expect(() => {
createProductForStandardEcommEvent(message, eventName);
}).toThrow(InstrumentationError);
});

// Returns null if the eventName is not a standard Bluecore event.
it('should return null when the eventName is not a standard Bluecore event', () => {
const message = {
event: 'some event',
properties: { name: 'product 1', products: [{ product_id: 1, name: 'prod1' }] },
};
const eventName = 'non-standard';
const result = createProductForStandardEcommEvent(message, eventName);
expect(result).toBeNull();
});

// Returns null if the eventName is not provided.
it('should return null when the eventName is not provided', () => {
const message = {
event: 'some event',
properties: { name: 'product 1' },
};
const result = createProductForStandardEcommEvent(message);
expect(result).toBeNull();
});

// Returns null if the properties are not provided.
it('should return null when the properties are not provided', () => {
const message = {
event: 'some event',
};
const eventName = 'some event';
const result = createProductForStandardEcommEvent(message, eventName);
expect(result).toBeNull();
});
});
57 changes: 57 additions & 0 deletions test/integrations/destinations/bluecore/ecommTestData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,4 +429,61 @@ export const ecomTestData = [
},
},
},
{
id: 'bluecore-track-test-6',
name: 'bluecore',
description:
'Track event call with Order Completed event without product array and not mapped in destination config. This will be sent with purchase name. This event without properties.products will generate error as products array is required for purchase event and ordered completed is a standard ecomm event',
scenario: 'Business',
feature: 'processor',
module: 'destination',
version: 'v0',
input: {
request: {
body: [
{
destination: destination,
metadata,
message: generateSimplifiedTrackPayload({
type: 'track',
event: 'Order Completed',
userId: 'sajal12',
context: {
traits: {
...commonTraits,
email: '[email protected]',
phone: '9112340375',
},
},
properties: commonPropsWithoutProducts,
anonymousId: '9c6bd77ea9da3e68',
originalTimestamp: '2021-01-25T15:32:56.409Z',
}),
},
],
},
},
output: {
response: {
status: 200,
body: [
{
error:
'[Bluecore]:: products array is required for purchase event: Workflow: procWorkflow, Step: prepareTrackPayload, ChildStep: undefined, OriginalError: [Bluecore]:: products array is required for purchase event',
metadata,
statTags: {
destType: 'BLUECORE',
destinationId: '',
errorCategory: 'dataValidation',
errorType: 'instrumentation',
feature: 'processor',
implementation: 'cdkV2',
module: 'destination',
},
statusCode: 400,
},
],
},
},
},
];

0 comments on commit 6b86e73

Please sign in to comment.