From 6766b288efa8c9438cff87984575f2fd19f3166b Mon Sep 17 00:00:00 2001 From: tr00d Date: Mon, 5 Jun 2023 14:25:54 +0200 Subject: [PATCH] Implement AutoArchive parameters on CreateSession --- OpenTok/OpenTok.cs | 42 ++++++++--- OpenTokTest/Session.cs | 158 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 9 deletions(-) diff --git a/OpenTok/OpenTok.cs b/OpenTok/OpenTok.cs index 976e957e..a053952b 100644 --- a/OpenTok/OpenTok.cs +++ b/OpenTok/OpenTok.cs @@ -6,6 +6,8 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Threading.Tasks; +using EnumsNET; +using OpenTokSDK.Render; namespace OpenTokSDK { @@ -149,6 +151,8 @@ public OpenTok(int apiKey, string apiSecret, string apiUrl) /// /// Enables end-to-end media encryption in routed sessions. /// + /// Name of the archives in auto archived sessions. A session that begins with archive mode 'always' will be using this archive name for all archives of that session. Passing 'archiveName' with archive mode 'manual' will cause an error response. + /// Resolution of the archives in auto archived sessions. A session that begins with archive mode 'always' will be using this resolution for all archives of that session. Passing 'archiveResolution' with archive mode 'manual' will cause an error response. /// /// A Session object representing the new session. The property of the /// is the session ID, which uniquely identifies the session. You will use @@ -157,7 +161,13 @@ public OpenTok(int apiKey, string apiSecret, string apiUrl) /// OT.initSession() /// method (to initialize an OpenTok session). /// - public Session CreateSession(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL, bool encryption = false) + public Session CreateSession( + string location = "", + MediaMode mediaMode = MediaMode.RELAYED, + ArchiveMode archiveMode = ArchiveMode.MANUAL, + bool encryption = false, + string archiveName = "", + RenderResolution archiveResolution = RenderResolution.StandardDefinitionLandscape) { if (!OpenTokUtils.TestIpAddress(location)) { @@ -169,15 +179,20 @@ public Session CreateSession(string location = "", MediaMode mediaMode = MediaMo throw new OpenTokArgumentException("A session with always archive mode must also have the routed media mode."); } - string preference = (mediaMode == MediaMode.RELAYED) ? "enabled" : "disabled"; + if (archiveName?.Length > 80) + { + throw new OpenTokArgumentException("ArchiveName length cannot exceed 80."); + } var headers = new Dictionary { { "Content-Type", "application/x-www-form-urlencoded" } }; var data = new Dictionary { {"location", location}, - {"p2p.preference", preference}, + {"p2p.preference", mediaMode == MediaMode.RELAYED ? "enabled" : "disabled"}, {"archiveMode", archiveMode.ToString().ToLowerInvariant()}, {"e2ee", encryption}, + {"archiveName", archiveName ?? string.Empty}, + {"archiveResolution", archiveResolution.AsString(EnumFormat.Description)}, }; var response = Client.Post("session/create", headers, data); @@ -251,6 +266,8 @@ public Session CreateSession(string location = "", MediaMode mediaMode = MediaMo /// /// Enables end-to-end media encryption in routed sessions. /// + /// Name of the archives in auto archived sessions. A session that begins with archive mode 'always' will be using this archive name for all archives of that session. Passing 'archiveName' with archive mode 'manual' will cause an error response. + /// Resolution of the archives in auto archived sessions. A session that begins with archive mode 'always' will be using this resolution for all archives of that session. Passing 'archiveResolution' with archive mode 'manual' will cause an error response. /// /// A Session object representing the new session. The property of the /// is the session ID, which uniquely identifies the session. You will use @@ -259,7 +276,9 @@ public Session CreateSession(string location = "", MediaMode mediaMode = MediaMo /// OT.initSession() /// method (to initialize an OpenTok session). /// - public async Task CreateSessionAsync(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL, bool encryption = false) + public async Task CreateSessionAsync(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL, bool encryption = false, + string archiveName = "", + RenderResolution archiveResolution = RenderResolution.StandardDefinitionLandscape) { if (!OpenTokUtils.TestIpAddress(location)) { @@ -270,18 +289,23 @@ public async Task CreateSessionAsync(string location = "", MediaMode me { throw new OpenTokArgumentException("A session with always archive mode must also have the routed media mode."); } - - string preference = mediaMode == MediaMode.RELAYED - ? "enabled" - : "disabled"; + + if (archiveName?.Length > 80) + { + throw new OpenTokArgumentException("ArchiveName length cannot exceed 80."); + } var headers = new Dictionary { { "Content-Type", "application/x-www-form-urlencoded" } }; var data = new Dictionary { {"location", location}, - {"p2p.preference", preference}, + {"p2p.preference", mediaMode == MediaMode.RELAYED + ? "enabled" + : "disabled"}, {"archiveMode", archiveMode.ToString().ToLowerInvariant()}, {"e2ee", encryption}, + {"archiveName", archiveName ?? string.Empty}, + {"archiveResolution", archiveResolution.AsString(EnumFormat.Description)}, }; var response = await Client.PostAsync("session/create", headers, data); diff --git a/OpenTokTest/Session.cs b/OpenTokTest/Session.cs index 60dd6706..0e1ad991 100644 --- a/OpenTokTest/Session.cs +++ b/OpenTokTest/Session.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; using System.Net; using System.Threading.Tasks; +using EnumsNET; using Moq; using OpenTokSDK; using OpenTokSDK.Exception; +using OpenTokSDK.Render; using OpenTokSDK.Util; using Xunit; @@ -58,6 +60,162 @@ public void CreateSessionSimple() mockClient.Verify(httpClient => httpClient.Post(It.Is(url => url.Equals(expectedUrl)), It.IsAny>(), It.IsAny>()), Times.Once()); } + + [Fact] + public void CreateSession_ShouldSendArchiveName() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == "TestArchiveName" + && dictionary["archiveResolution"].ToString() == "640x480"))) + .Returns(returnString); + var session = new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSession(archiveName: "TestArchiveName"); + Assert.NotNull(session); + } + + [Fact] + public void CreateSession_ShouldThrowException_GivenArchiveExceeds80Characters() + { + var session = new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = new Mock().Object, + }; + + var exception = Assert.Throws(() => session.CreateSession(archiveName: new string('*', 81))); + Assert.Equal("ArchiveName length cannot exceed 80.", exception.Message); + } + + [Fact] + public void CreateSession_ShouldSendArchiveResolution() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == string.Empty + && dictionary["archiveResolution"].ToString() == "1920x1080"))) + .Returns(returnString); + var session = new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSession(archiveResolution: RenderResolution.FullHighDefinitionLandscape); + Assert.NotNull(session); + } + + [Fact] + public void CreateSession_ShouldSendDefaultArchivingValues() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == string.Empty + && dictionary["archiveResolution"].ToString() == "640x480"))) + .Returns(returnString); + var session = new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSession(); + Assert.NotNull(session); + } + + [Fact] + public async Task CreateSessionAsync_ShouldSendArchiveName() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == "TestArchiveName" + && dictionary["archiveResolution"].ToString() == "640x480"))) + .Returns(Task.FromResult(returnString)); + var session = await new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSessionAsync(archiveName: "TestArchiveName"); + Assert.NotNull(session); + } + + [Fact] + public async Task CreateSessionAsync_ShouldThrowException_GivenArchiveExceeds80Characters() + { + var session = new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = new Mock().Object, + }; + + var exception = await Assert.ThrowsAsync(() => session.CreateSessionAsync(archiveName: new string('*', 81))); + Assert.Equal("ArchiveName length cannot exceed 80.", exception.Message); + } + + [Fact] + public async Task CreateSessionAsync_ShouldSendArchiveResolution() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == string.Empty + && dictionary["archiveResolution"].ToString() == "1920x1080"))) + .Returns(Task.FromResult(returnString)); + var session = await new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSessionAsync(archiveResolution: RenderResolution.FullHighDefinitionLandscape); + Assert.NotNull(session); + } + + [Fact] + public async Task CreateSessionAsync_ShouldSendDefaultArchivingValues() + { + var returnString = "<" + + "session_id>" + this.SessionId + "123456" + + "Mon Mar 17 00:41:31 PDT 2014"; + const string expectedUrl = "session/create"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync( + expectedUrl, + It.IsAny>(), + It.Is>(dictionary => + dictionary["archiveName"].ToString() == string.Empty + && dictionary["archiveResolution"].ToString() == "640x480"))) + .Returns(Task.FromResult(returnString)); + var session = await new OpenTok(this.ApiKey, this.ApiSecret) + { + Client = mockClient.Object, + }.CreateSessionAsync(); + Assert.NotNull(session); + } [Fact] public async Task CreateSessionAsyncSimple()