Skip to content

Commit ef759f5

Browse files
committed
async mediaCapabilities
1 parent 78539e5 commit ef759f5

File tree

2 files changed

+94
-58
lines changed

2 files changed

+94
-58
lines changed

media-capabilities/index.js

+26-14
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,35 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
import { useState, useEffect } from 'react';
17+
18+
const supported = typeof window !== 'undefined' && 'mediaCapabilities' in navigator;
1619

1720
const useMediaCapabilities = (mediaConfig, initialMediaCapabilities = {}) => {
18-
let mediaCapabilities = {
19-
supported: typeof window !== 'undefined' && 'mediaCapabilities' in navigator,
20-
hasMediaConfig: !!mediaConfig
21-
}
21+
initialMediaCapabilities = {
22+
supported,
23+
...initialMediaCapabilities
24+
};
25+
26+
const [mediaCapabilities, setMediaCapabilities] = useState(initialMediaCapabilities);
2227

23-
mediaCapabilities = (mediaCapabilities.supported && mediaCapabilities.hasMediaConfig) ?
24-
navigator.mediaCapabilities.decodingInfo(mediaConfig) :
25-
{
26-
...mediaCapabilities,
27-
...initialMediaCapabilities
28-
}
28+
const updateMediaCapabilities = mediaCapabilities => {
29+
setMediaCapabilities(mediaCapabilities);
30+
};
31+
32+
useEffect(() => {
33+
if (supported && !!mediaConfig) {
34+
navigator
35+
.mediaCapabilities
36+
.decodingInfo(mediaConfig)
37+
.then(updateMediaCapabilities);
38+
}
39+
})
2940

30-
return { mediaCapabilities };
41+
return {
42+
...mediaCapabilities,
43+
updateMediaCapabilities
44+
};
3145
};
3246

33-
export {
34-
useMediaCapabilities
35-
};
47+
export { useMediaCapabilities };

media-capabilities/media-capabilities.test.js

+68-44
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { renderHook } from '@testing-library/react-hooks';
18-
19-
import { useMediaCapabilities } from './';
17+
import { renderHook, act } from '@testing-library/react-hooks';
2018

2119
const mediaConfig = {
2220
type: 'file',
@@ -38,58 +36,84 @@ const mediaCapabilitiesMapper = {
3836

3937
describe('useMediaCapabilities', () => {
4038
test('should return supported flag on unsupported platforms', () => {
41-
const { result } = renderHook(() => useMediaCapabilities(mediaConfig));
42-
43-
expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: true, supported: false });
39+
jest.isolateModules(() => {
40+
const { useMediaCapabilities } = require('./');
41+
const { result } = renderHook(() => useMediaCapabilities(mediaConfig));
42+
43+
expect(result.current.supported).toEqual(false);
44+
})
4445
});
45-
46+
4647
test('should return supported and hasMediaConfig flags on unsupported platforms and no config given', () => {
47-
const { result } = renderHook(() => useMediaCapabilities());
48-
49-
expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: false, supported: false });
48+
jest.isolateModules(() => {
49+
const { useMediaCapabilities } = require('./');
50+
const { result } = renderHook(() => useMediaCapabilities());
51+
52+
expect(result.current.supported).toEqual(false);
53+
})
5054
});
51-
55+
5256
test('should return initialMediaCapabilities for unsupported', () => {
53-
const initialMediaCapabilities = {
54-
supported: true,
55-
smooth: false,
56-
powerEfficient: true
57-
};
58-
59-
const { result } = renderHook(() => useMediaCapabilities(mediaConfig, initialMediaCapabilities));
60-
61-
expect(result.current.mediaCapabilities.supported).toBe(true);
62-
expect(result.current.mediaCapabilities.smooth).toEqual(false);
63-
expect(result.current.mediaCapabilities.powerEfficient).toEqual(true);
57+
jest.isolateModules(() => {
58+
const initialMediaCapabilities = {
59+
supported: true,
60+
smooth: false,
61+
powerEfficient: true
62+
};
63+
64+
const { useMediaCapabilities } = require('./');
65+
const { result } = renderHook(() => useMediaCapabilities(mediaConfig, initialMediaCapabilities));
66+
67+
expect(result.current.supported).toBe(true);
68+
expect(result.current.smooth).toEqual(false);
69+
expect(result.current.powerEfficient).toEqual(true);
70+
});
6471
});
65-
72+
6673
test('should return hasMediaConfig flag when no config given', () => {
67-
Object.defineProperty(window.navigator, 'mediaCapabilities', {
68-
value: true,
69-
configurable: true,
70-
writable: true
74+
jest.isolateModules(() => {
75+
global.navigator.mediaCapabilities = true
76+
77+
const { useMediaCapabilities } = require('./');
78+
const { result } = renderHook(() => useMediaCapabilities());
79+
80+
expect(result.current.supported).toEqual(true);
7181
});
72-
73-
const { result } = renderHook(() => useMediaCapabilities());
74-
75-
expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: false, supported: true });
7682
});
7783

7884
test('should return MediaDecodingConfiguration for given media configuration', () => {
79-
Object.defineProperty(window.navigator, 'mediaCapabilities', {
80-
value: {
81-
decodingInfo: (mediaConfig) => mediaCapabilitiesMapper[mediaConfig.audio.contentType]
82-
},
83-
configurable: true,
84-
writable: true
85-
});
85+
jest.isolateModules(() => {
86+
global.navigator.mediaCapabilities = {
87+
decodingInfo: (mediaConfig) => new Promise(resolve => resolve(mediaCapabilitiesMapper[mediaConfig.audio.contentType]))
88+
};
89+
90+
const { useMediaCapabilities } = require('./');
91+
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilities(mediaConfig));
8692

87-
const { result } = renderHook(() => useMediaCapabilities(mediaConfig));
88-
89-
expect(result.current.mediaCapabilities).toEqual({
90-
powerEfficient: true,
91-
smooth: true,
92-
supported: true
93+
waitForNextUpdate().then(() => {
94+
expect(result.current.powerEfficient).toEqual(true);
95+
expect(result.current.smooth).toEqual(true);
96+
expect(result.current.supported).toEqual(true);
97+
});
9398
});
9499
});
100+
101+
test('should update the mediaCapabilities state', () => {
102+
jest.isolateModules(() => {
103+
const { useMediaCapabilities } = require('./');
104+
const { result } = renderHook(() => useMediaCapabilities());
105+
106+
const mockMediaCapabilitiesStatus = {
107+
powerEfficient: false,
108+
smooth: false,
109+
supported: false
110+
};
111+
112+
act(() => result.current.updateMediaCapabilities(mockMediaCapabilitiesStatus));
113+
114+
expect(result.current.powerEfficient).toEqual(mockMediaCapabilitiesStatus.powerEfficient);
115+
expect(result.current.smooth).toEqual(mockMediaCapabilitiesStatus.smooth);
116+
expect(result.current.supported).toEqual(mockMediaCapabilitiesStatus.supported);
117+
});
118+
})
95119
});

0 commit comments

Comments
 (0)