@npo/player 1.23.2 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/js/playeractions/handlers/error.js +2 -2
- package/lib/js/playeractions/handlers/error.test.js +2 -2
- package/lib/js/playeractions/handlers/handleoffsets.d.ts +4 -6
- package/lib/js/playeractions/handlers/handleoffsets.js +16 -17
- package/lib/js/playeractions/handlers/handleoffsets.test.js +73 -29
- package/lib/js/playeractions/handlers/mediasessionactions.js +24 -12
- package/lib/js/playeractions/handlers/processsourceconfig.js +16 -3
- package/lib/js/tracking/handlers/eventbinding.d.ts +1 -1
- package/lib/js/tracking/handlers/eventbinding.js +17 -23
- package/lib/js/tracking/handlers/eventlogging.d.ts +1 -1
- package/lib/js/tracking/handlers/eventlogging.js +18 -18
- package/lib/js/tracking/handlers/eventlogging.test.js +24 -24
- package/lib/js/tracking/handlers/playertrackerstart.js +4 -2
- package/lib/lang/nl.json +3 -1
- package/lib/npoplayer.d.ts +1 -2
- package/lib/npoplayer.js +25 -43
- package/lib/package.json +5 -5
- package/lib/services/a11y/setup.js +2 -2
- package/lib/services/a11y/setup.test.js +7 -8
- package/lib/services/advertHandlers/handlePreRolls.d.ts +2 -0
- package/lib/services/advertHandlers/handlePreRolls.js +132 -0
- package/lib/services/advertHandlers/handlePrerolls.test.js +52 -0
- package/lib/services/cdnProviders/cdnProviders.d.ts +4 -0
- package/lib/services/cdnProviders/cdnProviders.js +22 -0
- package/lib/services/cdnProviders/cndProviders.test.js +22 -0
- package/lib/services/eventListenerHandlers/removeEventListeners.d.ts +1 -1
- package/lib/services/eventListenerHandlers/removeEventListeners.js +4 -4
- package/lib/services/eventListenerHandlers/removeEventListeners.test.js +28 -13
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.d.ts +1 -1
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.js +3 -3
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.test.d.ts +2 -0
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.test.js +65 -0
- package/lib/services/localStorageHandlers/localStorageHandlers.d.ts +1 -1
- package/lib/services/localStorageHandlers/localStorageHandlers.test.js +0 -1
- package/lib/services/npoPlayerAPI/contants.d.ts +5 -0
- package/lib/services/npoPlayerAPI/contants.js +5 -0
- package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +16 -4
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +65 -3
- package/lib/services/npoPlayerAPI/npoPlayerAPI.test.js +66 -1
- package/lib/services/segmentHandlers/addSegmentEventListeners.js +3 -3
- package/lib/services/segmentHandlers/addSegmentEventListeners.test.js +10 -9
- package/lib/services/segmentHandlers/convertFragmentToSegment.d.ts +1 -1
- package/lib/services/segmentHandlers/handleSegmentSeek.d.ts +1 -1
- package/lib/services/segmentHandlers/handleSegmentSeek.test.js +4 -4
- package/lib/services/segmentHandlers/handleSegmentTimeChanged.d.ts +1 -1
- package/lib/services/segmentHandlers/handleSegmentTimeChanged.test.js +33 -24
- package/lib/services/segmentHandlers/initSegment.d.ts +1 -1
- package/lib/services/segmentHandlers/initSegment.test.js +3 -1
- package/lib/services/segmentHandlers/setSegmentMarkers.d.ts +1 -1
- package/lib/services/services.d.ts +3 -1
- package/lib/services/services.js +8 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.js +8 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.test.d.ts +1 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.test.js +36 -0
- package/lib/src/js/playeractions/handlers/handleoffsets.d.ts +4 -6
- package/lib/src/js/tracking/handlers/eventbinding.d.ts +1 -1
- package/lib/src/js/tracking/handlers/eventlogging.d.ts +1 -1
- package/lib/src/npoplayer.d.ts +1 -2
- package/lib/src/services/advertHandlers/handlePreRolls.d.ts +2 -0
- package/lib/src/services/advertHandlers/handlePrerolls.test.d.ts +1 -0
- package/lib/src/services/cdnProviders/cdnProviders.d.ts +4 -0
- package/lib/src/services/cdnProviders/cndProviders.test.d.ts +1 -0
- package/lib/src/services/eventListenerHandlers/removeEventListeners.d.ts +1 -1
- package/lib/src/services/liveStreamHandlers/handleLiveStreamControls.d.ts +1 -1
- package/lib/src/services/liveStreamHandlers/handleLiveStreamControls.test.d.ts +2 -0
- package/lib/src/services/localStorageHandlers/localStorageHandlers.d.ts +1 -1
- package/lib/src/services/npoPlayerAPI/contants.d.ts +5 -0
- package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +16 -4
- package/lib/src/services/segmentHandlers/convertFragmentToSegment.d.ts +1 -1
- package/lib/src/services/segmentHandlers/handleSegmentSeek.d.ts +1 -1
- package/lib/src/services/segmentHandlers/handleSegmentTimeChanged.d.ts +1 -1
- package/lib/src/services/segmentHandlers/initSegment.d.ts +1 -1
- package/lib/src/services/segmentHandlers/setSegmentMarkers.d.ts +1 -1
- package/lib/src/services/services.d.ts +3 -1
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -0
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoControls.test.d.ts +1 -0
- package/lib/src/types/events.d.ts +8 -1
- package/lib/src/types/interfaces.d.ts +8 -12
- package/lib/src/ui/components/audio/controlbar.d.ts +1 -1
- package/lib/src/ui/components/controlbar.d.ts +1 -1
- package/lib/src/ui/components/seekbar.d.ts +1 -1
- package/lib/src/ui/components/settingspanel.d.ts +1 -1
- package/lib/src/ui/components/verticalvideo/controlbar.d.ts +3 -0
- package/lib/src/ui/handlers/streamhandler.d.ts +2 -4
- package/lib/src/ui/uicontainer.d.ts +2 -2
- package/lib/tests/mocks/mockNpoplayer.js +0 -1
- package/lib/tests/mocks/playerContextMock.d.ts +67 -0
- package/lib/tests/mocks/playerContextMock.js +117 -0
- package/lib/types/events.d.ts +8 -1
- package/lib/types/events.js +184 -1
- package/lib/types/interfaces.d.ts +8 -12
- package/lib/types/interfaces.js +1 -0
- package/lib/ui/components/audio/controlbar.d.ts +1 -1
- package/lib/ui/components/audio/controlbar.js +6 -6
- package/lib/ui/components/controlbar.d.ts +1 -1
- package/lib/ui/components/controlbar.js +13 -11
- package/lib/ui/components/nativemobile/controlbar.js +0 -1
- package/lib/ui/components/seekbar.js +1 -1
- package/lib/ui/components/settingspanel.d.ts +1 -1
- package/lib/ui/components/settingspanel.js +68 -84
- package/lib/ui/components/topbar.js +6 -3
- package/lib/ui/components/verticalvideo/controlbar.d.ts +3 -0
- package/lib/ui/components/verticalvideo/controlbar.js +34 -0
- package/lib/ui/handlers/streamhandler.d.ts +2 -4
- package/lib/ui/handlers/streamhandler.js +16 -7
- package/lib/ui/nativemobileuifactory.js +2 -0
- package/lib/ui/uicontainer.d.ts +2 -2
- package/lib/ui/uicontainer.js +35 -29
- package/package.json +5 -5
- package/src/style/components/_settingspanel.scss +35 -3
- package/src/style/components/_subtitles.scss +29 -25
- package/src/style/components/_textbuttons.scss +2 -2
- package/src/style/components/_volumeslider.scss +1 -0
- package/src/style/components/vertical-video/_bottombar.scss +19 -0
- package/src/style/components/vertical-video/_buttons.scss +23 -0
- package/src/style/components/vertical-video/_hugeplaybacktogglebutton.scss +14 -0
- package/src/style/components/vertical-video/_seekbar.scss +19 -0
- package/src/style/components/vertical-video/_settingsbutton.scss +7 -0
- package/src/style/components/vertical-video/_settingspanel.scss +14 -0
- package/src/style/components/vertical-video/_shortvideo.scss +14 -0
- package/src/style/components/vertical-video/_subtitles.scss +3 -0
- package/src/style/components/vertical-video/_topbar.scss +17 -0
- package/src/style/components/vertical-video/_volumeslider.scss +9 -0
- package/src/style/npoplayer.css +74 -34
- package/src/style/npoplayer.scss +2 -1
- package/src/style/variants/_player-small.scss +18 -10
- package/src/style/variants/_player-vertical.scss +23 -0
- package/lib/js/ads/ster.d.ts +0 -4
- package/lib/js/ads/ster.js +0 -126
- package/lib/js/ads/ster.test.js +0 -63
- package/lib/js/cdnproviders.d.ts +0 -1
- package/lib/js/cdnproviders.js +0 -16
- package/lib/src/js/ads/ster.d.ts +0 -4
- package/lib/src/js/cdnproviders.d.ts +0 -1
- package/lib/tests/mocks/mockPlayerContext.d.ts +0 -2
- package/lib/tests/mocks/mockPlayerContext.js +0 -40
- /package/lib/{js/ads/ster.test.d.ts → services/advertHandlers/handlePrerolls.test.d.ts} +0 -0
- /package/lib/{src/js/ads/ster.test.d.ts → services/cdnProviders/cndProviders.test.d.ts} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import '@testing-library/jest-dom';
|
|
2
|
+
import { NpoPlayerEvent } from '../../types/events';
|
|
3
|
+
import { handleLiveStreamControls, updateForwardButtonState, toggleForwardButtons } from './handleLiveStreamControls';
|
|
4
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
5
|
+
export const TIME_SHIFT_THRESHOLD = -10;
|
|
6
|
+
describe('handleLiveStreamControls', () => {
|
|
7
|
+
let mockPlayerContext;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.clearAllMocks();
|
|
10
|
+
mockPlayerContext = createPlayerContextMock();
|
|
11
|
+
});
|
|
12
|
+
it('should add TimeChanged event listener and store it in eventListeners', () => {
|
|
13
|
+
handleLiveStreamControls(mockPlayerContext);
|
|
14
|
+
expect(mockPlayerContext.player.on).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoplayer.eventListeners?.liveStreamHandleTimeChangedCallback);
|
|
15
|
+
expect(mockPlayerContext.npoplayer.eventListeners?.liveStreamHandleTimeChangedCallback).toBeDefined();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('updateForwardButtonState', () => {
|
|
19
|
+
let mockPlayerContext;
|
|
20
|
+
let mockForwardButtons;
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
jest.clearAllMocks();
|
|
23
|
+
mockPlayerContext = createPlayerContextMock();
|
|
24
|
+
document.body.innerHTML = `
|
|
25
|
+
<div class="bmpui-ui-forwardbutton"></div>
|
|
26
|
+
<div class="bmpui-ui-forwardbutton"></div>
|
|
27
|
+
`;
|
|
28
|
+
mockForwardButtons = document.querySelectorAll('.bmpui-ui-forwardbutton');
|
|
29
|
+
jest.spyOn(mockPlayerContext.player, 'getTimeShift').mockReturnValue(TIME_SHIFT_THRESHOLD - 5);
|
|
30
|
+
jest.spyOn(mockPlayerContext.player, 'getContainer').mockReturnValue({
|
|
31
|
+
querySelectorAll: jest.fn().mockReturnValue(mockForwardButtons)
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
it('should update forward buttons state based on timeShift', () => {
|
|
35
|
+
updateForwardButtonState(mockPlayerContext.player);
|
|
36
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, expect.any(Function));
|
|
37
|
+
for (const forwardButton of mockForwardButtons) {
|
|
38
|
+
expect(forwardButton).toBeEnabled();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('toggleForwardButtons', () => {
|
|
43
|
+
let mockForwardButtons;
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
document.body.innerHTML = `
|
|
46
|
+
<div class="bmpui-ui-forwardbutton"></div>
|
|
47
|
+
<div class="bmpui-ui-forwardbutton"></div>
|
|
48
|
+
`;
|
|
49
|
+
mockForwardButtons = document.querySelectorAll('.bmpui-ui-forwardbutton');
|
|
50
|
+
});
|
|
51
|
+
it('should disable forward buttons if timeShift > TIME_SHIFT_THRESHOLD', () => {
|
|
52
|
+
toggleForwardButtons(mockForwardButtons, TIME_SHIFT_THRESHOLD + 5);
|
|
53
|
+
for (const forwardButton of mockForwardButtons) {
|
|
54
|
+
expect(forwardButton).toHaveAttribute('disabled', 'true');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
it('should enable forward buttons if timeShift <= TIME_SHIFT_THRESHOLD', () => {
|
|
58
|
+
for (const button of mockForwardButtons)
|
|
59
|
+
button.setAttribute('disabled', 'true');
|
|
60
|
+
toggleForwardButtons(mockForwardButtons, TIME_SHIFT_THRESHOLD - 5);
|
|
61
|
+
for (const forwardButton of mockForwardButtons) {
|
|
62
|
+
expect(forwardButton).toBeEnabled();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LocalStorageData, LocalStorageValues, PlayerContext } from 'types/interfaces';
|
|
1
|
+
import { LocalStorageData, LocalStorageValues, PlayerContext } from '../../types/interfaces';
|
|
2
2
|
export declare function setLocalStorage(key: LocalStorageValues, value: any): void;
|
|
3
3
|
export declare function getLocalStorage(): LocalStorageData;
|
|
4
4
|
export declare function setValuesBasedOnLocalStorage(playerContext: PlayerContext): void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AdBreak, AdConfig, PlayerAPI, PlayerConfig, SourceConfig, TimeMode, ViewMode } from 'bitmovin-player';
|
|
2
|
+
import { UIManager } from 'bitmovin-player-ui';
|
|
3
|
+
import { NpoPlayerUIVariants, PlayerContext, Technology } from 'types/interfaces';
|
|
4
|
+
import { NpoPlayerEventCallback, NpoPlayerEvent } from '../../types/events';
|
|
3
5
|
export declare class NpoPlayerAPI {
|
|
4
6
|
playerAPI: PlayerAPI;
|
|
5
7
|
constructor(playerAPI: PlayerAPI);
|
|
@@ -10,21 +12,31 @@ export declare class NpoPlayerAPI {
|
|
|
10
12
|
unmute(): void;
|
|
11
13
|
getVolume(): number;
|
|
12
14
|
setVolume(level: number): void;
|
|
15
|
+
increaseVolume(): void;
|
|
16
|
+
decreaseVolume(): void;
|
|
13
17
|
setViewMode(viewMode: ViewMode): void;
|
|
14
18
|
getViewMode(): ViewMode;
|
|
15
19
|
areSubtitlesEnabled(): boolean;
|
|
16
20
|
enableSubtitles(): void;
|
|
17
21
|
isPaused(): boolean;
|
|
18
22
|
isMuted(): boolean;
|
|
23
|
+
isLive(): boolean;
|
|
19
24
|
getSupportedDRM(): Promise<string[]>;
|
|
20
25
|
getSupportedTech(): Technology[];
|
|
21
|
-
off(eventType:
|
|
22
|
-
on(eventType:
|
|
26
|
+
off(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
|
|
27
|
+
on(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
|
|
23
28
|
seek(time: number): void;
|
|
29
|
+
timeShift(time: number): void;
|
|
24
30
|
getContainer(): HTMLElement;
|
|
25
31
|
getNpoPlayerElement(): Element | null;
|
|
26
32
|
addClassToNpoPlayerElement(className: string): void | undefined;
|
|
27
33
|
removeClassFromNpoPlayerElement(className: string): void | undefined;
|
|
34
|
+
toggleClassOnNpoPlayerElement(className: string, toggle: boolean): void | undefined;
|
|
28
35
|
getCurrentTime(mode?: TimeMode | undefined): number;
|
|
36
|
+
getDuration(): number;
|
|
29
37
|
getTimeShift(): number;
|
|
38
|
+
scheduleAds(adConfig: AdConfig): Promise<AdBreak[]>;
|
|
39
|
+
getActiveAdBreak(): AdBreak | null;
|
|
40
|
+
getConfig(mergedConfig?: boolean): PlayerConfig;
|
|
41
|
+
createUIManager(playerContext: PlayerContext, variant: NpoPlayerUIVariants): Promise<void | UIManager>;
|
|
30
42
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { UIManager } from 'bitmovin-player-ui';
|
|
2
|
+
import { customSpecificErrorMessageOverlayConfig } from '../../js/playeractions/handlers/customerrors';
|
|
3
|
+
import { processStream } from '../../ui/handlers/streamhandler';
|
|
4
|
+
import { createUIContainer } from '../../ui/uicontainer';
|
|
5
|
+
import { playerEventMap } from '../../types/events';
|
|
6
|
+
import { VOLUME_MAX, VOLUME_MIN, VOLUME_STEP } from './contants';
|
|
7
|
+
const externalCallbacksMap = new WeakMap();
|
|
1
8
|
export class NpoPlayerAPI {
|
|
2
9
|
constructor(playerAPI) {
|
|
3
10
|
this.playerAPI = playerAPI;
|
|
@@ -21,7 +28,16 @@ export class NpoPlayerAPI {
|
|
|
21
28
|
return this.playerAPI.getVolume();
|
|
22
29
|
}
|
|
23
30
|
setVolume(level) {
|
|
24
|
-
|
|
31
|
+
const volume = Math.max(VOLUME_MIN, Math.min(VOLUME_MAX, level));
|
|
32
|
+
this.playerAPI.setVolume(volume);
|
|
33
|
+
}
|
|
34
|
+
increaseVolume() {
|
|
35
|
+
const currentVolume = this.getVolume();
|
|
36
|
+
this.setVolume(currentVolume + VOLUME_STEP);
|
|
37
|
+
}
|
|
38
|
+
decreaseVolume() {
|
|
39
|
+
const currentVolume = this.getVolume();
|
|
40
|
+
this.setVolume(currentVolume - VOLUME_STEP);
|
|
25
41
|
}
|
|
26
42
|
setViewMode(viewMode) {
|
|
27
43
|
this.playerAPI.setViewMode(viewMode);
|
|
@@ -55,6 +71,9 @@ export class NpoPlayerAPI {
|
|
|
55
71
|
isMuted() {
|
|
56
72
|
return this.playerAPI.isMuted();
|
|
57
73
|
}
|
|
74
|
+
isLive() {
|
|
75
|
+
return this.playerAPI.isLive();
|
|
76
|
+
}
|
|
58
77
|
async getSupportedDRM() {
|
|
59
78
|
return (await this.playerAPI.getSupportedDRM());
|
|
60
79
|
}
|
|
@@ -62,14 +81,30 @@ export class NpoPlayerAPI {
|
|
|
62
81
|
return this.playerAPI.getSupportedTech();
|
|
63
82
|
}
|
|
64
83
|
off(eventType, callback) {
|
|
65
|
-
|
|
84
|
+
const externalEventType = playerEventMap[eventType];
|
|
85
|
+
const externalCallback = externalCallbacksMap.get(callback);
|
|
86
|
+
if (externalCallback) {
|
|
87
|
+
this.playerAPI.off(externalEventType, externalCallback);
|
|
88
|
+
externalCallbacksMap.delete(callback);
|
|
89
|
+
}
|
|
66
90
|
}
|
|
67
91
|
on(eventType, callback) {
|
|
68
|
-
|
|
92
|
+
const externalEventType = playerEventMap[eventType];
|
|
93
|
+
let externalCallback = externalCallbacksMap.get(callback);
|
|
94
|
+
if (!externalCallback) {
|
|
95
|
+
externalCallback = (args) => {
|
|
96
|
+
callback(args);
|
|
97
|
+
};
|
|
98
|
+
externalCallbacksMap.set(callback, externalCallback);
|
|
99
|
+
}
|
|
100
|
+
this.playerAPI.on(externalEventType, externalCallback);
|
|
69
101
|
}
|
|
70
102
|
seek(time) {
|
|
71
103
|
this.playerAPI.seek(time);
|
|
72
104
|
}
|
|
105
|
+
timeShift(time) {
|
|
106
|
+
this.playerAPI.timeShift(time);
|
|
107
|
+
}
|
|
73
108
|
getContainer() {
|
|
74
109
|
return this.playerAPI.getContainer();
|
|
75
110
|
}
|
|
@@ -82,10 +117,37 @@ export class NpoPlayerAPI {
|
|
|
82
117
|
removeClassFromNpoPlayerElement(className) {
|
|
83
118
|
this.getNpoPlayerElement()?.classList.remove(className);
|
|
84
119
|
}
|
|
120
|
+
toggleClassOnNpoPlayerElement(className, toggle) {
|
|
121
|
+
this.getNpoPlayerElement()?.classList.toggle(className, toggle);
|
|
122
|
+
}
|
|
85
123
|
getCurrentTime(mode) {
|
|
86
124
|
return this.playerAPI.getCurrentTime(mode);
|
|
87
125
|
}
|
|
126
|
+
getDuration() {
|
|
127
|
+
return this.playerAPI.getDuration();
|
|
128
|
+
}
|
|
88
129
|
getTimeShift() {
|
|
89
130
|
return this.playerAPI.getTimeShift();
|
|
90
131
|
}
|
|
132
|
+
async scheduleAds(adConfig) {
|
|
133
|
+
return this.playerAPI.ads.schedule(adConfig);
|
|
134
|
+
}
|
|
135
|
+
getActiveAdBreak() {
|
|
136
|
+
return this.playerAPI.ads.getActiveAdBreak();
|
|
137
|
+
}
|
|
138
|
+
getConfig(mergedConfig) {
|
|
139
|
+
return this.playerAPI.getConfig(mergedConfig);
|
|
140
|
+
}
|
|
141
|
+
async createUIManager(playerContext, variant) {
|
|
142
|
+
if (playerContext.npoplayer.uiManager === undefined || variant !== playerContext.npoplayer.variant) {
|
|
143
|
+
const uiConfig = {
|
|
144
|
+
errorMessages: customSpecificErrorMessageOverlayConfig,
|
|
145
|
+
disableAutoHideWhenHovered: true,
|
|
146
|
+
seekbarSnappingEnabled: false
|
|
147
|
+
};
|
|
148
|
+
playerContext.npoplayer.uiManager = new UIManager(this.playerAPI, createUIContainer(playerContext.npoplayer, this.playerAPI, variant, playerContext.npoplayer.container), uiConfig);
|
|
149
|
+
playerContext.npoplayer.variant = variant;
|
|
150
|
+
}
|
|
151
|
+
processStream(playerContext);
|
|
152
|
+
}
|
|
91
153
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { NpoPlayerAPI } from './npoPlayerAPI';
|
|
2
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
3
|
+
import { NpoPlayerEvent } from '../../types/events';
|
|
2
4
|
describe('NpoPlayerAPI', () => {
|
|
3
5
|
let mockPlayerAPI;
|
|
4
6
|
let npoPlayerAPI;
|
|
@@ -11,7 +13,9 @@ describe('NpoPlayerAPI', () => {
|
|
|
11
13
|
setViewMode: jest.fn(),
|
|
12
14
|
getViewMode: jest.fn(),
|
|
13
15
|
isPaused: jest.fn(),
|
|
14
|
-
isMuted: jest.fn()
|
|
16
|
+
isMuted: jest.fn(),
|
|
17
|
+
on: jest.fn(),
|
|
18
|
+
off: jest.fn()
|
|
15
19
|
};
|
|
16
20
|
npoPlayerAPI = new NpoPlayerAPI(mockPlayerAPI);
|
|
17
21
|
});
|
|
@@ -48,4 +52,65 @@ describe('NpoPlayerAPI', () => {
|
|
|
48
52
|
npoPlayerAPI.isMuted();
|
|
49
53
|
expect(mockPlayerAPI.isMuted).toHaveBeenCalled();
|
|
50
54
|
});
|
|
55
|
+
describe('NpoPlayerAPI Volume Control Tests', () => {
|
|
56
|
+
let playerContextMock;
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
playerContextMock = createPlayerContextMock();
|
|
59
|
+
playerContextMock.player.setVolume(50);
|
|
60
|
+
});
|
|
61
|
+
test('should set volume to a specific value', () => {
|
|
62
|
+
playerContextMock.player.setVolume(30);
|
|
63
|
+
expect(playerContextMock.player.getVolume()).toBe(30);
|
|
64
|
+
});
|
|
65
|
+
test('should not set volume above the maximum', () => {
|
|
66
|
+
playerContextMock.player.setVolume(110);
|
|
67
|
+
expect(playerContextMock.player.getVolume()).toBe(100);
|
|
68
|
+
});
|
|
69
|
+
test('should not set volume below the minimum', () => {
|
|
70
|
+
playerContextMock.player.setVolume(-10);
|
|
71
|
+
expect(playerContextMock.player.getVolume()).toBe(0);
|
|
72
|
+
});
|
|
73
|
+
test('should increase volume by 10', () => {
|
|
74
|
+
playerContextMock.player.increaseVolume();
|
|
75
|
+
expect(playerContextMock.player.getVolume()).toBe(60);
|
|
76
|
+
});
|
|
77
|
+
test('should not increase volume above the maximum', () => {
|
|
78
|
+
playerContextMock.player.setVolume(95);
|
|
79
|
+
playerContextMock.player.increaseVolume();
|
|
80
|
+
expect(playerContextMock.player.getVolume()).toBe(100);
|
|
81
|
+
});
|
|
82
|
+
test('should decrease volume by 10', () => {
|
|
83
|
+
playerContextMock.player.decreaseVolume();
|
|
84
|
+
expect(playerContextMock.player.getVolume()).toBe(40);
|
|
85
|
+
});
|
|
86
|
+
test('should not decrease volume below the minimum', () => {
|
|
87
|
+
playerContextMock.player.setVolume(5);
|
|
88
|
+
playerContextMock.player.decreaseVolume();
|
|
89
|
+
expect(playerContextMock.player.getVolume()).toBe(0);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe('Event handling', () => {
|
|
93
|
+
it('should add an event listener', () => {
|
|
94
|
+
const eventType = NpoPlayerEvent.TimeChanged;
|
|
95
|
+
const callback = jest.fn();
|
|
96
|
+
npoPlayerAPI.on(eventType, callback);
|
|
97
|
+
expect(mockPlayerAPI.on).toHaveBeenCalledWith(expect.any(String), expect.any(Function));
|
|
98
|
+
});
|
|
99
|
+
it('should remove an event listener', () => {
|
|
100
|
+
const eventType = NpoPlayerEvent.TimeChanged;
|
|
101
|
+
const callback = jest.fn();
|
|
102
|
+
npoPlayerAPI.on(eventType, callback);
|
|
103
|
+
npoPlayerAPI.off(eventType, callback);
|
|
104
|
+
expect(mockPlayerAPI.off).toHaveBeenCalledWith(expect.any(String), expect.any(Function));
|
|
105
|
+
});
|
|
106
|
+
it('should trigger the correct callback when event is emitted', () => {
|
|
107
|
+
const eventType = NpoPlayerEvent.TimeChanged;
|
|
108
|
+
const callback = jest.fn();
|
|
109
|
+
const mockArgs = { time: 123 };
|
|
110
|
+
npoPlayerAPI.on(eventType, callback);
|
|
111
|
+
const externalCallback = mockPlayerAPI.on.mock.calls[0][1];
|
|
112
|
+
externalCallback(mockArgs);
|
|
113
|
+
expect(callback).toHaveBeenCalledWith(mockArgs);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
51
116
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NpoPlayerEvent } from '../../types/events';
|
|
2
2
|
import { handleSegmentTimeChanged } from './handleSegmentTimeChanged';
|
|
3
3
|
import { handleSegmentSeek } from './handleSegmentSeek';
|
|
4
4
|
export const addSegmentEventListeners = (playerContext, segment) => {
|
|
5
5
|
const segmentHandleTimeChangedCallback = handleSegmentTimeChanged(playerContext, segment);
|
|
6
6
|
const segmentSeekFunctionCallback = handleSegmentSeek(playerContext, segment);
|
|
7
7
|
const { player, npoplayer } = playerContext;
|
|
8
|
-
player.on(
|
|
9
|
-
player.on(
|
|
8
|
+
player.on(NpoPlayerEvent.TimeChanged, segmentHandleTimeChangedCallback);
|
|
9
|
+
player.on(NpoPlayerEvent.Seek, segmentSeekFunctionCallback);
|
|
10
10
|
npoplayer.eventListeners = {
|
|
11
11
|
segmentHandleTimeChangedCallback,
|
|
12
12
|
segmentSeekFunctionCallback
|
|
@@ -2,7 +2,7 @@ import { PlayerEvent } from 'bitmovin-player';
|
|
|
2
2
|
import { addSegmentEventListeners } from './addSegmentEventListeners';
|
|
3
3
|
import { handleSegmentTimeChanged } from './handleSegmentTimeChanged';
|
|
4
4
|
import { handleSegmentSeek } from './handleSegmentSeek';
|
|
5
|
-
import
|
|
5
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
6
6
|
jest.mock('./handleSegmentTimeChanged', () => ({
|
|
7
7
|
handleSegmentTimeChanged: jest.fn()
|
|
8
8
|
}));
|
|
@@ -10,32 +10,33 @@ jest.mock('./handleSegmentSeek', () => ({
|
|
|
10
10
|
handleSegmentSeek: jest.fn()
|
|
11
11
|
}));
|
|
12
12
|
describe('addSegmentEventListeners', () => {
|
|
13
|
+
let mockPlayerContext;
|
|
13
14
|
const segment = { inpoint: 10, outpoint: 20, duration: 10 };
|
|
14
|
-
const context = { ...mockPlayerContext };
|
|
15
15
|
beforeEach(() => {
|
|
16
16
|
jest.clearAllMocks();
|
|
17
|
+
mockPlayerContext = createPlayerContextMock();
|
|
17
18
|
});
|
|
18
19
|
it('should add TimeChanged event listener', () => {
|
|
19
20
|
const segmentHandleTimeChangedCallback = jest.fn();
|
|
20
21
|
handleSegmentTimeChanged.mockReturnValue(segmentHandleTimeChangedCallback);
|
|
21
|
-
addSegmentEventListeners(
|
|
22
|
-
expect(
|
|
23
|
-
expect(handleSegmentTimeChanged).toHaveBeenCalledWith(
|
|
22
|
+
addSegmentEventListeners(mockPlayerContext, segment);
|
|
23
|
+
expect(mockPlayerContext.player.on).toHaveBeenCalledWith(PlayerEvent.TimeChanged, segmentHandleTimeChangedCallback);
|
|
24
|
+
expect(handleSegmentTimeChanged).toHaveBeenCalledWith(mockPlayerContext, segment);
|
|
24
25
|
});
|
|
25
26
|
it('should add Seek event listener', () => {
|
|
26
27
|
const segmentSeekFunctionCallback = jest.fn();
|
|
27
28
|
handleSegmentSeek.mockReturnValue(segmentSeekFunctionCallback);
|
|
28
29
|
addSegmentEventListeners(mockPlayerContext, segment);
|
|
29
|
-
expect(
|
|
30
|
-
expect(handleSegmentSeek).toHaveBeenCalledWith(
|
|
30
|
+
expect(mockPlayerContext.player.on).toHaveBeenCalledWith(PlayerEvent.Seek, segmentSeekFunctionCallback);
|
|
31
|
+
expect(handleSegmentSeek).toHaveBeenCalledWith(mockPlayerContext, segment);
|
|
31
32
|
});
|
|
32
33
|
it('should set segmentEventListeners in playerContext', () => {
|
|
33
34
|
const segmentHandleTimeChangedCallback = jest.fn();
|
|
34
35
|
const segmentSeekFunctionCallback = jest.fn();
|
|
35
36
|
handleSegmentTimeChanged.mockReturnValue(segmentHandleTimeChangedCallback);
|
|
36
37
|
handleSegmentSeek.mockReturnValue(segmentSeekFunctionCallback);
|
|
37
|
-
addSegmentEventListeners(
|
|
38
|
-
expect(
|
|
38
|
+
addSegmentEventListeners(mockPlayerContext, segment);
|
|
39
|
+
expect(mockPlayerContext.npoplayer.eventListeners).toEqual({
|
|
39
40
|
segmentHandleTimeChangedCallback,
|
|
40
41
|
segmentSeekFunctionCallback
|
|
41
42
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Fragment, Segment } from 'types/interfaces';
|
|
1
|
+
import { Fragment, Segment } from '../../types/interfaces';
|
|
2
2
|
export declare function convertFragmentToSegment(fragment: Fragment): Segment;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlayerContext, Segment } from 'types/interfaces';
|
|
1
|
+
import { PlayerContext, Segment } from '../../types/interfaces';
|
|
2
2
|
export declare const handleSegmentSeek: (playerContext: PlayerContext, segment: Segment) => (e: any) => void;
|
|
3
3
|
export declare const getSeekTarget: (event: any) => number;
|
|
4
4
|
export declare const isSeekOutsideSegment: (seekTarget: number, segment: Segment) => boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { handleSegmentSeek, getSeekTarget, isSeekOutsideSegment, clampSeekTarget } from './handleSegmentSeek';
|
|
2
|
-
import
|
|
3
|
-
describe('
|
|
2
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
3
|
+
describe('handleSegmentSeek', () => {
|
|
4
4
|
const SEGMENT_INPOINT = 500;
|
|
5
5
|
const SEGMENT_OUTPOINT = 1500;
|
|
6
6
|
const SEGMENT_DURATION = 1000;
|
|
@@ -8,14 +8,14 @@ describe('segmentHandler', () => {
|
|
|
8
8
|
const SEEK_TARGET_ABOVE = 1600;
|
|
9
9
|
const SEEK_TARGET_BELOW = 400;
|
|
10
10
|
let segment;
|
|
11
|
+
let mockPlayerContext;
|
|
11
12
|
beforeEach(() => {
|
|
12
13
|
segment = {
|
|
13
14
|
inpoint: SEGMENT_INPOINT,
|
|
14
15
|
outpoint: SEGMENT_OUTPOINT,
|
|
15
16
|
duration: SEGMENT_DURATION
|
|
16
17
|
};
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
18
|
+
mockPlayerContext = createPlayerContextMock();
|
|
19
19
|
jest.clearAllMocks();
|
|
20
20
|
});
|
|
21
21
|
describe('getSeekTarget', () => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { PlayerContext, Segment } from 'types/interfaces';
|
|
1
|
+
import { PlayerContext, Segment } from '../../types/interfaces';
|
|
2
2
|
export declare const handleSegmentTimeChanged: (playerContext: PlayerContext, segment: Segment) => (e: any) => void;
|
|
@@ -1,34 +1,43 @@
|
|
|
1
|
-
import { mockPlayerContext } from '../../../tests/mocks/mockPlayerContext';
|
|
2
1
|
import { handleSegmentTimeChanged } from './handleSegmentTimeChanged';
|
|
2
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
3
3
|
describe('handleSegmentTimeChanged', () => {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
let mockPlayerContext;
|
|
5
|
+
let mockSegment;
|
|
6
|
+
const INPOINT = 10;
|
|
7
|
+
const OUTPOINT = 20;
|
|
6
8
|
beforeEach(() => {
|
|
7
9
|
jest.clearAllMocks();
|
|
10
|
+
mockPlayerContext = createPlayerContextMock();
|
|
11
|
+
mockSegment = { inpoint: INPOINT, outpoint: OUTPOINT, duration: OUTPOINT - INPOINT };
|
|
8
12
|
});
|
|
9
|
-
it('should seek
|
|
10
|
-
const
|
|
11
|
-
handler
|
|
12
|
-
|
|
13
|
-
expect(
|
|
14
|
-
expect(
|
|
13
|
+
it('should seek to inpoint and pause when time is greater than outpoint', () => {
|
|
14
|
+
const event = { time: OUTPOINT + 1 };
|
|
15
|
+
const handler = handleSegmentTimeChanged(mockPlayerContext, mockSegment);
|
|
16
|
+
handler(event);
|
|
17
|
+
expect(mockPlayerContext.player.seek).toHaveBeenCalledWith(Math.max(INPOINT, OUTPOINT));
|
|
18
|
+
expect(mockPlayerContext.player.pause).toHaveBeenCalled();
|
|
19
|
+
expect(mockPlayerContext.player.addClassToNpoPlayerElement).toHaveBeenCalledWith('bmpui-player-state-replay');
|
|
15
20
|
});
|
|
16
|
-
it('should
|
|
17
|
-
const
|
|
18
|
-
handler
|
|
19
|
-
handler(
|
|
20
|
-
expect(
|
|
21
|
+
it('should seek to inpoint when time is less than inpoint', () => {
|
|
22
|
+
const event = { time: INPOINT - 1 };
|
|
23
|
+
const handler = handleSegmentTimeChanged(mockPlayerContext, mockSegment);
|
|
24
|
+
handler(event);
|
|
25
|
+
expect(mockPlayerContext.player.seek).toHaveBeenCalledWith(INPOINT);
|
|
21
26
|
});
|
|
22
|
-
it('should
|
|
23
|
-
const
|
|
24
|
-
handler
|
|
25
|
-
handler(
|
|
26
|
-
|
|
27
|
+
it('should seek to inpoint when time is greater than outpoint and isFinished is true', () => {
|
|
28
|
+
const event = { time: OUTPOINT + 1 };
|
|
29
|
+
const handler = handleSegmentTimeChanged(mockPlayerContext, mockSegment);
|
|
30
|
+
handler(event);
|
|
31
|
+
handler({ time: INPOINT - 1 });
|
|
32
|
+
handler(event);
|
|
33
|
+
expect(mockPlayerContext.player.seek).toHaveBeenCalledWith(INPOINT);
|
|
27
34
|
});
|
|
28
|
-
it('should not
|
|
29
|
-
const
|
|
30
|
-
handler
|
|
31
|
-
|
|
32
|
-
expect(
|
|
35
|
+
it('should not seek or pause when time is between inpoint and outpoint', () => {
|
|
36
|
+
const event = { time: (INPOINT + OUTPOINT) / 2 };
|
|
37
|
+
const handler = handleSegmentTimeChanged(mockPlayerContext, mockSegment);
|
|
38
|
+
handler(event);
|
|
39
|
+
expect(mockPlayerContext.player.seek).not.toHaveBeenCalled();
|
|
40
|
+
expect(mockPlayerContext.player.pause).not.toHaveBeenCalled();
|
|
41
|
+
expect(mockPlayerContext.player.addClassToNpoPlayerElement).not.toHaveBeenCalled();
|
|
33
42
|
});
|
|
34
43
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { initSegment } from './initSegment';
|
|
2
2
|
import { addSegmentEventListeners } from './addSegmentEventListeners';
|
|
3
3
|
import { convertFragmentToSegment } from './convertFragmentToSegment';
|
|
4
|
-
import
|
|
4
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
5
5
|
jest.mock('./addSegmentEventListeners');
|
|
6
6
|
jest.mock('./convertFragmentToSegment');
|
|
7
7
|
const createMockSegment = () => ({ inpoint: 10, outpoint: 20, duration: 10 });
|
|
@@ -9,8 +9,10 @@ const createMockFragment = () => ({
|
|
|
9
9
|
sections: [{ time: 0, duration: 10, title: 'Dummy fragment' }]
|
|
10
10
|
});
|
|
11
11
|
describe('initSegment', () => {
|
|
12
|
+
let mockPlayerContext;
|
|
12
13
|
beforeEach(() => {
|
|
13
14
|
jest.clearAllMocks();
|
|
15
|
+
mockPlayerContext = createPlayerContextMock();
|
|
14
16
|
});
|
|
15
17
|
it('should convert fragment to segment and seek to inpoint', () => {
|
|
16
18
|
const mockFragment = createMockFragment();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Segment, TimeLineMarker } from 'types/interfaces';
|
|
1
|
+
import { Segment, TimeLineMarker } from '../../types/interfaces';
|
|
2
2
|
export declare function setSegmentMarkers(segment: Segment, title: string): Array<TimeLineMarker>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiPayload, Fragment, PlayerContext, Profile, Segment, TimeLineMarker, LocalStorageData, LocalStorageValues } from 'types/interfaces';
|
|
1
|
+
import { ApiPayload, Fragment, PlayerContext, Profile, Segment, TimeLineMarker, LocalStorageData, LocalStorageValues, NpoPlayerUIVariants } from '../types/interfaces';
|
|
2
2
|
import { AVType } from '@npotag/tag/dist/types/src/streamTracker';
|
|
3
3
|
export declare class NpoPlayerServices {
|
|
4
4
|
getAVType(avType: string): AVType;
|
|
@@ -11,4 +11,6 @@ export declare class NpoPlayerServices {
|
|
|
11
11
|
getStoredUserPrefs(): LocalStorageData;
|
|
12
12
|
handleUserPrefs(playerContext: PlayerContext): void;
|
|
13
13
|
setAccessibilityAttributes(playerContext: PlayerContext): void;
|
|
14
|
+
schedulePreRolls(playerContext: PlayerContext): Promise<void>;
|
|
15
|
+
handleVerticalVideoControls(playerContext: PlayerContext, variant: NpoPlayerUIVariants): void;
|
|
14
16
|
}
|
package/lib/services/services.js
CHANGED
|
@@ -5,6 +5,8 @@ import * as DRMHandlers from './drmHandlers/drmhandlers';
|
|
|
5
5
|
import { setupAccessibilityAttributes } from './a11y/setup';
|
|
6
6
|
import { getLocalStorage, setLocalStorage, setValuesBasedOnLocalStorage } from './localStorageHandlers/localStorageHandlers';
|
|
7
7
|
import { getAVType } from './avTypeHandlers/getAVType';
|
|
8
|
+
import { handlePreRolls } from './advertHandlers/handlePreRolls';
|
|
9
|
+
import { handleVerticalVideoControls } from './verticalVideoHandlers/handleVerticalVideoControls';
|
|
8
10
|
export class NpoPlayerServices {
|
|
9
11
|
getAVType(avType) {
|
|
10
12
|
return getAVType(avType);
|
|
@@ -44,4 +46,10 @@ export class NpoPlayerServices {
|
|
|
44
46
|
}
|
|
45
47
|
return setupAccessibilityAttributes(playerContext);
|
|
46
48
|
}
|
|
49
|
+
async schedulePreRolls(playerContext) {
|
|
50
|
+
await handlePreRolls(playerContext);
|
|
51
|
+
}
|
|
52
|
+
handleVerticalVideoControls(playerContext, variant) {
|
|
53
|
+
return handleVerticalVideoControls(playerContext, variant);
|
|
54
|
+
}
|
|
47
55
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
2
|
+
export const handleVerticalVideoControls = (playerContext, variant) => {
|
|
3
|
+
const MAX_DURATION_IN_SECONDS = 30;
|
|
4
|
+
const isShortVideo = playerContext.player.getDuration() <= MAX_DURATION_IN_SECONDS;
|
|
5
|
+
const hasVerticalUI = variant === NpoPlayerUIVariants.VERTICAL;
|
|
6
|
+
const isVerticalShortVideo = hasVerticalUI && isShortVideo;
|
|
7
|
+
playerContext.player.toggleClassOnNpoPlayerElement('vertical-short-video', isVerticalShortVideo);
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
2
|
+
import { handleVerticalVideoControls } from './handleVerticalVideoControls';
|
|
3
|
+
import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
|
|
4
|
+
describe('handleVerticalVideoControls', () => {
|
|
5
|
+
const playerContextMock = createPlayerContextMock();
|
|
6
|
+
const shortVideoClass = 'vertical-short-video';
|
|
7
|
+
const shortVideoDuration = 20;
|
|
8
|
+
const longVideoDuration = 60;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
jest.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
test('should add vertical-short-video class for vertical UI and short video', () => {
|
|
13
|
+
;
|
|
14
|
+
playerContextMock.player.getDuration.mockReturnValue(shortVideoDuration);
|
|
15
|
+
handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.VERTICAL);
|
|
16
|
+
expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, true);
|
|
17
|
+
});
|
|
18
|
+
test('should not add vertical-short-video class for vertical UI and long video', () => {
|
|
19
|
+
;
|
|
20
|
+
playerContextMock.player.getDuration.mockReturnValue(longVideoDuration);
|
|
21
|
+
handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.VERTICAL);
|
|
22
|
+
expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
|
|
23
|
+
});
|
|
24
|
+
test('should not add vertical-short-video class for non-vertical UI and short video', () => {
|
|
25
|
+
;
|
|
26
|
+
playerContextMock.player.getDuration.mockReturnValue(shortVideoDuration);
|
|
27
|
+
handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.DEFAULT);
|
|
28
|
+
expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
|
|
29
|
+
});
|
|
30
|
+
test('should not add vertical-short-video class for non-vertical UI and long video', () => {
|
|
31
|
+
;
|
|
32
|
+
playerContextMock.player.getDuration.mockReturnValue(longVideoDuration);
|
|
33
|
+
handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.DEFAULT);
|
|
34
|
+
expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
|
|
35
|
+
});
|
|
36
|
+
});
|