diff --git a/common/changes/@snowplow/browser-plugin-media/fix-disallow-empty-string-media_2026-05-19-13-41.json b/common/changes/@snowplow/browser-plugin-media/fix-disallow-empty-string-media_2026-05-19-13-41.json new file mode 100644 index 000000000..bb82d12e2 --- /dev/null +++ b/common/changes/@snowplow/browser-plugin-media/fix-disallow-empty-string-media_2026-05-19-13-41.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@snowplow/browser-plugin-media", + "comment": "Prevent empty values in media entity", + "type": "none" + } + ], + "packageName": "@snowplow/browser-plugin-media" +} \ No newline at end of file diff --git a/plugins/browser-plugin-media/src/core.ts b/plugins/browser-plugin-media/src/core.ts index 54f9da276..d1b67ea7e 100644 --- a/plugins/browser-plugin-media/src/core.ts +++ b/plugins/browser-plugin-media/src/core.ts @@ -16,9 +16,14 @@ export function buildMediaPlayerEvent(event: MediaEvent): SelfDescribingJson { } export function buildMediaPlayerEntity(mediaPlayer: MediaPlayer): SelfDescribingJson { + const player = { ...mediaPlayer }; + if (player.label === '') delete player.label; + if (player.playerType === '') delete player.playerType; + if (player.quality === '') delete player.quality; + return { schema: MEDIA_PLAYER_SCHEMA, - data: removeEmptyProperties(mediaPlayer), + data: removeEmptyProperties(player), }; } diff --git a/plugins/browser-plugin-media/test/api.test.ts b/plugins/browser-plugin-media/test/api.test.ts index 2229243b9..47ab34441 100644 --- a/plugins/browser-plugin-media/test/api.test.ts +++ b/plugins/browser-plugin-media/test/api.test.ts @@ -316,6 +316,38 @@ describe('Media Tracking API', () => { ]); }); + it('strips empty string values from optional media player fields', () => { + startMediaTracking({ + id, + session: false, + player: { label: '', playerType: '', quality: '' }, + }); + + trackMediaPlay({ id }); + + const playerContext = eventQueue[0].context[0].data; + expect(playerContext).not.toHaveProperty('label'); + expect(playerContext).not.toHaveProperty('playerType'); + expect(playerContext).not.toHaveProperty('quality'); + }); + + it('preserves non-empty string values for optional media player fields', () => { + startMediaTracking({ + id, + session: false, + player: { label: 'My Video', playerType: 'html5', quality: '1080p' }, + }); + + trackMediaPlay({ id }); + + const playerContext = eventQueue[0].context[0].data; + expect(playerContext).toMatchObject({ + label: 'My Video', + playerType: 'html5', + quality: '1080p', + }); + }); + it('tracks error event', () => { startMediaTracking({ id, session: false });