#unit-testing #asp.net-core #asp.net-identity
Вопрос:
Я разрабатываю веб-приложение Angular с использованием ASP.Net Ядро 3.1 для API.
До сих пор я написал несколько модульных тестов интеграции с использованием пользовательского веб-приложения для создания тестового сервера.
Все тесты используют HttpClient для получения и отправки сообщений в API, работающий в пользовательском веб-приложении. Большинство из этих тестов сначала выполняют вход в систему для получения маркера, который будет использоваться для последующих запросов.
Я хотел бы добавить в приложение двухфакторную аутентификацию, но это неизбежно нарушит любые тесты, так как они не смогут получить шестизначный код, который будет отправлен по электронной почте.
Вот как в настоящее время выглядит тест без внедрения MFA. Есть ли способ дать тесту код MFA, чтобы он мог продолжать выполнять тесты?
Нужно ли мне просто ввести пользователя, у которого не включен MFA? Я на самом деле хочу, чтобы у всех пользователей был включен MFA в производстве.
Большое спасибо
using Xunit;
using System.Threading.Tasks;
using MyCompany.ViewModels.Authentication;
using MyCompany.StaffPortal.Tests.Shared;
using StaffPortal;
using Newtonsoft.Json;
using MyCompany.ServiceA.ViewModels;
using System.Collections.Generic;
using System.Net.Http;
namespace MyCompany.Tests.StaffPortal.ServiceA
{
public class ExtensionsControllerTests : TestBase
{
public ExtensionsControllerTests(CustomWebApplicationFactory<Startup> factory) : base(factory)
{
}
[Fact]
public async Task Test_GetExtensions()
{
//This line creates a new "web browser" and uses the login details provided to obtain and set up the token so that we can request information about an account.
HttpClient httpClient = await CreateAuthenticatedHttpClient("abcltd1@MyCompany.com", "test", 1);
//Perform any work and get the information from the API
//Contact the API using the token so check that it works
var getExtensionsResponse = await httpClient.GetAsync("/api/ServiceA/extensions/GetExtensions");
//Check that the response was OK
Assert.True(getExtensionsResponse.StatusCode == System.Net.HttpStatusCode.OK, "GetExtensions did not return an OK result.");
//Get and Convert the Content we received into a List of ServiceAExtensionViewModel, as that is what GetExtensions sends back to the browser.
var getExtensionsResponseContent = await getExtensionsResponse.Content.ReadAsStringAsync();
List<ServiceAExtensionViewModel> extensionList = JsonConvert.DeserializeObject<List<ServiceAExtensionViewModel>>(getExtensionsResponseContent);
//Check the information received matches our expectations
Assert.True(extensionList.Count == 2);
Assert.True(extensionList[0].PropertyA == 123);
Assert.True(extensionList[0].PropertyB == 0161);
Assert.True(extensionList[0].PropertyC == true);
}
}
}
Вот содержимое CreateAuthenticatedHttpClient() для справки.
protected async Task<HttpClient> CreateAuthenticatedHttpClient(string username, string password, int companyAccountId)
{
var httpClient = _factory.CreateClient(
new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
//Create the Login information to send to the server
var loginInformation = new LoginRequestModel
{
Username = username,
Password = password,
ReturnUrl = ""
};
//Convert it into Json which the server will understand
var validLoginRequestJson = ConvertToJson(loginInformation);
//Send the Json Login information to the server, and put the response we receive into loginResponse
//In the code below, httpClient is like a web browser. You give it the
var loginResponse = await httpClient.PostAsync("/api/authenticate", validLoginRequestJson);
//Check the loginResponse was a CREATED response, which means that the token was made
Assert.True(loginResponse.StatusCode == System.Net.HttpStatusCode.Created, "New Token was not returned.");
//Check the response is identified as being in Json format
Assert.Equal("application/json; charset=utf-8", loginResponse.Content.Headers.ContentType.ToString());
//Next we have to convert the received Json information into whatever we are expecting.
//In this case, we are expecting a AuthenticationResponseViewModel (because that's what the API sends back to the person trying to log in)
//First we get hold of the Content (which is in Json format)
var responseJsonString = await loginResponse.Content.ReadAsStringAsync();
//Second we convert the Json back into a real AuthenticationResponseViewModel
AuthenticationResponseViewModel authenticationResponseViewModel = JsonConvert.DeserializeObject<AuthenticationResponseViewModel>(responseJsonString);
//Now we take the Token from AuthenticationResponseViewModel, and add it into the httpClient so that we can check the Token works.
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authenticationResponseViewModel.token);
httpClient.DefaultRequestHeaders.Add("CompanyId", companyAccountId.ToString());
return httpClient;
}