Skip to content

Commit

Permalink
async mediaCapabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
wingleung committed Mar 16, 2020
1 parent 78539e5 commit 58aba42
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 72 deletions.
40 changes: 26 additions & 14 deletions media-capabilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useState, useEffect } from 'react';

const supported = typeof window !== 'undefined' && 'mediaCapabilities' in navigator;

const useMediaCapabilities = (mediaConfig, initialMediaCapabilities = {}) => {
let mediaCapabilities = {
supported: typeof window !== 'undefined' && 'mediaCapabilities' in navigator,
hasMediaConfig: !!mediaConfig
}
initialMediaCapabilities = {
supported,
...initialMediaCapabilities
};

const [mediaCapabilities, setMediaCapabilities] = useState(initialMediaCapabilities);

mediaCapabilities = (mediaCapabilities.supported && mediaCapabilities.hasMediaConfig) ?
navigator.mediaCapabilities.decodingInfo(mediaConfig) :
{
...mediaCapabilities,
...initialMediaCapabilities
}
const updateMediaCapabilities = mediaCapabilities => {
setMediaCapabilities(mediaCapabilities);
};

useEffect(() => {
if (supported && !!mediaConfig) {
navigator
.mediaCapabilities
.decodingInfo(mediaConfig)
.then(updateMediaCapabilities);
}
})

return { mediaCapabilities };
return {
...mediaCapabilities,
updateMediaCapabilities
};
};

export {
useMediaCapabilities
};
export { useMediaCapabilities };
140 changes: 82 additions & 58 deletions media-capabilities/media-capabilities.test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
/*
* Copyright 2019 Google LLC
*
* Licensed 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
*
* https://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 CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019 Google LLC
*
* Licensed 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
*
* https://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 CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { renderHook } from '@testing-library/react-hooks';

import { useMediaCapabilities } from './';
import { renderHook, act } from '@testing-library/react-hooks';

const mediaConfig = {
type: 'file',
Expand All @@ -38,58 +36,84 @@ const mediaCapabilitiesMapper = {

describe('useMediaCapabilities', () => {
test('should return supported flag on unsupported platforms', () => {
const { result } = renderHook(() => useMediaCapabilities(mediaConfig));

expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: true, supported: false });
jest.isolateModules(() => {
const { useMediaCapabilities } = require('./');
const { result } = renderHook(() => useMediaCapabilities(mediaConfig));

expect(result.current.supported).toEqual(false);
})
});

test('should return supported and hasMediaConfig flags on unsupported platforms and no config given', () => {
const { result } = renderHook(() => useMediaCapabilities());

expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: false, supported: false });
jest.isolateModules(() => {
const { useMediaCapabilities } = require('./');
const { result } = renderHook(() => useMediaCapabilities());

expect(result.current.supported).toEqual(false);
})
});

test('should return initialMediaCapabilities for unsupported', () => {
const initialMediaCapabilities = {
supported: true,
smooth: false,
powerEfficient: true
};

const { result } = renderHook(() => useMediaCapabilities(mediaConfig, initialMediaCapabilities));

expect(result.current.mediaCapabilities.supported).toBe(true);
expect(result.current.mediaCapabilities.smooth).toEqual(false);
expect(result.current.mediaCapabilities.powerEfficient).toEqual(true);
jest.isolateModules(() => {
const initialMediaCapabilities = {
supported: true,
smooth: false,
powerEfficient: true
};

const { useMediaCapabilities } = require('./');
const { result } = renderHook(() => useMediaCapabilities(mediaConfig, initialMediaCapabilities));

expect(result.current.supported).toBe(true);
expect(result.current.smooth).toEqual(false);
expect(result.current.powerEfficient).toEqual(true);
});
});

test('should return hasMediaConfig flag when no config given', () => {
Object.defineProperty(window.navigator, 'mediaCapabilities', {
value: true,
configurable: true,
writable: true
jest.isolateModules(() => {
global.navigator.mediaCapabilities = true

const { useMediaCapabilities } = require('./');
const { result } = renderHook(() => useMediaCapabilities());

expect(result.current.supported).toEqual(true);
});

const { result } = renderHook(() => useMediaCapabilities());

expect(result.current.mediaCapabilities).toEqual({ hasMediaConfig: false, supported: true });
});

test('should return MediaDecodingConfiguration for given media configuration', () => {
Object.defineProperty(window.navigator, 'mediaCapabilities', {
value: {
decodingInfo: (mediaConfig) => mediaCapabilitiesMapper[mediaConfig.audio.contentType]
},
configurable: true,
writable: true
});
jest.isolateModules(() => {
global.navigator.mediaCapabilities = {
decodingInfo: (mediaConfig) => new Promise(resolve => resolve(mediaCapabilitiesMapper[mediaConfig.audio.contentType]))
};

const { useMediaCapabilities } = require('./');
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilities(mediaConfig));

const { result } = renderHook(() => useMediaCapabilities(mediaConfig));

expect(result.current.mediaCapabilities).toEqual({
powerEfficient: true,
smooth: true,
supported: true
waitForNextUpdate().then(() => {
expect(result.current.powerEfficient).toEqual(true);
expect(result.current.smooth).toEqual(true);
expect(result.current.supported).toEqual(true);
});
});
});

test('should update the mediaCapabilities state', () => {
jest.isolateModules(() => {
const { useMediaCapabilities } = require('./');
const { result } = renderHook(() => useMediaCapabilities());

const mockMediaCapabilitiesStatus = {
powerEfficient: false,
smooth: false,
supported: false
};

act(() => result.current.updateMediaCapabilities(mockMediaCapabilitiesStatus));

expect(result.current.powerEfficient).toEqual(mockMediaCapabilitiesStatus.powerEfficient);
expect(result.current.smooth).toEqual(mockMediaCapabilitiesStatus.smooth);
expect(result.current.supported).toEqual(mockMediaCapabilitiesStatus.supported);
});
})
});

0 comments on commit 58aba42

Please sign in to comment.