-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
285 additions
and
36 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
OutOfSchool/OutOfSchool.AuthCommon/Config/EUSignServicePaths.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace OutOfSchool.AuthCommon.Config; | ||
|
||
public class EUSignServicePaths | ||
{ | ||
public string Certificate { get; set; } | ||
|
||
public string Decrypt { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
219 changes: 219 additions & 0 deletions
219
OutOfSchool/OutOfSchool.AuthServer.Tests/Services/GovCommunicationServiceTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
using Moq; | ||
using NUnit.Framework; | ||
using OutOfSchool.AuthCommon.Config; | ||
using OutOfSchool.AuthCommon.Models; | ||
using OutOfSchool.AuthCommon.Services.Interfaces; | ||
using OutOfSchool.AuthorizationServer.Services; | ||
using OutOfSchool.Common.Config; | ||
using OutOfSchool.Tests.Common; | ||
using static OutOfSchool.Tests.Common.HttpClientTestHelper; | ||
|
||
namespace OutOfSchool.AuthServer.Tests.Services; | ||
|
||
[TestFixture] | ||
public class GovCommunicationServiceTests | ||
{ | ||
private Mock<IOptions<CommunicationConfig>> communicationOptions; | ||
private Mock<IOptions<AuthorizationServerConfig>> authServerOptions; | ||
private Mock<IHttpClientFactory> httpClientFactory; | ||
private Mock<ILogger<GovIdentityCommunicationService>> logger; | ||
private Mock<HttpMessageHandler> handler; | ||
private HttpClient client; | ||
private readonly Uri eUSignServiceUri = new("https://sign.com"); | ||
private readonly Uri idServerUri = new("https://id.com"); | ||
private IGovIdentityCommunicationService communicationService; | ||
|
||
[SetUp] | ||
public void SetUp() | ||
{ | ||
handler = new Mock<HttpMessageHandler>(); | ||
client = new HttpClient(handler.Object); | ||
var communicationConfig = new CommunicationConfig | ||
{ | ||
ClientName = "test", | ||
MaxNumberOfRetries = 1, | ||
TimeoutInSeconds = 1, | ||
}; | ||
var authServerConfig = new AuthorizationServerConfig | ||
{ | ||
ExternalLogin = new ExternalLogin | ||
{ | ||
EUSignServiceUri = eUSignServiceUri, | ||
IdServerUri = idServerUri, | ||
IdServerPaths = new IdServerPaths | ||
{ | ||
UserInfo = "/userinfo" | ||
}, | ||
EUSignServicePaths = new EUSignServicePaths | ||
{ | ||
Certificate = "api/v1/certificate", | ||
Decrypt = "api/v1/decrypt", | ||
}, | ||
Parameters = new Parameters | ||
{ | ||
Fields = new Fields | ||
{ | ||
Key = "key", | ||
Value = "value", | ||
} | ||
} | ||
}, | ||
}; | ||
communicationOptions = new Mock<IOptions<CommunicationConfig>>(); | ||
communicationOptions.Setup(x => x.Value).Returns(communicationConfig); | ||
authServerOptions = new Mock<IOptions<AuthorizationServerConfig>>(); | ||
authServerOptions.Setup(x => x.Value).Returns(authServerConfig); | ||
httpClientFactory = new Mock<IHttpClientFactory>(); | ||
httpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client); | ||
logger = new Mock<ILogger<GovIdentityCommunicationService>>(); | ||
communicationService = | ||
new GovIdentityCommunicationService(httpClientFactory.Object, communicationOptions.Object, logger.Object, | ||
authServerOptions.Object); | ||
} | ||
|
||
[Test] | ||
public async Task GetUserInfo_WithCorrectRequest_ReturnsOkResponse() | ||
{ | ||
// Arrange | ||
var remoteUserId = "123"; | ||
var remoteToken = "secret"; | ||
var expectedEmail = "test@example.com"; | ||
|
||
var expected = new UserInfoResponse | ||
{ | ||
Email = expectedEmail, | ||
}; | ||
|
||
var certResponse = new CertificateResponse | ||
{ | ||
CertBase64 = "cert", | ||
}; | ||
var certSetup = SetupSendAsync(handler, HttpMethod.Get, | ||
new Uri(eUSignServiceUri, "api/v1/certificate").ToString()); | ||
ReturnsHttpResponseAsync(certSetup, certResponse, HttpStatusCode.OK); | ||
|
||
var infoResponse = new EnvelopedUserInfoResponse | ||
{ | ||
EncryptedUserInfo = "serialized_info", | ||
}; | ||
|
||
var infoSetup = SetupSendAsync(handler, HttpMethod.Get, new Uri(idServerUri, "/userinfo").ToString(), true); | ||
ReturnsHttpResponseAsync(infoSetup, infoResponse, HttpStatusCode.OK); | ||
|
||
var decryptSetup = | ||
SetupSendAsync(handler, HttpMethod.Post, new Uri(eUSignServiceUri, "api/v1/decrypt").ToString()); | ||
ReturnsHttpResponseAsync(decryptSetup, expected, HttpStatusCode.OK); | ||
|
||
// Act | ||
var userInfo = await communicationService.GetUserInfo(remoteUserId, remoteToken); | ||
|
||
// Assert | ||
userInfo.AssertRight(u => Assert.AreEqual(expectedEmail, u.Email)); | ||
} | ||
|
||
[Test] | ||
public async Task GetUserInfo_WithEUSignCertError_ReturnsErrorResponse() | ||
{ | ||
// Arrange | ||
var remoteUserId = "123"; | ||
var remoteToken = "secret"; | ||
var certSetup = SetupSendAsync(handler, HttpMethod.Get, | ||
new Uri(eUSignServiceUri, "api/v1/certificate").ToString()); | ||
ReturnsHttpResponseAsync(certSetup, null, HttpStatusCode.InternalServerError); | ||
|
||
// Act | ||
var userInfo = await communicationService.GetUserInfo(remoteUserId, remoteToken); | ||
|
||
// Assert | ||
userInfo.AssertLeft(e => | ||
{ | ||
Assert.IsInstanceOf<ExternalAuthError>(e); | ||
|
||
var error = (ExternalAuthError) e; | ||
Assert.AreEqual(ExternalAuthErrorGroup.Encryption, error.ErrorGroup); | ||
}); | ||
} | ||
|
||
[Test] | ||
public async Task GetUserInfo_WithGovError_ReturnsErrorResponse() | ||
{ | ||
// Arrange | ||
var remoteUserId = "123"; | ||
var remoteToken = "secret"; | ||
var certResponse = new CertificateResponse | ||
{ | ||
CertBase64 = "cert", | ||
}; | ||
var certSetup = SetupSendAsync(handler, HttpMethod.Get, | ||
new Uri(eUSignServiceUri, "api/v1/certificate").ToString()); | ||
ReturnsHttpResponseAsync(certSetup, certResponse, HttpStatusCode.OK); | ||
|
||
var errorResponse = new IdGovErrorResponse | ||
{ | ||
Error = 1, | ||
}; | ||
|
||
var infoSetup = SetupSendAsync(handler, HttpMethod.Get, new Uri(idServerUri, "/userinfo").ToString(), true); | ||
ReturnsHttpResponseAsync(infoSetup, errorResponse, HttpStatusCode.Unauthorized); | ||
|
||
// Act | ||
var userInfo = await communicationService.GetUserInfo(remoteUserId, remoteToken); | ||
|
||
// Assert | ||
userInfo.AssertLeft(e => | ||
{ | ||
Assert.IsInstanceOf<ExternalAuthError>(e); | ||
|
||
var error = (ExternalAuthError) e; | ||
Assert.AreEqual(ExternalAuthErrorGroup.IdGovUa, error.ErrorGroup); | ||
Assert.AreEqual(error.HttpStatusCode, HttpStatusCode.Unauthorized); | ||
Assert.AreEqual(error.Message, "1"); | ||
}); | ||
} | ||
|
||
[Test] | ||
public async Task GetUserInfo_WithEUSignDecryptError_ReturnsErrorResponse() | ||
{ | ||
// Arrange | ||
var remoteUserId = "123"; | ||
var remoteToken = "secret"; | ||
|
||
var certResponse = new CertificateResponse | ||
{ | ||
CertBase64 = "cert", | ||
}; | ||
var certSetup = SetupSendAsync(handler, HttpMethod.Get, | ||
new Uri(eUSignServiceUri, "api/v1/certificate").ToString()); | ||
ReturnsHttpResponseAsync(certSetup, certResponse, HttpStatusCode.OK); | ||
|
||
var infoResponse = new EnvelopedUserInfoResponse | ||
{ | ||
EncryptedUserInfo = "serialized_info", | ||
}; | ||
|
||
var infoSetup = SetupSendAsync(handler, HttpMethod.Get, new Uri(idServerUri, "/userinfo").ToString(), true); | ||
ReturnsHttpResponseAsync(infoSetup, infoResponse, HttpStatusCode.OK); | ||
|
||
var decryptSetup = | ||
SetupSendAsync(handler, HttpMethod.Post, new Uri(eUSignServiceUri, "api/v1/decrypt").ToString()); | ||
ReturnsHttpResponseAsync(decryptSetup, null, HttpStatusCode.InternalServerError); | ||
|
||
// Act | ||
var userInfo = await communicationService.GetUserInfo(remoteUserId, remoteToken); | ||
|
||
// Assert | ||
userInfo.AssertLeft(e => | ||
{ | ||
Assert.IsInstanceOf<ExternalAuthError>(e); | ||
|
||
var error = (ExternalAuthError) e; | ||
Assert.AreEqual(ExternalAuthErrorGroup.Encryption, error.ErrorGroup); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
OutOfSchool/Tests/OutOfSchool.Tests.Common/HttpClientTestHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#nullable enable | ||
|
||
using System; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Moq; | ||
using Moq.Language.Flow; | ||
using Moq.Protected; | ||
|
||
namespace OutOfSchool.Tests.Common; | ||
|
||
public static class HttpClientTestHelper | ||
{ | ||
public static ISetup<HttpMessageHandler, Task<HttpResponseMessage>> SetupSendAsync( | ||
Mock<HttpMessageHandler> handler, HttpMethod requestMethod, string requestUrl, bool contains = false) | ||
{ | ||
return handler.Protected().Setup<Task<HttpResponseMessage>>("SendAsync", | ||
ItExpr.Is<HttpRequestMessage>(r => | ||
r.Method == requestMethod && | ||
r.RequestUri != null && | ||
contains ? r.RequestUri.ToString().Contains(requestUrl) : r.RequestUri.ToString() == requestUrl), | ||
ItExpr.IsAny<CancellationToken>()); | ||
} | ||
|
||
public static IReturnsResult<HttpMessageHandler> ReturnsHttpResponseAsync( | ||
ISetup<HttpMessageHandler, Task<HttpResponseMessage>> moqSetup, | ||
object? responseBody, | ||
HttpStatusCode responseCode) | ||
{ | ||
var serializedResponse = JsonSerializer.Serialize(responseBody); | ||
var stringContent = new StringContent(serializedResponse ?? string.Empty); | ||
|
||
var responseMessage = new HttpResponseMessage | ||
{ | ||
StatusCode = responseCode, | ||
Content = stringContent, | ||
}; | ||
|
||
return moqSetup.ReturnsAsync(responseMessage); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters