Skip to content

Commit 1d44efe

Browse files
authored
test: add unit test for RequestFailedException (#153)
Signed-off-by: Junjie Gao <[email protected]>
1 parent 0e675c8 commit 1d44efe

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

Notation.Plugin.AzureKeyVault.Tests/ProgramTests.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using Xunit;
22
using Moq;
3-
using Notation.Plugin.AzureKeyVault.Command;
3+
using Azure;
44
using Notation.Plugin.Protocol;
55
using System.IO;
66
using System.Threading.Tasks;
77
using System;
8+
using Moq.Protected;
89

910
namespace Notation.Plugin.AzureKeyVault.Tests
1011
{
@@ -84,5 +85,47 @@ public async Task ExecuteAsync_HandlesInvalidCommands(string command)
8485
await Assert.ThrowsAsync<ValidationException>(() => Program.ExecuteAsync(args));
8586
}
8687
}
88+
// we need this because of method being protected
89+
internal interface IResponseMock
90+
{
91+
bool TryGetHeader(string name, out string value);
92+
}
93+
94+
// we need this to be able to define the callback with out parameter
95+
delegate bool TryGetHeaderCallback(string name, ref string value);
96+
97+
98+
[Theory]
99+
[InlineData(200, "{\"error\":{\"message\":\"TestErrorMessage\"}}", "TestErrorMessage")]
100+
[InlineData(500, "{\"error\":{\"message\":\"TestErrorMessage\"}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
101+
[InlineData(500, "{\"error2\":{\"message\":\"TestErrorMessage\"}}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
102+
[InlineData(500, "{\"error\":{\"message2\":\"TestErrorMessage\"}}", "Service request failed.\nStatus: 500\n\nHeaders:\n")]
103+
[InlineData(500, "{\"error\":{\"message\":\"\"}}", "\nStatus: 500\n\nHeaders:\n")]
104+
public void HandleAzureException(int code, string content, string expectedErrorMessage)
105+
{
106+
// Arrange
107+
Mock<Response> responseMock = new Mock<Response>();
108+
responseMock.SetupGet(r => r.Status).Returns(code);
109+
responseMock.SetupGet(r => r.Content).Returns(BinaryData.FromString(content));
110+
111+
// mock headers
112+
responseMock.CallBase = true;
113+
responseMock.Protected().As<IResponseMock>().Setup(m => m.TryGetHeader(It.IsAny<string>(), out It.Ref<string>.IsAny))
114+
.Returns(new TryGetHeaderCallback((string name, ref string value) =>
115+
{
116+
value = "ETAG";
117+
Console.WriteLine(name);
118+
return true;
119+
}));
120+
121+
var exception = new RequestFailedException(responseMock.Object);
122+
123+
// Act
124+
var errorResponse = Program.HandleAzureException(exception);
125+
126+
// Assert exit code 1
127+
Assert.Equal(expectedErrorMessage, errorResponse.ErrorMessage);
128+
Assert.Equal("ERROR", errorResponse.ErrorCode);
129+
}
87130
}
88131
}

Notation.Plugin.AzureKeyVault/Program.cs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,27 @@ public static async Task Main(string[] args)
1919
}
2020
catch (Azure.RequestFailedException e)
2121
{
22-
// wrap azure exception to notation plugin error response
23-
var rawResponse = e.GetRawResponse();
24-
if (rawResponse != null)
22+
Console.Error.WriteLine(HandleAzureException(e).ToJson());
23+
Environment.Exit(1);
24+
}
25+
catch (Exception e)
26+
{
27+
Error.PrintError(Error.ERROR, e.Message);
28+
Environment.Exit(1);
29+
}
30+
}
31+
32+
/// <summary>
33+
/// Handles Azure.RequestFailedException and returns ErrorResponse.
34+
/// </summary>
35+
/// <param name="e"></param>
36+
/// <returns></returns>
37+
public static ErrorResponse HandleAzureException(Azure.RequestFailedException e)
38+
{
39+
var rawResponse = e.GetRawResponse();
40+
if (rawResponse != null)
41+
{
42+
try
2543
{
2644
var content = JsonDocument.Parse(rawResponse.Content);
2745
if (content.RootElement.TryGetProperty("error", out var errorInfo) &&
@@ -30,23 +48,22 @@ public static async Task Main(string[] args)
3048
var errorMessage = errMsg.GetString();
3149
if (!string.IsNullOrEmpty(errorMessage))
3250
{
33-
Error.PrintError(
51+
return new ErrorResponse(
3452
errorCode: e.ErrorCode ?? Error.ERROR,
3553
errorMessage: errorMessage);
36-
Environment.Exit(1);
3754
}
3855
}
3956
}
40-
41-
// fallback to default error message
42-
Error.PrintError(Error.ERROR, e.Message);
43-
Environment.Exit(1);
44-
}
45-
catch (Exception e)
46-
{
47-
Error.PrintError(Error.ERROR, e.Message);
48-
Environment.Exit(1);
57+
catch (Exception)
58+
{
59+
// ignore
60+
}
4961
}
62+
63+
// fallback to default error message
64+
return new ErrorResponse(
65+
errorCode: e.ErrorCode ?? Error.ERROR,
66+
errorMessage: e.Message);
5067
}
5168

5269
public static async Task ExecuteAsync(string[] args)

0 commit comments

Comments
 (0)