From 8d3a23f076704d1f7fd72bba18b648aa0a29cf16 Mon Sep 17 00:00:00 2001 From: tr00d Date: Wed, 13 Nov 2024 16:31:36 +0100 Subject: [PATCH 1/7] build: update libraries, and include Vonage SDK --- OpenTok/OpenTok.csproj | 3 ++- OpenTokTest/OpenTokTest.csproj | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenTok/OpenTok.csproj b/OpenTok/OpenTok.csproj index d549705..1cb1ce9 100644 --- a/OpenTok/OpenTok.csproj +++ b/OpenTok/OpenTok.csproj @@ -27,9 +27,10 @@ - + + diff --git a/OpenTokTest/OpenTokTest.csproj b/OpenTokTest/OpenTokTest.csproj index a444a73..5e886ab 100644 --- a/OpenTokTest/OpenTokTest.csproj +++ b/OpenTokTest/OpenTokTest.csproj @@ -289,7 +289,7 @@ - + From 5691ff16224aee5da3c0f25602189730254c5023 Mon Sep 17 00:00:00 2001 From: tr00d Date: Wed, 13 Nov 2024 17:18:19 +0100 Subject: [PATCH 2/7] feat: implement shim to target Vonage Video API --- OpenTok/OpenTok.cs | 42 +++++++-- OpenTok/Session.cs | 43 +++++++-- OpenTok/Util/HttpClient.cs | 168 ++++++++++++--------------------- OpenTok/Util/TokenGenerator.cs | 45 ++++++++- 4 files changed, 173 insertions(+), 125 deletions(-) diff --git a/OpenTok/OpenTok.cs b/OpenTok/OpenTok.cs index 9a348a7..9063bdf 100644 --- a/OpenTok/OpenTok.cs +++ b/OpenTok/OpenTok.cs @@ -54,6 +54,10 @@ public partial class OpenTok "1080x1920" }; + private readonly string applicationId; + private readonly string privateKey; + private bool IsShim => !string.IsNullOrEmpty(applicationId); + /// /// Enables writing request/response details to console. @@ -97,6 +101,20 @@ public OpenTok(int apiKey, string apiSecret, string apiUrl) Client = new HttpClient(apiKey, apiSecret, OpenTokServer); Debug = false; } + + /// + /// Use for OpenTok to target Vonage Video API + /// + /// The application Id. + /// The private key. + public OpenTok(string applicationId, string privateKey) + { + this.applicationId = applicationId; + this.privateKey = privateKey; + OpenTokServer = "https://api.opentok.com"; + Client = new HttpClient(applicationId, privateKey); + Debug = false; + } /// /// Creates a new OpenTok session. @@ -220,8 +238,10 @@ public Session CreateSession( throw new OpenTokWebException("Session could not be provided. Are ApiKey and ApiSecret correctly set?"); } var sessionId = xmlDoc.GetElementsByTagName("session_id")[0].ChildNodes[0].Value; - var apiKey = Convert.ToInt32(xmlDoc.GetElementsByTagName("partner_id")[0].ChildNodes[0].Value); - return new Session(sessionId, apiKey, ApiSecret, location, mediaMode, archiveMode); + + return this.IsShim + ? Session.FromShim(sessionId, this.applicationId, this.privateKey, location, mediaMode, archiveMode) + : Session.FromLegacy(sessionId, Convert.ToInt32(xmlDoc.GetElementsByTagName("partner_id")[0].ChildNodes[0].Value), ApiSecret, location, mediaMode, archiveMode); } /// @@ -342,8 +362,9 @@ public async Task CreateSessionAsync(string location = "", MediaMode me throw new OpenTokWebException("Session could not be provided. Are ApiKey and ApiSecret correctly set?"); } var sessionId = xmlDoc.GetElementsByTagName("session_id")[0].ChildNodes[0].Value; - var apiKey = Convert.ToInt32(xmlDoc.GetElementsByTagName("partner_id")[0].ChildNodes[0].Value); - return new Session(sessionId, apiKey, ApiSecret, location, mediaMode, archiveMode); + return this.IsShim + ? Session.FromShim(sessionId, this.applicationId, this.privateKey, location, mediaMode, archiveMode) + : Session.FromLegacy(sessionId, Convert.ToInt32(xmlDoc.GetElementsByTagName("partner_id")[0].ChildNodes[0].Value), ApiSecret, location, mediaMode, archiveMode); } /// @@ -393,8 +414,16 @@ public string GenerateToken(string sessionId, Role role = Role.PUBLISHER, double throw new OpenTokArgumentException("Invalid Session id " + sessionId); } - Session session = new Session(sessionId, ApiKey, ApiSecret); - return session.GenerateToken(role, expireTime, data, initialLayoutClassList); + return new TokenGenerator().GenerateSessionToken(new TokenData() + { + ApiSecret = this.ApiSecret, + Role = role, + ApiKey = this.ApiKey.ToString(), + Data = data, + SessionId = sessionId, + ExpireTime = expireTime, + InitialLayoutClasses = initialLayoutClassList ?? Enumerable.Empty(), + }); } /// @@ -444,6 +473,7 @@ public string GenerateT1Token(string sessionId, Role role = Role.PUBLISHER, doub throw new OpenTokArgumentException("Invalid Session id " + sessionId); } + Session session = new Session(sessionId, ApiKey, ApiSecret); return session.GenerateT1Token(role, expireTime, data, initialLayoutClassList); } diff --git a/OpenTok/Session.cs b/OpenTok/Session.cs index 043f521..abacd15 100644 --- a/OpenTok/Session.cs +++ b/OpenTok/Session.cs @@ -9,6 +9,8 @@ using Microsoft.IdentityModel.Tokens; using OpenTokSDK.Util; using OpenTokSDK.Exception; +using Vonage.Request; +using Vonage.Video.Authentication; namespace OpenTokSDK { @@ -97,14 +99,37 @@ internal Session(string sessionId, int apiKey, string apiSecret) this.ApiSecret = apiSecret; } - internal Session(string sessionId, int apiKey, string apiSecret, string location, MediaMode mediaMode, ArchiveMode archiveMode) + internal static Session FromShim(string sessionId, string applicationId, string privateKey, string location, MediaMode mediaMode, ArchiveMode archiveMode) + { + return new Session() + { + Id = sessionId, + ArchiveMode = archiveMode, + MediaMode = mediaMode, + Location = location, + ApplicationId = applicationId, + PrivateKey = privateKey, + }; + } + + internal static Session FromLegacy(string sessionId, int apiKey, string apiSecret, string location, MediaMode mediaMode, ArchiveMode archiveMode) + { + return new Session() + { + Id = sessionId, + ArchiveMode = archiveMode, + MediaMode = mediaMode, + Location = location, + ApiKey = apiKey, + ApiSecret = apiSecret, + }; + } + + private string ApplicationId { get; set; } + private string PrivateKey { get; set; } + + private Session() { - this.Id = sessionId; - this.ApiKey = apiKey; - this.ApiSecret = apiSecret; - this.Location = location; - this.MediaMode = mediaMode; - this.ArchiveMode = archiveMode; } /// @@ -169,7 +194,9 @@ public string GenerateT1Token(Role role = Role.PUBLISHER, double expireTime = 0, /// /// The token string. public string GenerateToken(Role role = Role.PUBLISHER, double expireTime = 0, string data = null, List initialLayoutClassList = null) => - new TokenGenerator().GenerateToken(new TokenData() + !string.IsNullOrEmpty(this.ApplicationId) + ? new TokenGenerator().GenerateSessionToken(this.ApplicationId, this.PrivateKey, this.Id) + : new TokenGenerator().GenerateSessionToken(new TokenData() { ApiSecret = this.ApiSecret, Role = role, diff --git a/OpenTok/Util/HttpClient.cs b/OpenTok/Util/HttpClient.cs index e5ac338..defe499 100644 --- a/OpenTok/Util/HttpClient.cs +++ b/OpenTok/Util/HttpClient.cs @@ -1,28 +1,28 @@ +#region + using System; using System.Collections.Generic; -using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; using System.Net; -using System.Security.Cryptography; -using System.Text; using System.Threading.Tasks; using System.Web; using System.Xml; using JWT; -using JWT.Algorithms; -using JWT.Serializers; -using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using OpenTokSDK.Constants; using OpenTokSDK.Exception; +using Vonage; +using Vonage.Request; + +#endregion #pragma warning disable CS1591 namespace OpenTokSDK.Util { /// - /// For internal use. + /// For internal use. /// public class HttpClient { @@ -34,10 +34,8 @@ public class HttpClient 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ); - /// - /// The custom user-agent value. The HttpClient will append this value, if it exists, to the initial user-agent value. - /// - public string CustomUserAgent { get; internal set; } + private readonly string appId; + private readonly string privateKey; internal HttpClient() { @@ -56,13 +54,27 @@ public HttpClient(int apiKey, string apiSecret, string apiUrl = "") _apiUrl = apiUrl; } + public HttpClient(string appId, string privateKey) + { + this.appId = appId; + this.privateKey = privateKey; + _apiUrl = "https://video.api.vonage.com"; + } + + private bool IsShim => !string.IsNullOrEmpty(appId); + + /// + /// The custom user-agent value. The HttpClient will append this value, if it exists, to the initial user-agent value. + /// + public string CustomUserAgent { get; internal set; } + /// - /// Turns on and off debug logging + /// Turns on and off debug logging /// public bool Debug { get; set; } = false; /// - /// Timeout in milliseconds for the HttpWebRequests sent by the client. + /// Timeout in milliseconds for the HttpWebRequests sent by the client. /// public int? RequestTimeout { get; set; } @@ -140,9 +152,9 @@ public virtual Task DeleteAsync(string url, Dictionary h public string DoRequest(string url, Dictionary specificHeaders, Dictionary bodyData) { - string data = GetRequestPostData(bodyData, specificHeaders); + var data = GetRequestPostData(bodyData, specificHeaders); var headers = GetRequestHeaders(specificHeaders); - HttpWebRequest request = CreateRequest(url, headers, data); + var request = CreateRequest(url, headers, data); DebugLog("Request Method: " + request.Method); DebugLog("Request URI: " + request.RequestUri); DebugLogHeaders(request.Headers, "Request"); @@ -155,7 +167,7 @@ public string DoRequest(string url, Dictionary specificHeaders, SendData(request, data); } - using (response = (HttpWebResponse) request.GetResponse()) + using (response = (HttpWebResponse)request.GetResponse()) { DebugLog("Response Status Code: " + response.StatusCode); DebugLog("Response Status Description: " + response.StatusDescription); @@ -181,21 +193,19 @@ public string DoRequest(string url, Dictionary specificHeaders, catch (WebException e) { DebugLog("WebException Status: " + e.Status + ", Message: " + e.Message); - response = (HttpWebResponse) e.Response; + response = (HttpWebResponse)e.Response; if (response != null) { DebugLog("Response Status Code: " + response.StatusCode); DebugLog("Response Status Description: " + response.StatusDescription); DebugLogHeaders(response.Headers, "Response"); if (Debug) - { using (var stream = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException( "Response stream null"))) { DebugLog("Response Body: " + stream.ReadToEnd()); } - } } else if (e.Status == WebExceptionStatus.SendFailure) { @@ -211,9 +221,9 @@ public string DoRequest(string url, Dictionary specificHeaders, public async Task DoRequestAsync(string url, Dictionary specificHeaders, Dictionary bodyData) { - string data = GetRequestPostData(bodyData, specificHeaders); + var data = GetRequestPostData(bodyData, specificHeaders); var headers = GetRequestHeaders(specificHeaders); - HttpWebRequest request = CreateRequest(url, headers, data); + var request = CreateRequest(url, headers, data); DebugLog("Request Method: " + request.Method); DebugLog("Request URI: " + request.RequestUri); DebugLogHeaders(request.Headers, "Request"); @@ -252,14 +262,13 @@ public async Task DoRequestAsync(string url, Dictionary catch (WebException e) { DebugLog("WebException Status: " + e.Status + ", Message: " + e.Message); - response = (HttpWebResponse) e.Response; + response = (HttpWebResponse)e.Response; if (response != null) { DebugLog("Response Status Code: " + response.StatusCode); DebugLog("Response Status Description: " + response.StatusDescription); DebugLogHeaders(response.Headers, "Response"); if (Debug) - { using (var stream = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException( "Response stream null"))) @@ -267,7 +276,6 @@ public async Task DoRequestAsync(string url, Dictionary var body = await stream.ReadToEndAsync(); DebugLog($"Response Body: {body}"); } - } } OpenTokUtils.ValidateTlsVersion(e); @@ -277,7 +285,7 @@ public async Task DoRequestAsync(string url, Dictionary public XmlDocument ReadXmlResponse(string xml) { - XmlDocument xmlDoc = new XmlDocument(); + var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); return xmlDoc; } @@ -285,7 +293,7 @@ public XmlDocument ReadXmlResponse(string xml) private void SendData(HttpWebRequest request, string data) { LastRequest = data; - using (StreamWriter stream = new StreamWriter(request.GetRequestStream())) + using (var stream = new StreamWriter(request.GetRequestStream())) { stream.Write(data); } @@ -293,7 +301,7 @@ private void SendData(HttpWebRequest request, string data) private async Task SendDataAsync(HttpWebRequest request, string data) { - using (StreamWriter stream = new StreamWriter(await request.GetRequestStreamAsync().ConfigureAwait(false))) + using (var stream = new StreamWriter(await request.GetRequestStreamAsync().ConfigureAwait(false))) { await stream.WriteAsync(data).ConfigureAwait(false); } @@ -301,16 +309,13 @@ private async Task SendDataAsync(HttpWebRequest request, string data) private HttpWebRequest CreateRequest(string url, Dictionary headers, string data) { - Uri uri = new Uri($"{_apiUrl}/{url}"); - HttpWebRequest request = (HttpWebRequest) WebRequest.Create(uri); - if (RequestTimeout != null) - { - request.Timeout = (int) RequestTimeout; - } + var uri = new Uri($"{_apiUrl}/{url}"); + var request = (HttpWebRequest)WebRequest.Create(uri); + if (RequestTimeout != null) request.Timeout = (int)RequestTimeout; request.ContentLength = data.Length; - request.UserAgent = this.CustomUserAgent != null - ? $"{OpenTokVersion.GetVersion()}/{this.CustomUserAgent}" + request.UserAgent = CustomUserAgent != null + ? $"{OpenTokVersion.GetVersion()}/{CustomUserAgent}" : OpenTokVersion.GetVersion(); if (headers.ContainsKey("Content-Type")) { @@ -325,10 +330,7 @@ private HttpWebRequest CreateRequest(string url, Dictionary head headers.Remove("Method"); } - foreach (KeyValuePair entry in headers) - { - request.Headers.Add(entry.Key, entry.Value); - } + foreach (var entry in headers) request.Headers.Add(entry.Key, entry.Value); return request; } @@ -346,14 +348,9 @@ private string GetRequestPostData(Dictionary data, Dictionary data, Dictionary parameters) { - string data = string.Empty; - foreach (KeyValuePair pair in parameters) - { + var data = string.Empty; + foreach (var pair in parameters) data += pair.Key + "=" + HttpUtility.UrlEncode(pair.Value.ToString()) + "&"; - } return data.Substring(0, data.Length - 1); } @@ -379,68 +374,26 @@ private int CurrentTime() { IDateTimeProvider provider = new UtcDateTimeProvider(); var now = provider.GetNow(); - int secondsSinceEpoch = (int) Math.Round((now - _unixEpoch).TotalSeconds); + var secondsSinceEpoch = (int)Math.Round((now - _unixEpoch).TotalSeconds); return secondsSinceEpoch; } - private string GenerateJwt(int key, string secret, int expiryPeriod = 300) - { - int now = CurrentTime(); - int expiry = now + expiryPeriod; - var payload = new Dictionary - { - {"iss", Convert.ToString(key)}, - {"ist", "project"}, - {"iat", now}, - {"exp", expiry} - }; - IJwtAlgorithm algorithm = new HMACSHA256Algorithm(); - IJsonSerializer serializer = new JsonNetSerializer(); - IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); - IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder); - var token = encoder.Encode(payload, secret); - return token; - } - - private string GenerateJwt2(int apiKey, string apiSecret, int expiryPeriod = 300) + private string GenerateJwt() { - var tokenData = new byte[64]; - var rng = RandomNumberGenerator.Create(); - rng.GetBytes(tokenData); - var jwtTokenId = Convert.ToBase64String(tokenData); - var payload = new Dictionary - { - {"iss", apiKey}, - {"ist", "project"}, - {"role", "publisher"}, - {"session_id", "sessionid"}, - {"scope", "session.connect"}, - {"iat", (long) (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds}, - {"exp", (long) (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 300}, - {"jti", jwtTokenId}, - {"initial_layout_list", ""}, - {"nonce", OpenTokUtils.GetRandomNumber()}, - }; - // generate token that is valid for 7 days - var tokenHandler = new JwtSecurityTokenHandler(); - var key = Encoding.ASCII.GetBytes(apiSecret); - var tokenDescriptor = new SecurityTokenDescriptor - { - //Expires = DateTime.UtcNow.AddDays(7), - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256), - Claims = payload, - }; - var token = tokenHandler.CreateToken(tokenDescriptor); - var a = tokenHandler.WriteToken(token); - return a; + return IsShim + ? new TokenGenerator().GenerateToken(appId, privateKey) + : new TokenGenerator().GenerateLegacyToken(_apiKey, _apiSecret); } private Dictionary GetCommonHeaders() { return new Dictionary { - {"X-OPENTOK-AUTH", GenerateJwt(_apiKey, _apiSecret)}, - {"X-TB-VERSION", "1"}, + { + IsShim ? "Authorization" : "X-OPENTOK-AUTH", + IsShim ? "Bearer " + GenerateJwt() : GenerateJwt() + }, + { "X-TB-VERSION", "1" } }; } @@ -456,16 +409,11 @@ private void DebugLog(string message) private void DebugLogHeaders(WebHeaderCollection headers, string label) { if (Debug) - { - for (int i = 0; i < headers.Count; ++i) + for (var i = 0; i < headers.Count; ++i) { - string header = headers.GetKey(i); - foreach (string value in headers.GetValues(i)) - { - DebugLog(label + " Header: " + header + " = " + value); - } + var header = headers.GetKey(i); + foreach (var value in headers.GetValues(i)) DebugLog(label + " Header: " + header + " = " + value); } - } } } } \ No newline at end of file diff --git a/OpenTok/Util/TokenGenerator.cs b/OpenTok/Util/TokenGenerator.cs index fa9da6d..2a6b4a7 100644 --- a/OpenTok/Util/TokenGenerator.cs +++ b/OpenTok/Util/TokenGenerator.cs @@ -5,8 +5,14 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Cryptography; using System.Text; +using JWT; +using JWT.Algorithms; +using JWT.Serializers; using Microsoft.IdentityModel.Tokens; using OpenTokSDK.Exception; +using Vonage; +using Vonage.Request; +using Vonage.Video.Authentication; #endregion @@ -14,7 +20,7 @@ namespace OpenTokSDK.Util { internal class TokenGenerator { - public string GenerateToken(TokenData data) + public string GenerateSessionToken(TokenData data) { var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor @@ -26,6 +32,43 @@ public string GenerateToken(TokenData data) var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } + + public string GenerateSessionToken(string applicationId, string privateKey, string sessionId) + { + return new VideoTokenGenerator().GenerateToken( + Credentials.FromAppIdAndPrivateKey(applicationId, privateKey), + TokenAdditionalClaims.Parse(sessionId)).GetSuccessUnsafe().Token; + } + + public string GenerateLegacyToken(int key, string secret, int expiryPeriod = 300) + { + var now = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds(); + var expiry = now + expiryPeriod; + var payload = new Dictionary + { + { "iss", Convert.ToString(key) }, + { "ist", "project" }, + { "iat", now }, + { "exp", expiry } + }; + IJwtAlgorithm algorithm = new HMACSHA256Algorithm(); + IJsonSerializer serializer = new JsonNetSerializer(); + IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); + IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder); + var token = encoder.Encode(payload, secret); + return token; + } + + public string GenerateToken(string applicationId, string privateKey) + { + return new Jwt().GenerateToken(Credentials.FromAppIdAndPrivateKey(applicationId, privateKey)) + .GetSuccessUnsafe(); + } + + public string GenerateT1Token() + { + return null; + } } internal struct TokenData From fbecd537baeb2cebff1f58599244badb98302841 Mon Sep 17 00:00:00 2001 From: tr00d Date: Thu, 14 Nov 2024 11:07:35 +0100 Subject: [PATCH 3/7] feat: use either apikey or appid in all calls --- OpenTok/OpenTok.AudioConnector.cs | 4 +- OpenTok/OpenTok.Render.cs | 2 +- OpenTok/OpenTok.cs | 106 +++++++++++++++--------------- 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/OpenTok/OpenTok.AudioConnector.cs b/OpenTok/OpenTok.AudioConnector.cs index 2544b90..809d2f1 100644 --- a/OpenTok/OpenTok.AudioConnector.cs +++ b/OpenTok/OpenTok.AudioConnector.cs @@ -14,7 +14,7 @@ public partial class OpenTok public async Task StartAudioConnectorAsync(AudioConnectorStartRequest request) { var response = await this.Client.PostAsync( - $"v2/project/{this.ApiKey}/connect", + $"v2/project/{this.GetOpenTokId()}/connect", GetHeaderDictionary("application/json"), request.ToDataDictionary()); return JsonConvert.DeserializeObject(response); @@ -26,7 +26,7 @@ public async Task StartAudioConnectorAsync(AudioConnectorStartRe /// The OpenTok connection ID for the Audio Connector WebSocket connection in the OpenTok session. See . public async Task StopAudioConnectorAsync(string connectionId) => _ = await this.Client.PostAsync( - $"v2/project/{this.ApiKey}/connect/{connectionId}/stop", + $"v2/project/{this.GetOpenTokId()}/connect/{connectionId}/stop", new Dictionary(), new Dictionary()); } diff --git a/OpenTok/OpenTok.Render.cs b/OpenTok/OpenTok.Render.cs index 9d02cab..462ddc8 100644 --- a/OpenTok/OpenTok.Render.cs +++ b/OpenTok/OpenTok.Render.cs @@ -59,7 +59,7 @@ await this.Client.DeleteAsync( this.BuildUrlWithRouteParameter(RenderEndpoint, renderId), new Dictionary()); - private string BuildUrl(string endpoint) => $"v2/project/{this.ApiKey}{endpoint}"; + private string BuildUrl(string endpoint) => $"v2/project/{this.GetOpenTokId()}{endpoint}"; private string BuildUrlWithQueryParameter(string endpoint, string queryParameter) => $"{this.BuildUrl(endpoint)}?{queryParameter}"; diff --git a/OpenTok/OpenTok.cs b/OpenTok/OpenTok.cs index 9063bdf..90c1a7b 100644 --- a/OpenTok/OpenTok.cs +++ b/OpenTok/OpenTok.cs @@ -550,7 +550,7 @@ public Archive StartArchive(string sessionId, string name = "", bool hasVideo = { throw new OpenTokArgumentException("Session not valid"); } - string url = $"v2/project/{ApiKey}/archive"; + string url = $"v2/project/{this.GetOpenTokId()}/archive"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "sessionId", sessionId }, { "name", name }, { "hasVideo", hasVideo }, { "hasAudio", hasAudio }, { "outputMode", outputMode.ToString().ToLowerInvariant() } }; @@ -593,6 +593,8 @@ public Archive StartArchive(string sessionId, string name = "", bool hasVideo = return OpenTokUtils.GenerateArchive(response, ApiKey, ApiSecret, OpenTokServer); } + private string GetOpenTokId() => this.IsShim ? this.applicationId : this.ApiKey.ToString(); + /// /// Starts archiving an OpenTok session. /// @@ -665,7 +667,7 @@ public async Task StartArchiveAsync(string sessionId, string name = "", { throw new OpenTokArgumentException("Session not valid"); } - string url = $"v2/project/{ApiKey}/archive"; + string url = $"v2/project/{this.GetOpenTokId()}/archive"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -726,7 +728,7 @@ public async Task StartArchiveAsync(string sessionId, string name = "", /// The Archive object corresponding to the archive being stopped. public Archive StopArchive(string archiveId) { - string url = string.Format("v2/project/{0}/archive/{1}/stop", ApiKey, archiveId); + string url = string.Format("v2/project/{0}/archive/{1}/stop", this.GetOpenTokId(), archiveId); var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = Client.Post(url, headers, new Dictionary()); @@ -744,7 +746,7 @@ public Archive StopArchive(string archiveId) /// The Archive object corresponding to the archive being stopped. public async Task StopArchiveAsync(string archiveId) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}/stop"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/stop"; var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = await Client.PostAsync(url, headers, new Dictionary()); @@ -772,7 +774,7 @@ public ArchiveList ListArchives(int offset = 0, int count = 0, string sessionId { throw new OpenTokArgumentException("count cannot be smaller than 0"); } - string url = $"v2/project/{ApiKey}/archive?offset={offset}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive?offset={offset}"; if (count > 0) { @@ -815,7 +817,7 @@ public async Task ListArchivesAsync(int offset = 0, int count = 0, throw new OpenTokArgumentException("count cannot be smaller than 0"); } - string url = $"v2/project/{this.ApiKey}/archive?offset={offset}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive?offset={offset}"; if (count > 0) { url = $"{url}&count={count}"; @@ -843,7 +845,7 @@ public async Task ListArchivesAsync(int offset = 0, int count = 0, /// The object. public Archive GetArchive(string archiveId) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}"; string response = Client.Get(url); return JsonConvert.DeserializeObject(response); } @@ -855,7 +857,7 @@ public Archive GetArchive(string archiveId) /// The object. public async Task GetArchiveAsync(string archiveId) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}"; string response = await Client.GetAsync(url, null); return JsonConvert.DeserializeObject(response); } @@ -871,7 +873,7 @@ public async Task GetArchiveAsync(string archiveId) /// The archive ID of the archive you want to delete. public void DeleteArchive(string archiveId) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}"; var headers = new Dictionary(); Client.Delete(url, headers); } @@ -887,7 +889,7 @@ public void DeleteArchive(string archiveId) /// The archive ID of the archive you want to delete. public Task DeleteArchiveAsync(string archiveId) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}"; var headers = new Dictionary(); return Client.DeleteAsync(url, headers); } @@ -915,7 +917,7 @@ public void AddStreamToArchive(string archiveId, string streamId, bool hasAudio throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -950,7 +952,7 @@ public Task AddStreamToArchiveAsync(string archiveId, string streamId, bool hasA throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -980,7 +982,7 @@ public void RemoveStreamFromArchive(string archiveId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "removeStream", streamId } }; @@ -1005,7 +1007,7 @@ public Task RemoveStreamFromArchiveAsync(string archiveId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "removeStream", streamId } }; @@ -1030,7 +1032,7 @@ public Stream GetStream(string sessionId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty", nameof(streamId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream/{streamId}"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream/{streamId}"; string response = Client.Get(url); Stream stream = JsonConvert.DeserializeObject(response); Stream streamCopy = new Stream(); @@ -1056,7 +1058,7 @@ public async Task GetStreamAsync(string sessionId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty", nameof(streamId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream/{streamId}"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream/{streamId}"; string response = await Client.GetAsync(url); Stream stream = JsonConvert.DeserializeObject(response); Stream streamCopy = new Stream(); @@ -1077,7 +1079,7 @@ public StreamList ListStreams(string sessionId) { throw new OpenTokArgumentException("The sessionId cannot be null or empty", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream"; string response = Client.Get(url); JObject streams = JObject.Parse(response); JArray streamsArray = (JArray)streams["items"]; @@ -1098,7 +1100,7 @@ public async Task ListStreamsAsync(string sessionId) { throw new OpenTokArgumentException("The sessionId cannot be null or empty", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream"; string response = await Client.GetAsync(url); JObject streams = JObject.Parse(response); JArray streamsArray = (JArray)streams["items"]; @@ -1127,7 +1129,7 @@ public void ForceDisconnect(string sessionId, string connectionId) { throw new OpenTokArgumentException("Invalid session Id", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}"; var headers = new Dictionary(); Client.Delete(url, headers); } @@ -1153,7 +1155,7 @@ public async Task ForceDisconnectAsync(string sessionId, string connectionId) { throw new OpenTokArgumentException("Invalid session Id", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}"; var headers = new Dictionary(); await Client.DeleteAsync(url, headers); } @@ -1221,7 +1223,7 @@ public Broadcast StartBroadcast(string sessionId, bool hls = true, List rt int maxDuration = 7200, BroadcastLayout layout = null, StreamMode? streamMode = null, bool dvr = false, bool? lowLatency = null, string multiBroadcastTag = null, bool hasAudio = true, bool hasVideo = true) { var data = PrepareStartBroadcastData(sessionId, hls, rtmpList, resolution, maxDuration, layout, streamMode, dvr, lowLatency, multiBroadcastTag, hasAudio, hasVideo); - string url = $"v2/project/{ApiKey}/broadcast"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast"; var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = Client.Post(url, headers, data); return OpenTokUtils.GenerateBroadcast(response, ApiKey, ApiSecret, OpenTokServer); @@ -1290,7 +1292,7 @@ public async Task StartBroadcastAsync(string sessionId, bool hls = tr int maxDuration = 7200, BroadcastLayout layout = null, StreamMode? streamMode = null, bool dvr = false, bool? lowLatency = null, string multiBroadcastTag = null, bool hasAudio = true, bool hasVideo = true) { var data = PrepareStartBroadcastData(sessionId, hls, rtmpList, resolution, maxDuration, layout, streamMode, dvr, lowLatency, multiBroadcastTag, hasAudio, hasVideo); - string url = $"v2/project/{ApiKey}/broadcast"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast"; var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = await Client.PostAsync(url, headers, data); return OpenTokUtils.GenerateBroadcast(response, ApiKey, ApiSecret, OpenTokServer); @@ -1398,7 +1400,7 @@ private Dictionary PrepareStartBroadcastData(string sessionId, b /// public Broadcast StopBroadcast(string broadcastId) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/stop"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/stop"; var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = Client.Post(url, headers, new Dictionary()); return JsonConvert.DeserializeObject(response); @@ -1418,7 +1420,7 @@ public Broadcast StopBroadcast(string broadcastId) /// public async Task StopBroadcastAsync(string broadcastId) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/stop"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/stop"; var headers = new Dictionary { { "Content-Type", "application/json" } }; string response = await Client.PostAsync(url, headers, new Dictionary()); @@ -1438,7 +1440,7 @@ public async Task StopBroadcastAsync(string broadcastId) /// public Broadcast GetBroadcast(string broadcastId) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}"; string response = Client.Get(url); return OpenTokUtils.GenerateBroadcast(response, ApiKey, ApiSecret, OpenTokServer); } @@ -1456,7 +1458,7 @@ public Broadcast GetBroadcast(string broadcastId) /// public async Task GetBroadcastAsync(string broadcastId) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}"; string response = await Client.GetAsync(url); return OpenTokUtils.GenerateBroadcast(response, ApiKey, ApiSecret, OpenTokServer); } @@ -1469,7 +1471,7 @@ public async Task GetBroadcastAsync(string broadcastId) /// The BroadcastLayout that defines layout options for the broadcast. public void SetBroadcastLayout(string broadcastId, BroadcastLayout layout) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/layout"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/layout"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary(); if (layout != null) @@ -1509,7 +1511,7 @@ public void SetBroadcastLayout(string broadcastId, BroadcastLayout layout) /// The BroadcastLayout that defines layout options for the broadcast. public async Task SetBroadcastLayoutAsync(string broadcastId, BroadcastLayout layout) { - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/layout"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/layout"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary(); if (layout != null) @@ -1550,7 +1552,7 @@ public async Task SetBroadcastLayoutAsync(string broadcastId, BroadcastLayout la /// public bool SetArchiveLayout(string archiveId, ArchiveLayout layout) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/layout"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary(); @@ -1611,7 +1613,7 @@ public void AddStreamToBroadcast(string broadcastId, string streamId, bool hasAu throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -1647,7 +1649,7 @@ public Task AddStreamToBroadcastAsync(string broadcastId, string streamId, bool throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -1678,7 +1680,7 @@ public void RemoveStreamFromBroadcast(string broadcastId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -1707,7 +1709,7 @@ public Task RemoveStreamFromBroadcastAsync(string broadcastId, string streamId) throw new OpenTokArgumentException("The streamId cannot be null or empty"); } - string url = $"v2/project/{ApiKey}/broadcast/{broadcastId}/streams"; + string url = $"v2/project/{this.GetOpenTokId()}/broadcast/{broadcastId}/streams"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { @@ -1727,7 +1729,7 @@ public Task RemoveStreamFromBroadcastAsync(string broadcastId, string streamId) /// public async Task SetArchiveLayoutAsync(string archiveId, ArchiveLayout layout) { - string url = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + string url = $"v2/project/{this.GetOpenTokId()}/archive/{archiveId}/layout"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary(); @@ -1777,7 +1779,7 @@ public async Task SetArchiveLayoutAsync(string archiveId, ArchiveLayout la /// A list of StreamsProperties that defines class lists for one or more streams in the session. public void SetStreamClassLists(string sessionId, List streams) { - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var items = new List(); Dictionary data = new Dictionary(); @@ -1815,7 +1817,7 @@ public void SetStreamClassLists(string sessionId, List streams /// A list of StreamsProperties that defines class lists for one or more streams in the session. public async Task SetStreamClassListsAsync(string sessionId, List streams) { - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var items = new List(); Dictionary data = new Dictionary(); @@ -1854,8 +1856,8 @@ public void Signal(string sessionId, SignalProperties signalProperties, string c } string url = String.IsNullOrEmpty(connectionId) - ? $"v2/project/{ApiKey}/session/{sessionId}/signal" - : $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}/signal"; + ? $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/signal" + : $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}/signal"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary @@ -1880,8 +1882,8 @@ public async Task SignalAsync(string sessionId, SignalProperties signalPropertie } string url = String.IsNullOrEmpty(connectionId) - ? $"v2/project/{ApiKey}/session/{sessionId}/signal" - : $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}/signal"; + ? $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/signal" + : $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}/signal"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary @@ -1915,8 +1917,8 @@ public void PlayDTMF(string sessionId, string digits, string connectionId = null } string url = string.IsNullOrEmpty(connectionId) - ? $"v2/project/{ApiKey}/session/{sessionId}/play-dtmf" - : $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}/play-dtmf"; + ? $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/play-dtmf" + : $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}/play-dtmf"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "digits", digits } }; @@ -1937,8 +1939,8 @@ public Task PlayDTMFAsync(string sessionId, string digits, string connectionId = } string url = string.IsNullOrEmpty(connectionId) - ? $"v2/project/{ApiKey}/session/{sessionId}/play-dtmf" - : $"v2/project/{ApiKey}/session/{sessionId}/connection/{connectionId}/play-dtmf"; + ? $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/play-dtmf" + : $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/connection/{connectionId}/play-dtmf"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "digits", digits } }; @@ -1976,7 +1978,7 @@ public Sip Dial(string sessionId, string token, string sipUri, DialOptions optio throw new OpenTokArgumentException("Session Id is not valid"); } - string url = $"v2/project/{ApiKey}/dial"; + string url = $"v2/project/{this.GetOpenTokId()}/dial"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary @@ -2036,7 +2038,7 @@ public async Task DialAsync(string sessionId, string token, string sipUri, throw new OpenTokArgumentException("Session Id is not valid"); } - string url = $"v2/project/{ApiKey}/dial"; + string url = $"v2/project/{this.GetOpenTokId()}/dial"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary @@ -2081,7 +2083,7 @@ public void ForceMuteStream(string sessionId, string streamId) throw new OpenTokArgumentException("The streamId cannot be empty.", nameof(streamId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream/{streamId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream/{streamId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; Client.Post(url, headers, null); @@ -2109,7 +2111,7 @@ public async Task ForceMuteStreamAsync(string sessionId, string streamId) throw new OpenTokArgumentException("The streamId cannot be empty.", nameof(streamId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/stream/{streamId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/stream/{streamId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; await Client.PostAsync(url, headers, null); @@ -2138,7 +2140,7 @@ public void ForceMuteAll(string sessionId, string[] excludedStreamIds) throw new OpenTokArgumentException("The sessionId cannot be empty.", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "active", true }, { "excludedStreamIds", excludedStreamIds } }; @@ -2168,7 +2170,7 @@ public async Task ForceMuteAllAsync(string sessionId, string[] excludedStreamIds throw new OpenTokArgumentException("The sessionId cannot be empty.", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "active", true }, { "excludedStreamIds", excludedStreamIds } }; @@ -2198,7 +2200,7 @@ public void DisableForceMute(string sessionId) throw new OpenTokArgumentException("The sessionId cannot be empty.", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "active", false } }; @@ -2228,7 +2230,7 @@ public async Task DisableForceMuteAsync(string sessionId) throw new OpenTokArgumentException("The sessionId cannot be empty.", nameof(sessionId)); } - string url = $"v2/project/{ApiKey}/session/{sessionId}/mute"; + string url = $"v2/project/{this.GetOpenTokId()}/session/{sessionId}/mute"; var headers = new Dictionary { { "Content-Type", "application/json" } }; var data = new Dictionary { { "active", false } }; From ab50fa879f9b2ebd888ffd4380a669daeab2a666 Mon Sep 17 00:00:00 2001 From: tr00d Date: Thu, 14 Nov 2024 11:16:30 +0100 Subject: [PATCH 4/7] feat: add tests for StartArchive note: these tests are pointless as just they assert the called url. The custom HttpClient is mocked, so all the logic is avoided... --- OpenTokTest/ArchiveTests.cs | 3078 ++++++++++++++++++----------------- OpenTokTest/TestBase.cs | 2 + 2 files changed, 1562 insertions(+), 1518 deletions(-) diff --git a/OpenTokTest/ArchiveTests.cs b/OpenTokTest/ArchiveTests.cs index c0ac0e9..2253233 100644 --- a/OpenTokTest/ArchiveTests.cs +++ b/OpenTokTest/ArchiveTests.cs @@ -1,4 +1,6 @@ -using System; +#region + +using System; using System.Collections.Generic; using System.Threading.Tasks; using Moq; @@ -7,1775 +9,1815 @@ using OpenTokSDK.Util; using Xunit; -namespace OpenTokSDKTest +#endregion + +namespace OpenTokSDKTest; + +public class ArchiveTests : TestBase { - public class ArchiveTests : TestBase + [Fact] + public void StartArchive() { - // StartArchive + var responseJson = GetResponseJson(); - [Fact] - public void StartArchive() - { - string responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Returns(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(SessionId, null); - var mockClient = new Mock(); + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Returns(responseJson); + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public void StartArchiveWithShim() + { + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(GetResponseJson("StartArchive")); + var opentok = new OpenTok(ApplicationId, PrivateKey) + { + Client = mockClient.Object + }; + _ = opentok.StartArchive(SessionId, null); + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApplicationId + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public async Task StartArchiveAsync() + { + var responseJson = GetResponseJson(); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(SessionId, null); + var mockClient = new Mock(); - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(SessionId, null); + + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); + + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } + + [Fact] + public async Task StartArchiveAsyncWithShim() + { + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), It.IsAny>(), + It.IsAny>())).ReturnsAsync(GetResponseJson("StartArchiveAsync")); + var opentok = new OpenTok(ApplicationId, PrivateKey) + { + Client = mockClient.Object + }; + _ = await opentok.StartArchiveAsync(SessionId, null); + mockClient.Verify( + httpClient => httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApplicationId + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - [Fact] - public async Task StartArchiveAsync() - { - string responseJson = GetResponseJson(); + [Fact] + public void StartArchiveIndividual() + { + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(SessionId, outputMode: OutputMode.INDIVIDUAL); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(SessionId, null); + Assert.NotNull(archive); + Assert.Equal(OutputMode.INDIVIDUAL, archive.OutputMode); - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } + [Fact] + public async Task StartArchiveAsyncIndividual() + { + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - [Fact] - public void StartArchiveIndividual() - { - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(SessionId, outputMode: OutputMode.INDIVIDUAL); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(SessionId, outputMode: OutputMode.INDIVIDUAL); - Assert.NotNull(archive); - Assert.Equal(OutputMode.INDIVIDUAL, archive.OutputMode); + Assert.NotNull(archive); + Assert.Equal(OutputMode.INDIVIDUAL, archive.OutputMode); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - [Fact] - public async Task StartArchiveAsyncIndividual() - { - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + [Fact] + public void StartArchiveWithSDResolution() + { + var sessionId = "SESSIONID"; + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(SessionId, outputMode: OutputMode.INDIVIDUAL); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); - Assert.NotNull(archive); - Assert.Equal(OutputMode.INDIVIDUAL, archive.OutputMode); + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - [Fact] - public void StartArchiveWithSDResolution() - { - string sessionId = "SESSIONID"; - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + [Fact] + public async Task StartArchiveAsyncWithSDResolution() + { + var sessionId = "SESSIONID"; + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); + var archive = + await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); - [Fact] - public async Task StartArchiveAsyncWithSDResolution() - { - string sessionId = "SESSIONID"; - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - - Archive archive = - await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); - - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); - - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } - - [Fact] - public void StartArchiveScreenShareInvalidType() - { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - ArchiveLayout layout = new ArchiveLayout - {Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.BestFit}; + [Fact] + public void StartArchiveScreenShareInvalidType() + { + var opentok = new OpenTok(ApiKey, ApiSecret); - var exception = Assert.Throws(() => opentok.StartArchive("abcd", layout: layout)); - Assert.Equal( - $"Could not set screenShareLayout. When screenShareType is set, layout.Type must be bestFit, was {layout.Type}", - exception.Message); - } + var layout = new ArchiveLayout + { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.BestFit }; - [Fact] - public async Task StartArchiveAsyncScreenShareInvalidType() - { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - ArchiveLayout layout = new ArchiveLayout - {Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.BestFit}; - - var exception = await Assert.ThrowsAsync(async () => - await opentok.StartArchiveAsync("abcd", layout: layout)); - Assert.Equal( - $"Could not set screenShareLayout. When screenShareType is set, layout.Type must be bestFit, was {layout.Type}", - exception.Message); - } - - [Fact] - public void StartArchiveCustomLayout() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + var exception = Assert.Throws(() => opentok.StartArchive("abcd", layout: layout)); + Assert.Equal( + $"Could not set screenShareLayout. When screenShareType is set, layout.Type must be bestFit, was {layout.Type}", + exception.Message); + } - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + [Fact] + public async Task StartArchiveAsyncScreenShareInvalidType() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout + { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.BestFit }; + + var exception = await Assert.ThrowsAsync(async () => + await opentok.StartArchiveAsync("abcd", layout: layout)); + Assert.Equal( + $"Could not set screenShareLayout. When screenShareType is set, layout.Type must be bestFit, was {layout.Type}", + exception.Message); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.custom, - StyleSheet = "stream.instructor {position: absolute; width: 100%; height:50%;}" - }; - Archive archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout); - - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); - - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } + [Fact] + public void StartArchiveCustomLayout() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout + { + Type = LayoutType.custom, + StyleSheet = "stream.instructor {position: absolute; width: 100%; height:50%;}" + }; + var archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout); + + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); + + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - [Fact] - public async Task StartArchiveAsyncCustomLayout() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + [Fact] + public async Task StartArchiveAsyncCustomLayout() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.custom, - StyleSheet = "stream.instructor {position: absolute; width: 100%; height:50%;}" - }; - Archive archive = await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, - resolution: resolution, layout: layout); - - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); - - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } - - [Fact] - public void StartArchiveVerticalLayout() + var layout = new ArchiveLayout { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + Type = LayoutType.custom, + StyleSheet = "stream.instructor {position: absolute; width: 100%; height:50%;}" + }; + var archive = await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, + resolution: resolution, layout: layout); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.verticalPresentation, - StyleSheet = "" - }; - - Archive archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout); - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - [Fact] - public async Task StartArchiveAsyncVerticalLayout() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.verticalPresentation, - StyleSheet = "" - }; - - Archive archive = await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, - resolution: resolution, layout: layout); - - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } - - [Fact] - public void StartArchiveVerticalLayoutWithStyleSheet() + [Fact] + public void StartArchiveVerticalLayout() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout + { + Type = LayoutType.verticalPresentation, + StyleSheet = "" + }; + + var archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout); + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public async Task StartArchiveAsyncVerticalLayout() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout + { + Type = LayoutType.verticalPresentation, + StyleSheet = "" + }; + + var archive = await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, + resolution: resolution, layout: layout); + + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public void StartArchiveVerticalLayoutWithStyleSheet() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + Type = LayoutType.verticalPresentation, + StyleSheet = "blah" + }; - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + var exception = Assert.Throws(() => + opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout)); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.verticalPresentation, - StyleSheet = "blah" - }; + Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", + exception.Message); + } - var exception = Assert.Throws(() => - opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout)); + [Fact] + public async Task StartArchiveAsyncVerticalLayoutWithStyleSheet() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + + var mockClient = new Mock(); - Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", - exception.Message); - } + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - [Fact] - public async Task StartArchiveAsyncVerticalLayoutWithStyleSheet() + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); + Type = LayoutType.verticalPresentation, + StyleSheet = "blah" + }; - var mockClient = new Mock(); + var exception = await Assert.ThrowsAsync(async () => + await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout)); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", + exception.Message); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout - { - Type = LayoutType.verticalPresentation, - StyleSheet = "blah" - }; + [Fact] + public void StartArchiveCustomLayoutMissingStylesheet() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - var exception = await Assert.ThrowsAsync(async () => - await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout)); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", - exception.Message); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var layout = new ArchiveLayout { Type = LayoutType.custom }; - [Fact] - public void StartArchiveCustomLayoutMissingStylesheet() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + var exception = Assert.Throws(() => + opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout)); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", + exception.Message); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - var layout = new ArchiveLayout {Type = LayoutType.custom}; + [Fact] + public async Task StartArchiveAsyncCustomLayoutMissingStylesheet() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - var exception = Assert.Throws(() => - opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout)); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", - exception.Message); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - [Fact] - public async Task StartArchiveAsyncCustomLayoutMissingStylesheet() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + var layout = new ArchiveLayout { Type = LayoutType.custom }; + var exception = await Assert.ThrowsAsync(async () => + await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, + layout: layout)); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", + exception.Message); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + [Fact] + public void StartArchiveWithHDResolution() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - var layout = new ArchiveLayout {Type = LayoutType.custom}; - var exception = await Assert.ThrowsAsync(async () => - await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution, - layout: layout)); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - Assert.Equal("Could not set layout, stylesheet must be set if and only if type is custom", - exception.Message); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); - [Fact] - public void StartArchiveWithHDResolution() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); + + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public async Task StartArchiveAsyncWithHDResolution() + { + var sessionId = "SESSIONID"; + var resolution = "1280x720"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); + var archive = + await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + Assert.NotNull(archive); + Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); + Assert.Equal(resolution, archive.Resolution); + + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - [Fact] - public async Task StartArchiveAsyncWithHDResolution() - { - string sessionId = "SESSIONID"; - string resolution = "1280x720"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + [Fact] + public void StartArchiveCreateInvalidIndividualModeArchivingWithResolution() + { + var sessionId = "SESSIONID"; + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - Archive archive = - await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.COMPOSED, resolution: resolution); + var exception = Assert.Throws(() => + opentok.StartArchive(sessionId, outputMode: OutputMode.INDIVIDUAL, resolution: resolution)); - Assert.NotNull(archive); - Assert.Equal(OutputMode.COMPOSED, archive.OutputMode); - Assert.Equal(resolution, archive.Resolution); + Assert.Equal("Resolution can't be specified for Individual Archives", exception.Message); + } - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } + [Fact] + public async Task StartArchiveAsyncCreateInvalidIndividualModeArchivingWithResolution() + { + var sessionId = "SESSIONID"; + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - [Fact] - public void StartArchiveCreateInvalidIndividualModeArchivingWithResolution() - { - string sessionId = "SESSIONID"; - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + var exception = await Assert.ThrowsAsync(async () => + await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.INDIVIDUAL, resolution: resolution)); - var exception = Assert.Throws(() => - opentok.StartArchive(sessionId, outputMode: OutputMode.INDIVIDUAL, resolution: resolution)); + Assert.Equal("Resolution can't be specified for Individual Archives", exception.Message); + } - Assert.Equal("Resolution can't be specified for Individual Archives", exception.Message); - } + [Fact] + public void StartArchiveNoResolution() + { + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - [Fact] - public async Task StartArchiveAsyncCreateInvalidIndividualModeArchivingWithResolution() - { - string sessionId = "SESSIONID"; - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - - var exception = await Assert.ThrowsAsync(async () => - await opentok.StartArchiveAsync(sessionId, outputMode: OutputMode.INDIVIDUAL, resolution: resolution)); - - Assert.Equal("Resolution can't be specified for Individual Archives", exception.Message); - } - - [Fact] - public void StartArchiveNoResolution() - { - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(SessionId); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(SessionId); + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); + Assert.Equal(resolution, archive.Resolution); - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); - Assert.Equal(resolution, archive.Resolution); + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + [Fact] + public async Task StartArchiveAsyncNoResolution() + { + var resolution = "640x480"; + var responseJson = GetResponseJson(); + var mockClient = new Mock(); + + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(SessionId); + + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); + Assert.Equal(resolution, archive.Resolution); + + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - [Fact] - public async Task StartArchiveAsyncNoResolution() - { - string resolution = "640x480"; - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(SessionId); - - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); - Assert.Equal(resolution, archive.Resolution); - - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } - - [Fact] - public void StartArchiveVoiceOnly() - { - string responseJson = GetResponseJson(); - var mockClient = new Mock(); + [Fact] + public void StartArchiveVoiceOnly() + { + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())).Returns(responseJson); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())).Returns(responseJson); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(SessionId, hasVideo: false); + + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); + + mockClient.Verify( + httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), It.IsAny>()), Times.Once()); + } + + [Fact] + public async Task StartArchiveAsyncVoiceOnly() + { + var responseJson = GetResponseJson(); + var mockClient = new Mock(); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(SessionId, hasVideo: false); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(SessionId, hasVideo: false); - mockClient.Verify( - httpClient => httpClient.Post(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + Assert.NotNull(archive); + Assert.Equal(SessionId, archive.SessionId); + Assert.NotEqual(Guid.Empty, archive.Id); + + mockClient.Verify( + httpClient => + httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - [Fact] - public async Task StartArchiveAsyncVoiceOnly() - { - string responseJson = GetResponseJson(); - var mockClient = new Mock(); - - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(SessionId, hasVideo: false); - - Assert.NotNull(archive); - Assert.Equal(SessionId, archive.SessionId); - Assert.NotEqual(Guid.Empty, archive.Id); - - mockClient.Verify( - httpClient => - httpClient.PostAsync(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), It.IsAny>()), Times.Once()); - } - - [Fact] - public void StartArchiveAutoStreamMode() - { - string sessionId = "SESSIONID"; - string responseJson = GetResponseJson(); - Dictionary dataSent = null; + [Fact] + public void StartArchiveAutoStreamMode() + { + var sessionId = "SESSIONID"; + var responseJson = GetResponseJson(); + Dictionary dataSent = null; - var mockClient = new Mock(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Returns(responseJson) - .Callback, Dictionary>((url, headers, data) => - { - dataSent = data; - }); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Returns(responseJson) + .Callback, Dictionary>((url, headers, data) => + { + dataSent = data; + }); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(sessionId, streamMode: StreamMode.Auto); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(sessionId, streamMode: StreamMode.Auto); - Assert.NotNull(archive); - Assert.Equal(StreamMode.Auto, archive.StreamMode); + Assert.NotNull(archive); + Assert.Equal(StreamMode.Auto, archive.StreamMode); - Assert.True(dataSent.ContainsKey("streamMode")); - Assert.Equal("auto", dataSent["streamMode"]); + Assert.True(dataSent.ContainsKey("streamMode")); + Assert.Equal("auto", dataSent["streamMode"]); - mockClient.Verify( - httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + mockClient.Verify( + httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public async Task StartArchiveAsyncAutoStreamMode() - { - string sessionId = "SESSIONID"; - string responseJson = GetResponseJson(); - Dictionary dataSent = null; + [Fact] + public async Task StartArchiveAsyncAutoStreamMode() + { + var sessionId = "SESSIONID"; + var responseJson = GetResponseJson(); + Dictionary dataSent = null; - var mockClient = new Mock(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson) - .Callback, Dictionary>((url, headers, data) => - { - dataSent = data; - }); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson) + .Callback, Dictionary>((url, headers, data) => + { + dataSent = data; + }); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(sessionId, streamMode: StreamMode.Auto); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(sessionId, streamMode: StreamMode.Auto); - Assert.NotNull(archive); - Assert.Equal(StreamMode.Auto, archive.StreamMode); + Assert.NotNull(archive); + Assert.Equal(StreamMode.Auto, archive.StreamMode); - Assert.True(dataSent.ContainsKey("streamMode")); - Assert.Equal("auto", dataSent["streamMode"]); + Assert.True(dataSent.ContainsKey("streamMode")); + Assert.Equal("auto", dataSent["streamMode"]); - mockClient.Verify( - httpClient => httpClient.PostAsync(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + mockClient.Verify( + httpClient => httpClient.PostAsync(It.IsAny(), It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public void StartArchiveManualStreamMode() - { - string sessionId = "SESSIONID"; - string responseJson = GetResponseJson(); - Dictionary dataSent = null; + [Fact] + public void StartArchiveManualStreamMode() + { + var sessionId = "SESSIONID"; + var responseJson = GetResponseJson(); + Dictionary dataSent = null; - var mockClient = new Mock(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Returns(responseJson) - .Callback, Dictionary>((url, headers, data) => - { - dataSent = data; - }); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Returns(responseJson) + .Callback, Dictionary>((url, headers, data) => + { + dataSent = data; + }); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StartArchive(sessionId, streamMode: StreamMode.Manual); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StartArchive(sessionId, streamMode: StreamMode.Manual); - Assert.NotNull(archive); - Assert.Equal(StreamMode.Manual, archive.StreamMode); + Assert.NotNull(archive); + Assert.Equal(StreamMode.Manual, archive.StreamMode); - Assert.True(dataSent.ContainsKey("streamMode")); - Assert.Equal("manual", dataSent["streamMode"]); + Assert.True(dataSent.ContainsKey("streamMode")); + Assert.Equal("manual", dataSent["streamMode"]); - mockClient.Verify( - httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + mockClient.Verify( + httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public async Task StartArchiveAsyncManualStreamMode() - { - string sessionId = "SESSIONID"; - string responseJson = GetResponseJson(); - Dictionary dataSent = null; + [Fact] + public async Task StartArchiveAsyncManualStreamMode() + { + var sessionId = "SESSIONID"; + var responseJson = GetResponseJson(); + Dictionary dataSent = null; - var mockClient = new Mock(); + var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson) - .Callback, Dictionary>((url, headers, data) => - { - dataSent = data; - }); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson) + .Callback, Dictionary>((url, headers, data) => + { + dataSent = data; + }); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StartArchiveAsync(sessionId, streamMode: StreamMode.Manual); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StartArchiveAsync(sessionId, streamMode: StreamMode.Manual); - Assert.NotNull(archive); - Assert.Equal(StreamMode.Manual, archive.StreamMode); + Assert.NotNull(archive); + Assert.Equal(StreamMode.Manual, archive.StreamMode); - Assert.True(dataSent.ContainsKey("streamMode")); - Assert.Equal("manual", dataSent["streamMode"]); + Assert.True(dataSent.ContainsKey("streamMode")); + Assert.Equal("manual", dataSent["streamMode"]); - mockClient.Verify( - httpClient => httpClient.PostAsync(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + mockClient.Verify( + httpClient => httpClient.PostAsync(It.IsAny(), It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public void StartArchiveWithMultiArchiveTag() - { - string responseJson = GetResponseJson(); - string multiArchiveTagName = "multiArchiveTag"; - string multiArchiveTag = "TestArchiveTag"; - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Returns(responseJson); - OpenTok opentok = this.BuildOpenTok(mockClient.Object); - Archive archive = opentok.StartArchive(SessionId, multiArchiveTag: multiArchiveTag); - Assert.NotNull(archive); - Assert.Equal(multiArchiveTag, archive.MultiArchiveTag); - Assert.NotEqual(Guid.Empty, archive.Id); - mockClient.Verify( - httpClient => httpClient.Post( - It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), - It.Is>(dictionary => - dictionary.ContainsKey(multiArchiveTagName) && dictionary[multiArchiveTagName].ToString() == multiArchiveTag)), - Times.Once()); - } - - [Fact] - public async Task StartArchiveWithMultiArchiveTagAsync() - { - string responseJson = GetResponseJson(); - string multiArchiveTagName = "multiArchiveTag"; - string multiArchiveTag = "TestArchiveTag"; - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), It.IsAny>())) - .ReturnsAsync(responseJson); - OpenTok opentok = this.BuildOpenTok(mockClient.Object); - Archive archive = await opentok.StartArchiveAsync(SessionId, multiArchiveTag: multiArchiveTag); - Assert.NotNull(archive); - Assert.Equal(multiArchiveTag, archive.MultiArchiveTag); - Assert.NotEqual(Guid.Empty, archive.Id); - mockClient.Verify( - httpClient => httpClient.PostAsync( - It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), - It.IsAny>(), - It.Is>(dictionary => - dictionary.ContainsKey(multiArchiveTagName) && dictionary[multiArchiveTagName].ToString() == multiArchiveTag)), - Times.Once()); - } - - // AddStreamToArchive - - [Theory] - [InlineData("")] - [InlineData(null)] - public void AddStreamToArchiveInvalidArchiveIdThrowsException(string archiveId) - { - string streamId = "1234567890"; + [Fact] + public void StartArchiveWithMultiArchiveTag() + { + var responseJson = GetResponseJson(); + var multiArchiveTagName = "multiArchiveTag"; + var multiArchiveTag = "TestArchiveTag"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Returns(responseJson); + var opentok = BuildOpenTok(mockClient.Object); + var archive = opentok.StartArchive(SessionId, multiArchiveTag: multiArchiveTag); + Assert.NotNull(archive); + Assert.Equal(multiArchiveTag, archive.MultiArchiveTag); + Assert.NotEqual(Guid.Empty, archive.Id); + mockClient.Verify( + httpClient => httpClient.Post( + It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), + It.Is>(dictionary => + dictionary.ContainsKey(multiArchiveTagName) && + dictionary[multiArchiveTagName].ToString() == multiArchiveTag)), + Times.Once()); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + [Fact] + public async Task StartArchiveWithMultiArchiveTagAsync() + { + var responseJson = GetResponseJson(); + var multiArchiveTagName = "multiArchiveTag"; + var multiArchiveTag = "TestArchiveTag"; + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), It.IsAny>())) + .ReturnsAsync(responseJson); + var opentok = BuildOpenTok(mockClient.Object); + var archive = await opentok.StartArchiveAsync(SessionId, multiArchiveTag: multiArchiveTag); + Assert.NotNull(archive); + Assert.Equal(multiArchiveTag, archive.MultiArchiveTag); + Assert.NotEqual(Guid.Empty, archive.Id); + mockClient.Verify( + httpClient => httpClient.PostAsync( + It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive")), + It.IsAny>(), + It.Is>(dictionary => + dictionary.ContainsKey(multiArchiveTagName) && + dictionary[multiArchiveTagName].ToString() == multiArchiveTag)), + Times.Once()); + } - Assert.Throws(() => opentok.AddStreamToArchive(archiveId, streamId)); - } + // AddStreamToArchive - [Fact] - public void AddStreamToArchiveCorrectUrl() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; - - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; - - var mockClient = new Mock(MockBehavior.Strict); - mockClient - .Setup(httpClient => httpClient.Patch(expectedUrl, It.IsAny>(), - It.IsAny>())) - .Returns("") - .Verifiable(); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - opentok.AddStreamToArchive(archiveId, streamId); - - mockClient.Verify(); - } - - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void AddStreamToArchiveHeaderAndDataCorrect(bool hasAudio, bool hasVideo) - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; - - Dictionary headersSent = null; - Dictionary dataSent = null; - - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.Patch(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Callback, Dictionary>((url, headers, data) => - { - headersSent = headers; - dataSent = data; - }); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - opentok.AddStreamToArchive(archiveId, streamId, hasAudio, hasVideo); - - Assert.NotNull(headersSent); - Assert.Equal(new Dictionary {{"Content-Type", "application/json"}}, headersSent); - - Assert.NotNull(dataSent); - Assert.Equal( - new Dictionary - {{"addStream", streamId}, {"hasAudio", hasAudio}, {"hasVideo", hasVideo}}, dataSent); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - public async Task AddStreamToArchiveAsyncInvalidArchiveIdThrowsException(string archiveId) - { - string streamId = "1234567890"; + [Theory] + [InlineData("")] + [InlineData(null)] + public void AddStreamToArchiveInvalidArchiveIdThrowsException(string archiveId) + { + var streamId = "1234567890"; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + var opentok = new OpenTok(ApiKey, ApiSecret); - await Assert.ThrowsAsync(async () => - await opentok.AddStreamToArchiveAsync(archiveId, streamId)); - } + Assert.Throws(() => opentok.AddStreamToArchive(archiveId, streamId)); + } - [Fact] - public async Task AddStreamToArchiveAsyncCorrectUrl() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; - - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; - - var mockClient = new Mock(MockBehavior.Strict); - mockClient - .Setup(httpClient => httpClient.PatchAsync(expectedUrl, It.IsAny>(), - It.IsAny>())) - .ReturnsAsync("") - .Verifiable(); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - await opentok.AddStreamToArchiveAsync(archiveId, streamId); - - mockClient.Verify(); - } - - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task AddStreamToArchiveAsyncHeaderAndDataCorrect(bool hasAudio, bool hasVideo) - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; - - Dictionary headersSent = null; - Dictionary dataSent = null; - - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.PatchAsync(It.IsAny(), It.IsAny>(), - It.IsAny>())) - - .Callback, Dictionary>((url, headers, data) => - { - headersSent = headers; - dataSent = data; - }); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - await opentok.AddStreamToArchiveAsync(archiveId, streamId, hasAudio, hasVideo); - - Assert.NotNull(headersSent); - Assert.Equal(new Dictionary {{"Content-Type", "application/json"}}, headersSent); - - Assert.NotNull(dataSent); - Assert.Equal( - new Dictionary - {{"addStream", streamId}, {"hasAudio", hasAudio}, {"hasVideo", hasVideo}}, dataSent); - } - - // RemoveStreamFromArchive - - [Theory] - [InlineData("")] - [InlineData(null)] - public void RemoveStreamFromArchiveInvalidArchiveIdThrowsException(string archiveId) - { - string streamId = "1234567890"; + [Fact] + public void AddStreamToArchiveCorrectUrl() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; - Assert.Throws(() => opentok.RemoveStreamFromArchive(archiveId, streamId)); - } + var mockClient = new Mock(MockBehavior.Strict); + mockClient + .Setup(httpClient => httpClient.Patch(expectedUrl, It.IsAny>(), + It.IsAny>())) + .Returns("") + .Verifiable(); - [Fact] - public void RemoveStreamFromArchiveCorrectUrl() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + opentok.AddStreamToArchive(archiveId, streamId); - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + mockClient.Verify(); + } - var mockClient = new Mock(MockBehavior.Strict); - mockClient - .Setup(httpClient => httpClient.Patch(expectedUrl, It.IsAny>(), - It.IsAny>())) - .Returns("") - .Verifiable(); + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void AddStreamToArchiveHeaderAndDataCorrect(bool hasAudio, bool hasVideo) + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - opentok.RemoveStreamFromArchive(archiveId, streamId); + Dictionary headersSent = null; + Dictionary dataSent = null; - mockClient.Verify(); - } + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.Patch(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Callback, Dictionary>((url, headers, data) => + { + headersSent = headers; + dataSent = data; + }); - [Fact] - public void RemoveStreamFromArchiveHeaderAndDataCorrect() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; - - Dictionary headersSent = null; - Dictionary dataSent = null; - - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.Patch(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Callback, Dictionary>((url, headers, data) => - { - headersSent = headers; - dataSent = data; - }); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - opentok.RemoveStreamFromArchive(archiveId, streamId); - - Assert.NotNull(headersSent); - Assert.Equal(new Dictionary {{"Content-Type", "application/json"}}, headersSent); - - Assert.NotNull(dataSent); - Assert.Equal(new Dictionary {{"removeStream", streamId}}, dataSent); - } - - [Theory] - [InlineData("")] - [InlineData(null)] - public async Task RemoveStreamFromArchiveAsyncInvalidArchiveIdThrowsException(string archiveId) - { - string streamId = "1234567890"; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + opentok.AddStreamToArchive(archiveId, streamId, hasAudio, hasVideo); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + Assert.NotNull(headersSent); + Assert.Equal(new Dictionary { { "Content-Type", "application/json" } }, headersSent); - await Assert.ThrowsAsync(async () => - await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId)); - } + Assert.NotNull(dataSent); + Assert.Equal( + new Dictionary + { { "addStream", streamId }, { "hasAudio", hasAudio }, { "hasVideo", hasVideo } }, dataSent); + } - [Fact] - public async Task RemoveStreamFromArchiveAsyncCorrectUrl() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task AddStreamToArchiveAsyncInvalidArchiveIdThrowsException(string archiveId) + { + var streamId = "1234567890"; - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + var opentok = new OpenTok(ApiKey, ApiSecret); - var mockClient = new Mock(MockBehavior.Strict); - mockClient - .Setup(httpClient => httpClient.PatchAsync(expectedUrl, It.IsAny>(), - It.IsAny>())) - .ReturnsAsync("") - .Verifiable(); + await Assert.ThrowsAsync(async () => + await opentok.AddStreamToArchiveAsync(archiveId, streamId)); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId); + [Fact] + public async Task AddStreamToArchiveAsyncCorrectUrl() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; - mockClient.Verify(); - } + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; - [Fact] - public async Task RemoveStreamFromArchiveAsyncHeaderAndDataCorrect() - { - string archiveId = "ARCHIVEID"; - string streamId = "1234567890"; + var mockClient = new Mock(MockBehavior.Strict); + mockClient + .Setup(httpClient => httpClient.PatchAsync(expectedUrl, It.IsAny>(), + It.IsAny>())) + .ReturnsAsync("") + .Verifiable(); - Dictionary headersSent = null; - Dictionary dataSent = null; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + await opentok.AddStreamToArchiveAsync(archiveId, streamId); - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.PatchAsync(It.IsAny(), It.IsAny>(), - It.IsAny>())) - .Callback, Dictionary>((url, headers, data) => - { - headersSent = headers; - dataSent = data; - }); + mockClient.Verify(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public async Task AddStreamToArchiveAsyncHeaderAndDataCorrect(bool hasAudio, bool hasVideo) + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId); + Dictionary headersSent = null; + Dictionary dataSent = null; - Assert.NotNull(headersSent); - Assert.Equal(new Dictionary {{"Content-Type", "application/json"}}, headersSent); + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.PatchAsync(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Callback, Dictionary>((url, headers, data) => + { + headersSent = headers; + dataSent = data; + }); - Assert.NotNull(dataSent); - Assert.Equal(new Dictionary {{"removeStream", streamId}}, dataSent); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + await opentok.AddStreamToArchiveAsync(archiveId, streamId, hasAudio, hasVideo); - // Get Archive + Assert.NotNull(headersSent); + Assert.Equal(new Dictionary { { "Content-Type", "application/json" } }, headersSent); - [Fact] - public void GetArchive() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); + Assert.NotNull(dataSent); + Assert.Equal( + new Dictionary + { { "addStream", streamId }, { "hasAudio", hasAudio }, { "hasVideo", hasVideo } }, dataSent); + } + + // RemoveStreamFromArchive + + [Theory] + [InlineData("")] + [InlineData(null)] + public void RemoveStreamFromArchiveInvalidArchiveIdThrowsException(string archiveId) + { + var streamId = "1234567890"; + + var opentok = new OpenTok(ApiKey, ApiSecret); + + Assert.Throws(() => opentok.RemoveStreamFromArchive(archiveId, streamId)); + } + + [Fact] + public void RemoveStreamFromArchiveCorrectUrl() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; - OpenTok opentok = new OpenTok(ApiKey, ApiSecret) + var mockClient = new Mock(MockBehavior.Strict); + mockClient + .Setup(httpClient => httpClient.Patch(expectedUrl, It.IsAny>(), + It.IsAny>())) + .Returns("") + .Verifiable(); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + opentok.RemoveStreamFromArchive(archiveId, streamId); + + mockClient.Verify(); + } + + [Fact] + public void RemoveStreamFromArchiveHeaderAndDataCorrect() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; + + Dictionary headersSent = null; + Dictionary dataSent = null; + + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.Patch(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Callback, Dictionary>((url, headers, data) => { - Client = mockClient.Object - }; - Archive archive = opentok.GetArchive(archiveId); - - Assert.NotNull(archive); - Assert.Equal(ApiKey, archive.PartnerId); - Assert.Equal(archiveId, archive.Id.ToString()); - Assert.Equal(1395187836000L, archive.CreatedAt); - Assert.Equal(62, archive.Duration); - Assert.Equal("", archive.Name); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(8347554, archive.Size); - Assert.Equal(ArchiveStatus.AVAILABLE, archive.Status); - Assert.Equal("http://tokbox.com.archive2.s3.amazonaws.com/123456%2F" + archiveId + - "%2Farchive.mp4?Expires=13951" + - "94362&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - archive.Url); - - mockClient.Verify( - httpClient => - httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), - Times.Once()); - } - - [Fact] - public async Task GetArchiveAsync() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); + headersSent = headers; + dataSent = data; + }); - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) - .ReturnsAsync(returnString); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + opentok.RemoveStreamFromArchive(archiveId, streamId); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret) + Assert.NotNull(headersSent); + Assert.Equal(new Dictionary { { "Content-Type", "application/json" } }, headersSent); + + Assert.NotNull(dataSent); + Assert.Equal(new Dictionary { { "removeStream", streamId } }, dataSent); + } + + [Theory] + [InlineData("")] + [InlineData(null)] + public async Task RemoveStreamFromArchiveAsyncInvalidArchiveIdThrowsException(string archiveId) + { + var streamId = "1234567890"; + + var opentok = new OpenTok(ApiKey, ApiSecret); + + await Assert.ThrowsAsync(async () => + await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId)); + } + + [Fact] + public async Task RemoveStreamFromArchiveAsyncCorrectUrl() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; + + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/streams"; + + var mockClient = new Mock(MockBehavior.Strict); + mockClient + .Setup(httpClient => httpClient.PatchAsync(expectedUrl, It.IsAny>(), + It.IsAny>())) + .ReturnsAsync("") + .Verifiable(); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId); + + mockClient.Verify(); + } + + [Fact] + public async Task RemoveStreamFromArchiveAsyncHeaderAndDataCorrect() + { + var archiveId = "ARCHIVEID"; + var streamId = "1234567890"; + + Dictionary headersSent = null; + Dictionary dataSent = null; + + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.PatchAsync(It.IsAny(), It.IsAny>(), + It.IsAny>())) + .Callback, Dictionary>((url, headers, data) => { - Client = mockClient.Object - }; - Archive archive = await opentok.GetArchiveAsync(archiveId); - - Assert.NotNull(archive); - Assert.Equal(ApiKey, archive.PartnerId); - Assert.Equal(archiveId, archive.Id.ToString()); - Assert.Equal(1395187836000L, archive.CreatedAt); - Assert.Equal(62, archive.Duration); - Assert.Equal("", archive.Name); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(8347554, archive.Size); - Assert.Equal(ArchiveStatus.AVAILABLE, archive.Status); - Assert.Equal("http://tokbox.com.archive2.s3.amazonaws.com/123456%2F" + archiveId + - "%2Farchive.mp4?Expires=13951" + - "94362&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - archive.Url); - - mockClient.Verify( - httpClient => - httpClient.GetAsync( - It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), - Times.Once()); - } - - [Fact] - public void GetExpiredArchive() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.GetArchive(archiveId); - - Assert.NotNull(archive); - Assert.Equal(ArchiveStatus.EXPIRED, archive.Status); - - mockClient.Verify( - httpClient => - httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), - Times.Once()); - } - - [Fact] - public async Task GetExpiredArchiveAsync() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); - - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) - .ReturnsAsync(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.GetArchiveAsync(archiveId); - - Assert.NotNull(archive); - Assert.Equal(ArchiveStatus.EXPIRED, archive.Status); - - mockClient.Verify( - httpClient => - httpClient.GetAsync( - It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), - Times.Once()); - } - - [Fact] - public void GetArchiveWithUnknownProperties() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); + headersSent = headers; + dataSent = data; + }); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + await opentok.RemoveStreamFromArchiveAsync(archiveId, streamId); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.GetArchive(archiveId); + Assert.NotNull(headersSent); + Assert.Equal(new Dictionary { { "Content-Type", "application/json" } }, headersSent); - Assert.NotNull(archive); + Assert.NotNull(dataSent); + Assert.Equal(new Dictionary { { "removeStream", streamId } }, dataSent); + } - mockClient.Verify( - httpClient => - httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), - Times.Once()); - } + // Get Archive - [Fact] - public async Task GetArchiveWithUnknownPropertiesAsync() - { - string archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; - string returnString = GetResponseJson(new Dictionary - {{"archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8"}}); + [Fact] + public void GetArchive() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); + + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret) + { + Client = mockClient.Object + }; + var archive = opentok.GetArchive(archiveId); + + Assert.NotNull(archive); + Assert.Equal(ApiKey, archive.PartnerId); + Assert.Equal(archiveId, archive.Id.ToString()); + Assert.Equal(1395187836000L, archive.CreatedAt); + Assert.Equal(62, archive.Duration); + Assert.Equal("", archive.Name); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(8347554, archive.Size); + Assert.Equal(ArchiveStatus.AVAILABLE, archive.Status); + Assert.Equal("http://tokbox.com.archive2.s3.amazonaws.com/123456%2F" + archiveId + + "%2Farchive.mp4?Expires=13951" + + "94362&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + archive.Url); + + mockClient.Verify( + httpClient => + httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), + Times.Once()); + } - var mockClient = new Mock(); - mockClient - .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) - .ReturnsAsync(returnString); + [Fact] + public async Task GetArchiveAsync() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); + + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) + .ReturnsAsync(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret) + { + Client = mockClient.Object + }; + var archive = await opentok.GetArchiveAsync(archiveId); + + Assert.NotNull(archive); + Assert.Equal(ApiKey, archive.PartnerId); + Assert.Equal(archiveId, archive.Id.ToString()); + Assert.Equal(1395187836000L, archive.CreatedAt); + Assert.Equal(62, archive.Duration); + Assert.Equal("", archive.Name); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(8347554, archive.Size); + Assert.Equal(ArchiveStatus.AVAILABLE, archive.Status); + Assert.Equal("http://tokbox.com.archive2.s3.amazonaws.com/123456%2F" + archiveId + + "%2Farchive.mp4?Expires=13951" + + "94362&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + archive.Url); + + mockClient.Verify( + httpClient => + httpClient.GetAsync( + It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), + Times.Once()); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.GetArchiveAsync(archiveId); + [Fact] + public void GetExpiredArchive() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.GetArchive(archiveId); + + Assert.NotNull(archive); + Assert.Equal(ArchiveStatus.EXPIRED, archive.Status); + + mockClient.Verify( + httpClient => + httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), + Times.Once()); + } - Assert.NotNull(archive); + [Fact] + public async Task GetExpiredArchiveAsync() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); - mockClient.Verify( - httpClient => - httpClient.GetAsync( - It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), - Times.Once()); - } + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) + .ReturnsAsync(returnString); - // Delete Archive + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.GetArchiveAsync(archiveId); - [Fact] - public void DeleteArchive() - { - string archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; + Assert.NotNull(archive); + Assert.Equal(ArchiveStatus.EXPIRED, archive.Status); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Delete(It.IsAny(), - It.IsAny>())); + mockClient.Verify( + httpClient => + httpClient.GetAsync( + It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), + Times.Once()); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - opentok.DeleteArchive(archiveId); + [Fact] + public void GetArchiveWithUnknownProperties() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); - mockClient.Verify(httpClient => httpClient.Delete(It.Is( - url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), - It.IsAny>()), Times.Once()); - } + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); - [Fact] - public void DeleteArchiveFromArchiveObject() - { - Guid archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.GetArchive(archiveId); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Delete(It.IsAny(), - It.IsAny>())); + Assert.NotNull(archive); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + mockClient.Verify( + httpClient => + httpClient.Get(It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId))), + Times.Once()); + } - Archive archive = new Archive(opentok); - archive.Id = archiveId; + [Fact] + public async Task GetArchiveWithUnknownPropertiesAsync() + { + var archiveId = "936da01f-9abd-4d9d-80c7-02af85c822a8"; + var returnString = GetResponseJson(new Dictionary + { { "archiveId", "936da01f-9abd-4d9d-80c7-02af85c822a8" } }); - archive.Delete(); + var mockClient = new Mock(); + mockClient + .Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) + .ReturnsAsync(returnString); - mockClient.Verify(httpClient => httpClient.Delete(It.Is( - url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}")), - It.IsAny>()), Times.Once()); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.GetArchiveAsync(archiveId); - [Fact] - public async Task DeleteArchiveAsync() - { - string archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; + Assert.NotNull(archive); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.DeleteAsync(It.IsAny(), - It.IsAny>())); + mockClient.Verify( + httpClient => + httpClient.GetAsync( + It.Is(url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), null), + Times.Once()); + } - OpenTok opentok = new OpenTok(ApiKey, ApiSecret) - { - Client = mockClient.Object - }; - await opentok.DeleteArchiveAsync(archiveId); + // Delete Archive - mockClient.Verify(httpClient => httpClient.DeleteAsync(It.Is( - url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), - It.IsAny>()), Times.Once()); - } + [Fact] + public void DeleteArchive() + { + var archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; - [Fact] - public async Task DeleteArchiveAsyncFromArchiveObject() - { - Guid archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Delete(It.IsAny(), + It.IsAny>())); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.DeleteAsync(It.IsAny(), - It.IsAny>())); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + opentok.DeleteArchive(archiveId); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret) - { - Client = mockClient.Object - }; + mockClient.Verify(httpClient => httpClient.Delete(It.Is( + url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), + It.IsAny>()), Times.Once()); + } - Archive archive = new Archive(opentok); - archive.Id = archiveId; + [Fact] + public void DeleteArchiveFromArchiveObject() + { + var archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); - await archive.DeleteAsync(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Delete(It.IsAny(), + It.IsAny>())); - mockClient.Verify(httpClient => httpClient.DeleteAsync(It.Is( - url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), - It.IsAny>()), Times.Once()); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - // Set Archive Layout + var archive = new Archive(opentok); + archive.Id = archiveId; - [Fact] - public void SetArchiveLayoutScreenShareType() - { - var archiveId = "123456789"; - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + archive.Delete(); - var expectedHeaders = new Dictionary - { - {"Content-Type", "application/json"} - }; + mockClient.Verify(httpClient => httpClient.Delete(It.Is( + url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}")), + It.IsAny>()), Times.Once()); + } - var expectedData = new Dictionary - { - {"type", "bestFit"}, - {"screenshareType", "pip"} - }; + [Fact] + public async Task DeleteArchiveAsync() + { + var archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; - var mockClient = new Mock(MockBehavior.Strict); - mockClient.Setup(c => c.Put(expectedUrl, expectedHeaders, expectedData)) - .Returns("") - .Verifiable(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.DeleteAsync(It.IsAny(), + It.IsAny>())); - var opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + var opentok = new OpenTok(ApiKey, ApiSecret) + { + Client = mockClient.Object + }; + await opentok.DeleteArchiveAsync(archiveId); - var layout = new ArchiveLayout - { - Type = LayoutType.bestFit, - ScreenShareType = ScreenShareLayoutType.Pip - }; + mockClient.Verify(httpClient => httpClient.DeleteAsync(It.Is( + url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), + It.IsAny>()), Times.Once()); + } + + [Fact] + public async Task DeleteArchiveAsyncFromArchiveObject() + { + var archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); - Assert.True(opentok.SetArchiveLayout(archiveId, layout)); - } + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.DeleteAsync(It.IsAny(), + It.IsAny>())); - [Fact] - public async Task SetArchiveLayoutAsyncScreenShareType() + var opentok = new OpenTok(ApiKey, ApiSecret) { - var archiveId = "123456789"; - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + Client = mockClient.Object + }; - var expectedHeaders = new Dictionary - { - {"Content-Type", "application/json"} - }; + var archive = new Archive(opentok); + archive.Id = archiveId; - var expectedData = new Dictionary - { - {"type", "bestFit"}, - {"screenshareType", "pip"} - }; + await archive.DeleteAsync(); - var mockClient = new Mock(MockBehavior.Strict); - mockClient.Setup(c => c.PutAsync(expectedUrl, expectedHeaders, expectedData)) - .ReturnsAsync("") - .Verifiable(); + mockClient.Verify(httpClient => httpClient.DeleteAsync(It.Is( + url => url.Equals("v2/project/" + ApiKey + "/archive/" + archiveId)), + It.IsAny>()), Times.Once()); + } - var opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + // Set Archive Layout - var layout = new ArchiveLayout - { - Type = LayoutType.bestFit, - ScreenShareType = ScreenShareLayoutType.Pip - }; + [Fact] + public void SetArchiveLayoutScreenShareType() + { + var archiveId = "123456789"; + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; - Assert.True(await opentok.SetArchiveLayoutAsync(archiveId, layout)); - } + var expectedHeaders = new Dictionary + { + { "Content-Type", "application/json" } + }; - [Fact] - public void SetArchiveLayoutCustomLayoutTypeNoStylesheetThrowsException() + var expectedData = new Dictionary { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - Type = LayoutType.custom - }; + { "type", "bestFit" }, + { "screenshareType", "pip" } + }; - var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); - Assert.Contains("Invalid layout, layout is custom but no stylesheet provided", exception.Message); - Assert.Equal("layout", exception.ParamName); - } + var mockClient = new Mock(MockBehavior.Strict); + mockClient.Setup(c => c.Put(expectedUrl, expectedHeaders, expectedData)) + .Returns("") + .Verifiable(); - [Fact] - public async Task SetArchiveLayoutAsyncCustomLayoutTypeNoStylesheetThrowsException() - { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - Type = LayoutType.custom - }; - - var exception = - await Assert.ThrowsAsync(async () => - await opentok.SetArchiveLayoutAsync("12345", layout)); - Assert.Contains("Invalid layout, layout is custom but no stylesheet provided", exception.Message); - Assert.Equal("layout", exception.ParamName); - } - - [Fact] - public void SetArchiveLayoutNonCustomLayoutTypeStylesheetProvidedThrowsException() + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - Type = LayoutType.bestFit, - StyleSheet = "bob" - }; + Type = LayoutType.bestFit, + ScreenShareType = ScreenShareLayoutType.Pip + }; + + Assert.True(opentok.SetArchiveLayout(archiveId, layout)); + } - var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); - Assert.Contains("Invalid layout, layout is not custom, but stylesheet is set", exception.Message); - Assert.Equal("layout", exception.ParamName); - } + [Fact] + public async Task SetArchiveLayoutAsyncScreenShareType() + { + var archiveId = "123456789"; + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; - [Fact] - public async Task SetArchiveLayoutAsyncNonCustomLayoutTypeStylesheetProvidedThrowsException() + var expectedHeaders = new Dictionary { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - Type = LayoutType.bestFit, - StyleSheet = "bob" - }; - - var exception = - await Assert.ThrowsAsync(async () => - await opentok.SetArchiveLayoutAsync("12345", layout)); - Assert.Contains("Invalid layout, layout is not custom, but stylesheet is set", exception.Message); - Assert.Equal("layout", exception.ParamName); - } - - [Fact] - public void SetArchiveLayoutTypeNotBestfitThrowsException() + { "Content-Type", "application/json" } + }; + + var expectedData = new Dictionary { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - ScreenShareType = ScreenShareLayoutType.BestFit, - Type = LayoutType.pip - }; + { "type", "bestFit" }, + { "screenshareType", "pip" } + }; + + var mockClient = new Mock(MockBehavior.Strict); + mockClient.Setup(c => c.PutAsync(expectedUrl, expectedHeaders, expectedData)) + .ReturnsAsync("") + .Verifiable(); - var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); - Assert.Contains("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); - Assert.Equal("layout", exception.ParamName); - } + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - [Fact] - public async Task SetArchiveLayoutAsyncTypeNotBestfitThrowsException() + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout - { - ScreenShareType = ScreenShareLayoutType.BestFit, - Type = LayoutType.pip - }; - - var exception = - await Assert.ThrowsAsync(() => - opentok.SetArchiveLayoutAsync("12345", layout)); - Assert.Contains("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); - Assert.Equal("layout", exception.ParamName); - } - - [Fact] - public void SetArchiveScreenShareTypeInvalid() + Type = LayoutType.bestFit, + ScreenShareType = ScreenShareLayoutType.Pip + }; + + Assert.True(await opentok.SetArchiveLayoutAsync(archiveId, layout)); + } + + [Fact] + public void SetArchiveLayoutCustomLayoutTypeNoStylesheetThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.Pip }; - - var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); - - Assert.StartsWith("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); - Assert.Equal("layout", exception.ParamName); - } - - [Fact] - public async Task SetArchiveScreenShareTypeInvalidAsync() + Type = LayoutType.custom + }; + + var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); + Assert.Contains("Invalid layout, layout is custom but no stylesheet provided", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public async Task SetArchiveLayoutAsyncCustomLayoutTypeNoStylesheetThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.Pip }; - - var exception = await Assert.ThrowsAsync(async () => await opentok.SetArchiveLayoutAsync("12345", layout)); - - Assert.StartsWith("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); - Assert.Equal("layout", exception.ParamName); - } - - [Fact] - public void SetArchiveScreenShareType() + Type = LayoutType.custom + }; + + var exception = + await Assert.ThrowsAsync(async () => + await opentok.SetArchiveLayoutAsync("12345", layout)); + Assert.Contains("Invalid layout, layout is custom but no stylesheet provided", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public void SetArchiveLayoutNonCustomLayoutTypeStylesheetProvidedThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout { Type = LayoutType.bestFit, ScreenShareType = ScreenShareLayoutType.Pip }; - var headers = new Dictionary { { "Content-Type", "application/json" } }; - var archiveId = "123456789"; - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; - var mockClient = new Mock(); - opentok.Client = mockClient.Object; - mockClient.Setup(c => c.Put(expectedUrl, headers, It.Is>(x => (string)x["type"] == "bestFit" && (string)x["screenshareType"] == "pip"))); - Assert.True(opentok.SetArchiveLayout(archiveId, layout)); - } - - [Fact] - public async Task SetArchiveScreenShareTypeAsync() + Type = LayoutType.bestFit, + StyleSheet = "bob" + }; + + var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); + Assert.Contains("Invalid layout, layout is not custom, but stylesheet is set", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public async Task SetArchiveLayoutAsyncNonCustomLayoutTypeStylesheetProvidedThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { - var opentok = new OpenTok(ApiKey, ApiSecret); - var layout = new ArchiveLayout { Type = LayoutType.bestFit, ScreenShareType = ScreenShareLayoutType.Pip }; - var headers = new Dictionary { { "Content-Type", "application/json" } }; - var archiveId = "123456789"; - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; - var mockClient = new Mock(); - opentok.Client = mockClient.Object; - mockClient.Setup(c => c.Put(expectedUrl, headers, It.Is>(x => (string)x["type"] == "bestFit" && (string)x["screenshareType"] == "pip"))); - - var response = await opentok.SetArchiveLayoutAsync(archiveId, layout); - Assert.True(response); - } - - // Stop Archive - - [Fact] - public void StopArchive() + Type = LayoutType.bestFit, + StyleSheet = "bob" + }; + + var exception = + await Assert.ThrowsAsync(async () => + await opentok.SetArchiveLayoutAsync("12345", layout)); + Assert.Contains("Invalid layout, layout is not custom, but stylesheet is set", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public void SetArchiveLayoutTypeNotBestfitThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { - Guid archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); - string returnString = GetResponseJson(); - - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), - It.IsAny>(), - It.IsAny>())) - .Returns(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = opentok.StopArchive(archiveId.ToString()); - - Assert.NotNull(archive); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(archiveId, archive.Id); - Assert.Equal(ArchiveStatus.STOPPED, archive.Status); - - mockClient.Verify(httpClient => httpClient.Post(It.Is( - url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + ScreenShareType = ScreenShareLayoutType.BestFit, + Type = LayoutType.pip + }; + + var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); + Assert.Contains("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public async Task SetArchiveLayoutAsyncTypeNotBestfitThrowsException() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout + { + ScreenShareType = ScreenShareLayoutType.BestFit, + Type = LayoutType.pip + }; + + var exception = + await Assert.ThrowsAsync(() => + opentok.SetArchiveLayoutAsync("12345", layout)); + Assert.Contains("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public void SetArchiveScreenShareTypeInvalid() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.Pip }; + + var exception = Assert.Throws(() => opentok.SetArchiveLayout("12345", layout)); + + Assert.StartsWith("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public async Task SetArchiveScreenShareTypeInvalidAsync() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { Type = LayoutType.pip, ScreenShareType = ScreenShareLayoutType.Pip }; + + var exception = + await Assert.ThrowsAsync(async () => + await opentok.SetArchiveLayoutAsync("12345", layout)); + + Assert.StartsWith("Invalid layout, when ScreenShareType is set, Type must be bestFit", exception.Message); + Assert.Equal("layout", exception.ParamName); + } + + [Fact] + public void SetArchiveScreenShareType() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { Type = LayoutType.bestFit, ScreenShareType = ScreenShareLayoutType.Pip }; + var headers = new Dictionary { { "Content-Type", "application/json" } }; + var archiveId = "123456789"; + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + var mockClient = new Mock(); + opentok.Client = mockClient.Object; + mockClient.Setup(c => c.Put(expectedUrl, headers, + It.Is>(x => + (string)x["type"] == "bestFit" && (string)x["screenshareType"] == "pip"))); + Assert.True(opentok.SetArchiveLayout(archiveId, layout)); + } + + [Fact] + public async Task SetArchiveScreenShareTypeAsync() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var layout = new ArchiveLayout { Type = LayoutType.bestFit, ScreenShareType = ScreenShareLayoutType.Pip }; + var headers = new Dictionary { { "Content-Type", "application/json" } }; + var archiveId = "123456789"; + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/layout"; + var mockClient = new Mock(); + opentok.Client = mockClient.Object; + mockClient.Setup(c => c.Put(expectedUrl, headers, + It.Is>(x => + (string)x["type"] == "bestFit" && (string)x["screenshareType"] == "pip"))); + + var response = await opentok.SetArchiveLayoutAsync(archiveId, layout); + Assert.True(response); + } + + // Stop Archive + + [Fact] + public void StopArchive() + { + var archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); + var returnString = GetResponseJson(); + + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + It.IsAny>())) + .Returns(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = opentok.StopArchive(archiveId.ToString()); + + Assert.NotNull(archive); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(archiveId, archive.Id); + Assert.Equal(ArchiveStatus.STOPPED, archive.Status); + + mockClient.Verify(httpClient => httpClient.Post(It.Is( + url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public void StopArchiveFromArchiveObject() - { - Guid archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); - string returnString = GetResponseJson(); - - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), - It.IsAny>(), - It.IsAny>())) - .Returns(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - - Archive archive = new Archive(opentok); - archive.Id = archiveId; - archive.SessionId = "SESSIONID"; - archive.Stop(); - - Assert.NotNull(archive); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(archiveId, archive.Id); - Assert.Equal(ArchiveStatus.STOPPED, archive.Status); - - mockClient.Verify(httpClient => httpClient.Post(It.Is( - url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + [Fact] + public void StopArchiveFromArchiveObject() + { + var archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); + var returnString = GetResponseJson(); + + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Post(It.IsAny(), It.IsAny>(), - It.IsAny>()), Times.Once()); - } + It.IsAny>())) + .Returns(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + + var archive = new Archive(opentok); + archive.Id = archiveId; + archive.SessionId = "SESSIONID"; + archive.Stop(); + + Assert.NotNull(archive); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(archiveId, archive.Id); + Assert.Equal(ArchiveStatus.STOPPED, archive.Status); + + mockClient.Verify(httpClient => httpClient.Post(It.Is( + url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + It.IsAny>(), + It.IsAny>()), Times.Once()); + } - [Fact] - public async Task StopArchiveAsync() - { - string archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; - string returnString = GetResponseJson(); - - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), - It.IsAny>())) - .ReturnsAsync(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - Archive archive = await opentok.StopArchiveAsync(archiveId); - - Assert.NotNull(archive); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(archiveId, archive.Id.ToString()); - - var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/stop"; - - mockClient.Verify(httpClient => httpClient - .PostAsync(It.Is( - url => url.Equals(expectedUrl)), - It.IsAny>(), - It.IsAny>()), Times.Once()); - } - - [Fact] - public async Task StopArchiveAsyncFromArchiveObject() - { - Guid archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); - string returnString = GetResponseJson(); + [Fact] + public async Task StopArchiveAsync() + { + var archiveId = "30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"; + var returnString = GetResponseJson(); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), - It.IsAny>(), - It.IsAny>())) - .ReturnsAsync(returnString); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), + It.IsAny>())) + .ReturnsAsync(returnString); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archive = await opentok.StopArchiveAsync(archiveId); - Archive archive = new Archive(opentok); - archive.Id = archiveId; - archive.SessionId = "SESSIONID"; - await archive.StopAsync(); + Assert.NotNull(archive); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(archiveId, archive.Id.ToString()); - Assert.NotNull(archive); - Assert.Equal("SESSIONID", archive.SessionId); - Assert.Equal(archiveId, archive.Id); + var expectedUrl = $"v2/project/{ApiKey}/archive/{archiveId}/stop"; - mockClient.Verify(httpClient => httpClient.PostAsync(It.Is( - url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + mockClient.Verify(httpClient => httpClient + .PostAsync(It.Is( + url => url.Equals(expectedUrl)), It.IsAny>(), It.IsAny>()), Times.Once()); - } + } - // List Archives - - [Fact] - public void ListArchives() - { - string returnString = GetResponseJson(); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + [Fact] + public async Task StopArchiveAsyncFromArchiveObject() + { + var archiveId = new Guid("30b3ebf1-ba36-4f5b-8def-6f70d9986fe9"); + var returnString = GetResponseJson(); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - ArchiveList archives = opentok.ListArchives(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.PostAsync(It.IsAny(), + It.IsAny>(), + It.IsAny>())) + .ReturnsAsync(returnString); - Assert.NotNull(archives); - Assert.Equal(6, archives.Count); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; - mockClient.Verify( - httpClient => - httpClient.Get(It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0"))), - Times.Once()); - } + var archive = new Archive(opentok); + archive.Id = archiveId; + archive.SessionId = "SESSIONID"; + await archive.StopAsync(); - [Fact] - public void ListArchivesWithValidSessionId() - { - var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4"; - string returnString = GetResponseJson(); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); + Assert.NotNull(archive); + Assert.Equal("SESSIONID", archive.SessionId); + Assert.Equal(archiveId, archive.Id); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - ArchiveList archives = opentok.ListArchives(sessionId: sessionId); + mockClient.Verify(httpClient => httpClient.PostAsync(It.Is( + url => url.Equals($"v2/project/{ApiKey}/archive/{archiveId}/stop")), + It.IsAny>(), + It.IsAny>()), Times.Once()); + } - Assert.NotNull(archives); - Assert.Equal(6, archives.Count); + // List Archives - mockClient.Verify( - httpClient => httpClient.Get(It.Is(url => - url.Equals($"v2/project/{ApiKey}/archive?offset=0&sessionId={sessionId}"))), Times.Once()); - } + [Fact] + public void ListArchives() + { + var returnString = GetResponseJson(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); - [Fact] - public void ListArchivesBadCount() - { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archives = opentok.ListArchives(); - var exception = Assert.Throws(() => opentok.ListArchives(count: -5)); - Assert.Equal("count cannot be smaller than 0", exception.Message); - } + Assert.NotNull(archives); + Assert.Equal(6, archives.Count); - [Fact] - public void ListArchivesBadSessionId() - { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); + mockClient.Verify( + httpClient => + httpClient.Get(It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0"))), + Times.Once()); + } - var exception = Assert.Throws(() => - opentok.ListArchives(sessionId: "This-is-not-a-valid-session-id")); - Assert.Equal("Session Id is not valid", exception.Message); - } + [Fact] + public void ListArchivesWithValidSessionId() + { + var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4"; + var returnString = GetResponseJson(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.Get(It.IsAny())).Returns(returnString); - [Fact] - public async Task ListArchivesAsync() - { - string returnString = GetResponseJson(); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) - .ReturnsAsync(returnString); - - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - ArchiveList archives = await opentok.ListArchivesAsync(); - - Assert.NotNull(archives); - Assert.Equal(6, archives.Count); - - mockClient.Verify( - httpClient => - httpClient.GetAsync(It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0")), - null), Times.Once()); - } - - [Fact] - public async Task ListArchivesAsyncWithValidSessionId() - { - var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4"; - string returnString = GetResponseJson(); - var mockClient = new Mock(); - mockClient.Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) - .ReturnsAsync(returnString); + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archives = opentok.ListArchives(sessionId: sessionId); - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - opentok.Client = mockClient.Object; - ArchiveList archives = await opentok.ListArchivesAsync(sessionId: sessionId); + Assert.NotNull(archives); + Assert.Equal(6, archives.Count); - Assert.NotNull(archives); - Assert.Equal(6, archives.Count); + mockClient.Verify( + httpClient => httpClient.Get(It.Is(url => + url.Equals($"v2/project/{ApiKey}/archive?offset=0&sessionId={sessionId}"))), Times.Once()); + } - mockClient.Verify(httpClient => - httpClient.GetAsync( - It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0&sessionId={sessionId}")), + [Fact] + public void ListArchivesBadCount() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + + var exception = Assert.Throws(() => opentok.ListArchives(count: -5)); + Assert.Equal("count cannot be smaller than 0", exception.Message); + } + + [Fact] + public void ListArchivesBadSessionId() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + + var exception = Assert.Throws(() => + opentok.ListArchives(sessionId: "This-is-not-a-valid-session-id")); + Assert.Equal("Session Id is not valid", exception.Message); + } + + [Fact] + public async Task ListArchivesAsync() + { + var returnString = GetResponseJson(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) + .ReturnsAsync(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archives = await opentok.ListArchivesAsync(); + + Assert.NotNull(archives); + Assert.Equal(6, archives.Count); + + mockClient.Verify( + httpClient => + httpClient.GetAsync(It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0")), null), Times.Once()); - } + } - [Fact] - public async Task ListArchivesAsyncBadCount() - { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - var exception = - await Assert.ThrowsAsync(async () => - await opentok.ListArchivesAsync(count: -5)); - Assert.Equal("count cannot be smaller than 0", exception.Message); - } - - [Fact] - public async Task ListArchivesAsyncBadSessionId() + [Fact] + public async Task ListArchivesAsyncWithValidSessionId() + { + var sessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4"; + var returnString = GetResponseJson(); + var mockClient = new Mock(); + mockClient.Setup(httpClient => httpClient.GetAsync(It.IsAny(), null)) + .ReturnsAsync(returnString); + + var opentok = new OpenTok(ApiKey, ApiSecret); + opentok.Client = mockClient.Object; + var archives = await opentok.ListArchivesAsync(sessionId: sessionId); + + Assert.NotNull(archives); + Assert.Equal(6, archives.Count); + + mockClient.Verify(httpClient => + httpClient.GetAsync( + It.Is(url => url.Equals($"v2/project/{ApiKey}/archive?offset=0&sessionId={sessionId}")), + null), Times.Once()); + } + + [Fact] + public async Task ListArchivesAsyncBadCount() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var exception = + await Assert.ThrowsAsync(async () => + await opentok.ListArchivesAsync(count: -5)); + Assert.Equal("count cannot be smaller than 0", exception.Message); + } + + [Fact] + public async Task ListArchivesAsyncBadSessionId() + { + var opentok = new OpenTok(ApiKey, ApiSecret); + var exception = await Assert.ThrowsAsync(async () => + await opentok.ListArchivesAsync(sessionId: "This-is-not-a-valid-session-id")); + + Assert.Equal("Session Id is not valid", exception.Message); + } + + private OpenTok BuildOpenTok(HttpClient client) + { + return new OpenTok(ApiKey, ApiSecret) { - OpenTok opentok = new OpenTok(ApiKey, ApiSecret); - var exception = await Assert.ThrowsAsync(async () => - await opentok.ListArchivesAsync(sessionId: "This-is-not-a-valid-session-id")); - - Assert.Equal("Session Id is not valid", exception.Message); - } - - private OpenTok BuildOpenTok(HttpClient client) => - new OpenTok(this.ApiKey, this.ApiSecret) - { - Client = client, - }; + Client = client + }; } } \ No newline at end of file diff --git a/OpenTokTest/TestBase.cs b/OpenTokTest/TestBase.cs index d903625..160510f 100644 --- a/OpenTokTest/TestBase.cs +++ b/OpenTokTest/TestBase.cs @@ -12,6 +12,8 @@ public abstract class TestBase protected string ApiSecret = "1234567890abcdef1234567890abcdef1234567890"; protected int ApiKey = 123456; protected string SessionId = "1_MX4xMjM0NTZ-flNhdCBNYXIgMTUgMTQ6NDI6MjMgUERUIDIwMTR-MC40OTAxMzAyNX4"; + protected string ApplicationId = "123"; + protected string PrivateKey = "456"; #if NETCOREAPP2_0_OR_GREATER private static readonly Assembly ThisAssembly = typeof(TestBase).GetTypeInfo().Assembly; From 64fd480e037358e7e65dc15f052c410145bf5432 Mon Sep 17 00:00:00 2001 From: tr00d Date: Thu, 14 Nov 2024 13:26:21 +0100 Subject: [PATCH 5/7] refactor: remove unused method --- OpenTok/Util/TokenGenerator.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/OpenTok/Util/TokenGenerator.cs b/OpenTok/Util/TokenGenerator.cs index 2a6b4a7..1056b06 100644 --- a/OpenTok/Util/TokenGenerator.cs +++ b/OpenTok/Util/TokenGenerator.cs @@ -64,11 +64,6 @@ public string GenerateToken(string applicationId, string privateKey) return new Jwt().GenerateToken(Credentials.FromAppIdAndPrivateKey(applicationId, privateKey)) .GetSuccessUnsafe(); } - - public string GenerateT1Token() - { - return null; - } } internal struct TokenData From fe26d7d1ac9749995beb76456512e626f1396daa Mon Sep 17 00:00:00 2001 From: tr00d Date: Thu, 14 Nov 2024 13:26:34 +0100 Subject: [PATCH 6/7] feat: make GetOpenTokId public --- OpenTok/OpenTok.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenTok/OpenTok.cs b/OpenTok/OpenTok.cs index 90c1a7b..2eb7c0e 100644 --- a/OpenTok/OpenTok.cs +++ b/OpenTok/OpenTok.cs @@ -593,7 +593,11 @@ public Archive StartArchive(string sessionId, string name = "", bool hasVideo = return OpenTokUtils.GenerateArchive(response, ApiKey, ApiSecret, OpenTokServer); } - private string GetOpenTokId() => this.IsShim ? this.applicationId : this.ApiKey.ToString(); + /// + /// Retrieves either the Api Key or Application Id associated with the OpenTok object. + /// + /// The identifier. + public string GetOpenTokId() => this.IsShim ? this.applicationId : this.ApiKey.ToString(); /// /// Starts archiving an OpenTok session. From fef04797f5824672a17e39c7448c10bf4baafc1e Mon Sep 17 00:00:00 2001 From: tr00d Date: Thu, 14 Nov 2024 13:27:00 +0100 Subject: [PATCH 7/7] feat: add archiving features to the BlazorSampleApp --- BlazorHelloWorld/Components/Pages/Home.razor | 19 +++++++++-- .../Infrastructure/VideoService.cs | 32 ++++++++++++++++--- BlazorHelloWorld/Program.cs | 2 +- BlazorHelloWorld/appsettings.json | 6 ++-- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/BlazorHelloWorld/Components/Pages/Home.razor b/BlazorHelloWorld/Components/Pages/Home.razor index 3655ef0..c10a73a 100644 --- a/BlazorHelloWorld/Components/Pages/Home.razor +++ b/BlazorHelloWorld/Components/Pages/Home.razor @@ -23,17 +23,32 @@
+
+ + +
@code { + private bool isArchiving => this.archiveId != Guid.Empty; + private SessionCredentials session; + private Guid archiveId; + protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (firstRender) { - var session = Service.CreateSession(); - await JavascriptRuntime.InvokeVoidAsync("initializeStream", Service.GetApiKey(), session.SessionId, session.Token); + this.session = Service.CreateSession(); + await JavascriptRuntime.InvokeVoidAsync("initializeStream", Service.GetOpenTokId(), session.SessionId, session.Token); } } + private async Task StartArchiving() + { + var archive = await Service.StartArchiving(this.session.SessionId); + this.archiveId = archive.Id; + } + + private Task StopArchiving() => Service.StopArchiving(this.archiveId.ToString()); } \ No newline at end of file diff --git a/BlazorHelloWorld/Infrastructure/VideoService.cs b/BlazorHelloWorld/Infrastructure/VideoService.cs index 76982b8..fdb5a5c 100644 --- a/BlazorHelloWorld/Infrastructure/VideoService.cs +++ b/BlazorHelloWorld/Infrastructure/VideoService.cs @@ -10,11 +10,28 @@ namespace BlazorHelloWorld.Infrastructure; public class VideoService { private readonly OpenTok openTok; + private readonly string apiKey; public VideoService(OpenTokOptions options) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - openTok = new OpenTok(Convert.ToInt32(options.ApiKey), options.ApiSecret); + this.openTok = InitializeClient(options); + } + + private OpenTok InitializeClient(OpenTokOptions options) + { + if (!string.IsNullOrEmpty(options.ApplicationId) && !string.IsNullOrEmpty(options.PrivateKey)) + { + return new OpenTok(options.ApplicationId, options.PrivateKey); + } + + if (!string.IsNullOrEmpty(options.ApiKey) && !string.IsNullOrEmpty(options.ApiSecret) + && int.TryParse(options.ApiKey, out var key)) + { + return new OpenTok(key, options.ApiSecret); + } + + throw new ArgumentException("Missing credentials"); } public SessionCredentials CreateSession() @@ -23,12 +40,19 @@ public SessionCredentials CreateSession() return new SessionCredentials(session.Id, session.GenerateToken()); } - public int GetApiKey() + public string GetOpenTokId() => this.openTok.GetOpenTokId(); + + public async Task StartArchiving(string sessionId) + { + return await openTok.StartArchiveAsync(sessionId); + } + + public async Task StopArchiving(string archiveId) { - return openTok.ApiKey; + await openTok.StopArchiveAsync(archiveId); } } -public record OpenTokOptions(string ApiKey, string ApiSecret); +public record OpenTokOptions(string ApiKey, string ApiSecret, string ApplicationId, string PrivateKey); public record SessionCredentials(string SessionId, string Token); \ No newline at end of file diff --git a/BlazorHelloWorld/Program.cs b/BlazorHelloWorld/Program.cs index ae3b2f8..ecbae3a 100644 --- a/BlazorHelloWorld/Program.cs +++ b/BlazorHelloWorld/Program.cs @@ -5,7 +5,7 @@ var options = builder.Configuration.GetSection(nameof(OpenTokOptions)).Get(); builder.Services.AddRazorComponents().AddInteractiveServerComponents(); builder.Services.AddServerSideBlazor(); -builder.Services.AddSingleton(options); +builder.Services.AddSingleton(options); builder.Services.AddScoped(); var app = builder.Build(); app.UseHttpsRedirection(); diff --git a/BlazorHelloWorld/appsettings.json b/BlazorHelloWorld/appsettings.json index d8c32a3..bbee824 100644 --- a/BlazorHelloWorld/appsettings.json +++ b/BlazorHelloWorld/appsettings.json @@ -7,7 +7,9 @@ }, "AllowedHosts": "*", "OpenTokOptions": { - "ApiKey": "47581421", - "ApiSecret": "c7715696b35c11b025b7cddd399b035f879cc0dd" + "ApiKey": "", + "ApiSecret": "", + "ApplicationId": "", + "PrivateKey": "" } }