@outbook/webcomponents-player 1.5.0 → 1.5.1
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/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { isValidTrackIndex } from './is-valid-track-index.js';
|
|
3
|
-
|
|
4
|
-
const playlist = [{ file: '/audio/valid.mp3' }, { file: '/audio/other.mp3' }];
|
|
5
|
-
|
|
6
|
-
describe('isValidTrackIndex', () => {
|
|
7
|
-
it('accepts an in-range integer for a track with an audio file', () => {
|
|
8
|
-
expect(isValidTrackIndex({ index: 1, playlist })).toBe(true);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it.each([-1, 2, 0.5, '0', NaN])('rejects an invalid index: %s', index => {
|
|
12
|
-
expect(isValidTrackIndex({ index, playlist })).toBe(false);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it.each([undefined, null, '', ' ', 42])(
|
|
16
|
-
'rejects a track without a valid audio file: %s',
|
|
17
|
-
file => {
|
|
18
|
-
expect(isValidTrackIndex({ index: 0, playlist: [{ file }] })).toBe(false);
|
|
19
|
-
}
|
|
20
|
-
);
|
|
21
|
-
});
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
clearMediaSession,
|
|
4
|
-
setupMediaSession,
|
|
5
|
-
syncMediaSession
|
|
6
|
-
} from './setup-media-session.js';
|
|
7
|
-
|
|
8
|
-
const originalMediaSession = navigator.mediaSession;
|
|
9
|
-
const originalMediaMetadata = globalThis.MediaMetadata;
|
|
10
|
-
const MEDIA_SESSION_ACTIONS = [
|
|
11
|
-
'play',
|
|
12
|
-
'pause',
|
|
13
|
-
'stop',
|
|
14
|
-
'nexttrack',
|
|
15
|
-
'previoustrack'
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
function createMediaSessionSpy() {
|
|
19
|
-
const actionHandlers = new Map();
|
|
20
|
-
return {
|
|
21
|
-
actionHandlers,
|
|
22
|
-
mediaSession: {
|
|
23
|
-
setActionHandler: vi.fn((action, handler) => {
|
|
24
|
-
actionHandlers.set(action, handler);
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
Object.defineProperty(navigator, 'mediaSession', {
|
|
32
|
-
configurable: true,
|
|
33
|
-
value: originalMediaSession
|
|
34
|
-
});
|
|
35
|
-
globalThis.MediaMetadata = originalMediaMetadata;
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('setupMediaSession', () => {
|
|
39
|
-
it('does not change Media Session for an invalid track selection', () => {
|
|
40
|
-
const { mediaSession } = createMediaSessionSpy();
|
|
41
|
-
Object.defineProperty(navigator, 'mediaSession', {
|
|
42
|
-
configurable: true,
|
|
43
|
-
value: mediaSession
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
expect(
|
|
47
|
-
setupMediaSession({
|
|
48
|
-
owner: Symbol('player-owner'),
|
|
49
|
-
index: 0,
|
|
50
|
-
playlist: [{ file: '' }],
|
|
51
|
-
handleAudio: {}
|
|
52
|
-
})
|
|
53
|
-
).toBe(false);
|
|
54
|
-
expect(mediaSession.setActionHandler).not.toHaveBeenCalled();
|
|
55
|
-
expect(mediaSession.metadata).toBeUndefined();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('configures Media Session for a valid track selection', () => {
|
|
59
|
-
const { mediaSession } = createMediaSessionSpy();
|
|
60
|
-
Object.defineProperty(navigator, 'mediaSession', {
|
|
61
|
-
configurable: true,
|
|
62
|
-
value: mediaSession
|
|
63
|
-
});
|
|
64
|
-
globalThis.MediaMetadata = class MediaMetadata {
|
|
65
|
-
constructor(metadata) {
|
|
66
|
-
Object.assign(this, metadata);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
expect(
|
|
71
|
-
setupMediaSession({
|
|
72
|
-
owner: Symbol('player-owner'),
|
|
73
|
-
index: 0,
|
|
74
|
-
playlist: [{ file: '/audio/valid.mp3', title: 'Valid track' }],
|
|
75
|
-
handleAudio: {
|
|
76
|
-
next: vi.fn(),
|
|
77
|
-
previous: vi.fn(),
|
|
78
|
-
play: vi.fn(),
|
|
79
|
-
pause: vi.fn(),
|
|
80
|
-
stop: vi.fn()
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
).toBe(true);
|
|
84
|
-
expect(mediaSession.metadata.title).toBe('Valid track');
|
|
85
|
-
expect(mediaSession.setActionHandler).toHaveBeenCalledTimes(5);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('only lets the owning player clear Media Session handlers', () => {
|
|
89
|
-
const { actionHandlers, mediaSession } = createMediaSessionSpy();
|
|
90
|
-
const firstOwner = Symbol('first-player');
|
|
91
|
-
const secondOwner = Symbol('second-player');
|
|
92
|
-
const firstHandleAudio = {
|
|
93
|
-
next: vi.fn(),
|
|
94
|
-
previous: vi.fn(),
|
|
95
|
-
play: vi.fn(),
|
|
96
|
-
pause: vi.fn(),
|
|
97
|
-
stop: vi.fn()
|
|
98
|
-
};
|
|
99
|
-
const secondHandleAudio = {
|
|
100
|
-
next: vi.fn(),
|
|
101
|
-
previous: vi.fn(),
|
|
102
|
-
play: vi.fn(),
|
|
103
|
-
pause: vi.fn(),
|
|
104
|
-
stop: vi.fn()
|
|
105
|
-
};
|
|
106
|
-
Object.defineProperty(navigator, 'mediaSession', {
|
|
107
|
-
configurable: true,
|
|
108
|
-
value: mediaSession
|
|
109
|
-
});
|
|
110
|
-
globalThis.MediaMetadata = class MediaMetadata {
|
|
111
|
-
constructor(metadata) {
|
|
112
|
-
Object.assign(this, metadata);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
setupMediaSession({
|
|
117
|
-
owner: firstOwner,
|
|
118
|
-
index: 0,
|
|
119
|
-
playlist: [{ file: '/audio/first.mp3', title: 'First track' }],
|
|
120
|
-
handleAudio: firstHandleAudio
|
|
121
|
-
});
|
|
122
|
-
setupMediaSession({
|
|
123
|
-
owner: secondOwner,
|
|
124
|
-
index: 0,
|
|
125
|
-
playlist: [{ file: '/audio/second.mp3', title: 'Second track' }],
|
|
126
|
-
handleAudio: secondHandleAudio
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
expect(clearMediaSession({ owner: firstOwner })).toBe(false);
|
|
130
|
-
expect(mediaSession.metadata.title).toBe('Second track');
|
|
131
|
-
expect(actionHandlers.get('play')).toBe(secondHandleAudio.play);
|
|
132
|
-
|
|
133
|
-
expect(clearMediaSession({ owner: secondOwner })).toBe(true);
|
|
134
|
-
expect(mediaSession.metadata).toBeNull();
|
|
135
|
-
MEDIA_SESSION_ACTIONS.forEach(action => {
|
|
136
|
-
expect(actionHandlers.get(action)).toBeNull();
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('returns unmount cleanup that clears the owning player session', () => {
|
|
141
|
-
const { actionHandlers, mediaSession } = createMediaSessionSpy();
|
|
142
|
-
const owner = Symbol('player-owner');
|
|
143
|
-
Object.defineProperty(navigator, 'mediaSession', {
|
|
144
|
-
configurable: true,
|
|
145
|
-
value: mediaSession
|
|
146
|
-
});
|
|
147
|
-
globalThis.MediaMetadata = class MediaMetadata {
|
|
148
|
-
constructor(metadata) {
|
|
149
|
-
Object.assign(this, metadata);
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const cleanup = syncMediaSession({
|
|
154
|
-
owner,
|
|
155
|
-
index: 0,
|
|
156
|
-
playlist: [{ file: '/audio/track.mp3', title: 'Track to clean up' }],
|
|
157
|
-
handleAudio: {
|
|
158
|
-
next: vi.fn(),
|
|
159
|
-
previous: vi.fn(),
|
|
160
|
-
play: vi.fn(),
|
|
161
|
-
pause: vi.fn(),
|
|
162
|
-
stop: vi.fn()
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
expect(mediaSession.metadata.title).toBe('Track to clean up');
|
|
167
|
-
|
|
168
|
-
cleanup();
|
|
169
|
-
|
|
170
|
-
expect(clearMediaSession({ owner })).toBe(false);
|
|
171
|
-
expect(mediaSession.metadata).toBeNull();
|
|
172
|
-
MEDIA_SESSION_ACTIONS.forEach(action => {
|
|
173
|
-
expect(actionHandlers.get(action)).toBeNull();
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
});
|