Skip to content

Commit

Permalink
fix: conditionally add device permissions (#86)
Browse files Browse the repository at this point in the history
* feat: conditionally add device permissions

* chore: use ternary operator

* test: when permission are denied

---------

Co-authored-by: evujici <[email protected]>
  • Loading branch information
edvujic and evujici authored Sep 20, 2024
1 parent 6153bc9 commit 9e2d55a
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
65 changes: 65 additions & 0 deletions src/device/device-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
createDisplayStream,
createDisplayStreamWithAudio,
createMicrophoneStream,
getDevices,
} from './device-management';
import { WebrtcCoreError, WebrtcCoreErrorType } from '../errors';

jest.mock('../mocks/media-stream-stub');

Expand Down Expand Up @@ -254,4 +256,67 @@ describe('Device Management', () => {
expect(localDisplayStream.contentHint).toBe('motion');
});
});

describe('getDevices', () => {
it('should call ensureDevicePermissions with both audio and video input kinds when no deviceKind is provided', async () => {
expect.hasAssertions();
const mockDevices = [
{ kind: 'audioinput', deviceId: 'audio1' },
{ kind: 'videoinput', deviceId: 'video1' },
] as MediaDeviceInfo[];

jest.spyOn(media, 'ensureDevicePermissions').mockResolvedValue(mockDevices);
jest.spyOn(media, 'enumerateDevices').mockResolvedValue(mockDevices);

const devices = await getDevices();
expect(media.ensureDevicePermissions).toHaveBeenCalledWith(
[media.DeviceKind.AudioInput, media.DeviceKind.VideoInput],
media.enumerateDevices
);
expect(devices).toStrictEqual(mockDevices);
});

it('should call ensureDevicePermissions with the provided deviceKind', async () => {
expect.hasAssertions();
const mockDevices = [{ kind: 'audioinput', deviceId: 'audio1' }] as MediaDeviceInfo[];

jest.spyOn(media, 'ensureDevicePermissions').mockResolvedValue(mockDevices);
jest.spyOn(media, 'enumerateDevices').mockResolvedValue(mockDevices);

const devices = await getDevices(media.DeviceKind.AudioInput);
expect(media.ensureDevicePermissions).toHaveBeenCalledWith(
[media.DeviceKind.AudioInput],
media.enumerateDevices
);
expect(devices).toStrictEqual(mockDevices);
});

it('should filter devices based on the provided deviceKind', async () => {
expect.hasAssertions();
const mockDevices = [
{ kind: 'audioinput', deviceId: 'audio1' },
{ kind: 'videoinput', deviceId: 'video1' },
] as MediaDeviceInfo[];

jest.spyOn(media, 'ensureDevicePermissions').mockResolvedValue(mockDevices);
jest.spyOn(media, 'enumerateDevices').mockResolvedValue(mockDevices);

const devices = await getDevices(media.DeviceKind.AudioInput);
expect(devices).toStrictEqual([{ kind: 'audioinput', deviceId: 'audio1' }]);
});

it('should throw WebrtcCoreError when device permissions are denied', async () => {
expect.hasAssertions();
jest.spyOn(media, 'ensureDevicePermissions').mockImplementation(() => {
throw new Error();
});

const expectedError = new WebrtcCoreError(
WebrtcCoreErrorType.DEVICE_PERMISSION_DENIED,
'Failed to ensure device permissions'
);

await expect(getDevices()).rejects.toStrictEqual(expectedError);
});
});
});
9 changes: 5 additions & 4 deletions src/device/device-management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,12 @@ export async function createDisplayStreamWithAudio<
*/
export async function getDevices(deviceKind?: media.DeviceKind): Promise<MediaDeviceInfo[]> {
let devices: MediaDeviceInfo[];
const deviceKinds = deviceKind
? [deviceKind]
: [media.DeviceKind.AudioInput, media.DeviceKind.VideoInput];

try {
devices = await media.ensureDevicePermissions(
[media.DeviceKind.AudioInput, media.DeviceKind.VideoInput],
media.enumerateDevices
);
devices = await media.ensureDevicePermissions(deviceKinds, media.enumerateDevices);
} catch (error) {
throw new WebrtcCoreError(
WebrtcCoreErrorType.DEVICE_PERMISSION_DENIED,
Expand Down

0 comments on commit 9e2d55a

Please sign in to comment.