From 20f2e1aa4c813ec1a885f581da0cb79c556d62c8 Mon Sep 17 00:00:00 2001 From: Shi Su <67605788+shi-su@users.noreply.github.com> Date: Mon, 21 Aug 2023 13:15:11 -0700 Subject: [PATCH] Receive notification messages from server and print received messages to console (#2731) Co-authored-by: Shi Su --- CHANGELOG.md | 2 + docs/classes/monitortask.html | 26 +- protocol/SignalingProtocol.proto | 14 +- src/signalingprotocol/SignalingProtocol.d.ts | 115 +++++++- src/signalingprotocol/SignalingProtocol.js | 278 +++++++++++++++++++ src/task/MonitorTask.ts | 27 +- test/task/MonitorTask.test.ts | 78 ++++++ 7 files changed, 524 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10a460ff54..f29566e9ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Allow receiving notification messages from server and print messages received to console + ### Removed ### Changed diff --git a/docs/classes/monitortask.html b/docs/classes/monitortask.html index 3a46f72302..f2ad30395b 100644 --- a/docs/classes/monitortask.html +++ b/docs/classes/monitortask.html @@ -141,7 +141,7 @@

constructor

Parameters

@@ -178,7 +178,7 @@

Protected taskName

@@ -196,7 +196,7 @@

audioVideoDidStart

@@ -219,7 +219,7 @@

audioVideoDidStartConnecting

@@ -248,7 +248,7 @@

audioVideoDidStop

@@ -306,7 +306,7 @@

connectionHealthDidChange

@@ -353,7 +353,7 @@

handleSignalingClientEvent

@@ -406,7 +406,7 @@

metricsDidReceive

@@ -481,7 +481,7 @@

pauseResubscribeCheck

  • Returns void

    @@ -499,7 +499,7 @@

    removeObserver

    @@ -521,7 +521,7 @@

    resumeResubscribeCheck

  • Returns void

    @@ -539,7 +539,7 @@

    run

    @@ -594,7 +594,7 @@

    videoTileDidUpdate

    diff --git a/protocol/SignalingProtocol.proto b/protocol/SignalingProtocol.proto index 3ca068a2c5..7ba3de9575 100644 --- a/protocol/SignalingProtocol.proto +++ b/protocol/SignalingProtocol.proto @@ -26,6 +26,7 @@ message SdkSignalFrame { PRIMARY_MEETING_JOIN = 25; PRIMARY_MEETING_JOIN_ACK = 26; PRIMARY_MEETING_LEAVE = 27; + NOTIFICATION = 34; } required uint64 timestamp_ms = 1; required Type type = 2; @@ -50,6 +51,7 @@ message SdkSignalFrame { optional SdkPrimaryMeetingJoinFrame primary_meeting_join = 26; optional SdkPrimaryMeetingJoinAckFrame primary_meeting_join_ack = 27; optional SdkPrimaryMeetingLeaveFrame primary_meeting_leave = 28; + optional SdkNotificationFrame notification = 35; } message SdkErrorFrame { @@ -430,6 +432,16 @@ message SdkVideoSubscriptionConfiguration { optional uint32 group_id = 6; } +message SdkNotificationFrame { + enum NotificationLevel { + INFO = 1; + WARNING = 2; + ERROR = 3; + } + optional NotificationLevel level = 1 [default=ERROR]; + optional string message = 2; +} + message SdkPrimaryMeetingJoinFrame { optional SdkMeetingSessionCredentials credentials = 1; } @@ -449,4 +461,4 @@ message SdkMeetingSessionCredentials { enum SdkVideoCodecCapability { VP8 = 1; H264_CONSTRAINED_BASELINE_PROFILE = 3; -}; \ No newline at end of file +}; diff --git a/src/signalingprotocol/SignalingProtocol.d.ts b/src/signalingprotocol/SignalingProtocol.d.ts index 3559fc3e99..8308772116 100644 --- a/src/signalingprotocol/SignalingProtocol.d.ts +++ b/src/signalingprotocol/SignalingProtocol.d.ts @@ -71,6 +71,9 @@ export interface ISdkSignalFrame { /** SdkSignalFrame primaryMeetingLeave */ primaryMeetingLeave?: (ISdkPrimaryMeetingLeaveFrame|null); + + /** SdkSignalFrame notification */ + notification?: (ISdkNotificationFrame|null); } /** Represents a SdkSignalFrame. */ @@ -151,6 +154,9 @@ export class SdkSignalFrame implements ISdkSignalFrame { /** SdkSignalFrame primaryMeetingLeave. */ public primaryMeetingLeave?: (ISdkPrimaryMeetingLeaveFrame|null); + /** SdkSignalFrame notification. */ + public notification?: (ISdkNotificationFrame|null); + /** * Creates a new SdkSignalFrame instance using the specified properties. * @param [properties] Properties to set @@ -246,7 +252,8 @@ export namespace SdkSignalFrame { REMOTE_VIDEO_UPDATE = 24, PRIMARY_MEETING_JOIN = 25, PRIMARY_MEETING_JOIN_ACK = 26, - PRIMARY_MEETING_LEAVE = 27 + PRIMARY_MEETING_LEAVE = 27, + NOTIFICATION = 34 } } @@ -4715,6 +4722,112 @@ export class SdkVideoSubscriptionConfiguration implements ISdkVideoSubscriptionC public toJSON(): { [k: string]: any }; } +/** Properties of a SdkNotificationFrame. */ +export interface ISdkNotificationFrame { + + /** SdkNotificationFrame level */ + level?: (SdkNotificationFrame.NotificationLevel|null); + + /** SdkNotificationFrame message */ + message?: (string|null); +} + +/** Represents a SdkNotificationFrame. */ +export class SdkNotificationFrame implements ISdkNotificationFrame { + + /** + * Constructs a new SdkNotificationFrame. + * @param [properties] Properties to set + */ + constructor(properties?: ISdkNotificationFrame); + + /** SdkNotificationFrame level. */ + public level: SdkNotificationFrame.NotificationLevel; + + /** SdkNotificationFrame message. */ + public message: string; + + /** + * Creates a new SdkNotificationFrame instance using the specified properties. + * @param [properties] Properties to set + * @returns SdkNotificationFrame instance + */ + public static create(properties?: ISdkNotificationFrame): SdkNotificationFrame; + + /** + * Encodes the specified SdkNotificationFrame message. Does not implicitly {@link SdkNotificationFrame.verify|verify} messages. + * @param message SdkNotificationFrame message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: ISdkNotificationFrame, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified SdkNotificationFrame message, length delimited. Does not implicitly {@link SdkNotificationFrame.verify|verify} messages. + * @param message SdkNotificationFrame message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: ISdkNotificationFrame, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a SdkNotificationFrame message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns SdkNotificationFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SdkNotificationFrame; + + /** + * Decodes a SdkNotificationFrame message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns SdkNotificationFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SdkNotificationFrame; + + /** + * Verifies a SdkNotificationFrame message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a SdkNotificationFrame message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns SdkNotificationFrame + */ + public static fromObject(object: { [k: string]: any }): SdkNotificationFrame; + + /** + * Creates a plain object from a SdkNotificationFrame message. Also converts values to other types if specified. + * @param message SdkNotificationFrame + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: SdkNotificationFrame, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this SdkNotificationFrame to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; +} + +export namespace SdkNotificationFrame { + + /** NotificationLevel enum. */ + enum NotificationLevel { + INFO = 1, + WARNING = 2, + ERROR = 3 + } +} + /** Properties of a SdkPrimaryMeetingJoinFrame. */ export interface ISdkPrimaryMeetingJoinFrame { diff --git a/src/signalingprotocol/SignalingProtocol.js b/src/signalingprotocol/SignalingProtocol.js index d4a240ff92..3d5b78785d 100644 --- a/src/signalingprotocol/SignalingProtocol.js +++ b/src/signalingprotocol/SignalingProtocol.js @@ -38,6 +38,7 @@ $root.SdkSignalFrame = (function() { * @property {ISdkPrimaryMeetingJoinFrame|null} [primaryMeetingJoin] SdkSignalFrame primaryMeetingJoin * @property {ISdkPrimaryMeetingJoinAckFrame|null} [primaryMeetingJoinAck] SdkSignalFrame primaryMeetingJoinAck * @property {ISdkPrimaryMeetingLeaveFrame|null} [primaryMeetingLeave] SdkSignalFrame primaryMeetingLeave + * @property {ISdkNotificationFrame|null} [notification] SdkSignalFrame notification */ /** @@ -239,6 +240,14 @@ $root.SdkSignalFrame = (function() { */ SdkSignalFrame.prototype.primaryMeetingLeave = null; + /** + * SdkSignalFrame notification. + * @member {ISdkNotificationFrame|null|undefined} notification + * @memberof SdkSignalFrame + * @instance + */ + SdkSignalFrame.prototype.notification = null; + /** * Creates a new SdkSignalFrame instance using the specified properties. * @function create @@ -307,6 +316,8 @@ $root.SdkSignalFrame = (function() { $root.SdkPrimaryMeetingJoinAckFrame.encode(message.primaryMeetingJoinAck, writer.uint32(/* id 27, wireType 2 =*/218).fork()).ldelim(); if (message.primaryMeetingLeave != null && Object.hasOwnProperty.call(message, "primaryMeetingLeave")) $root.SdkPrimaryMeetingLeaveFrame.encode(message.primaryMeetingLeave, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim(); + if (message.notification != null && Object.hasOwnProperty.call(message, "notification")) + $root.SdkNotificationFrame.encode(message.notification, writer.uint32(/* id 35, wireType 2 =*/282).fork()).ldelim(); return writer; }; @@ -410,6 +421,9 @@ $root.SdkSignalFrame = (function() { case 28: message.primaryMeetingLeave = $root.SdkPrimaryMeetingLeaveFrame.decode(reader, reader.uint32()); break; + case 35: + message.notification = $root.SdkNotificationFrame.decode(reader, reader.uint32()); + break; default: reader.skipType(tag & 7); break; @@ -475,6 +489,7 @@ $root.SdkSignalFrame = (function() { case 25: case 26: case 27: + case 34: break; } if (message.error != null && message.hasOwnProperty("error")) { @@ -582,6 +597,11 @@ $root.SdkSignalFrame = (function() { if (error) return "primaryMeetingLeave." + error; } + if (message.notification != null && message.hasOwnProperty("notification")) { + var error = $root.SdkNotificationFrame.verify(message.notification); + if (error) + return "notification." + error; + } return null; }; @@ -691,6 +711,10 @@ $root.SdkSignalFrame = (function() { case 27: message.type = 27; break; + case "NOTIFICATION": + case 34: + message.type = 34; + break; } if (object.error != null) { if (typeof object.error !== "object") @@ -797,6 +821,11 @@ $root.SdkSignalFrame = (function() { throw TypeError(".SdkSignalFrame.primaryMeetingLeave: object expected"); message.primaryMeetingLeave = $root.SdkPrimaryMeetingLeaveFrame.fromObject(object.primaryMeetingLeave); } + if (object.notification != null) { + if (typeof object.notification !== "object") + throw TypeError(".SdkSignalFrame.notification: object expected"); + message.notification = $root.SdkNotificationFrame.fromObject(object.notification); + } return message; }; @@ -841,6 +870,7 @@ $root.SdkSignalFrame = (function() { object.primaryMeetingJoin = null; object.primaryMeetingJoinAck = null; object.primaryMeetingLeave = null; + object.notification = null; } if (message.timestampMs != null && message.hasOwnProperty("timestampMs")) if (typeof message.timestampMs === "number") @@ -891,6 +921,8 @@ $root.SdkSignalFrame = (function() { object.primaryMeetingJoinAck = $root.SdkPrimaryMeetingJoinAckFrame.toObject(message.primaryMeetingJoinAck, options); if (message.primaryMeetingLeave != null && message.hasOwnProperty("primaryMeetingLeave")) object.primaryMeetingLeave = $root.SdkPrimaryMeetingLeaveFrame.toObject(message.primaryMeetingLeave, options); + if (message.notification != null && message.hasOwnProperty("notification")) + object.notification = $root.SdkNotificationFrame.toObject(message.notification, options); return object; }; @@ -930,6 +962,7 @@ $root.SdkSignalFrame = (function() { * @property {number} PRIMARY_MEETING_JOIN=25 PRIMARY_MEETING_JOIN value * @property {number} PRIMARY_MEETING_JOIN_ACK=26 PRIMARY_MEETING_JOIN_ACK value * @property {number} PRIMARY_MEETING_LEAVE=27 PRIMARY_MEETING_LEAVE value + * @property {number} NOTIFICATION=34 NOTIFICATION value */ SdkSignalFrame.Type = (function() { var valuesById = {}, values = Object.create(valuesById); @@ -954,6 +987,7 @@ $root.SdkSignalFrame = (function() { values[valuesById[25] = "PRIMARY_MEETING_JOIN"] = 25; values[valuesById[26] = "PRIMARY_MEETING_JOIN_ACK"] = 26; values[valuesById[27] = "PRIMARY_MEETING_LEAVE"] = 27; + values[valuesById[34] = "NOTIFICATION"] = 34; return values; })(); @@ -12565,6 +12599,250 @@ $root.SdkVideoSubscriptionConfiguration = (function() { return SdkVideoSubscriptionConfiguration; })(); +$root.SdkNotificationFrame = (function() { + + /** + * Properties of a SdkNotificationFrame. + * @exports ISdkNotificationFrame + * @interface ISdkNotificationFrame + * @property {SdkNotificationFrame.NotificationLevel|null} [level] SdkNotificationFrame level + * @property {string|null} [message] SdkNotificationFrame message + */ + + /** + * Constructs a new SdkNotificationFrame. + * @exports SdkNotificationFrame + * @classdesc Represents a SdkNotificationFrame. + * @implements ISdkNotificationFrame + * @constructor + * @param {ISdkNotificationFrame=} [properties] Properties to set + */ + function SdkNotificationFrame(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * SdkNotificationFrame level. + * @member {SdkNotificationFrame.NotificationLevel} level + * @memberof SdkNotificationFrame + * @instance + */ + SdkNotificationFrame.prototype.level = 3; + + /** + * SdkNotificationFrame message. + * @member {string} message + * @memberof SdkNotificationFrame + * @instance + */ + SdkNotificationFrame.prototype.message = ""; + + /** + * Creates a new SdkNotificationFrame instance using the specified properties. + * @function create + * @memberof SdkNotificationFrame + * @static + * @param {ISdkNotificationFrame=} [properties] Properties to set + * @returns {SdkNotificationFrame} SdkNotificationFrame instance + */ + SdkNotificationFrame.create = function create(properties) { + return new SdkNotificationFrame(properties); + }; + + /** + * Encodes the specified SdkNotificationFrame message. Does not implicitly {@link SdkNotificationFrame.verify|verify} messages. + * @function encode + * @memberof SdkNotificationFrame + * @static + * @param {ISdkNotificationFrame} message SdkNotificationFrame message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SdkNotificationFrame.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.level != null && Object.hasOwnProperty.call(message, "level")) + writer.uint32(/* id 1, wireType 0 =*/8).int32(message.level); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.message); + return writer; + }; + + /** + * Encodes the specified SdkNotificationFrame message, length delimited. Does not implicitly {@link SdkNotificationFrame.verify|verify} messages. + * @function encodeDelimited + * @memberof SdkNotificationFrame + * @static + * @param {ISdkNotificationFrame} message SdkNotificationFrame message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + SdkNotificationFrame.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a SdkNotificationFrame message from the specified reader or buffer. + * @function decode + * @memberof SdkNotificationFrame + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {SdkNotificationFrame} SdkNotificationFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SdkNotificationFrame.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.SdkNotificationFrame(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.level = reader.int32(); + break; + case 2: + message.message = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a SdkNotificationFrame message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof SdkNotificationFrame + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {SdkNotificationFrame} SdkNotificationFrame + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + SdkNotificationFrame.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a SdkNotificationFrame message. + * @function verify + * @memberof SdkNotificationFrame + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + SdkNotificationFrame.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.level != null && message.hasOwnProperty("level")) + switch (message.level) { + default: + return "level: enum value expected"; + case 1: + case 2: + case 3: + break; + } + if (message.message != null && message.hasOwnProperty("message")) + if (!$util.isString(message.message)) + return "message: string expected"; + return null; + }; + + /** + * Creates a SdkNotificationFrame message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof SdkNotificationFrame + * @static + * @param {Object.} object Plain object + * @returns {SdkNotificationFrame} SdkNotificationFrame + */ + SdkNotificationFrame.fromObject = function fromObject(object) { + if (object instanceof $root.SdkNotificationFrame) + return object; + var message = new $root.SdkNotificationFrame(); + switch (object.level) { + case "INFO": + case 1: + message.level = 1; + break; + case "WARNING": + case 2: + message.level = 2; + break; + case "ERROR": + case 3: + message.level = 3; + break; + } + if (object.message != null) + message.message = String(object.message); + return message; + }; + + /** + * Creates a plain object from a SdkNotificationFrame message. Also converts values to other types if specified. + * @function toObject + * @memberof SdkNotificationFrame + * @static + * @param {SdkNotificationFrame} message SdkNotificationFrame + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + SdkNotificationFrame.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + object.level = options.enums === String ? "ERROR" : 3; + object.message = ""; + } + if (message.level != null && message.hasOwnProperty("level")) + object.level = options.enums === String ? $root.SdkNotificationFrame.NotificationLevel[message.level] : message.level; + if (message.message != null && message.hasOwnProperty("message")) + object.message = message.message; + return object; + }; + + /** + * Converts this SdkNotificationFrame to JSON. + * @function toJSON + * @memberof SdkNotificationFrame + * @instance + * @returns {Object.} JSON object + */ + SdkNotificationFrame.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * NotificationLevel enum. + * @name SdkNotificationFrame.NotificationLevel + * @enum {number} + * @property {number} INFO=1 INFO value + * @property {number} WARNING=2 WARNING value + * @property {number} ERROR=3 ERROR value + */ + SdkNotificationFrame.NotificationLevel = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[1] = "INFO"] = 1; + values[valuesById[2] = "WARNING"] = 2; + values[valuesById[3] = "ERROR"] = 3; + return values; + })(); + + return SdkNotificationFrame; +})(); + $root.SdkPrimaryMeetingJoinFrame = (function() { /** diff --git a/src/task/MonitorTask.ts b/src/task/MonitorTask.ts index 777381e86b..55318d98a7 100644 --- a/src/task/MonitorTask.ts +++ b/src/task/MonitorTask.ts @@ -20,7 +20,11 @@ import RemovableObserver from '../removableobserver/RemovableObserver'; import SignalingClientEvent from '../signalingclient/SignalingClientEvent'; import SignalingClientEventType from '../signalingclient/SignalingClientEventType'; import SignalingClientObserver from '../signalingclientobserver/SignalingClientObserver'; -import { ISdkBitrateFrame, SdkSignalFrame } from '../signalingprotocol/SignalingProtocol'; +import { + ISdkBitrateFrame, + SdkNotificationFrame, + SdkSignalFrame, +} from '../signalingprotocol/SignalingProtocol'; import AudioLogEvent from '../statscollector/AudioLogEvent'; import { Maybe } from '../utils/Types'; import VideoTileState from '../videotile/VideoTileState'; @@ -331,6 +335,27 @@ export default class MonitorTask } if (event.type === SignalingClientEventType.ReceivedSignalFrame) { + if (event.message.type === SdkSignalFrame.Type.NOTIFICATION) { + switch (event.message.notification.level) { + case SdkNotificationFrame.NotificationLevel.INFO: + this.logger.info( + `Received notification from server: ${event.message.notification.message}` + ); + break; + case SdkNotificationFrame.NotificationLevel.WARNING: + this.logger.warn(`Received warning from server: ${event.message.notification.message}`); + break; + case SdkNotificationFrame.NotificationLevel.ERROR: + this.logger.error(`Received error from server: ${event.message.notification.message}`); + break; + default: + this.logger.error( + `Received notification from server with unknown level ${event.message.notification.level}: ${event.message.notification.message}` + ); + break; + } + return; + } if (!!event.message.bitrates) { const bitrateFrame: ISdkBitrateFrame = event.message.bitrates; this.context.videoStreamIndex.integrateBitratesFrame(bitrateFrame); diff --git a/test/task/MonitorTask.test.ts b/test/task/MonitorTask.test.ts index 1c0afa7bde..9159ee15ae 100644 --- a/test/task/MonitorTask.test.ts +++ b/test/task/MonitorTask.test.ts @@ -39,6 +39,7 @@ import { SdkBitrate, SdkBitrateFrame, SdkErrorFrame, + SdkNotificationFrame, SdkSignalFrame, } from '../../src/signalingprotocol/SignalingProtocol.js'; import AudioLogEvent from '../../src/statscollector/AudioLogEvent'; @@ -58,6 +59,7 @@ import DefaultWebSocketAdapter from '../../src/websocketadapter/DefaultWebSocket import DOMMockBehavior from '../dommock/DOMMockBehavior'; import DOMMockBuilder from '../dommock/DOMMockBuilder'; import CreateMeetingResponseMock from '../meetingsession/CreateMeetingResponseMock'; +import { MockLogger } from '../voicefocus/MockLogger'; function createSignalingEventForBitrateFrame(logger: Logger): SignalingClientEvent { const webSocketAdapter = new DefaultWebSocketAdapter(logger); @@ -1354,5 +1356,81 @@ describe('MonitorTask', () => { context.eventController.publishEvent('meetingEnded'); }); }); + + it('logs notification messages with corresponding to level specified', async () => { + const mockLogger = new MockLogger(); + const webSocketAdapter = new DefaultWebSocketAdapter(mockLogger); + + const message = SdkSignalFrame.create(); + message.notification = SdkNotificationFrame.create(); + message.type = SdkSignalFrame.Type.NOTIFICATION; + message.notification.level = SdkNotificationFrame.NotificationLevel.INFO; + message.notification.message = 'Mock info level notification'; + + task.handleSignalingClientEvent( + new SignalingClientEvent( + new DefaultSignalingClient(webSocketAdapter, mockLogger), + SignalingClientEventType.ReceivedSignalFrame, + message + ) + ); + expect( + mockLogger.info.calledWith( + 'Received notification from server: Mock info level notification' + ) + ); + + message.notification.level = SdkNotificationFrame.NotificationLevel.WARNING; + message.notification.message = 'Mock warning level notification'; + + task.handleSignalingClientEvent( + new SignalingClientEvent( + new DefaultSignalingClient(webSocketAdapter, mockLogger), + SignalingClientEventType.ReceivedSignalFrame, + message + ) + ); + expect( + mockLogger.warn.calledWith('Received warning from server: Mock warning level notification') + ); + + message.notification.level = SdkNotificationFrame.NotificationLevel.ERROR; + message.notification.message = 'Mock error level notification'; + + task.handleSignalingClientEvent( + new SignalingClientEvent( + new DefaultSignalingClient(webSocketAdapter, mockLogger), + SignalingClientEventType.ReceivedSignalFrame, + message + ) + ); + expect( + mockLogger.error.calledWith('Received error from server: Mock error level notification') + ); + }); + + it('logs error when level is not specified', async () => { + const mockLogger = new MockLogger(); + const webSocketAdapter = new DefaultWebSocketAdapter(mockLogger); + + const message = SdkSignalFrame.create(); + message.notification = SdkNotificationFrame.create(); + message.type = SdkSignalFrame.Type.NOTIFICATION; + message.notification.level = null; + message.notification.message = 'Mock notification with invalid level'; + + task.handleSignalingClientEvent( + new SignalingClientEvent( + new DefaultSignalingClient(webSocketAdapter, mockLogger), + SignalingClientEventType.ReceivedSignalFrame, + message + ) + ); + expect( + mockLogger.info.calledWith( + 'Received notification from server with unknown level null: Mock notification with invalid level' + ) + ); + }); }); });