diff --git a/src/components/MediaCollection/createMediaSessionCacheManager.js b/src/components/MediaCollection/createMediaSessionCacheManager.js index 6d2e01b04..2154c361a 100644 --- a/src/components/MediaCollection/createMediaSessionCacheManager.js +++ b/src/components/MediaCollection/createMediaSessionCacheManager.js @@ -18,34 +18,42 @@ export default () => { }; const saveHeartbeat = ({ playerId, heartbeatId }) => { - const mediaSession = mediaSessionCache[playerId]; - if (!mediaSession) { + const sessionDetails = mediaSessionCache[playerId]; + + if (!sessionDetails) { return; } - mediaSession.heartbeatId = heartbeatId; + + sessionDetails.heartbeatId = heartbeatId; }; const stopHeartbeat = ({ playerId }) => { - const mediaSession = mediaSessionCache[playerId]; - if (!mediaSession) { + const sessionDetails = mediaSessionCache[playerId]; + + if (!sessionDetails) { return; } - clearInterval(mediaSession.heartbeatId); - mediaSession.heartbeatId = null; + + clearInterval(sessionDetails.heartbeatId); + + sessionDetails.heartbeatId = null; }; const updateLastTriggeredEventTS = ({ playerId }) => { - const player = mediaSessionCache[playerId]; - if (!player) { + const sessionDetails = mediaSessionCache[playerId]; + + if (!sessionDetails) { return; } - player.latestTriggeredEvent = Date.now(); + + sessionDetails.latestTriggeredEvent = Date.now(); }; const storeSession = ({ playerId, sessionDetails }) => { if (mediaSessionCache === undefined) { mediaSessionCache = {}; } + mediaSessionCache[playerId] = sessionDetails; }; diff --git a/src/components/MediaCollection/createUpdateMediaSessionState.js b/src/components/MediaCollection/createUpdateMediaSessionState.js index c09b8f525..96e614dbd 100644 --- a/src/components/MediaCollection/createUpdateMediaSessionState.js +++ b/src/components/MediaCollection/createUpdateMediaSessionState.js @@ -14,9 +14,6 @@ import MediaEvents from "./constants/eventTypes"; export default ({ mediaSessionCacheManager }) => { return ({ playerId, eventType }) => { - if (!playerId) { - return; - } if ( eventType === MediaEvents.SESSION_COMPLETE || eventType === MediaEvents.SESSION_END @@ -24,8 +21,6 @@ export default ({ mediaSessionCacheManager }) => { mediaSessionCacheManager.stopHeartbeat({ playerId }); } - mediaSessionCacheManager.updateLastTriggeredEventTS({ - playerId - }); + mediaSessionCacheManager.updateLastTriggeredEventTS({ playerId }); }; }; diff --git a/src/components/MediaCollection/validateMediaEventOptions.js b/src/components/MediaCollection/validateMediaEventOptions.js index 5769c817d..983aa790b 100644 --- a/src/components/MediaCollection/validateMediaEventOptions.js +++ b/src/components/MediaCollection/validateMediaEventOptions.js @@ -27,6 +27,7 @@ export default ({ options }) => { mediaCollection: objectOf(anything()) }).required() }).required(), + objectOf({ xdm: objectOf({ eventType: string().required(), @@ -39,6 +40,7 @@ export default ({ options }) => { }).required() }).required() ], + "Error validating the sendMediaEvent command options." ); diff --git a/src/components/MediaCollection/validateMediaSessionOptions.js b/src/components/MediaCollection/validateMediaSessionOptions.js index b5a787c5e..20183f89e 100644 --- a/src/components/MediaCollection/validateMediaSessionOptions.js +++ b/src/components/MediaCollection/validateMediaSessionOptions.js @@ -31,6 +31,7 @@ export default ({ options }) => { }) }) }).required(), + objectOf({ xdm: objectOf({ mediaCollection: objectOf({ @@ -40,6 +41,7 @@ export default ({ options }) => { }) }).required() ], + "Error validating the createMediaSession command options." ); diff --git a/test/unit/specs/components/MediaCollection/createHeartbeatEngine.spec.js b/test/unit/specs/components/MediaCollection/createHeartbeatEngine.spec.js index 92de9ab3f..eb3702b22 100644 --- a/test/unit/specs/components/MediaCollection/createHeartbeatEngine.spec.js +++ b/test/unit/specs/components/MediaCollection/createHeartbeatEngine.spec.js @@ -14,7 +14,7 @@ governing permissions and limitations under the License. import createHeartbeatEngine from "../../../../../src/components/MediaCollection/createHeartbeatEngine"; -describe("createHeartbeatEngine", () => { +describe("MediaCollection::createHeartbeatEngine", () => { let config; let mediaEventManager; let mediaSessionCacheManager; diff --git a/test/unit/specs/components/MediaCollection/createMediaEventManager.spec.js b/test/unit/specs/components/MediaCollection/createMediaEventManager.spec.js index fa35b6a72..b771fb8cf 100644 --- a/test/unit/specs/components/MediaCollection/createMediaEventManager.spec.js +++ b/test/unit/specs/components/MediaCollection/createMediaEventManager.spec.js @@ -14,7 +14,7 @@ governing permissions and limitations under the License. import createMediaEventManager from "../../../../../src/components/MediaCollection/createMediaEventManager"; -describe("createMediaEventManager", () => { +describe("MediaCollection::createMediaEventManager", () => { let config; let eventManager; let consent; diff --git a/test/unit/specs/components/MediaCollection/createMediaRequest.spec.js b/test/unit/specs/components/MediaCollection/createMediaRequest.spec.js index a492303ef..7a52270a4 100644 --- a/test/unit/specs/components/MediaCollection/createMediaRequest.spec.js +++ b/test/unit/specs/components/MediaCollection/createMediaRequest.spec.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. import createMediaRequest from "../../../../../src/components/MediaCollection/createMediaRequest"; -describe("createMediaRequest", () => { +describe("MediaCollection::createMediaRequest", () => { it("should call createRequest with correct parameters", () => { const mediaRequestPayload = {}; // replace with valid payload const action = "testAction"; diff --git a/test/unit/specs/components/MediaCollection/createMediaRequestPayload.spec.js b/test/unit/specs/components/MediaCollection/createMediaRequestPayload.spec.js deleted file mode 100644 index 26ef92385..000000000 --- a/test/unit/specs/components/MediaCollection/createMediaRequestPayload.spec.js +++ /dev/null @@ -1,11 +0,0 @@ -/* -Copyright 2023 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. -*/ diff --git a/test/unit/specs/components/MediaCollection/createMediaSessionCacheManager.spec.js b/test/unit/specs/components/MediaCollection/createMediaSessionCacheManager.spec.js index 26ef92385..fc767b47b 100644 --- a/test/unit/specs/components/MediaCollection/createMediaSessionCacheManager.spec.js +++ b/test/unit/specs/components/MediaCollection/createMediaSessionCacheManager.spec.js @@ -9,3 +9,70 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + +import createMediaSessionCacheManager from "../../../../../src/components/MediaCollection/createMediaSessionCacheManager"; + +describe("MediaCollection::createMediaSessionCacheManager", () => { + let mediaSessionCacheManager; + + beforeEach(() => { + mediaSessionCacheManager = createMediaSessionCacheManager(); + }); + + it("getSession should return correct session", () => { + const playerId = "player1"; + const sessionDetails = { id: "session1" }; + mediaSessionCacheManager.storeSession({ playerId, sessionDetails }); + + const result = mediaSessionCacheManager.getSession(playerId); + + expect(result).toEqual(sessionDetails); + }); + + it("stopHeartbeat should stop the heartbeat", () => { + const playerId = "player1"; + const sessionDetails = { id: "session1", heartbeatId: 1 }; + + mediaSessionCacheManager.storeSession({ playerId, sessionDetails }); + + const result = mediaSessionCacheManager.getSession(playerId); + + mediaSessionCacheManager.stopHeartbeat({ playerId }); + + expect(result.heartbeatId).toEqual(null); + }); + + it("updateLastTriggeredEventTS should update the timestamp", () => { + const playerId = "player1"; + const now = Date.now(); + const sessionDetails = { id: "session1", heartbeatId: 1 }; + + mediaSessionCacheManager.storeSession({ playerId, sessionDetails }); + mediaSessionCacheManager.updateLastTriggeredEventTS({ playerId }); + + const session = mediaSessionCacheManager.getSession(playerId); + + expect(session.latestTriggeredEvent).toBeGreaterThanOrEqual(now); + }); + + it("storeSession should store the session", () => { + const playerId = "player1"; + const sessionDetails = { id: "session1" }; + mediaSessionCacheManager.storeSession({ playerId, sessionDetails }); + + const session = mediaSessionCacheManager.getSession(playerId); + + expect(session).toEqual(sessionDetails); + }); + + it("saveHeartbeat should save the heartbeat", () => { + const playerId = "player1"; + const sessionDetails = { id: "session1" }; + mediaSessionCacheManager.storeSession({ playerId, sessionDetails }); + mediaSessionCacheManager.saveHeartbeat({ playerId, heartbeatId: 1 }); + + const session = mediaSessionCacheManager.getSession(playerId); + + expect(session.heartbeatId).toEqual(1); + }); +}); diff --git a/test/unit/specs/components/MediaCollection/createUpdateMediaSessionState.spec.js b/test/unit/specs/components/MediaCollection/createUpdateMediaSessionState.spec.js index 26ef92385..1cdaad0cf 100644 --- a/test/unit/specs/components/MediaCollection/createUpdateMediaSessionState.spec.js +++ b/test/unit/specs/components/MediaCollection/createUpdateMediaSessionState.spec.js @@ -9,3 +9,42 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + +import createUpdateMediaSessionState from "../../../../../src/components/MediaCollection/createUpdateMediaSessionState"; +import MediaEvents from "../../../../../src/components/MediaCollection/constants/eventTypes"; + +describe("MediaCollection::createUpdateMediaSessionState", () => { + let mediaSessionCacheManager; + let updateSessionState; + + beforeEach(() => { + mediaSessionCacheManager = jasmine.createSpyObj( + "mediaSessionCacheManager", + ["stopHeartbeat", "updateLastTriggeredEventTS"] + ); + updateSessionState = createUpdateMediaSessionState({ + mediaSessionCacheManager + }); + }); + + it("should stop the heart beat when session completes", () => { + updateSessionState({ + playerId: "playerId", + eventType: MediaEvents.SESSION_COMPLETE + }); + + expect(mediaSessionCacheManager.stopHeartbeat).toHaveBeenCalled(); + expect( + mediaSessionCacheManager.updateLastTriggeredEventTS + ).toHaveBeenCalled(); + }); + + it("should update the last event when session is ongoing", () => { + updateSessionState({ playerId: "playerId", eventType: MediaEvents.PLAY }); + + expect(mediaSessionCacheManager.stopHeartbeat).not.toHaveBeenCalled(); + expect( + mediaSessionCacheManager.updateLastTriggeredEventTS + ).toHaveBeenCalled(); + }); +}); diff --git a/test/unit/specs/components/MediaCollection/validateMediaEventOptions.spec.js b/test/unit/specs/components/MediaCollection/validateMediaEventOptions.spec.js index 26ef92385..88295a122 100644 --- a/test/unit/specs/components/MediaCollection/validateMediaEventOptions.spec.js +++ b/test/unit/specs/components/MediaCollection/validateMediaEventOptions.spec.js @@ -9,3 +9,56 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + +import validateMediaEventOptions from "../../../../../src/components/MediaCollection/validateMediaEventOptions"; + +describe("MediaCollection::validateMediaEventOptions", () => { + it("should not fail when payerId and xdm are used", () => { + const options = { + playerId: "playerId", + xdm: { + eventType: "eventType", + mediaCollection: { + playhead: 0, + sessionID: "sessionID" + } + } + }; + + expect(() => { + validateMediaEventOptions({ options }); + }).not.toThrowError(); + }); + + it("should not fail when xdm with playhead is used", () => { + const options = { + xdm: { + eventType: "eventType", + mediaCollection: { + playhead: 0, + sessionID: "sessionID" + } + } + }; + + expect(() => { + validateMediaEventOptions({ options }); + }).not.toThrowError(); + }); + + it("should throw an error when invalid options are passed", () => { + const options = { + xdm: { + eventType: "eventType", + mediaCollection: { + playhead: "0", + sessionID: "sessionID" + } + } + }; + + expect(() => { + validateMediaEventOptions({ options }); + }).toThrowError(); + }); +}); diff --git a/test/unit/specs/components/MediaCollection/validateMediaSessionOptions.spec.js b/test/unit/specs/components/MediaCollection/validateMediaSessionOptions.spec.js index 26ef92385..fe048423f 100644 --- a/test/unit/specs/components/MediaCollection/validateMediaSessionOptions.spec.js +++ b/test/unit/specs/components/MediaCollection/validateMediaSessionOptions.spec.js @@ -9,3 +9,56 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + +import validateMediaSessionOptions from "../../../../../src/components/MediaCollection/validateMediaSessionOptions"; + +describe("MediaCollection::validateMediaSessionOptions", () => { + it("should not fail when playerId, callback and xdm are used", () => { + const options = { + playerId: "playerId", + onBeforeMediaEvent: () => {}, + xdm: { + eventType: "eventType", + mediaCollection: { + sessionDetails: {} + } + } + }; + + expect(() => { + validateMediaSessionOptions({ options }); + }).not.toThrowError(); + }); + + it("should not fail when playerId, callback and xdm are used", () => { + const options = { + xdm: { + eventType: "eventType", + mediaCollection: { + playhead: 0, + sessionDetails: {} + } + } + }; + + expect(() => { + validateMediaSessionOptions({ options }); + }).not.toThrowError(); + }); + + it("should throw an error when invalid options are passed", () => { + const options = { + xdm: { + eventType: "eventType", + mediaCollection: { + playhead: "0", + sessionID: "sessionID" + } + } + }; + + expect(() => { + validateMediaSessionOptions({ options }); + }).toThrowError(); + }); +});