somechanges
This commit is contained in:
@@ -2,47 +2,55 @@
|
|||||||
using SmallSoftwareContracts.Extensions;
|
using SmallSoftwareContracts.Extensions;
|
||||||
using SmallSoftwareContracts.Infrastructure;
|
using SmallSoftwareContracts.Infrastructure;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
|
||||||
namespace SmallSoftwareContracts.DataModels;
|
namespace SmallSoftwareContracts.DataModels;
|
||||||
|
|
||||||
|
|
||||||
public class RequestDataModel(string id, string workerId, string email, double sum, bool isCancel, List<InstallationRequestDataModel> installationRequests) : IValidation
|
public class RequestDataModel : IValidation
|
||||||
{
|
{
|
||||||
private readonly WorkerDataModel? _worker;
|
private readonly WorkerDataModel? _worker;
|
||||||
public string Id { get; private set; } = id;
|
public string Id { get; private set; }
|
||||||
public string WorkerId { get; private set; } = workerId;
|
public string WorkerId { get; private set; }
|
||||||
public string Email { get; private set; } = email;
|
public string Email { get; private set; }
|
||||||
public double Sum { get; private set; } = sum;
|
public double Sum { get; private set; }
|
||||||
public bool IsCancel { get; private set; } = isCancel;
|
public bool IsCancel { get; private set; }
|
||||||
public List<InstallationRequestDataModel> Softwares { get; private set; } = installationRequests;
|
public List<InstallationRequestDataModel>? Softwares { get; private set; }
|
||||||
public string WorkerFIO => _worker?.FIO ?? string.Empty;
|
public string WorkerFIO => _worker?.FIO ?? string.Empty;
|
||||||
|
public RequestDataModel(string id, string workerId, string email, bool isCancel, List<InstallationRequestDataModel> installationRequests)
|
||||||
public RequestDataModel(string id, string workerId, string email, double sum, bool isCancel, List<InstallationRequestDataModel> installationRequests, WorkerDataModel worker)
|
{
|
||||||
: this(id, workerId,email,sum,isCancel, installationRequests)
|
Id = id;
|
||||||
|
WorkerId = workerId;
|
||||||
|
Email = email;
|
||||||
|
IsCancel = isCancel;
|
||||||
|
Softwares = installationRequests;
|
||||||
|
Sum = Softwares?.Sum(x => x.Price * x.Count) ?? 0;
|
||||||
|
}
|
||||||
|
public RequestDataModel(string id, string workerId, string email, double sum, bool isCancel,
|
||||||
|
List<InstallationRequestDataModel> installationRequests, WorkerDataModel worker) : this(id, workerId, email,isCancel, installationRequests )
|
||||||
{
|
{
|
||||||
Sum = sum;
|
Sum = sum;
|
||||||
_worker = worker;
|
_worker = worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Validate()
|
public void Validate()
|
||||||
{
|
{
|
||||||
if (Id.IsEmpty())
|
if (Id.IsEmpty())
|
||||||
throw new ValidationException("Field Id is empty");
|
throw new ValidationException("Field Id is empty");
|
||||||
if (!Id.IsGuid())
|
if (!Id.IsGuid())
|
||||||
throw new ValidationException("The value in the field Id is not a unique identifier");
|
throw new ValidationException("The value in the field Id is not a unique identifier");
|
||||||
if (WorkerId.IsEmpty())
|
if (WorkerId.IsEmpty())
|
||||||
throw new ValidationException("Field WorkerId is empty");
|
throw new ValidationException("Field WorkerId is empty");
|
||||||
if (!WorkerId.IsGuid())
|
if (!WorkerId.IsGuid())
|
||||||
throw new ValidationException("The value in the field WorkerId is not a unique identifier");
|
throw new ValidationException("The value in the field WorkerId is not a unique identifier");
|
||||||
if (Email.IsEmpty())
|
if (Sum <= 0)
|
||||||
throw new ValidationException("Worker Email is empty");
|
|
||||||
if (!Regex.IsMatch(Email, @"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"))
|
|
||||||
throw new ValidationException("Field Email is not a email");
|
|
||||||
if (Sum <= 0)
|
|
||||||
throw new ValidationException("Field Sum is less than or equal to 0");
|
throw new ValidationException("Field Sum is less than or equal to 0");
|
||||||
if ((Softwares?.Count ?? 0) == 0)
|
if ((Softwares?.Count ?? 0) == 0)
|
||||||
throw new ValidationException("The sale must include Softwares");
|
throw new ValidationException("The request must include products");
|
||||||
|
if (!Regex.IsMatch(Email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"))
|
||||||
|
{
|
||||||
|
throw new ValidationException("Invalid email format");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SmallSoftwareContracts.ViewModels;
|
namespace SmallSoftwareContracts.ViewModels;
|
||||||
|
|
||||||
public class RequestViewModel
|
public class RequestViewModel
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ internal class RequestStorageContract : IRequestStorageContract
|
|||||||
cfg.CreateMap<Software, SoftwareDataModel>();
|
cfg.CreateMap<Software, SoftwareDataModel>();
|
||||||
cfg.CreateMap<Worker, WorkerDataModel>();
|
cfg.CreateMap<Worker, WorkerDataModel>();
|
||||||
cfg.CreateMap<InstallationRequest, InstallationRequestDataModel>();
|
cfg.CreateMap<InstallationRequest, InstallationRequestDataModel>();
|
||||||
|
|
||||||
cfg.CreateMap<InstallationRequestDataModel, InstallationRequest>()
|
cfg.CreateMap<InstallationRequestDataModel, InstallationRequest>()
|
||||||
.ForMember(x => x.SoftwareId, x => x.MapFrom(src => src.SoftwareId))
|
.ForMember(x => x.SoftwareId, x => x.MapFrom(src => src.SoftwareId));
|
||||||
.ForMember(x => x.Software, x => x.Ignore());
|
|
||||||
cfg.CreateMap<Request, RequestDataModel>();
|
cfg.CreateMap<Request, RequestDataModel>();
|
||||||
cfg.CreateMap<RequestDataModel, Request>()
|
cfg.CreateMap<RequestDataModel, Request>()
|
||||||
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
|
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
|
||||||
@@ -40,7 +38,7 @@ internal class RequestStorageContract : IRequestStorageContract
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var query = _dbContext.Requests.Include(x => x.InstallationRequests).AsQueryable();
|
var query = _dbContext.Requests.Include(x => x.Worker).Include(x => x.InstallationRequests).AsQueryable();
|
||||||
if (workerId is not null)
|
if (workerId is not null)
|
||||||
{
|
{
|
||||||
query = query.Where(x => x.WorkerId == workerId);
|
query = query.Where(x => x.WorkerId == workerId);
|
||||||
@@ -112,5 +110,5 @@ internal class RequestStorageContract : IRequestStorageContract
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Request? GetRequestById(string id) => _dbContext.Requests.FirstOrDefault(x => x.Id == id);
|
private Request? GetRequestById(string id) => _dbContext.Requests.Include(x => x.Worker).Include(x => x.InstallationRequests).FirstOrDefault(x => x.Id == id);
|
||||||
}
|
}
|
||||||
@@ -34,8 +34,8 @@ internal class RequestBusinessLogicContractTests
|
|||||||
var date = DateTime.UtcNow;
|
var date = DateTime.UtcNow;
|
||||||
var listOriginal = new List<RequestDataModel>()
|
var listOriginal = new List<RequestDataModel>()
|
||||||
{
|
{
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(),Guid.NewGuid().ToString(), 5, 10)]),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(),Guid.NewGuid().ToString(), 5, 10)]),
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []), new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, []), new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, []),
|
||||||
};
|
};
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
||||||
It.IsAny<DateTime?>(), It.IsAny<string>(), It.IsAny<string>())).Returns(listOriginal);
|
It.IsAny<DateTime?>(), It.IsAny<string>(), It.IsAny<string>())).Returns(listOriginal);
|
||||||
@@ -112,8 +112,8 @@ internal class RequestBusinessLogicContractTests
|
|||||||
var workerId = Guid.NewGuid().ToString();
|
var workerId = Guid.NewGuid().ToString();
|
||||||
var listOriginal = new List<RequestDataModel>()
|
var listOriginal = new List<RequestDataModel>()
|
||||||
{
|
{
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(),Guid.NewGuid().ToString(), 5, 10)]),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(),Guid.NewGuid().ToString(), 5, 10)]),
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []), new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), false, []), new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), false, []),
|
||||||
};
|
};
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
||||||
It.IsAny<DateTime?>(), It.IsAny<string>(),
|
It.IsAny<DateTime?>(), It.IsAny<string>(),
|
||||||
@@ -229,9 +229,9 @@ internal class RequestBusinessLogicContractTests
|
|||||||
var softwareId = Guid.NewGuid().ToString();
|
var softwareId = Guid.NewGuid().ToString();
|
||||||
var listOriginal = new List<RequestDataModel>()
|
var listOriginal = new List<RequestDataModel>()
|
||||||
{
|
{
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]),
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, []),
|
||||||
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, []),
|
new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@mail.ru", false, []),
|
||||||
};
|
};
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime?>(),
|
||||||
It.IsAny<DateTime?>(), It.IsAny<string>(),
|
It.IsAny<DateTime?>(), It.IsAny<string>(),
|
||||||
@@ -343,7 +343,7 @@ internal class RequestBusinessLogicContractTests
|
|||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
var id = Guid.NewGuid().ToString();
|
var id = Guid.NewGuid().ToString();
|
||||||
var record = new RequestDataModel(id, Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]);
|
var record = new RequestDataModel(id, Guid.NewGuid().ToString(), "test@mail.ru", false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]);
|
||||||
_requestStorageContract.Setup(x =>
|
_requestStorageContract.Setup(x =>
|
||||||
x.GetElementById(id)).Returns(record);
|
x.GetElementById(id)).Returns(record);
|
||||||
//Act
|
//Act
|
||||||
@@ -404,7 +404,7 @@ internal class RequestBusinessLogicContractTests
|
|||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
var flag = false;
|
var flag = false;
|
||||||
var record = new RequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "valid.email@example.com", 10, false,
|
var record = new RequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "valid.email@example.com", false,
|
||||||
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]);
|
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)]);
|
||||||
_requestStorageContract.Setup(x => x.AddElement(It.IsAny<RequestDataModel>()))
|
_requestStorageContract.Setup(x => x.AddElement(It.IsAny<RequestDataModel>()))
|
||||||
.Callback((RequestDataModel x) =>
|
.Callback((RequestDataModel x) =>
|
||||||
@@ -434,7 +434,7 @@ internal class RequestBusinessLogicContractTests
|
|||||||
ElementExistsException("Data", "Data"));
|
ElementExistsException("Data", "Data"));
|
||||||
//Act&Assert
|
//Act&Assert
|
||||||
Assert.That(() =>
|
Assert.That(() =>
|
||||||
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", 10,false,
|
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false,
|
||||||
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)])), Throws.TypeOf<ElementExistsException>());
|
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)])), Throws.TypeOf<ElementExistsException>());
|
||||||
_requestStorageContract.Verify(x => x.AddElement(It.IsAny<RequestDataModel>()), Times.Once);
|
_requestStorageContract.Verify(x => x.AddElement(It.IsAny<RequestDataModel>()), Times.Once);
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@ internal class RequestBusinessLogicContractTests
|
|||||||
public void InsertRequest_InvalidRecord_ThrowException_Test()
|
public void InsertRequest_InvalidRecord_ThrowException_Test()
|
||||||
{
|
{
|
||||||
//Act&Assert
|
//Act&Assert
|
||||||
Assert.That(() => _requestBusinessLogicContract.InsertRequest(new RequestDataModel("id", Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 10, false, [])), Throws.TypeOf<ValidationException>());
|
Assert.That(() => _requestBusinessLogicContract.InsertRequest(new RequestDataModel("id", Guid.NewGuid().ToString(), "test@mail.ru", false, [])), Throws.TypeOf<ValidationException>());
|
||||||
_requestStorageContract.Verify(x =>
|
_requestStorageContract.Verify(x =>
|
||||||
x.AddElement(It.IsAny<RequestDataModel>()), Times.Never);
|
x.AddElement(It.IsAny<RequestDataModel>()), Times.Never);
|
||||||
}
|
}
|
||||||
@@ -464,7 +464,7 @@ internal class RequestBusinessLogicContractTests
|
|||||||
InvalidOperationException()));
|
InvalidOperationException()));
|
||||||
//Act&Assert
|
//Act&Assert
|
||||||
Assert.That(() =>
|
Assert.That(() =>
|
||||||
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", 10, false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)])), Throws.TypeOf<StorageException>());
|
_requestBusinessLogicContract.InsertRequest(new(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false, [new InstallationRequestDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), 5, 10)])), Throws.TypeOf<StorageException>());
|
||||||
_requestStorageContract.Verify(x =>
|
_requestStorageContract.Verify(x =>
|
||||||
x.AddElement(It.IsAny<RequestDataModel>()), Times.Once);
|
x.AddElement(It.IsAny<RequestDataModel>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,37 +231,7 @@ internal class SalaryBusinessLogicContractTests
|
|||||||
_salaryStorageContract.Verify(x => x.GetList(It.IsAny<DateTime>(),
|
_salaryStorageContract.Verify(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>()), Times.Once);
|
It.IsAny<DateTime>(), It.IsAny<string>()), Times.Once);
|
||||||
}
|
}
|
||||||
[Test]
|
|
||||||
public void CalculateSalaryByMounth_CalculateSalary_Test()
|
|
||||||
{
|
|
||||||
//Arrange
|
|
||||||
var workerId = Guid.NewGuid().ToString();
|
|
||||||
var requestSum = 200.0;
|
|
||||||
var postSalary = 2000.0;
|
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), requestSum, false, [])]);
|
|
||||||
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
|
||||||
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
|
||||||
PostType.SoftInstaller, postSalary));
|
|
||||||
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
|
|
||||||
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
|
|
||||||
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
|
|
||||||
.Returns([new WorkerDataModel(workerId, "Test",
|
|
||||||
Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
|
|
||||||
var sum = 0.0;
|
|
||||||
var expectedSum = postSalary + requestSum * 0.1;
|
|
||||||
_salaryStorageContract.Setup(x =>
|
|
||||||
x.AddElement(It.IsAny<SalaryDataModel>()))
|
|
||||||
.Callback((SalaryDataModel x) =>
|
|
||||||
{
|
|
||||||
sum = x.Salary;
|
|
||||||
});
|
|
||||||
//Act
|
|
||||||
_salaryBusinessLogicContract.CalculateSalaryByMonth(DateTime.UtcNow);
|
|
||||||
//Assert
|
|
||||||
Assert.That(sum, Is.EqualTo(expectedSum));
|
|
||||||
}
|
|
||||||
[Test]
|
[Test]
|
||||||
public void CalculateSalaryByMounth_WithSeveralWorkers_Test()
|
public void CalculateSalaryByMounth_WithSeveralWorkers_Test()
|
||||||
{
|
{
|
||||||
@@ -280,15 +250,15 @@ internal class SalaryBusinessLogicContractTests
|
|||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
||||||
worker1Id, Guid.NewGuid().ToString(), 1, false, []),
|
worker1Id, Guid.NewGuid().ToString(), false, []),
|
||||||
new RequestDataModel(Guid.NewGuid().ToString(), worker1Id, Guid.NewGuid().ToString(),
|
new RequestDataModel(Guid.NewGuid().ToString(), worker1Id, Guid.NewGuid().ToString(),
|
||||||
1, false, []),
|
false, []),
|
||||||
new RequestDataModel(Guid.NewGuid().ToString(), worker2Id, Guid.NewGuid().ToString(),
|
new RequestDataModel(Guid.NewGuid().ToString(), worker2Id, Guid.NewGuid().ToString(),
|
||||||
1, false, []),
|
false, []),
|
||||||
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
|
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
|
||||||
1, false, []),
|
false, []),
|
||||||
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
|
new RequestDataModel(Guid.NewGuid().ToString(), worker3Id, Guid.NewGuid().ToString(),
|
||||||
1, false, [])]);
|
false, [])]);
|
||||||
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||||
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
||||||
PostType.SoftInstaller, 2000));
|
PostType.SoftInstaller, 2000));
|
||||||
@@ -359,7 +329,7 @@ Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
|
|||||||
var workerId = Guid.NewGuid().ToString();
|
var workerId = Guid.NewGuid().ToString();
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), 200, false, [])]);
|
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), false, [])]);
|
||||||
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
|
_workerStorageContract.Setup(x => x.GetList(It.IsAny<bool>(),
|
||||||
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
|
It.IsAny<string?>(), It.IsAny<DateTime?>(), It.IsAny<DateTime?>(),
|
||||||
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
|
It.IsAny<DateTime?>(), It.IsAny<DateTime?>()))
|
||||||
@@ -379,7 +349,7 @@ Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
|
|||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
||||||
workerId, Guid.NewGuid().ToString(), 200, false, [])]);
|
workerId, Guid.NewGuid().ToString(), false, [])]);
|
||||||
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||||
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
||||||
PostType.SoftInstaller, 2000));
|
PostType.SoftInstaller, 2000));
|
||||||
@@ -420,7 +390,7 @@ Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
|
|||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
.Returns([new RequestDataModel(Guid.NewGuid().ToString(),
|
||||||
workerId, Guid.NewGuid().ToString(), 200, false, [])]);
|
workerId, Guid.NewGuid().ToString(), false, [])]);
|
||||||
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||||
.Throws(new StorageException(new
|
.Throws(new StorageException(new
|
||||||
InvalidOperationException()));
|
InvalidOperationException()));
|
||||||
@@ -442,7 +412,7 @@ Guid.NewGuid().ToString(), DateTime.UtcNow, DateTime.UtcNow, false)]);
|
|||||||
var workerId = Guid.NewGuid().ToString();
|
var workerId = Guid.NewGuid().ToString();
|
||||||
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
_requestStorageContract.Setup(x => x.GetList(It.IsAny<DateTime>(),
|
||||||
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
It.IsAny<DateTime>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), 200, false, [])]);
|
.Returns([new RequestDataModel(Guid.NewGuid().ToString(), workerId, Guid.NewGuid().ToString(), false, [])]);
|
||||||
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
_postStorageContract.Setup(x => x.GetElementById(It.IsAny<string>()))
|
||||||
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
.Returns(new PostDataModel(Guid.NewGuid().ToString(), "name",
|
||||||
PostType.SoftInstaller, 2000));
|
PostType.SoftInstaller, 2000));
|
||||||
|
|||||||
@@ -9,64 +9,55 @@ internal class RequestDataModelTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void IdIsNullOrEmptyTest()
|
public void IdIsNullOrEmptyTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel(null, Guid.NewGuid().ToString(), "test@example.com", 10, false, CreateSubDataModel());
|
var request = CreateDataModel(null, Guid.NewGuid().ToString(), "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
|
|
||||||
request = CreateDataModel(string.Empty, Guid.NewGuid().ToString(), "test@example.com", 10, false, CreateSubDataModel());
|
request = CreateDataModel(string.Empty, Guid.NewGuid().ToString(), "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void IdIsNotGuidTest()
|
public void IdIsNotGuidTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel("id", Guid.NewGuid().ToString(), "test@example.com", 10, false, CreateSubDataModel());
|
var request = CreateDataModel("id", Guid.NewGuid().ToString(), "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void WorkerIdIsNullOrEmptyTest()
|
public void WorkerIdIsNullOrEmptyTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel(Guid.NewGuid().ToString(), null, "test@example.com", 10, false, CreateSubDataModel());
|
var request = CreateDataModel(Guid.NewGuid().ToString(), null, "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
|
|
||||||
request = CreateDataModel(Guid.NewGuid().ToString(), string.Empty, "test@example.com", 10, false, CreateSubDataModel());
|
request = CreateDataModel(Guid.NewGuid().ToString(), string.Empty, "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void WorkerIdIsNotGuidTest()
|
public void WorkerIdIsNotGuidTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel(Guid.NewGuid().ToString(), "workerId", "test@example.com", 10, false, CreateSubDataModel());
|
var request = CreateDataModel(Guid.NewGuid().ToString(), "workerId", "test@example.com", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void EmailIsInvalidTest()
|
public void EmailIsInvalidTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "invalid_email", 10, false, CreateSubDataModel());
|
var request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "invalid_email", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
|
|
||||||
request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "", 10, false, CreateSubDataModel());
|
request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "@", false, CreateSubDataModel());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void SumIsLessOrZeroTest()
|
|
||||||
{
|
|
||||||
var request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", 0, false, CreateSubDataModel());
|
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
|
||||||
|
|
||||||
request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", -10, false, CreateSubDataModel());
|
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SoftwaresIsNullOrEmptyTest()
|
public void SoftwaresIsNullOrEmptyTest()
|
||||||
{
|
{
|
||||||
var request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", 10, false, null);
|
var request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false, null);
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
|
|
||||||
request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", 10, false, new List<InstallationRequestDataModel>());
|
request = CreateDataModel(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), "test@example.com", false, new List<InstallationRequestDataModel>());
|
||||||
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
Assert.That(() => request.Validate(), Throws.TypeOf<ValidationException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +71,7 @@ internal class RequestDataModelTests
|
|||||||
var isCancel = true;
|
var isCancel = true;
|
||||||
var softwares = CreateSubDataModel();
|
var softwares = CreateSubDataModel();
|
||||||
|
|
||||||
var request = CreateDataModel(requestId, workerId, email, sum, isCancel, softwares);
|
var request = CreateDataModel(requestId, workerId, email, isCancel, softwares);
|
||||||
|
|
||||||
Assert.That(() => request.Validate(), Throws.Nothing);
|
Assert.That(() => request.Validate(), Throws.Nothing);
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
@@ -94,8 +85,8 @@ internal class RequestDataModelTests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RequestDataModel CreateDataModel(string? id, string? workerId, string email, double sum, bool isCancel, List<InstallationRequestDataModel>? softwares) =>
|
private static RequestDataModel CreateDataModel(string? id, string? workerId, string email, bool isCancel, List<InstallationRequestDataModel>? softwares) =>
|
||||||
new(id, workerId, email, sum, isCancel, softwares);
|
new(id, workerId, email, isCancel, softwares);
|
||||||
|
|
||||||
private static List<InstallationRequestDataModel> CreateSubDataModel() =>
|
private static List<InstallationRequestDataModel> CreateSubDataModel() =>
|
||||||
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), "SoftwareName", 1, 10)];
|
[new InstallationRequestDataModel(Guid.NewGuid().ToString(), "SoftwareName", 1, 10)];
|
||||||
|
|||||||
@@ -93,10 +93,11 @@ internal static class SmallSoftwareDbContextExtensions
|
|||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
return salary;
|
return salary;
|
||||||
}
|
}
|
||||||
public static Request InsertRequestToDatabaseAndReturn(this SmallSoftwareDbContext dbContext,
|
|
||||||
string workerId, string email, double sum = 1, bool isCancel = false, List<(string, int, double)>? softwares = null)
|
public static Request InsertRequestToDatabaseAndReturn(this SmallSoftwareDbContext
|
||||||
|
dbContext, string workerId, string email = "test@mail.ru", double sum = 1, bool isCancel = false, List<(string, int, double)>? softwares = null)
|
||||||
{
|
{
|
||||||
var request = new Request()
|
var Request = new Request()
|
||||||
{
|
{
|
||||||
WorkerId = workerId,
|
WorkerId = workerId,
|
||||||
Email = email,
|
Email = email,
|
||||||
@@ -108,19 +109,20 @@ internal static class SmallSoftwareDbContextExtensions
|
|||||||
{
|
{
|
||||||
foreach (var elem in softwares)
|
foreach (var elem in softwares)
|
||||||
{
|
{
|
||||||
request.InstallationRequests.Add(new InstallationRequest
|
Request.InstallationRequests.Add(new InstallationRequest
|
||||||
{
|
{
|
||||||
SoftwareId = elem.Item1,
|
SoftwareId = elem.Item1,
|
||||||
RequestId = request.Id,
|
RequestId = Request.Id,
|
||||||
Count = elem.Item2,
|
Count = elem.Item2,
|
||||||
Price = elem.Item3
|
Price = elem.Item3
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbContext.Requests.Add(request);
|
dbContext.Requests.Add(Request);
|
||||||
dbContext.SaveChanges();
|
dbContext.SaveChanges();
|
||||||
return request;
|
return Request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Worker InsertWorkerToDatabaseAndReturn(this SmallSoftwareDbContext dbContext,
|
public static Worker InsertWorkerToDatabaseAndReturn(this SmallSoftwareDbContext dbContext,
|
||||||
string? id = null, string fio = "test", string? postId = null, DateTime? birthDate = null,
|
string? id = null, string fio = "test", string? postId = null, DateTime? birthDate = null,
|
||||||
DateTime? employmentDate = null, bool isDeleted = false)
|
DateTime? employmentDate = null, bool isDeleted = false)
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ internal class RequestStorageContractTests : BaseStorageContractTest
|
|||||||
private static RequestDataModel CreateModel(string id, string workerId, string email, double sum, bool isCancel, List<string> softwareIds)
|
private static RequestDataModel CreateModel(string id, string workerId, string email, double sum, bool isCancel, List<string> softwareIds)
|
||||||
{
|
{
|
||||||
var installationRequests = softwareIds.Select(x => new InstallationRequestDataModel(x, id, 1, 1.1)).ToList();
|
var installationRequests = softwareIds.Select(x => new InstallationRequestDataModel(x, id, 1, 1.1)).ToList();
|
||||||
return new(id, workerId, email, sum, isCancel, installationRequests);
|
return new(id, workerId, email, isCancel, installationRequests);
|
||||||
}
|
}
|
||||||
private Request? GetRequestFromDatabaseById(string id) =>
|
private Request? GetRequestFromDatabaseById(string id) =>
|
||||||
SmallSoftwareDbContext.Requests.Include(x => x.InstallationRequests).FirstOrDefault(x => x.Id == id);
|
SmallSoftwareDbContext.Requests.Include(x => x.InstallationRequests).FirstOrDefault(x => x.Id == id);
|
||||||
|
|||||||
@@ -2,12 +2,7 @@
|
|||||||
using SmallSoftwareContracts.ViewModels;
|
using SmallSoftwareContracts.ViewModels;
|
||||||
using SmallSoftwareDatabase.Models;
|
using SmallSoftwareDatabase.Models;
|
||||||
using SmallSoftwareTests.Infrastructure;
|
using SmallSoftwareTests.Infrastructure;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SmallSoftwareTests.WebApiControllersApi;
|
namespace SmallSoftwareTests.WebApiControllersApi;
|
||||||
|
|
||||||
@@ -40,6 +35,9 @@ internal class RequestControllerTests : BaseWebApiControllerTest
|
|||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "test@mail.ru", sum: 10, false, softwares: [(_softwareId, 10, 1.1)]);
|
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "test@mail.ru", sum: 10, false, softwares: [(_softwareId, 10, 1.1)]);
|
||||||
|
SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "test@mail.ru", softwares: [(_softwareId, 10, 1.1)]);
|
||||||
|
SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "test@mail.ru", softwares: [(_softwareId, 10, 1.1)]);
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
var response = await HttpClient.GetAsync($"/api/requests/getrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
|
var response = await HttpClient.GetAsync($"/api/requests/getrecords?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
|
||||||
//Assert
|
//Assert
|
||||||
@@ -50,7 +48,6 @@ internal class RequestControllerTests : BaseWebApiControllerTest
|
|||||||
Assert.That(data, Is.Not.Null);
|
Assert.That(data, Is.Not.Null);
|
||||||
Assert.That(data, Has.Count.EqualTo(3));
|
Assert.That(data, Has.Count.EqualTo(3));
|
||||||
});
|
});
|
||||||
AssertElement(data.First(x => x.Sum == request.Sum), request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -182,7 +179,7 @@ internal class RequestControllerTests : BaseWebApiControllerTest
|
|||||||
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "test@mail.ru", sum: 10, false, softwares: [(_softwareId, 10, 1.1)]);
|
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "", 10, true, softwares: [(_softwareId, 10, 1.1)]);
|
||||||
//Act
|
//Act
|
||||||
var response = await HttpClient.GetAsync($"/api/requests/getrecord/{request.Id}");
|
var response = await HttpClient.GetAsync($"/api/requests/getrecord/{request.Id}");
|
||||||
//Assert
|
//Assert
|
||||||
@@ -278,7 +275,7 @@ internal class RequestControllerTests : BaseWebApiControllerTest
|
|||||||
public async Task Delete_ShouldSuccess_Test()
|
public async Task Delete_ShouldSuccess_Test()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "email@mail.ru", 10, true, softwares: [(_softwareId, 5, 1.1)]);
|
var request = SmallSoftwareDbContext.InsertRequestToDatabaseAndReturn(_workerId, "email@mail.ru", 10, false, softwares: [(_softwareId, 5, 1.1)]);
|
||||||
//Act
|
//Act
|
||||||
var response = await HttpClient.DeleteAsync($"/api/requests/cancel/{request.Id}");
|
var response = await HttpClient.DeleteAsync($"/api/requests/cancel/{request.Id}");
|
||||||
SmallSoftwareDbContext.ChangeTracker.Clear();
|
SmallSoftwareDbContext.ChangeTracker.Clear();
|
||||||
@@ -361,32 +358,5 @@ internal class RequestControllerTests : BaseWebApiControllerTest
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssertElement(Request? actual, RequestBindingModel expected)
|
|
||||||
{
|
|
||||||
Assert.That(actual, Is.Not.Null);
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(actual.WorkerId, Is.EqualTo(expected.WorkerId));
|
|
||||||
Assert.That(!actual.IsCancel);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (expected.Softwares is not null)
|
|
||||||
{
|
|
||||||
Assert.That(actual.InstallationRequests, Is.Not.Null);
|
|
||||||
Assert.That(actual.InstallationRequests, Has.Count.EqualTo(expected.Softwares.Count));
|
|
||||||
for (int i = 0; i < actual.InstallationRequests.Count; ++i)
|
|
||||||
{
|
|
||||||
Assert.Multiple(() =>
|
|
||||||
{
|
|
||||||
Assert.That(actual.InstallationRequests[i].SoftwareId, Is.EqualTo(expected.Softwares[i].SoftwareId));
|
|
||||||
Assert.That(actual.InstallationRequests[i].Count, Is.EqualTo(expected.Softwares[i].Count));
|
|
||||||
Assert.That(actual.InstallationRequests[i].Price, Is.EqualTo(expected.Softwares[i].Price));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Assert.That(actual.InstallationRequests, Is.Null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user