From 80aeefbcee7510c66199d7fb0889af168950849b Mon Sep 17 00:00:00 2001 From: satyam Date: Wed, 22 Apr 2026 16:36:56 +0530 Subject: [PATCH 1/2] fix: added project name to user mappings ui (#9) * fix: added project name to user mappings ui * fix: adding null check for properties in payload * fix: mapping moe field with project name * fix: test cases --- .../__snapshots__/snapshot.test.ts.snap | 2 + .../__snapshots__/snapshot.test.ts.snap | 2 + .../trackEvent/__tests__/index.test.ts | 108 +++++++++++++++--- .../moengage/trackEvent/generated-types.ts | 4 + .../destinations/moengage/trackEvent/index.ts | 15 ++- 5 files changed, 116 insertions(+), 15 deletions(-) diff --git a/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap index 5f435f04124..ba8c4f3c69f 100644 --- a/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap @@ -52,6 +52,7 @@ Object { }, "event": "E@t!q#n(^u", "properties": Object { + "moe_project_name": "E@t!q#n(^u", "testType": "E@t!q#n(^u", }, "timestamp": "2021-02-01T00:00:00.000Z", @@ -69,6 +70,7 @@ Object { "os": Object {}, }, "event": "E@t!q#n(^u", + "properties": Object {}, "type": "E@t!q#n(^u", "update_existing_only": false, } diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap index 91c759c5ce0..cac0ea88b0f 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap @@ -16,6 +16,7 @@ Object { }, "event": "[3(wtAyZqr", "properties": Object { + "moe_project_name": "[3(wtAyZqr", "testType": "[3(wtAyZqr", }, "timestamp": "2021-02-01T00:00:00.000Z", @@ -33,6 +34,7 @@ Object { "os": Object {}, }, "event": "[3(wtAyZqr", + "properties": Object {}, "type": "[3(wtAyZqr", "update_existing_only": false, } diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts index 3e457a680b6..db8bf8e25f4 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts @@ -3,17 +3,14 @@ import { createTestEvent, createTestIntegration } from '@segment/actions-core' import Destination from '../../index' import { getEndpointByRegion } from '../../regional-endpoints' - const testDestination = createTestIntegration(Destination) -const api_id = "APP_ID" -const api_key = "APP_KEY" -const region = "SOME_REGION" - +const api_id = 'APP_ID' +const api_key = 'APP_KEY' +const region = 'SOME_REGION' const endpoint = getEndpointByRegion() describe('ActionsMoengage.trackEvent', () => { - it('should validate action fields', async () => { const event = createTestEvent({ event: 'Test Event' }) @@ -28,17 +25,98 @@ describe('ActionsMoengage.trackEvent', () => { region } }) - + expect(responses.length).toBe(1) expect(responses[0].status).toBe(200) expect(responses[0].data).toMatchObject({}) - expect(responses[0].options.json).toMatchObject( - { - type: 'track', - event: 'Test Event', - context: {library: { version: '2.11.1' }} + expect(responses[0].options.json).toMatchObject({ + type: 'track', + event: 'Test Event', + context: { library: { version: '2.11.1' } } + }) + }) + + it('should include project_name in properties when provided', async () => { + const event = createTestEvent({ + event: 'Test Event', + properties: { key1: 'value1' } + }) + + nock(`${endpoint}`).post(`/v1/integrations/segment?appId=${api_id}`).reply(200, {}) + + const responses = await testDestination.testAction('trackEvent', { + event, + useDefaultMappings: true, + mapping: { project_name: 'MyProject' }, + settings: { + api_id, + api_key, + region + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + expect(responses[0].options.json).toMatchObject({ + type: 'track', + event: 'Test Event', + properties: { + key1: 'value1', + moe_project_name: 'MyProject' + } + }) + }) + + it('should not include project_name in properties when it is empty string', async () => { + const event = createTestEvent({ + event: 'Test Event', + properties: { key1: 'value1' } + }) + + nock(`${endpoint}`).post(`/v1/integrations/segment?appId=${api_id}`).reply(200, {}) + + const responses = await testDestination.testAction('trackEvent', { + event, + useDefaultMappings: true, + mapping: { project_name: '' }, + settings: { + api_id, + api_key, + region + } + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + const payload = responses[0].options.json as Record + const properties = payload.properties as Record + expect(properties).not.toHaveProperty('moe_project_name') + expect(properties).toMatchObject({ key1: 'value1' }) + }) + + it('should not include project_name in properties when it is not provided', async () => { + const event = createTestEvent({ + event: 'Test Event', + properties: { key1: 'value1' } + }) + + nock(`${endpoint}`).post(`/v1/integrations/segment?appId=${api_id}`).reply(200, {}) + + const responses = await testDestination.testAction('trackEvent', { + event, + useDefaultMappings: true, + settings: { + api_id, + api_key, + region } - ) + }) + + expect(responses.length).toBe(1) + expect(responses[0].status).toBe(200) + const payload = responses[0].options.json as Record + const properties = payload.properties as Record + expect(properties).not.toHaveProperty('moe_project_name') }) it('should require event field', async () => { @@ -49,7 +127,9 @@ describe('ActionsMoengage.trackEvent', () => { try { await testDestination.testAction('trackEvent', { - event, useDefaultMappings: true, settings: { + event, + useDefaultMappings: true, + settings: { api_id, api_key, region diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/generated-types.ts b/packages/destination-actions/src/destinations/moengage/trackEvent/generated-types.ts index 400024d0b4c..0d7fa1d26f2 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/generated-types.ts +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/generated-types.ts @@ -39,6 +39,10 @@ export interface Payload { properties?: { [k: string]: unknown } + /** + * Enter the Project Name from MoEngage Settings > Portfolio. Values must match exactly. Mismatched events stay at the portfolio level and are unusable for project-level analysis. Leave this field blank if Portfolio is not enabled for your workspace. + */ + project_name?: string /** * If set to true, events from the Segment will only trigger updates for users who already exist in Moengage. */ diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts b/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts index c8caf3fdfee..9659df19cf5 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts @@ -84,6 +84,14 @@ const action: ActionDefinition = { '@path': '$.properties' } }, + project_name: { + label: 'Project Name', + type: 'string', + description: + 'Enter the Project Name from MoEngage Settings > Portfolio. Values must match exactly. Mismatched events stay at the portfolio level and are unusable for project-level analysis. Leave this field blank if Portfolio is not enabled for your workspace.', + required: false, + default: '' + }, update_existing_only: { label: 'Update Existing Users Only', type: 'boolean', @@ -98,6 +106,11 @@ const action: ActionDefinition = { throw new IntegrationError('Missing API ID or API KEY', 'Missing required field', 400) } + const properties = payload.properties ? { ...payload.properties } : {} + if (payload.project_name) { + properties.moe_project_name = payload.project_name + } + const event = { type: payload.type, user_id: payload.userId, @@ -108,7 +121,7 @@ const action: ActionDefinition = { os: { name: payload.os_name }, library: { version: payload.library_version } }, - properties: payload.properties, + properties, timestamp: payload.timestamp, update_existing_only: payload.update_existing_only || false } From 2b3705fbc00df13ec812ec6792da1f94db74651c Mon Sep 17 00:00:00 2001 From: satyam Date: Fri, 24 Apr 2026 18:07:31 +0530 Subject: [PATCH 2/2] fix: resolving comments (#10) --- .../__tests__/__snapshots__/snapshot.test.ts.snap | 1 - .../__tests__/__snapshots__/snapshot.test.ts.snap | 1 - .../moengage/trackEvent/__tests__/index.test.ts | 8 +++----- .../src/destinations/moengage/trackEvent/index.ts | 7 +++++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap index ba8c4f3c69f..3108f8d4b65 100644 --- a/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/moengage/__tests__/__snapshots__/snapshot.test.ts.snap @@ -70,7 +70,6 @@ Object { "os": Object {}, }, "event": "E@t!q#n(^u", - "properties": Object {}, "type": "E@t!q#n(^u", "update_existing_only": false, } diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap index cac0ea88b0f..d82f545035c 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/__snapshots__/snapshot.test.ts.snap @@ -34,7 +34,6 @@ Object { "os": Object {}, }, "event": "[3(wtAyZqr", - "properties": Object {}, "type": "[3(wtAyZqr", "update_existing_only": false, } diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts index db8bf8e25f4..1066c9205d8 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/__tests__/index.test.ts @@ -125,8 +125,8 @@ describe('ActionsMoengage.trackEvent', () => { nock(`${endpoint}`).post(`/v1/integrations/segment?appId=${api_id}`).reply(200, {}) - try { - await testDestination.testAction('trackEvent', { + await expect( + testDestination.testAction('trackEvent', { event, useDefaultMappings: true, settings: { @@ -135,8 +135,6 @@ describe('ActionsMoengage.trackEvent', () => { region } }) - } catch (e) { - expect(e.message).toBe("The root value is missing the required field 'event'.") - } + ).rejects.toThrow("The root value is missing the required field 'event'.") }) }) diff --git a/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts b/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts index 9659df19cf5..919d83507ab 100644 --- a/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts +++ b/packages/destination-actions/src/destinations/moengage/trackEvent/index.ts @@ -106,9 +106,12 @@ const action: ActionDefinition = { throw new IntegrationError('Missing API ID or API KEY', 'Missing required field', 400) } - const properties = payload.properties ? { ...payload.properties } : {} + let properties = payload.properties if (payload.project_name) { - properties.moe_project_name = payload.project_name + properties = { + ...(payload.properties ?? {}), + moe_project_name: payload.project_name + } } const event = {