From e916e3995917c2f3e55291587de1bdae3c42e309 Mon Sep 17 00:00:00 2001 From: Abhi591 Date: Thu, 25 Jul 2024 09:47:56 +0530 Subject: [PATCH] fix: track Params to allow eventProps as third param --- CHANGELOG.md | 7 +++++++ lib/VWOClient.ts | 10 +++++----- lib/api/TrackEvent.ts | 6 +++--- .../evaluators/SegmentEvaluator.ts | 18 +++++++++++++----- .../evaluators/SegmentOperandEvaluator.ts | 4 ++-- test/e2e/TrackEvent.test.ts | 10 +++++----- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 654cc86..dd83e2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.4.0] - 2024-06-21 + +### Fixed + +- fix: add support for DSL where featureIdValue could be `off` +- refactor: make eventProperties as third parameter + ## [1.3.0] - 2024-06-20 ### Fixed diff --git a/lib/VWOClient.ts b/lib/VWOClient.ts index 27040dd..2d53258 100644 --- a/lib/VWOClient.ts +++ b/lib/VWOClient.ts @@ -46,8 +46,8 @@ export interface IVWOClient { getFlag(featureKey: string, context: Record): Record; trackEvent( eventName: string, - eventProperties: Record, context: Record, + eventProperties: Record, ): Promise>; setAttribute(attributeKey: string, attributeValue: string, context: Record): void; } @@ -151,14 +151,14 @@ export class VWOClient implements IVWOClient { * This method validates the types of the inputs and ensures the settings and user context are valid before proceeding. * * @param {string} eventName - The name of the event to track. - * @param {Record} eventProperties - The properties associated with the event. * @param {ContextModel} context - The context in which the event is being tracked, must include a valid user ID. + * @param {Record} eventProperties - The properties associated with the event. * @returns {Promise>} - A promise that resolves to the result of the tracking operation. */ trackEvent( eventName: string, - eventProperties: Record = {}, context: Record, + eventProperties: Record = {}, ): Promise> { const apiName = 'trackEvent'; const deferredObject = new Deferred(); @@ -192,7 +192,7 @@ export class VWOClient implements IVWOClient { LogManager.Instance.error( buildMessage(ErrorLogMessagesEnum.API_INVALID_PARAM, { apiName, - key: 'featureKey', + key: 'eventProperties', type: getType(eventProperties), correctType: 'object', }), @@ -217,7 +217,7 @@ export class VWOClient implements IVWOClient { // Proceed with tracking the event new TrackApi() - .track(this.settings, eventName, eventProperties, contextModel, hookManager) + .track(this.settings, eventName, contextModel, eventProperties, hookManager) .then((data) => { deferredObject.resolve(data); }) diff --git a/lib/api/TrackEvent.ts b/lib/api/TrackEvent.ts index a15152a..5c38a6a 100644 --- a/lib/api/TrackEvent.ts +++ b/lib/api/TrackEvent.ts @@ -28,16 +28,16 @@ interface ITrack { * Tracks an event with given properties and context. * @param settings Configuration settings for the tracking. * @param eventName Name of the event to track. - * @param eventProperties Properties associated with the event. * @param context Contextual information like user details. + * @param eventProperties Properties associated with the event. * @param hookManager Manager for handling hooks and callbacks. * @returns A promise that resolves to a record indicating the success or failure of the event tracking. */ track( settings: SettingsModel, eventName: string, - eventProperties: any, context: ContextModel, + eventProperties: any, hookManager: HooksManager, ): Promise>; } @@ -50,8 +50,8 @@ export class TrackApi implements ITrack { async track( settings: SettingsModel, eventName: string, - eventProperties: any, context: ContextModel, + eventProperties: any, hookManager: HooksManager, ): Promise> { if (doesEventBelongToAnyFeature(eventName, settings)) { diff --git a/lib/packages/segmentation-evaluator/evaluators/SegmentEvaluator.ts b/lib/packages/segmentation-evaluator/evaluators/SegmentEvaluator.ts index cc90702..893b385 100644 --- a/lib/packages/segmentation-evaluator/evaluators/SegmentEvaluator.ts +++ b/lib/packages/segmentation-evaluator/evaluators/SegmentEvaluator.ts @@ -106,16 +106,20 @@ export class SegmentEvaluator implements Segmentation { const featureIdKey: string = Object.keys(featureIdObject)[0]; const featureIdValue: string = featureIdObject[featureIdKey]; - if (featureIdValue === 'on') { + if (featureIdValue === 'on' || featureIdValue === 'off') { const features = this.settings.getFeatures(); const feature = features.find((feature) => feature.getId() === parseInt(featureIdKey)); if (feature) { const featureKey = feature.getKey(); const result = await this.checkInUserStorage(this.settings, featureKey, this.context); + // if the result is false, then we need to return true as feature is not present in the user storage + if (featureIdValue === 'off') { + return !result; + } return result; } else { - console.error('Feature not found with featureIdKey:', featureIdKey); + LogManager.Instance.error('Feature not found with featureIdKey: ' + featureIdKey); return null; // Handle the case when feature is not found } } @@ -197,7 +201,7 @@ export class SegmentEvaluator implements Segmentation { async checkLocationPreSegmentation(locationMap: Record): Promise { // Ensure user's IP address is available if (this.context?.getIpAddress() === undefined) { - LogManager.Instance.info('To evaluate location pre Segment, please pass ipAddress in context object'); + LogManager.Instance.error('To evaluate location pre Segment, please pass ipAddress in context object'); return false; } // Check if location data is available and matches the expected values @@ -219,7 +223,7 @@ export class SegmentEvaluator implements Segmentation { async checkUserAgentParser(uaParserMap: Record): Promise { // Ensure user's user agent is available if (!this.context?.getUserAgent() || this.context?.getUserAgent() === undefined) { - LogManager.Instance.info('To evaluate user agent related segments, please pass userAgent in context object'); + LogManager.Instance.error('To evaluate user agent related segments, please pass userAgent in context object'); return false; } // Check if user agent data is available and matches the expected values @@ -264,6 +268,10 @@ export class SegmentEvaluator implements Segmentation { for (const key in actualMap) { if (Object.prototype.hasOwnProperty.call(expectedMap, key)) { const expectedValues = expectedMap[key]; + // convert expected values to lowercase + expectedValues.forEach((value, index) => { + expectedValues[index] = value.toLowerCase(); + }); const actualValue = actualMap[key]; // Handle wildcard patterns for all keys @@ -273,7 +281,7 @@ export class SegmentEvaluator implements Segmentation { // Extract pattern from wildcard string const wildcardPattern = val.slice(9, -1); // Convert wildcard pattern to regex and check if it matches the actual value - const regex = new RegExp(wildcardPattern.replace(/\*/g, '.*')); // Convert wildcard pattern to regex + const regex = new RegExp(wildcardPattern.replace(/\*/g, '.*'), 'i'); // Convert wildcard pattern to regex, 'i' for case-insensitive // Check if the actual value matches the regex pattern for the key if (regex.test(actualValue)) { // match found, return true as we only need to check if any of the expected values match the actual value diff --git a/lib/packages/segmentation-evaluator/evaluators/SegmentOperandEvaluator.ts b/lib/packages/segmentation-evaluator/evaluators/SegmentOperandEvaluator.ts index d7065c0..ace0b07 100644 --- a/lib/packages/segmentation-evaluator/evaluators/SegmentOperandEvaluator.ts +++ b/lib/packages/segmentation-evaluator/evaluators/SegmentOperandEvaluator.ts @@ -53,7 +53,7 @@ export class SegmentOperandEvaluator { const listIdRegex = /inlist\((\w+:\d+)\)/; const match = operand.match(listIdRegex); if (!match || match.length < 2) { - console.error("Invalid 'inList' operand format"); + LogManager.Instance.error("Invalid 'inList' operand format"); return false; } @@ -74,7 +74,7 @@ export class SegmentOperandEvaluator { } return res; } catch (error) { - console.error('Error while fetching data:', error); + LogManager.Instance.error('Error while fetching data: ' + error); return false; } } else { diff --git a/test/e2e/TrackEvent.test.ts b/test/e2e/TrackEvent.test.ts index e9a0484..d8d2e52 100644 --- a/test/e2e/TrackEvent.test.ts +++ b/test/e2e/TrackEvent.test.ts @@ -44,7 +44,7 @@ describe('VWOClient trackEvent method', () => { const context = { id: '123' }; // Call the trackEvent method - const result = await vwoClient.trackEvent(eventName, eventProperties, context); + const result = await vwoClient.trackEvent(eventName, context, eventProperties); // Assert that the method resolves with the correct data expect(result).toEqual({ [eventName]: true }); @@ -59,7 +59,7 @@ describe('VWOClient trackEvent method', () => { const context = { id: '123' }; // Call the trackEvent method - const result = await vwoClient.trackEvent(eventName, eventProperties, context); + const result = await vwoClient.trackEvent(eventName, context, eventProperties); // Assert that the method resolves with the correct data expect(result).toEqual({ [eventName]: false }); @@ -74,7 +74,7 @@ describe('VWOClient trackEvent method', () => { const context = { id: '123' }; // Call the trackEvent method - const result = await vwoClient.trackEvent(eventName, eventProperties, context); + const result = await vwoClient.trackEvent(eventName, context, eventProperties); // Assert that the method resolves with the correct data expect(result).toEqual({ [eventName]: false }); @@ -89,7 +89,7 @@ describe('VWOClient trackEvent method', () => { const context = { id: '123' }; // Call the trackEvent method - const result = await vwoClient.trackEvent(eventName, eventProperties, context); + const result = await vwoClient.trackEvent(eventName, context, eventProperties); // Assert that the method resolves with the correct data expect(result).toEqual({ [eventName]: false }); @@ -104,7 +104,7 @@ describe('VWOClient trackEvent method', () => { const context = {}; // Invalid context without userId // Call the trackEvent method - const result = await vwoClient.trackEvent(eventName, eventProperties, context); + const result = await vwoClient.trackEvent(eventName, context, eventProperties); // Assert that the method resolves with the correct data expect(result).toEqual({ [eventName]: false });