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

[DEVX-6818] AutoArchive #227

Merged
merged 1 commit into from
Jun 20, 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
42 changes: 33 additions & 9 deletions OpenTok/OpenTok.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using EnumsNET;
using OpenTokSDK.Render;

namespace OpenTokSDK
{
Expand Down Expand Up @@ -149,6 +151,8 @@ public OpenTok(int apiKey, string apiSecret, string apiUrl)
/// <param name="encryption">
/// Enables <a href="https://tokbox.com/developer/guides/end-to-end-encryption/">end-to-end media encryption</a> in routed sessions.
/// </param>
/// <param name="archiveName">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.</param>
/// <param name="archiveResolution">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.</param>
/// <returns>
/// A Session object representing the new session. The <see cref="Session.Id"/> property of the
/// <see cref="Session"/> is the session ID, which uniquely identifies the session. You will use
Expand All @@ -157,7 +161,13 @@ public OpenTok(int apiKey, string apiSecret, string apiUrl)
/// <a href="http://tokbox.com/opentok/libraries/client/js/reference/OT.html#initSession">OT.initSession()</a>
/// method (to initialize an OpenTok session).
/// </returns>
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))
{
Expand All @@ -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<string, string> { { "Content-Type", "application/x-www-form-urlencoded" } };
var data = new Dictionary<string, object>
{
{"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);
Expand Down Expand Up @@ -251,6 +266,8 @@ public Session CreateSession(string location = "", MediaMode mediaMode = MediaMo
/// <param name="encryption">
/// Enables <a href="https://tokbox.com/developer/guides/end-to-end-encryption/">end-to-end media encryption</a> in routed sessions.
/// </param>
/// <param name="archiveName">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.</param>
/// <param name="archiveResolution">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.</param>
/// <returns>
/// A Session object representing the new session. The <see cref="Session.Id"/> property of the
/// <see cref="Session"/> is the session ID, which uniquely identifies the session. You will use
Expand All @@ -259,7 +276,9 @@ public Session CreateSession(string location = "", MediaMode mediaMode = MediaMo
/// <a href="http://tokbox.com/opentok/libraries/client/js/reference/OT.html#initSession">OT.initSession()</a>
/// method (to initialize an OpenTok session).
/// </returns>
public async Task<Session> CreateSessionAsync(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL, bool encryption = false)
public async Task<Session> CreateSessionAsync(string location = "", MediaMode mediaMode = MediaMode.RELAYED, ArchiveMode archiveMode = ArchiveMode.MANUAL, bool encryption = false,
string archiveName = "",
RenderResolution archiveResolution = RenderResolution.StandardDefinitionLandscape)
{
if (!OpenTokUtils.TestIpAddress(location))
{
Expand All @@ -270,18 +289,23 @@ public async Task<Session> 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<string, string> { { "Content-Type", "application/x-www-form-urlencoded" } };
var data = new Dictionary<string, object>
{
{"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);
Expand Down
158 changes: 158 additions & 0 deletions OpenTokTest/Session.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -58,6 +60,162 @@ public void CreateSessionSimple()

mockClient.Verify(httpClient => httpClient.Post(It.Is<string>(url => url.Equals(expectedUrl)), It.IsAny<Dictionary<string, string>>(), It.IsAny<Dictionary<string, object>>()), Times.Once());
}

[Fact]
public void CreateSession_ShouldSendArchiveName()
{
var returnString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.Post(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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<HttpClient>().Object,
};

var exception = Assert.Throws<OpenTokArgumentException>(() => session.CreateSession(archiveName: new string('*', 81)));
Assert.Equal("ArchiveName length cannot exceed 80.", exception.Message);
}

[Fact]
public void CreateSession_ShouldSendArchiveResolution()
{
var returnString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.Post(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.Post(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.PostAsync(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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<HttpClient>().Object,
};

var exception = await Assert.ThrowsAsync<OpenTokArgumentException>(() => session.CreateSessionAsync(archiveName: new string('*', 81)));
Assert.Equal("ArchiveName length cannot exceed 80.", exception.Message);
}

[Fact]
public async Task CreateSessionAsync_ShouldSendArchiveResolution()
{
var returnString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.PostAsync(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sessions><Session><" +
"session_id>" + this.SessionId + "</session_id><partner_id>123456</partner_id><create_dt>" +
"Mon Mar 17 00:41:31 PDT 2014</create_dt></Session></sessions>";
const string expectedUrl = "session/create";
var mockClient = new Mock<HttpClient>();
mockClient.Setup(httpClient => httpClient.PostAsync(
expectedUrl,
It.IsAny<Dictionary<string, string>>(),
It.Is<Dictionary<string, object>>(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()
Expand Down