From 712d84ce140c871a30dc2d15084a79248b4d4554 Mon Sep 17 00:00:00 2001 From: Ilya Krupcov Date: Tue, 28 May 2024 18:27:37 +0300 Subject: [PATCH 1/3] Add validator --- .../ProposalValidatorTests.cs | 44 +++++++++++++++++++ .../TDDLesson.Orders.Tests.csproj | 4 ++ TDDLesson.Orders/ProposalValidationRequest.cs | 3 ++ TDDLesson.Orders/ProposalValidator.cs | 15 +++++++ TDDLesson.sln.DotSettings.user | 7 +-- 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 TDDLesson.Orders.Tests/ProposalValidatorTests.cs create mode 100644 TDDLesson.Orders/ProposalValidationRequest.cs create mode 100644 TDDLesson.Orders/ProposalValidator.cs diff --git a/TDDLesson.Orders.Tests/ProposalValidatorTests.cs b/TDDLesson.Orders.Tests/ProposalValidatorTests.cs new file mode 100644 index 0000000..6903e4e --- /dev/null +++ b/TDDLesson.Orders.Tests/ProposalValidatorTests.cs @@ -0,0 +1,44 @@ +using FluentAssertions; +using TDDLesson; + +namespace TestProject1; + +[TestClass] +public class ProposalValidatorTests +{ + private readonly ProposalValidator _proposalValidator = new(); + + [TestMethod] + public void IsProposalValid_IsValid_True() + { + var request = new ProposalValidationRequest(101, 31); + + var result = _proposalValidator.IsProposalValid(request); + + result.Should().BeTrue(); + } + + [TestMethod] + [DataRow(100)] + [DataRow(50)] + public void IsProposalValid_EmployeeAmountIsInvalid_False(int employeeAmount) + { + var request = new ProposalValidationRequest(employeeAmount, 31); + + var result = _proposalValidator.IsProposalValid(request); + + result.Should().BeFalse(); + } + + [TestMethod] + [DataRow(30)] + [DataRow(15)] + public void IsProposalValid_ItRevenuePercentIsInvalid_False(int itRevenuePercent) + { + var request = new ProposalValidationRequest(101, itRevenuePercent); + + var result = _proposalValidator.IsProposalValid(request); + + result.Should().BeFalse(); + } +} \ No newline at end of file diff --git a/TDDLesson.Orders.Tests/TDDLesson.Orders.Tests.csproj b/TDDLesson.Orders.Tests/TDDLesson.Orders.Tests.csproj index 39ef181..63c456b 100644 --- a/TDDLesson.Orders.Tests/TDDLesson.Orders.Tests.csproj +++ b/TDDLesson.Orders.Tests/TDDLesson.Orders.Tests.csproj @@ -23,4 +23,8 @@ + + + + diff --git a/TDDLesson.Orders/ProposalValidationRequest.cs b/TDDLesson.Orders/ProposalValidationRequest.cs new file mode 100644 index 0000000..b240c39 --- /dev/null +++ b/TDDLesson.Orders/ProposalValidationRequest.cs @@ -0,0 +1,3 @@ +namespace TDDLesson; + +public record ProposalValidationRequest(int EmployeesAmount, float ItRevenuePercent); \ No newline at end of file diff --git a/TDDLesson.Orders/ProposalValidator.cs b/TDDLesson.Orders/ProposalValidator.cs new file mode 100644 index 0000000..7d6239c --- /dev/null +++ b/TDDLesson.Orders/ProposalValidator.cs @@ -0,0 +1,15 @@ +namespace TDDLesson; + +public class ProposalValidator +{ + public bool IsProposalValid(ProposalValidationRequest proposalValidationRequest) + { + if (proposalValidationRequest.EmployeesAmount <= 100) + return false; + + if (proposalValidationRequest.ItRevenuePercent <= 30) + return false; + + return true; + } +} \ No newline at end of file diff --git a/TDDLesson.sln.DotSettings.user b/TDDLesson.sln.DotSettings.user index 12ec2da..4a0db42 100644 --- a/TDDLesson.sln.DotSettings.user +++ b/TDDLesson.sln.DotSettings.user @@ -1,6 +1,7 @@  4294967293 /usr/local/share/dotnet/sdk/8.0.203/MSBuild.dll - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Solution /> -</SessionState> \ No newline at end of file + + + + \ No newline at end of file From 6327a8487061c12b9a81f16af03ba16d51044bc6 Mon Sep 17 00:00:00 2001 From: AlexPoziev Date: Tue, 28 May 2024 19:27:20 +0300 Subject: [PATCH 2/3] feat: NotificationService --- .../NotificationServiceTests.cs | 47 +++++++++++++++++++ .../ProposalValidatorTests.cs | 14 +++--- TDDLesson.Orders/EmailDto.cs | 3 ++ TDDLesson.Orders/NotificationRequest.cs | 3 ++ TDDLesson.Orders/NotificationService.cs | 19 ++++++++ TDDLesson.Orders/ProposalValidator.cs | 4 +- 6 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 TDDLesson.Orders.Tests/NotificationServiceTests.cs create mode 100644 TDDLesson.Orders/EmailDto.cs create mode 100644 TDDLesson.Orders/NotificationRequest.cs create mode 100644 TDDLesson.Orders/NotificationService.cs diff --git a/TDDLesson.Orders.Tests/NotificationServiceTests.cs b/TDDLesson.Orders.Tests/NotificationServiceTests.cs new file mode 100644 index 0000000..80109a4 --- /dev/null +++ b/TDDLesson.Orders.Tests/NotificationServiceTests.cs @@ -0,0 +1,47 @@ +using System.Runtime.InteropServices.JavaScript; +using FluentAssertions; +using TDDLesson; + +namespace TestProject1; + +[TestClass] +public class NotificationServiceTests +{ + [TestMethod] + [DataRow(100)] + [DataRow(50)] + public void ShouldReturnNull_WhenEmployeesNumberLessThan100(int employeeAmount) + { + var notificationRequest = new NotificationRequest(employeeAmount, new DateTime(2024, 07, 01), "123@gmail.com"); + + + var emailDto = NotificationService.CreateNotification(notificationRequest); + + + emailDto.Should().BeNull(); + } + + [TestMethod] + public void ShouldReturnNull_WhenDataNotInInterval() + { + var notificationRequest = new NotificationRequest(101, new DateTime(1990, 07, 01), "123@gmail.com"); + + + var emailDto = NotificationService.CreateNotification(notificationRequest); + + + emailDto.Should().BeNull(); + } + + [TestMethod] + public void ShouldReturnEmailDto_WhenCorrectData() + { + var notificationRequest = new NotificationRequest(101, new DateTime(2024, 07, 01), "123@gmail.com"); + + + var emailDto = NotificationService.CreateNotification(notificationRequest); + + + emailDto.Should().NotBeNull(); + } +} \ No newline at end of file diff --git a/TDDLesson.Orders.Tests/ProposalValidatorTests.cs b/TDDLesson.Orders.Tests/ProposalValidatorTests.cs index 6903e4e..a7fcd8f 100644 --- a/TDDLesson.Orders.Tests/ProposalValidatorTests.cs +++ b/TDDLesson.Orders.Tests/ProposalValidatorTests.cs @@ -6,14 +6,12 @@ namespace TestProject1; [TestClass] public class ProposalValidatorTests { - private readonly ProposalValidator _proposalValidator = new(); - [TestMethod] - public void IsProposalValid_IsValid_True() + public void ShouldBeValid_WhenEmployeesAndRevenueInCorrectInterval() { var request = new ProposalValidationRequest(101, 31); - var result = _proposalValidator.IsProposalValid(request); + var result = ProposalValidator.IsProposalValid(request); result.Should().BeTrue(); } @@ -21,11 +19,11 @@ public void IsProposalValid_IsValid_True() [TestMethod] [DataRow(100)] [DataRow(50)] - public void IsProposalValid_EmployeeAmountIsInvalid_False(int employeeAmount) + public void ShouldBeInvalid_WhenEmployeesNumberLessThan100(int employeeAmount) { var request = new ProposalValidationRequest(employeeAmount, 31); - var result = _proposalValidator.IsProposalValid(request); + var result = ProposalValidator.IsProposalValid(request); result.Should().BeFalse(); } @@ -33,11 +31,11 @@ public void IsProposalValid_EmployeeAmountIsInvalid_False(int employeeAmount) [TestMethod] [DataRow(30)] [DataRow(15)] - public void IsProposalValid_ItRevenuePercentIsInvalid_False(int itRevenuePercent) + public void ShouldBeInvalid_WhenRevenueAmountLessThan30(int itRevenuePercent) { var request = new ProposalValidationRequest(101, itRevenuePercent); - var result = _proposalValidator.IsProposalValid(request); + var result = ProposalValidator.IsProposalValid(request); result.Should().BeFalse(); } diff --git a/TDDLesson.Orders/EmailDto.cs b/TDDLesson.Orders/EmailDto.cs new file mode 100644 index 0000000..01e3ce1 --- /dev/null +++ b/TDDLesson.Orders/EmailDto.cs @@ -0,0 +1,3 @@ +namespace TDDLesson; + +public record EmailDto(string MailTo, string Subject, string Body); \ No newline at end of file diff --git a/TDDLesson.Orders/NotificationRequest.cs b/TDDLesson.Orders/NotificationRequest.cs new file mode 100644 index 0000000..fc8bce0 --- /dev/null +++ b/TDDLesson.Orders/NotificationRequest.cs @@ -0,0 +1,3 @@ +namespace TDDLesson; + +public record NotificationRequest(int EmployeesNumber, DateTime HandleDate, string MailTo); \ No newline at end of file diff --git a/TDDLesson.Orders/NotificationService.cs b/TDDLesson.Orders/NotificationService.cs new file mode 100644 index 0000000..1cb1efd --- /dev/null +++ b/TDDLesson.Orders/NotificationService.cs @@ -0,0 +1,19 @@ +namespace TDDLesson; + +public static class NotificationService +{ + public static EmailDto? CreateNotification(NotificationRequest request) + { + if (request.HandleDate < new DateTime(2024, 06, 01) || request.HandleDate > new DateTime(2024, 09, 01)) + { + return null; + } + if (request.EmployeesNumber <= 100) + { + return null; + } + + return new EmailDto("test@gmail.com", "test", "test2"); + } +} + diff --git a/TDDLesson.Orders/ProposalValidator.cs b/TDDLesson.Orders/ProposalValidator.cs index 7d6239c..24930b3 100644 --- a/TDDLesson.Orders/ProposalValidator.cs +++ b/TDDLesson.Orders/ProposalValidator.cs @@ -1,8 +1,8 @@ namespace TDDLesson; -public class ProposalValidator +public static class ProposalValidator { - public bool IsProposalValid(ProposalValidationRequest proposalValidationRequest) + public static bool IsProposalValid(ProposalValidationRequest proposalValidationRequest) { if (proposalValidationRequest.EmployeesAmount <= 100) return false; From 3c7e47b509011f7f560229dc9bc8f8bd9a3213c7 Mon Sep 17 00:00:00 2001 From: Nataly Turbina Date: Tue, 28 May 2024 21:03:19 +0400 Subject: [PATCH 3/3] add handler --- .../NotificationServiceTests.cs | 66 +++++++++++++++---- .../AccreditationProposalProcessor.cs | 46 ++++++++++++- TDDLesson.Orders/NotificationRequest.cs | 2 +- TDDLesson.Orders/NotificationService.cs | 7 +- TDDLesson.Orders/ProposalData.cs | 12 ++++ 5 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 TDDLesson.Orders/ProposalData.cs diff --git a/TDDLesson.Orders.Tests/NotificationServiceTests.cs b/TDDLesson.Orders.Tests/NotificationServiceTests.cs index 80109a4..eaf6e1e 100644 --- a/TDDLesson.Orders.Tests/NotificationServiceTests.cs +++ b/TDDLesson.Orders.Tests/NotificationServiceTests.cs @@ -8,40 +8,80 @@ namespace TestProject1; public class NotificationServiceTests { [TestMethod] - [DataRow(100)] - [DataRow(50)] - public void ShouldReturnNull_WhenEmployeesNumberLessThan100(int employeeAmount) + public void ShouldReturnNull_WhenEmployeesNotSaved() { - var notificationRequest = new NotificationRequest(employeeAmount, new DateTime(2024, 07, 01), "123@gmail.com"); - + var notificationRequest = new NotificationRequest( + false, + 99, + new DateTime(2024, 07, 01), + "123@gmail.com"); var emailDto = NotificationService.CreateNotification(notificationRequest); - - + emailDto.Should().BeNull(); } [TestMethod] public void ShouldReturnNull_WhenDataNotInInterval() { - var notificationRequest = new NotificationRequest(101, new DateTime(1990, 07, 01), "123@gmail.com"); - + var notificationRequest = new NotificationRequest( + true, + 101, + new DateTime(1990, 07, 01), + "123@gmail.com"); var emailDto = NotificationService.CreateNotification(notificationRequest); - - + emailDto.Should().BeNull(); } [TestMethod] public void ShouldReturnEmailDto_WhenCorrectData() { - var notificationRequest = new NotificationRequest(101, new DateTime(2024, 07, 01), "123@gmail.com"); + var notificationRequest = new NotificationRequest( + true, + 101, + new DateTime(2024, 07, 01), + "123@gmail.com"); + + var emailDto = NotificationService.CreateNotification(notificationRequest); + emailDto.Should().NotBeNull(); + } + + [TestMethod] + public void ShouldReturnEmailDtoWithoutInvite_WhenCorrectDataAndLess500Employee() + { + var notificationRequest = new NotificationRequest( + true, + 150, + new DateTime(2024, 07, 01), + "123@gmail.com"); var emailDto = NotificationService.CreateNotification(notificationRequest); + + emailDto.Should().NotBeNull(); + emailDto.MailTo.Should().Be("123@gmail.com"); + emailDto.Subject.Should().Be(NotificationService.Subject); + emailDto.Body.Should().Be(NotificationService.ProcessedMessage); - + } + + [TestMethod] + public void ShouldReturnEmailDtoWithInvite_WhenCorrectDataAndMore500Employee() + { + var notificationRequest = new NotificationRequest( + true, + 550, + new DateTime(2024, 07, 01), + "123@gmail.com"); + + var emailDto = NotificationService.CreateNotification(notificationRequest); + emailDto.Should().NotBeNull(); + emailDto.MailTo.Should().Be("123@gmail.com"); + emailDto.Subject.Should().Be(NotificationService.Subject); + emailDto.Body.Should().Be(NotificationService.ProcessedMessage + " " + NotificationService.InviteMessage); + } } \ No newline at end of file diff --git a/TDDLesson.Orders/AccreditationProposalProcessor.cs b/TDDLesson.Orders/AccreditationProposalProcessor.cs index a0ded80..5a8acb7 100644 --- a/TDDLesson.Orders/AccreditationProposalProcessor.cs +++ b/TDDLesson.Orders/AccreditationProposalProcessor.cs @@ -4,15 +4,59 @@ public class AccreditationProposalProcessor { private readonly IRevenueService _revenueService; private readonly IRepository _orderRepository; + private readonly IEmailClient _emailClient; - public AccreditationProposalProcessor(IRevenueService revenueService, IRepository orderRepository) + public AccreditationProposalProcessor(IRevenueService revenueService, IRepository orderRepository, IEmailClient emailClient) { _revenueService = revenueService; _orderRepository = orderRepository; + _emailClient = emailClient; } public async Task HandleProposal(ProposalDto dto) { + var itRevenuePercent = _revenueService.GetRevenuePercent(dto.CompanyNumber); + var proposalValidationRequest = new ProposalValidationRequest( + EmployeesAmount: dto.EmployeesAmount, + ItRevenuePercent: itRevenuePercent + ); + var valid = ProposalValidator.IsProposalValid(proposalValidationRequest); + + if (!valid) + return; + + var saved = false; + try + { + await _orderRepository.SaveAsync(new ProposalData + { + CompanyEmail = dto.CompanyEmail, + CompanyName = dto.CompanyName, + CompanyNumber = dto.CompanyNumber, + EmployeesAmount = dto.EmployeesAmount + }); + + saved = true; + } + catch (Exception e) + { + } + + + var notificationRequest = new NotificationRequest( + Saved: saved, + EmployeesNumber: dto.EmployeesAmount, + HandleDate: DateTime.UtcNow, + MailTo: dto.CompanyEmail); + + var emailDto = NotificationService.CreateNotification(notificationRequest); + + if (emailDto != null) + await _emailClient.SendEmail( + mailTo: emailDto.MailTo, + subject: emailDto.Subject, + body: emailDto.Body); + } } \ No newline at end of file diff --git a/TDDLesson.Orders/NotificationRequest.cs b/TDDLesson.Orders/NotificationRequest.cs index fc8bce0..d48c098 100644 --- a/TDDLesson.Orders/NotificationRequest.cs +++ b/TDDLesson.Orders/NotificationRequest.cs @@ -1,3 +1,3 @@ namespace TDDLesson; -public record NotificationRequest(int EmployeesNumber, DateTime HandleDate, string MailTo); \ No newline at end of file +public record NotificationRequest(bool Saved, int EmployeesNumber, DateTime HandleDate, string MailTo); \ No newline at end of file diff --git a/TDDLesson.Orders/NotificationService.cs b/TDDLesson.Orders/NotificationService.cs index 1cb1efd..174914b 100644 --- a/TDDLesson.Orders/NotificationService.cs +++ b/TDDLesson.Orders/NotificationService.cs @@ -2,6 +2,10 @@ namespace TDDLesson; public static class NotificationService { + public const string Subject = "Proposal info."; + public const string ProcessedMessage = "Proposal processed."; + public const string InviteMessage = "We invite you to the forum on the development of the IT industry."; + public static EmailDto? CreateNotification(NotificationRequest request) { if (request.HandleDate < new DateTime(2024, 06, 01) || request.HandleDate > new DateTime(2024, 09, 01)) @@ -13,7 +17,8 @@ public static class NotificationService return null; } - return new EmailDto("test@gmail.com", "test", "test2"); + var body = request.EmployeesNumber <= 500 ? ProcessedMessage : ProcessedMessage + " " + InviteMessage; + return new EmailDto(request.MailTo, Subject, body); } } diff --git a/TDDLesson.Orders/ProposalData.cs b/TDDLesson.Orders/ProposalData.cs new file mode 100644 index 0000000..2d1c433 --- /dev/null +++ b/TDDLesson.Orders/ProposalData.cs @@ -0,0 +1,12 @@ +namespace TDDLesson; + +public class ProposalData +{ + public required int CompanyNumber { get; set; } + + public required string CompanyName { get; set; } + + public required string CompanyEmail { get; set; } + + public required int EmployeesAmount { get; set; } +} \ No newline at end of file