Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/test-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
strategy:
matrix:
os: [windows-2022, windows-2025, ubuntu-22.04, ubuntu-24.04]
dotnet: [6.0.x, 7.0.x, 8.0.x]
dotnet: [6.0.x, 7.0.x, 8.0.x, 10.0.x]
fail-fast: false
steps:
- name: Checkout
Expand All @@ -50,4 +50,5 @@ jobs:
OPERATING_SYSTEM: ${{ matrix.os }}
DOTNET_VERSION: ${{ matrix.dotnet }}
run: |
dotnet test src/Bandwidth.Standard.Test --filter DisplayName~Bandwidth.Standard.Test.Unit
npm install -g @stoplight/prism-cli
prism mock ./bandwidth.yml & dotnet test src/Bandwidth.Standard.Test --filter DisplayName~Bandwidth.Standard.Test.Unit
531 changes: 112 additions & 419 deletions src/Bandwidth.Standard.Test/Unit/Api/CallsApiTests.cs

Large diffs are not rendered by default.

275 changes: 95 additions & 180 deletions src/Bandwidth.Standard.Test/Unit/Api/ConferencesApiTests.cs

Large diffs are not rendered by default.

427 changes: 61 additions & 366 deletions src/Bandwidth.Standard.Test/Unit/Api/EndpointsApiTests.cs

Large diffs are not rendered by default.

201 changes: 54 additions & 147 deletions src/Bandwidth.Standard.Test/Unit/Api/MFAApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,41 @@
*/

using System;
using System.Net;
using Xunit;

using Bandwidth.Standard.Client;
using Bandwidth.Standard.Api;
using Bandwidth.Standard.Model;
using Moq;
using System.Net;

namespace Bandwidth.Standard.Test.Unit.Api
{
/// <summary>
/// Class for testing MFAApi
/// MFAApi Unit Tests
/// </summary>
public class MFAApiTests : IDisposable
{
private MFAApi instance;
private Mock<ISynchronousClient> mockClient;
private Mock<IAsynchronousClient> mockAsynchronousClient;
private Configuration fakeConfiguration;
private readonly MFAApi instance;

private readonly string accountId = Environment.GetEnvironmentVariable("BW_ACCOUNT_ID");
private readonly string userNumber = Environment.GetEnvironmentVariable("USER_NUMBER");
private readonly string bwNumber = Environment.GetEnvironmentVariable("BW_NUMBER");
private readonly string messagingApplicationId = Environment.GetEnvironmentVariable("BW_MESSAGING_APPLICATION_ID");
private readonly string voiceApplicationId = Environment.GetEnvironmentVariable("BW_VOICE_APPLICATION_ID");

private readonly string message = "Your temporary {NAME} {SCOPE} code is {CODE}";
private readonly int digits = 6;

public MFAApiTests()
{
mockClient = new Mock<ISynchronousClient>();
mockAsynchronousClient = new Mock<IAsynchronousClient>();
fakeConfiguration = new Configuration();
fakeConfiguration.BasePath = "https://mfa.bandwidth.com/api/v1";
fakeConfiguration.Username = "username";
fakeConfiguration.Password = "password";
instance = new MFAApi(mockClient.Object, mockAsynchronousClient.Object, fakeConfiguration);
Configuration configuration = new()
{
BasePath = "http://127.0.0.1:4010",
IgnoreOperationServers = true,
OAuthClientId = Environment.GetEnvironmentVariable("BW_CLIENT_ID"),
OAuthClientSecret = Environment.GetEnvironmentVariable("BW_CLIENT_SECRET")
};
instance = new MFAApi(configuration);
}

public void Dispose()
Expand All @@ -60,15 +66,19 @@ public void InstanceTest()
[Fact]
public void GenerateMessagingCodeTest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "66fd98ae-ac8d-a00f-7fcd-ba3280aeb9b1", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);

var apiResponse = new ApiResponse<MessagingCodeResponse>(HttpStatusCode.OK, new MessagingCodeResponse("123-456-abcd"));
mockClient.Setup(x => x.Post<MessagingCodeResponse>("/accounts/{accountId}/code/messaging", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
var response = instance.GenerateMessagingCodeWithHttpInfo(accountId, codeRequest);

Assert.IsType<ApiResponse<MessagingCodeResponse>>(response);
CodeRequest codeRequest = new(
to: userNumber,
from: bwNumber,
applicationId: messagingApplicationId,
message: message,
digits: digits
);

ApiResponse<MessagingCodeResponse> response = instance.GenerateMessagingCodeWithHttpInfo(accountId, codeRequest);

Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.IsType<MessagingCodeResponse>(response.Data);
Assert.Equal(29, response.Data.MessageId.Length);
}

/// <summary>
Expand All @@ -77,15 +87,19 @@ public void GenerateMessagingCodeTest()
[Fact]
public void GenerateVoiceCodeTest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "66fd98ae-ac8d-a00f-7fcd-ba3280aeb9b1", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);

var apiResponse = new ApiResponse<VoiceCodeResponse>(HttpStatusCode.OK, new VoiceCodeResponse("c-1234"));
mockClient.Setup(x => x.Post<VoiceCodeResponse>("/accounts/{accountId}/code/voice", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
var response = instance.GenerateVoiceCodeWithHttpInfo(accountId, codeRequest);

Assert.IsType<ApiResponse<VoiceCodeResponse>>(response);
CodeRequest codeRequest = new(
to: userNumber,
from: bwNumber,
applicationId: voiceApplicationId,
message: message,
digits: digits
);

ApiResponse<VoiceCodeResponse> response = instance.GenerateVoiceCodeWithHttpInfo(accountId, codeRequest);

Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.IsType<VoiceCodeResponse>(response.Data);
Assert.Equal(47, response.Data.CallId.Length);
}

/// <summary>
Expand All @@ -94,125 +108,18 @@ public void GenerateVoiceCodeTest()
[Fact]
public void VerifyCodeTest()
{
string accountId = "9900000";
VerifyCodeRequest verifyCodeRequest = new VerifyCodeRequest("+19195551234", "2FA", 3, "123456");

var apiResponse = new ApiResponse<VerifyCodeResponse>(HttpStatusCode.OK, new VerifyCodeResponse(true));
mockClient.Setup(x => x.Post<VerifyCodeResponse>("/accounts/{accountId}/code/verify", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
var response = instance.VerifyCodeWithHttpInfo(accountId, verifyCodeRequest);

Assert.IsType<ApiResponse<VerifyCodeResponse>>(response);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}

/// <summary>
/// Test failed Generate Messaging Code Request
/// </summary>
[Fact]
public void GenerateMessagingCodeBadRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "not-an-application-id", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);

var apiResponse = new ApiResponse<MessagingCodeResponse>(HttpStatusCode.BadRequest, null);
mockClient.Setup(x => x.Post<MessagingCodeResponse>("/accounts/{accountId}/code/messaging", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateMessagingCode(accountId, codeRequest));

Assert.Equal("Error calling GenerateMessagingCode: ", Exception.Message);
Assert.Equal(400, Exception.ErrorCode);
}

/// <summary>
/// Test failed Generate Voice Code Request
/// </summary>
[Fact]
public void GenerateVoiceCodeBadRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "not-an-application-id", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);

var apiResponse = new ApiResponse<VoiceCodeResponse>(HttpStatusCode.BadRequest, null);
mockClient.Setup(x => x.Post<VoiceCodeResponse>("/accounts/{accountId}/code/voice", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateVoiceCode(accountId, codeRequest));

Assert.Equal("Error calling GenerateVoiceCode: ", Exception.Message);
Assert.Equal(400, Exception.ErrorCode);
}

/// <summary>
/// Test unauthorized Generate Messaging Code Request
/// </summary>
[Fact]
public void GenerateMessagingCodeUnauthorizedRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "123-456-abcd", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);
fakeConfiguration.Username = "badUsername";
fakeConfiguration.Password = "badPassword";

var apiResponse = new ApiResponse<MessagingCodeResponse>(HttpStatusCode.Unauthorized, new MessagingCodeResponse("Unauthorized"));
mockClient.Setup(x => x.Post<MessagingCodeResponse>("/accounts/{accountId}/code/messaging", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateMessagingCode(accountId, codeRequest));

Assert.Equal("Error calling GenerateMessagingCode: ", Exception.Message);
Assert.Equal(401, Exception.ErrorCode);
}

/// <summary>
/// Test unauthorized Generate Voice Code Request
/// </summary>
[Fact]
public void GenerateVoiceCodeUnauthorizedRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "123-456-abcd", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);
fakeConfiguration.Username = "badUsername";
fakeConfiguration.Password = "badPassword";

var apiResponse = new ApiResponse<VoiceCodeResponse>(HttpStatusCode.Unauthorized, new VoiceCodeResponse("Unauthorized"));
mockClient.Setup(x => x.Post<VoiceCodeResponse>("/accounts/{accountId}/code/voice", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateVoiceCode(accountId, codeRequest));

Assert.Equal("Error calling GenerateVoiceCode: ", Exception.Message);
Assert.Equal(401, Exception.ErrorCode);
}

/// <summary>
/// Test forbidden Generate Messaging Code Request
/// </summary>
[Fact]
public void GenerateMessagingCodeForbiddenRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "123-456-abcd", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);
fakeConfiguration.Username = "forbiddenUsername";
fakeConfiguration.Password = "badPassword";

var apiResponse = new ApiResponse<MessagingCodeResponse>(HttpStatusCode.Forbidden, new MessagingCodeResponse("Missing Authentication Token"));
mockClient.Setup(x => x.Post<MessagingCodeResponse>("/accounts/{accountId}/code/messaging", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateMessagingCode(accountId, codeRequest));

Assert.Equal("Error calling GenerateMessagingCode: ", Exception.Message);
Assert.Equal(403, Exception.ErrorCode);
}

/// <summary>
/// Test forbidden Generate Voice Code Request
/// </summary>
[Fact]
public void GenerateVoiceCodeForbiddenRequest()
{
string accountId = "9900000";
CodeRequest codeRequest = new CodeRequest("+19195551234", "+19195554321", "123-456-abcd", "2FA", "Your temporary {NAME} {SCOPE} code is {CODE}", 6);
fakeConfiguration.Username = "forbiddenUsername";
fakeConfiguration.Password = "badPassword";
VerifyCodeRequest verifyCodeRequest = new(
to: userNumber,
scope: "login",
expirationTimeInMinutes: 3,
code: "12345"
);

var apiResponse = new ApiResponse<VoiceCodeResponse>(HttpStatusCode.Forbidden, new VoiceCodeResponse("Missing Authentication Token"));
mockClient.Setup(x => x.Post<VoiceCodeResponse>("/accounts/{accountId}/code/voice", It.IsAny<RequestOptions>(), fakeConfiguration)).Returns(apiResponse);
ApiException Exception = Assert.Throws<ApiException>(() => instance.GenerateVoiceCode(accountId, codeRequest));
ApiResponse<VerifyCodeResponse> response = instance.VerifyCodeWithHttpInfo(accountId, verifyCodeRequest);

Assert.Equal("Error calling GenerateVoiceCode: ", Exception.Message);
Assert.Equal(403, Exception.ErrorCode);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.IsType<VerifyCodeResponse>(response.Data);
Assert.IsType<bool>(response.Data.Valid);
}
}
}
Loading
Loading