Skip to content

Commit

Permalink
test: add unit test for RequestFailedException (#153)
Browse files Browse the repository at this point in the history
Signed-off-by: Junjie Gao <junjiegao@microsoft.com>
  • Loading branch information
JeyJeyGao authored Jan 30, 2024
1 parent 0e675c8 commit 1d44efe
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 15 deletions.
45 changes: 44 additions & 1 deletion Notation.Plugin.AzureKeyVault.Tests/ProgramTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using Xunit;
using Moq;
using Notation.Plugin.AzureKeyVault.Command;
using Azure;
using Notation.Plugin.Protocol;
using System.IO;
using System.Threading.Tasks;
using System;
using Moq.Protected;

namespace Notation.Plugin.AzureKeyVault.Tests
{
Expand Down Expand Up @@ -84,5 +85,47 @@ public async Task ExecuteAsync_HandlesInvalidCommands(string command)
await Assert.ThrowsAsync<ValidationException>(() => Program.ExecuteAsync(args));
}
}
// we need this because of method being protected
internal interface IResponseMock
{
bool TryGetHeader(string name, out string value);
}

// we need this to be able to define the callback with out parameter
delegate bool TryGetHeaderCallback(string name, ref string value);


[Theory]
[InlineData(200, "{\"error\":{\"message\":\"TestErrorMessage\"}}", "TestErrorMessage")]
[InlineData(500, "{\"error\":{\"message\":\"TestErrorMessage\"}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
[InlineData(500, "{\"error2\":{\"message\":\"TestErrorMessage\"}}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
[InlineData(500, "{\"error\":{\"message2\":\"TestErrorMessage\"}}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
[InlineData(500, "{\"error\":{\"message\":\"\"}}", "\nStatus: 500\n\nHeaders:\n")]
public void HandleAzureException(int code, string content, string expectedErrorMessage)
{
// Arrange
Mock<Response> responseMock = new Mock<Response>();
responseMock.SetupGet(r => r.Status).Returns(code);
responseMock.SetupGet(r => r.Content).Returns(BinaryData.FromString(content));

// mock headers
responseMock.CallBase = true;
responseMock.Protected().As<IResponseMock>().Setup(m => m.TryGetHeader(It.IsAny<string>(), out It.Ref<string>.IsAny))
.Returns(new TryGetHeaderCallback((string name, ref string value) =>
{
value = "ETAG";
Console.WriteLine(name);
return true;
}));

var exception = new RequestFailedException(responseMock.Object);

// Act
var errorResponse = Program.HandleAzureException(exception);

// Assert exit code 1
Assert.Equal(expectedErrorMessage, errorResponse.ErrorMessage);
Assert.Equal("ERROR", errorResponse.ErrorCode);
}
}
}
45 changes: 31 additions & 14 deletions Notation.Plugin.AzureKeyVault/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,27 @@ public static async Task Main(string[] args)
}
catch (Azure.RequestFailedException e)
{
// wrap azure exception to notation plugin error response
var rawResponse = e.GetRawResponse();
if (rawResponse != null)
Console.Error.WriteLine(HandleAzureException(e).ToJson());
Environment.Exit(1);
}
catch (Exception e)
{
Error.PrintError(Error.ERROR, e.Message);
Environment.Exit(1);
}
}

/// <summary>
/// Handles Azure.RequestFailedException and returns ErrorResponse.
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public static ErrorResponse HandleAzureException(Azure.RequestFailedException e)
{
var rawResponse = e.GetRawResponse();
if (rawResponse != null)
{
try
{
var content = JsonDocument.Parse(rawResponse.Content);
if (content.RootElement.TryGetProperty("error", out var errorInfo) &&
Expand All @@ -30,23 +48,22 @@ public static async Task Main(string[] args)
var errorMessage = errMsg.GetString();
if (!string.IsNullOrEmpty(errorMessage))
{
Error.PrintError(
return new ErrorResponse(
errorCode: e.ErrorCode ?? Error.ERROR,
errorMessage: errorMessage);
Environment.Exit(1);
}
}
}

// fallback to default error message
Error.PrintError(Error.ERROR, e.Message);
Environment.Exit(1);
}
catch (Exception e)
{
Error.PrintError(Error.ERROR, e.Message);
Environment.Exit(1);
catch (Exception)
{
// ignore
}
}

// fallback to default error message
return new ErrorResponse(
errorCode: e.ErrorCode ?? Error.ERROR,
errorMessage: e.Message);
}

public static async Task ExecuteAsync(string[] args)
Expand Down

0 comments on commit 1d44efe

Please sign in to comment.