Files
Pibd-21_Semin_D.A._SmallSof…/SmallSoftwareProject/SmallSoftwareTests/LocalizationTests/BaseLocalizationControllerTests.cs
2025-04-24 10:28:47 +04:00

455 lines
18 KiB
C#

using SmallSoftwareDatabase;
using SmallSoftwareTests.Infrastructure;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using System.Text.Json;
using SmallSoftwareContracts.DataModels;
using SmallSoftwareContracts.Enums;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
using SmallSoftwareContracts.BindingModels;
using Castle.Core.Configuration;
using SmallSoftwareContracts.Infrastructure.PostConfigurations;
using static NUnit.Framework.Internal.OSPlatform;
namespace SmallSoftwareTests.LocalizationTests;
internal abstract class BaseLocalizationControllerTests
{
protected abstract string GetLocale();
private WebApplicationFactory<Program> _webApplication;
protected HttpClient HttpClient { get; private set; }
protected static SmallSoftwareDbContext SmallSoftwareDbContext { get; private set; }
protected static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
private static string _manufacturerId;
private static string _workerId;
private static string _softwareId;
private static string _postId;
[OneTimeSetUp]
public void OneTimeSetUp()
{
_webApplication = new CustomWebApplicationFactory<Program>();
HttpClient = _webApplication
.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
using var loggerFactory = new LoggerFactory();
loggerFactory.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build())
.CreateLogger());
services.AddSingleton(loggerFactory);
});
})
.CreateClient();
var request = HttpClient.GetAsync("/login/user").GetAwaiter().GetResult();
var data = request.Content.ReadAsStringAsync().GetAwaiter().GetResult();
HttpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {data}");
HttpClient.DefaultRequestHeaders.Add("Accept-Language", GetLocale());
SmallSoftwareDbContext = _webApplication.Services.GetRequiredService<SmallSoftwareDbContext>();
SmallSoftwareDbContext.Database.EnsureDeleted();
SmallSoftwareDbContext.Database.EnsureCreated();
}
[SetUp]
public void SetUp()
{
_workerId = SmallSoftwareDbContext.InsertWorkerToDatabaseAndReturn(fio: "Worker").Id;
_manufacturerId = SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(manufacturerName: "Manufacturer").Id;
_softwareId = SmallSoftwareDbContext.InsertSoftwareToDatabaseAndReturn(_manufacturerId, softwareName: "Software").Id;
_postId = SmallSoftwareDbContext.InsertPostToDatabaseAndReturn(postName: "Post").PostId;
}
[TearDown]
public void TearDown()
{
SmallSoftwareDbContext.RemoveManufacturersFromDatabase();
SmallSoftwareDbContext.RemoveSalariesFromDatabase();
SmallSoftwareDbContext.RemoveRequestsFromDatabase();
SmallSoftwareDbContext.RemoveWorkersFromDatabase();
SmallSoftwareDbContext.RemovePostsFromDatabase();
SmallSoftwareDbContext.RemoveSoftwaresFromDatabase();
SmallSoftwareDbContext.RemoveManufacturersFromDatabase();
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
SmallSoftwareDbContext?.Database.EnsureDeleted();
SmallSoftwareDbContext?.Dispose();
HttpClient?.Dispose();
_webApplication?.Dispose();
}
[Test]
public async Task LoadSoftwares_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var manufacturer1 = new ManufacturerDataModel(Guid.NewGuid().ToString(), "name1");
var manufacturer2 = new ManufacturerDataModel(Guid.NewGuid().ToString(), "name2");
SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(manufacturer1.Id, manufacturerName: manufacturer1.ManufacturerName);
SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(manufacturer2.Id, manufacturerName: manufacturer2.ManufacturerName);
var softwareId1 = Guid.NewGuid().ToString();
var softwareId2 = Guid.NewGuid().ToString();
var software1 = SmallSoftwareDbContext.InsertSoftwareToDatabaseAndReturn(manufacturer1.Id, softwareId1, "name1", SoftwareType.Windows, 10, false);
var software2 = SmallSoftwareDbContext.InsertSoftwareToDatabaseAndReturn(manufacturer2.Id, softwareId2, "name2", SoftwareType.Windows, 10, false);
SmallSoftwareDbContext.InsertSoftwareHistoryToDatabaseAndReturn(softwareId1, 22, DateTime.UtcNow);
SmallSoftwareDbContext.InsertSoftwareHistoryToDatabaseAndReturn(softwareId2, 21, DateTime.UtcNow);
SmallSoftwareDbContext.InsertSoftwareHistoryToDatabaseAndReturn(softwareId1, 33, DateTime.UtcNow);
SmallSoftwareDbContext.InsertSoftwareHistoryToDatabaseAndReturn(softwareId1, 32, DateTime.UtcNow);
SmallSoftwareDbContext.InsertSoftwareHistoryToDatabaseAndReturn(softwareId2, 65, DateTime.UtcNow);
//Act
var response = await HttpClient.GetAsync("/api/report/LoadSoftwares");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
using var data = await response.Content.ReadAsStreamAsync();
Assert.That(data, Is.Not.Null);
Assert.That(data.Length, Is.GreaterThan(0));
await AssertStreamAsync(response, $"file-{GetLocale()}.docx");
}
[Test]
public async Task LoadRequests_WhenHaveRecords_ShouldSuccess_Test()
{
// Arrange
var manufacturer1 = SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(manufacturerName: "name 1");
var manufacturer2 = SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(manufacturerName: "name 2");
var worker1 = SmallSoftwareDbContext.InsertWorkerToDatabaseAndReturn();
var worker2 = SmallSoftwareDbContext.InsertWorkerToDatabaseAndReturn();
var software1 = SmallSoftwareDbContext.InsertSoftwareToDatabaseAndReturn(manufacturer1.Id,
softwareName: "name 1");
var software2 = SmallSoftwareDbContext.InsertSoftwareToDatabaseAndReturn(manufacturer2.Id,
softwareName: "name 2");
SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(
worker1.Id,
sum: 100,
email: "cdsfs@dd.ru",
softwares: [(software1.Id, 10, 1.1), (software2.Id, 10, 1.1)]);
SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(
worker2.Id,
sum: 200,
email: "cdswws@dd.ru",
softwares: [(software1.Id, 10, 1.1)]);
// Act
var response = await HttpClient.GetAsync(
$"/api/report/loadrequests?" +
$"fromDate={DateTime.Now.AddDays(-1):MM/dd/yyyy HH:mm:ss}&" + $"toDate={DateTime.Now.AddDays(1):MM/dd/yyyy HH:mm:ss}");
// Assert
await AssertStreamAsync(response, $"file-{GetLocale()}.xlsx");
}
[Test]
public async Task LoadSalary_WhenHaveRecords_ShouldSuccess_Test()
{
// Arrange
var post = SmallSoftwareDbContext.InsertPostToDatabaseAndReturn(postName: "Post for salary test");
var worker1 = SmallSoftwareDbContext.InsertWorkerToDatabaseAndReturn(
fio: "fio 1",
postId: post.PostId).AddPost(post);
var worker2 = SmallSoftwareDbContext.InsertWorkerToDatabaseAndReturn(
fio: "fio 2",
postId: post.PostId).AddPost(post);
SmallSoftwareDbContext.InsertSalaryToDatabaseAndReturn(
worker1.Id,
workerSalary: 100,
salaryDate: DateTime.UtcNow.AddDays(-10));
SmallSoftwareDbContext.InsertSalaryToDatabaseAndReturn(
worker1.Id,
workerSalary: 1000,
salaryDate: DateTime.UtcNow.AddDays(-5));
SmallSoftwareDbContext.InsertSalaryToDatabaseAndReturn(
worker1.Id,
workerSalary: 200,
salaryDate: DateTime.UtcNow.AddDays(5));
SmallSoftwareDbContext.InsertSalaryToDatabaseAndReturn(
worker2.Id,
workerSalary: 500,
salaryDate: DateTime.UtcNow.AddDays(-5));
SmallSoftwareDbContext.InsertSalaryToDatabaseAndReturn(
worker2.Id,
workerSalary: 300,
salaryDate: DateTime.UtcNow.AddDays(-3));
// Act
var response = await HttpClient.GetAsync(
$"/api/report/loadsalary?" +
$"fromDate={DateTime.Now.AddDays(-7):MM/dd/yyyy HH:mm:ss}&" + $"toDate={DateTime.Now.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
// Assert
await AssertStreamAsync(response, $"file-{GetLocale()}.pdf");
}
private static async Task AssertStreamAsync(HttpResponseMessage response, string fileNameForSave = "")
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
using var data = await response.Content.ReadAsStreamAsync();
Assert.That(data, Is.Not.Null);
Assert.That(data.Length, Is.GreaterThan(0));
await SaveStreamAsync(data, fileNameForSave);
}
private static async Task SaveStreamAsync(Stream stream, string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
return;
}
var path = Path.Combine(Directory.GetCurrentDirectory(), fileName);
if (File.Exists(path))
{
File.Delete(path);
}
stream.Position = 0;
using var fileStream = new FileStream(path, FileMode.OpenOrCreate);
await stream.CopyToAsync(fileStream);
}
protected abstract string MessageElementNotFound();
[TestCase("manufacturers")]
[TestCase("posts")]
[TestCase("softwares/getrecord")]
[TestCase("requests/getrecord")]
[TestCase("workers/getrecord")]
public async Task Api_GetElement_NotFound_Test(string path)
{
//Act
var response = await
HttpClient.GetAsync($"/api/{path}/{Guid.NewGuid()}");
//Assert
Assert.That(JToken.Parse(await
response.Content.ReadAsStringAsync()).ToString(),
Does.StartWith(MessageElementNotFound()));
}
protected abstract string MessageElementExists();
private static IEnumerable<TestCaseData> TestDataElementExists()
{
yield return new TestCaseData(() => {
var model = CreateManufacturerModel();
SmallSoftwareDbContext.InsertManufacturerToDatabaseAndReturn(model.Id);
return model;
}, "manufacturers");
yield return new TestCaseData(() => {
var model = CreatePostModel();
SmallSoftwareDbContext.InsertPostToDatabaseAndReturn(model.Id);
return model;
}, "posts");
}
[TestCaseSource(nameof(TestDataElementExists))]
public async Task Api_Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test(Func<object> createModel, string path)
{
//Arrange
var model = createModel();
//Act
var response = await HttpClient.PostAsync($"/api/{path}",
MakeContent(model));
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response: {response.StatusCode}, Content: {responseContent}");
//Assert
Assert.That(JToken.Parse(await
response.Content.ReadAsStringAsync()).ToString(),
Does.StartWith(MessageElementExists()));
}
private static IEnumerable<TestCaseData> TestDataIdIncorrect()
{
yield return new TestCaseData(() => {
var model = CreateManufacturerModel();
model.Id = "Id";
return model;
}, "manufacturers");
yield return new TestCaseData(() => {
var model = CreateWorkerModel(_manufacturerId);
model.Id = "Id";
return model;
}, "workers/register");
}
protected abstract string MessageElementIdIncorrect();
[TestCaseSource(nameof(TestDataIdIncorrect))]
public async Task Api_Post_WhenDataIsIncorrect_ShouldBadRequest_Test(Func<object> createModel, string path)
{
//Arrange
var model = createModel();
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/{path}", MakeContent(model));
//Assert
Assert.That(JToken.Parse(await responseWithIdIncorrect.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageElementIdIncorrect()));
}
[TestCase("posts")]
[TestCase("workers/delete")]
public async Task Api_DelElement_NotFound_Test(string path)
{
//Act
var response = await HttpClient.DeleteAsync($"/api/{path}/{Guid.NewGuid()}");
//Assert
Assert.That(JToken.Parse(await response.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageElementNotFound()));
}
protected abstract string MessageValidationErrorIDIsEmpty();
private static IEnumerable<TestCaseData> TestDataValidationErrorIdIsEmpty()
{
yield return new TestCaseData(() =>
{
var model = CreatePostModel();
model.Id = "";
return model;
}, "posts");
yield return new TestCaseData(() => {
var model = CreateWorkerModel(_postId);
model.Id = "";
return model;
}, "workers/changeinfo/");
}
[TestCaseSource(nameof(TestDataValidationErrorIdIsEmpty))]
public async Task Api_Put_ValidationError_IdIsEmpty_ShouldBadRequest_Test(Func<object> createModel, string path)
{
//Arrange
var model = createModel();
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/{path}", MakeContent(model));
//Assert
Assert.That(JToken.Parse(await responseWithIdIncorrect.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageValidationErrorIDIsEmpty()));
}
protected abstract string MessageValidationErrorIDIsNotGuid();
private static IEnumerable<TestCaseData> TestDataValidationErrorIdIsNotGuid()
{
yield return new TestCaseData(() =>
{
var model = CreatePostModel();
model.Id = "id";
return model;
}, "posts");
yield return new TestCaseData(() => {
var model = CreateWorkerModel(_postId);
model.Id = "id";
return model;
}, "workers/changeinfo/");
}
[TestCaseSource(nameof(TestDataValidationErrorIdIsNotGuid))]
public async Task Api_Put_ValidationError_IIsNotGuid_ShouldBadRequest_Test(Func<object> createModel, string path)
{
//Arrange
var model = createModel();
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/{path}", MakeContent(model));
//Assert
Assert.That(JToken.Parse(await responseWithIdIncorrect.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageValidationErrorIDIsNotGuid()));
}
protected abstract string MessageElemenValidationErrorPostNameEmpty();
[TestCase("posts")]
public async Task Api_Put_ValidationError_PostNameIsEmpty_ShouldBadRequest_Test(string path)
{
//Arrange
var model = CreatePostModel();
model.PostName = "";
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/{path}", MakeContent(model));
//Assert
Assert.That(JToken.Parse(await responseWithIdIncorrect.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageElemenValidationErrorPostNameEmpty()));
}
protected abstract string MessageElemenValidationErrorFioISEmpty();
[TestCase("workers/changeinfo/")]
public async Task Api_Put_ValidationError_FioIsEmpty_ShouldBadRequest_Test(string path)
{
//Arrange
var model = CreateWorkerModel(_postId);
model.FIO = "";
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/{path}", MakeContent(model));
//Assert
Assert.That(JToken.Parse(await responseWithIdIncorrect.Content.ReadAsStringAsync()).ToString(), Does.StartWith(MessageElemenValidationErrorFioISEmpty()));
}
private static async Task<T?> GetModelFromResponseAsync<T>(HttpResponseMessage response) =>
JsonSerializer.Deserialize<T>(await response.Content.ReadAsStringAsync(), JsonSerializerOptions);
private static StringContent MakeContent(object model) =>
new(JsonSerializer.Serialize(model), Encoding.UTF8, "application/json");
private static ManufacturerBindingModel CreateManufacturerModel(string? id = null, string? manufacturerName = null)
=> new()
{
Id = id ?? Guid.NewGuid().ToString(),
ManufacturerName = manufacturerName ?? $"name_{Guid.NewGuid()}"
};
private static PostBindingModel CreatePostModel(string? postId = null, string postName = "name", PostType postType = PostType.SoftInstaller, double salary = 10)
=> new()
{
Id = postId ?? Guid.NewGuid().ToString(),
PostName = postName,
PostType = postType.ToString(),
Salary = salary
};
private static SoftwareBindingModel CreateSoftwareModel(string manufacturerId, string? id = null, string softwareName = "name", SoftwareType softwareType = SoftwareType.Windows, double price = 1)
=> new()
{
Id = id ?? Guid.NewGuid().ToString(),
ManufacturerId = manufacturerId,
SoftwareName = softwareName,
SoftwareType = softwareType.ToString(),
Price = price
};
private static WorkerBindingModel CreateWorkerModel(string postId, string? id = null, string fio = "fio", DateTime? birthDate = null, DateTime? employmentDate = null, string? configuration = null)
{
return new()
{
Id = id ?? Guid.NewGuid().ToString(),
FIO = fio,
PostId = postId,
BirthDate = birthDate ?? DateTime.UtcNow.AddYears(-22),
EmploymentDate = employmentDate ?? DateTime.UtcNow.AddDays(-5),
ConfigurationJson = configuration ?? JsonSerializer.Serialize(new PostConfiguration() { Rate = 10 })
};
}
}