Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spark 401353 fix media tests #33

Merged
merged 3 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ module.exports = {
'react/react-in-jsx-scope': 0,
},
},
{
files: ['**/*.spec.ts'],
rules: {
'jsdoc/require-description': 0,
'@typescript-eslint/no-shadow': 0,
'jsdoc/require-jsdoc': 0,
'react/display-name': 0,
'react/prop-types': 0,
'react/react-in-jsx-scope': 0,
},
},
],
settings: {
'import/parsers': {
Expand Down
37 changes: 25 additions & 12 deletions packages/webrtc-core/src/device/device-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ describe('Device Management', () => {
.mockImplementation()
.mockReturnValue(Promise.resolve(mockStream as unknown as MediaStream));

const track = new MediaStreamTrack();
const mockTrack = new MediaStreamTrack();
mockStream.getAudioTracks.mockReturnValue([track]);
mockStream.getVideoTracks.mockReturnValue([mockTrack]);
const audioTrack = new MediaStreamTrack();
const videoTrack = new MediaStreamTrack();
mockStream.getAudioTracks.mockReturnValue([audioTrack]);
mockStream.getVideoTracks.mockReturnValue([videoTrack]);

it('should call getUserMedia', async () => {
expect.assertions(1);
Expand Down Expand Up @@ -115,7 +115,7 @@ describe('Device Management', () => {

it('should call getUserMedia', async () => {
expect.assertions(1);
mockStream.getAudioTracks.mockReturnValue([track]);

await createMicrophoneTrack({ deviceId: 'test-device-id-audio' });
expect(media.getUserMedia).toHaveBeenCalledWith({
audio: {
Expand Down Expand Up @@ -167,7 +167,6 @@ describe('Device Management', () => {
it('should call getUserMedia', async () => {
expect.assertions(1);

mockStream.getVideoTracks.mockReturnValue([track]);
await createCameraTrack({ deviceId: 'test-device-id-video' });
expect(media.getUserMedia).toHaveBeenCalledWith({
video: {
Expand Down Expand Up @@ -213,10 +212,10 @@ describe('Device Management', () => {
.mockImplementation()
.mockReturnValue(Promise.resolve(mockStream as unknown as MediaStream));

const track = new MediaStreamTrack();
const mockTrack = new MediaStreamTrack();
mockStream.getAudioTracks.mockReturnValue([track]);
mockStream.getVideoTracks.mockReturnValue([mockTrack]);
const audioTrack = new MediaStreamTrack();
const videoTrack = new MediaStreamTrack();
mockStream.getAudioTracks.mockReturnValue([audioTrack]);
mockStream.getVideoTracks.mockReturnValue([videoTrack]);
it('should call getDisplayMedia', async () => {
expect.assertions(1);

Expand All @@ -242,7 +241,6 @@ describe('Device Management', () => {
width: 1920,
height: 1080,
frameRate: 30,
suppressLocalAudioPlayback: true,
},
withAudio: false,
});
Expand All @@ -253,7 +251,6 @@ describe('Device Management', () => {
width: 1920,
height: 1080,
frameRate: 30,
suppressLocalAudioPlayback: true,
},
audio: false,
});
Expand All @@ -270,6 +267,22 @@ describe('Device Management', () => {
expect(localDisplayTrack).toBeInstanceOf(LocalDisplayTrack);
expect(localComputerAudioTrack).toBeInstanceOf(LocalComputerAudioTrack);
});

it('should return a LocalDisplayTrack instance without LocalComputerAudioTrack instance', async () => {
expect.assertions(2);
mockStream.getAudioTracks.mockReturnValue([]);
jest
.spyOn(media, 'getDisplayMedia')
.mockImplementation()
.mockReturnValue(Promise.resolve(mockStream as unknown as MediaStream));

const { localDisplayTrack, localComputerAudioTrack } = await createDisplayTrack({
constraints: { deviceId: 'test-device-id-display' },
withAudio: false,
});
expect(localDisplayTrack).toBeInstanceOf(LocalDisplayTrack);
expect(localComputerAudioTrack).toBeUndefined();
});
});
describe('getDevices', () => {
const mockAudioDevice = mocked(new MediaDeviceInfoStub('audioinput'));
Expand Down
28 changes: 28 additions & 0 deletions packages/webrtc-core/src/media/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ describe('enumerateDevices', () => {
});
});

describe('setOnDeviceChangeHandler', () => {
it('should call setOnDeviceChangeHandler correctly', async () => {
expect.assertions(1);
const mockedNavigatorStub = createBrowserMock(Navigator, 'navigator');
const mockHandler = jest.fn();
media.setOnDeviceChangeHandler(mockHandler);
expect(mockedNavigatorStub.mediaDevices.ondevicechange).toBe(mockHandler);
});
});

describe('checkDevicePermissions', () => {
it('should checkDevicePermissions for status: granted', async () => {
expect.assertions(1);

const mockedNavigatorStub = createBrowserMock(Navigator, 'navigator');
// mock 'granted' query response
mockedNavigatorStub.permissions.query
.mockReturnValueOnce(Promise.resolve(createPermissionStatus('granted')))
.mockReturnValueOnce(Promise.resolve(createPermissionStatus('granted')));

const permissionGranted = await media.checkDevicePermissions([
media.DeviceKind.AudioInput,
media.DeviceKind.VideoInput,
]);
expect(permissionGranted).toBe(true);
});
});

describe('ensureDevicePermissions', () => {
it('should call the callback.', async () => {
expect.assertions(2);
Expand Down
27 changes: 27 additions & 0 deletions packages/webrtc-core/src/media/local-audio-track.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createMockedStream } from '../util/test-utils';
import { LocalAudioTrack } from './local-audio-track';
import MediaStreamStub from '../mocks/media-stream-stub';
import { createBrowserMock } from '../mocks/create-browser-mock';
/**
* A dummy LocalAudioTrack implementation so we can instantiate it for testing.
*/
class TestLocalAudioTrack extends LocalAudioTrack {}

describe('LocalAudioTrack', () => {
createBrowserMock(MediaStreamStub, 'MediaStream');
const mockStream = createMockedStream();
let localAudioTrack: TestLocalAudioTrack;
beforeEach(() => {
localAudioTrack = new TestLocalAudioTrack(mockStream.getTracks()[0]);
});

it('Should call applyConstraints on track when setEncoderConstaints is called', () => {
expect.assertions(2);
const encoderConstraints = { echoCancellation: true, channelCount: 1, sampleSize: 16 };

jest.spyOn(localAudioTrack, 'getMediaStreamTrack');
localAudioTrack.setEncoderConstraints(encoderConstraints);
expect(localAudioTrack.getMediaStreamTrack).toHaveBeenCalledTimes(1);
expect(mockStream.getTracks()[0].applyConstraints).toHaveBeenCalledWith(encoderConstraints);
});
});
68 changes: 67 additions & 1 deletion packages/webrtc-core/src/media/local-track.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { createMockedStream } from '../util/test-utils';
import { LocalTrack } from './local-track';

import MediaStreamStub from '../mocks/media-stream-stub';
import { createBrowserMock } from '../mocks/create-browser-mock';
/**
* A dummy LocalTrack implementation so we can instantiate it for testing.
*/
class TestLocalTrack extends LocalTrack {}

describe('LocalTrack', () => {
createBrowserMock(MediaStreamStub, 'MediaStream');
const mockStream = createMockedStream();
let localTrack: LocalTrack;
beforeEach(() => {
Expand Down Expand Up @@ -52,6 +54,70 @@ describe('LocalTrack', () => {
expect(emitted).toBe(true);
});

it('should add, set and dispose video effect correctly', async () => {
expect.assertions(4);
const videotrack = new MediaStreamTrack();
const effect = {
load: jest.fn(),

getUnderlyingStream: () => {
return {
getAudioTracks: () => {
return [];
},

getVideoTracks: () => {
return [videotrack];
},
};
},
};

localTrack.kind = 'video';
jest.spyOn(localTrack, 'setMediaStreamTrackWithEffects');
jest.spyOn(effect, 'getUnderlyingStream');
await localTrack.addEffect('videoEffect', effect);

expect(effect.load).toHaveBeenCalledTimes(1);
expect(effect.getUnderlyingStream).toHaveBeenCalledTimes(1);
expect(localTrack.setMediaStreamTrackWithEffects).toHaveBeenCalledWith(videotrack);
expect(localTrack.getEffect('videoEffect')).toBe(effect);
});

it('should add, set and dispose audio effect correctly', async () => {
expect.assertions(6);
const audioTrack = new MediaStreamTrack();
const effect = {
load: jest.fn(),
dispose: jest.fn(),
getUnderlyingStream: () => {
return {
getAudioTracks: () => {
return [audioTrack];
},
getVideoTracks: () => {
return [];
},
};
},
};

localTrack.kind = 'audio';
jest.spyOn(localTrack, 'setMediaStreamTrackWithEffects');
jest.spyOn(effect, 'getUnderlyingStream');
await localTrack.addEffect('audioEffect', effect);

expect(effect.load).toHaveBeenCalledTimes(1);
expect(effect.getUnderlyingStream).toHaveBeenCalledTimes(1);
expect(localTrack.setMediaStreamTrackWithEffects).toHaveBeenCalledWith(audioTrack);
expect(localTrack.getEffect('audioEffect')).toBe(effect);

await localTrack.disposeEffects();

expect(effect.dispose).toHaveBeenCalledTimes(1);
expect(localTrack.getEffect('audioEffect')).toBeUndefined();
});

it('should setPublished correctly', () => {
expect.assertions(4);

Expand Down
27 changes: 27 additions & 0 deletions packages/webrtc-core/src/media/local-video-track.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createMockedStream } from '../util/test-utils';
import { LocalVideoTrack } from './local-video-track';
import MediaStreamStub from '../mocks/media-stream-stub';
import { createBrowserMock } from '../mocks/create-browser-mock';
/**
* A dummy LocalVideoTrack implementation so we can instantiate it for testing.
*/
class TestLocalVideoTrack extends LocalVideoTrack {}

describe('LocalVideoTrack', () => {
createBrowserMock(MediaStreamStub, 'MediaStream');
const mockStream = createMockedStream();
let localVideoTrack: TestLocalVideoTrack;
beforeEach(() => {
localVideoTrack = new TestLocalVideoTrack(mockStream.getTracks()[0]);
});

it('Should call applyConstraints on track when setEncoderConstaints is called', () => {
expect.assertions(2);
const encoderConstraints = { frameRate: 30, width: 1920, height: 1080 };

jest.spyOn(localVideoTrack, 'getMediaStreamTrack');
localVideoTrack.setEncoderConstraints(encoderConstraints);
expect(localVideoTrack.getMediaStreamTrack).toHaveBeenCalledTimes(1);
expect(mockStream.getTracks()[0].applyConstraints).toHaveBeenCalledWith(encoderConstraints);
});
});
8 changes: 1 addition & 7 deletions packages/webrtc-core/src/media/local-video-track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@ type BaseVideoConstraints = Pick<
MediaTrackConstraints,
'aspectRatio' | 'height' | 'width' | 'frameRate' | 'deviceId'
>;

type BaseDisplayConstraints = Pick<
MediaTrackConstraints,
'aspectRatio' | 'height' | 'width' | 'frameRate' | 'deviceId' | 'suppressLocalAudioPlayback'
>;

export interface CameraConstraints extends BaseVideoConstraints {
facingMode?: FacingMode;
}

export interface DisplayConstraints extends BaseDisplayConstraints {
export interface DisplayConstraints extends BaseVideoConstraints {
displaySurface?: DisplaySurface;
logicalSurface?: boolean;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/webrtc-core/src/mocks/media-stream-track-stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class MediaStreamTrackStub {
removeEventListener(event: string, handler: any): void {
this.eventListeners.delete(event);
}

applyConstraints(mediaTrackConstaints: MediaTrackConstraints): void {}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions packages/webrtc-core/src/mocks/navigator-stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ const enumerateDevices = async (): Promise<MediaDeviceInfo[]> => {
return [];
};

/**
* @param event
*/
const ondevicechange = (event: Event) => {
return event;
};

/**
* A permissions.query stub.
*
Expand All @@ -47,6 +54,7 @@ const mediaDevices = {
enumerateDevices,
getDisplayMedia,
getUserMedia,
ondevicechange,
};

const permissions = {
Expand Down