455 lines
18 KiB
C#
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 })
|
|
};
|
|
}
|
|
|
|
}
|