From 9b97d73f1948efaaa0a6dc037bb3c4c79b985cde Mon Sep 17 00:00:00 2001 From: Spencer Smith Date: Thu, 22 Jan 2026 15:58:17 -0700 Subject: [PATCH 1/3] Pass event to timestamp context function in streamingMedia --- .../StreamingMedia/createMediaEventManager.js | 2 +- .../helpers/mocks/mediaSessionResponse.json | 13 +++ .../integration/helpers/mswjs/handlers.js | 27 +++++++ .../specs/StreamingMedia/mediaEvents.spec.js | 80 +++++++++++++++++++ .../createMediaEventManager.spec.js | 4 +- 5 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 packages/core/test/integration/helpers/mocks/mediaSessionResponse.json create mode 100644 packages/core/test/integration/specs/StreamingMedia/mediaEvents.spec.js diff --git a/packages/core/src/components/StreamingMedia/createMediaEventManager.js b/packages/core/src/components/StreamingMedia/createMediaEventManager.js index d66387c6e..e583b686f 100644 --- a/packages/core/src/components/StreamingMedia/createMediaEventManager.js +++ b/packages/core/src/components/StreamingMedia/createMediaEventManager.js @@ -25,7 +25,7 @@ export default ({ createMediaEvent({ options }) { const event = eventManager.createEvent(); const { xdm } = options; - setTimestamp(xdm); + setTimestamp(event); event.setUserXdm(xdm); if (xdm.eventType === MediaEvents.AD_START) { diff --git a/packages/core/test/integration/helpers/mocks/mediaSessionResponse.json b/packages/core/test/integration/helpers/mocks/mediaSessionResponse.json new file mode 100644 index 000000000..3bccc432a --- /dev/null +++ b/packages/core/test/integration/helpers/mocks/mediaSessionResponse.json @@ -0,0 +1,13 @@ +{ + "requestId": "media-session-request-id", + "handle": [ + { + "payload": [ + { + "sessionId": "test-session-id-12345" + } + ], + "type": "media-analytics:new-session" + } + ] +} diff --git a/packages/core/test/integration/helpers/mswjs/handlers.js b/packages/core/test/integration/helpers/mswjs/handlers.js index 21a7c27b7..86429307d 100644 --- a/packages/core/test/integration/helpers/mswjs/handlers.js +++ b/packages/core/test/integration/helpers/mswjs/handlers.js @@ -175,3 +175,30 @@ export const setConsentHandler = http.post( throw new Error("Handler not configured properly"); }, ); + +export const mediaSessionHandler = http.post( + /https:\/\/edge.adobedc.net\/ee\/.*\/?v1\/interact/, + + async (req) => { + const url = new URL(req.request.url); + const configId = url.searchParams.get("configId"); + + if (configId === "bc1a10e0-aee4-4e0e-ac5b-cdbb9abbec83") { + return HttpResponse.text( + await readFile( + `${server.config.root}/packages/core/test/integration/helpers/mocks/mediaSessionResponse.json`, + ), + ); + } + + throw new Error("Handler not configured properly"); + }, +); + +export const mediaEventHandler = http.post( + /https:\/\/edge.adobedc.net\/ee\/va\/.*\/?v1\//, + + async () => { + return new HttpResponse(null, { status: 204 }); + }, +); diff --git a/packages/core/test/integration/specs/StreamingMedia/mediaEvents.spec.js b/packages/core/test/integration/specs/StreamingMedia/mediaEvents.spec.js new file mode 100644 index 000000000..31c451203 --- /dev/null +++ b/packages/core/test/integration/specs/StreamingMedia/mediaEvents.spec.js @@ -0,0 +1,80 @@ +/* +Copyright 2025 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +import { test, expect, describe } from "../../helpers/testsSetup/extend.js"; +import { + mediaSessionHandler, + mediaEventHandler, +} from "../../helpers/mswjs/handlers.js"; +import alloyConfig from "../../helpers/alloy/config.js"; + +const streamingMediaConfig = { + ...alloyConfig, + streamingMedia: { + channel: "test channel", + playerName: "test player", + }, +}; + +describe("Streaming Media Events", () => { + test("media events include timestamp in xdm", async ({ + alloy, + worker, + networkRecorder, + }) => { + worker.use(mediaSessionHandler, mediaEventHandler); + + await alloy("configure", streamingMediaConfig); + + await alloy("createMediaSession", { + playerId: "player1", + xdm: { + mediaCollection: { + sessionDetails: { + length: 60, + contentType: "VOD", + name: "test video", + }, + }, + }, + getPlayerDetails: () => ({ + playhead: 10, + qoeDataDetails: { + bitrate: 1000, + droppedFrames: 0, + framesPerSecond: 30, + timeToStart: 100, + }, + }), + }); + + const sessionCall = await networkRecorder.findCall(/edge\.adobedc\.net/); + expect(sessionCall).toBeDefined(); + expect(sessionCall.request.body.events[0].xdm.timestamp).toBeDefined(); + expect(sessionCall.request.body.events[0].xdm.eventType).toBe( + "media.sessionStart", + ); + + await alloy("sendMediaEvent", { + playerId: "player1", + xdm: { + eventType: "media.play", + }, + }); + + const mediaEventCalls = await networkRecorder.findCalls(/\/va\//); + expect(mediaEventCalls.length).toBeGreaterThan(0); + + const playEvent = mediaEventCalls[0]; + expect(playEvent.request.body.events[0].xdm.timestamp).toBeDefined(); + expect(playEvent.request.body.events[0].xdm.eventType).toBe("media.play"); + }); +}); diff --git a/packages/core/test/unit/specs/components/StreamingMedia/createMediaEventManager.spec.js b/packages/core/test/unit/specs/components/StreamingMedia/createMediaEventManager.spec.js index 5675569c2..e15a74744 100644 --- a/packages/core/test/unit/specs/components/StreamingMedia/createMediaEventManager.spec.js +++ b/packages/core/test/unit/specs/components/StreamingMedia/createMediaEventManager.spec.js @@ -47,12 +47,13 @@ describe("StreamingMedia::createMediaEventManager", () => { setTimestamp, }); }); - it("should create a media event with user xdm", () => { + it("should create a media event with user xdm and call setTimestamp with the event", () => { const options = { xdm: {}, }; const event = { setUserXdm: vi.fn(), + mergeXdm: vi.fn(), toJSON: () => ({ a: 1, }), @@ -62,6 +63,7 @@ describe("StreamingMedia::createMediaEventManager", () => { options, }); expect(result.toJSON()).toEqual(event.toJSON()); + expect(setTimestamp).toHaveBeenCalledWith(event); }); it("should create a media session with player name, channel, and version", () => { const options = { From b0de5a5df8375331f8a5f24618a4a4e975963003 Mon Sep 17 00:00:00 2001 From: Spencer Smith Date: Fri, 23 Jan 2026 12:28:55 -0700 Subject: [PATCH 2/3] Add changeset for patch (bugfix) --- .changeset/violet-signs-go.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/violet-signs-go.md diff --git a/.changeset/violet-signs-go.md b/.changeset/violet-signs-go.md new file mode 100644 index 000000000..ca816af7e --- /dev/null +++ b/.changeset/violet-signs-go.md @@ -0,0 +1,5 @@ +--- +"@adobe/alloy-core": patch +--- + +Fixed regression causing errors when using streaming media events From 102f7e6c1e47690ab9a44961b651eef02749986c Mon Sep 17 00:00:00 2001 From: Spencer Smith Date: Tue, 27 Jan 2026 11:16:19 -0700 Subject: [PATCH 3/3] Fix regex pattern for media event detection in integration test --- packages/core/test/integration/helpers/mswjs/handlers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/test/integration/helpers/mswjs/handlers.js b/packages/core/test/integration/helpers/mswjs/handlers.js index 86429307d..fdb7c6a03 100644 --- a/packages/core/test/integration/helpers/mswjs/handlers.js +++ b/packages/core/test/integration/helpers/mswjs/handlers.js @@ -196,7 +196,7 @@ export const mediaSessionHandler = http.post( ); export const mediaEventHandler = http.post( - /https:\/\/edge.adobedc.net\/ee\/va\/.*\/?v1\//, + /https:\/\/edge.adobedc.net\/ee(\/[^/]+)?\/va\/v1\//, async () => { return new HttpResponse(null, { status: 204 });