From 754513fd293954473d0c68eb2d8d530a579afcb8 Mon Sep 17 00:00:00 2001 From: shaed-parkar <41630528+shaed-parkar@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:59:21 +0100 Subject: [PATCH] VIH-10126 update default value for IsMultiDayHearing and AudioRecordingRequired (#713) Update swagger doc to use fluent validation rules --- .../V2/Requests/BookNewHearingRequestV2.cs | 8 +++- .../V2/Requests/LinkedParticipantRequestV2.cs | 13 ++++++- .../Services/RandomGeneratorTests.cs | 1 + .../V1/UpdateHearingRequestValidationTests.cs | 14 +++---- .../V2/EndpointRequestValidationV2Tests.cs | 7 ++-- ...LinkedParticipantRequestValidationTests.cs | 10 ++--- .../ConfigureServicesExtensions.cs | 39 +++++++++++++------ .../Controllers/V1/HearingsController.cs | 11 +++++- .../V2/HearingParticipantsControllerV2.cs | 4 +- .../Controllers/V2/HearingsControllerV2.cs | 2 +- ...ntRequestV2ToLinkedParticipantDtoMapper.cs | 2 +- BookingsApi/BookingsApi/Startup.cs | 12 +++++- .../Validations/Common/DataInputValidator.cs | 10 +++++ .../JudiciaryParticipantRequestValidation.cs | 2 +- .../V1/UpdateHearingRequestValidation.cs | 7 ++-- ...ipantsToHearingRequestInputValidationV2.cs | 16 -------- ...antsToHearingRequestRefDataValidationV2.cs | 20 ++++++++++ .../BookNewHearingRequestInputValidationV2.cs | 2 + ...okNewHearingRequestRefDataValidationV2.cs} | 5 ++- .../V2/EndpointRequestValidationV2.cs | 2 +- .../LinkedParticipantRequestValidationV2.cs | 2 +- ...ingParticipantsRequestInputValidationV2.cs | 1 + ...ParticipantsRequestRefDataValidationV2.cs} | 4 +- 23 files changed, 129 insertions(+), 65 deletions(-) create mode 100644 BookingsApi/BookingsApi/Validations/Common/DataInputValidator.cs create mode 100644 BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestRefDataValidationV2.cs rename BookingsApi/BookingsApi/Validations/V2/{BookNewHearingRequestDataValidationV2.cs => BookNewHearingRequestRefDataValidationV2.cs} (90%) rename BookingsApi/BookingsApi/Validations/V2/{UpdateHearingParticipantsRequestDataValidationV2.cs => UpdateHearingParticipantsRequestRefDataValidationV2.cs} (88%) diff --git a/BookingsApi/BookingsApi.Contract/V2/Requests/BookNewHearingRequestV2.cs b/BookingsApi/BookingsApi.Contract/V2/Requests/BookNewHearingRequestV2.cs index 469246aff..4be961317 100644 --- a/BookingsApi/BookingsApi.Contract/V2/Requests/BookNewHearingRequestV2.cs +++ b/BookingsApi/BookingsApi.Contract/V2/Requests/BookNewHearingRequestV2.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using BookingsApi.Contract.V1.Requests; namespace BookingsApi.Contract.V2.Requests @@ -71,8 +72,13 @@ public BookNewHearingRequestV2() /// /// Gets or sets the audio recording required flag, value true is indicated that recording is required, otherwise false /// - public bool AudioRecordingRequired { get; set; } + [DefaultValue(false)] + public bool AudioRecordingRequired { get; set; } = false; + /// + /// Is the booking part of a multi-day hearing? + /// + [DefaultValue(false)] public bool IsMultiDayHearing { get; set; } = false; public List Endpoints { get; set; } diff --git a/BookingsApi/BookingsApi.Contract/V2/Requests/LinkedParticipantRequestV2.cs b/BookingsApi/BookingsApi.Contract/V2/Requests/LinkedParticipantRequestV2.cs index ec3ba2cbc..d14605f20 100644 --- a/BookingsApi/BookingsApi.Contract/V2/Requests/LinkedParticipantRequestV2.cs +++ b/BookingsApi/BookingsApi.Contract/V2/Requests/LinkedParticipantRequestV2.cs @@ -4,8 +4,19 @@ namespace BookingsApi.Contract.V2.Requests { public class LinkedParticipantRequestV2 { + /// + /// The contact email for the participant to create a link for + /// public string ParticipantContactEmail { get; set; } + + /// + /// The contact email for the participant to create a link with + /// public string LinkedParticipantContactEmail { get; set; } - public LinkedParticipantTypeV2 TypeV2 { get; set; } + + /// + /// The type of link to create + /// + public LinkedParticipantTypeV2 Type { get; set; } } } \ No newline at end of file diff --git a/BookingsApi/BookingsApi.UnitTests/Services/RandomGeneratorTests.cs b/BookingsApi/BookingsApi.UnitTests/Services/RandomGeneratorTests.cs index 327615d4f..dc2884262 100644 --- a/BookingsApi/BookingsApi.UnitTests/Services/RandomGeneratorTests.cs +++ b/BookingsApi/BookingsApi.UnitTests/Services/RandomGeneratorTests.cs @@ -33,6 +33,7 @@ public void Should_throw_exception_on_taking_more_than_available() [TestCase("637330171125319309", 13u, 4u, "3373")] [TestCase("607330171125309309", 13u, 4u, "3370")] public void Should_return_correct_ticks(string source, uint skip, uint take, string expected) + { var result = _randomGenerator.GetWeakDeterministic(long.Parse(source), skip, take); diff --git a/BookingsApi/BookingsApi.UnitTests/Validation/V1/UpdateHearingRequestValidationTests.cs b/BookingsApi/BookingsApi.UnitTests/Validation/V1/UpdateHearingRequestValidationTests.cs index ea43e2017..ea009d5a2 100644 --- a/BookingsApi/BookingsApi.UnitTests/Validation/V1/UpdateHearingRequestValidationTests.cs +++ b/BookingsApi/BookingsApi.UnitTests/Validation/V1/UpdateHearingRequestValidationTests.cs @@ -7,15 +7,11 @@ namespace BookingsApi.UnitTests.Validation.V1 public class UpdateHearingRequestValidationTests { private UpdateHearingRequestValidation _validator; - private DateTime _scheduledDateTime; - private VideoHearing _hearing; [SetUp] public void SetUp() { - _scheduledDateTime = DateTime.Today.AddDays(5).AddHours(10).AddMinutes(30); - _hearing = new VideoHearingBuilder().WithScheduledDateTime(_scheduledDateTime).Build(); - _validator = new UpdateHearingRequestValidation(_hearing); + _validator = new UpdateHearingRequestValidation(); } [Test] @@ -40,7 +36,7 @@ public async Task Should_return_missing_hearing_venue_name_error() var result = await _validator.ValidateAsync(request); // assert - result.Errors.Any(x => x.ErrorMessage == UpdateHearingRequestValidation.NoHearingVenueNameErrorMessage) + result.Errors.Exists(x => x.ErrorMessage == UpdateHearingRequestValidation.NoHearingVenueNameErrorMessage) .Should().BeTrue(); } @@ -53,7 +49,7 @@ public async Task Should_return_hearing_schedule_date_time_in_past_error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == UpdateHearingRequestValidation.ScheduleDateTimeInPastErrorMessage) + result.Errors.Exists(x => x.ErrorMessage == UpdateHearingRequestValidation.ScheduleDateTimeInPastErrorMessage) .Should().BeTrue(); } @@ -66,7 +62,7 @@ public async Task Should_return_hearing_schedule_duration_error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == UpdateHearingRequestValidation.NoScheduleDurationErrorMessage) + result.Errors.Exists(x => x.ErrorMessage == UpdateHearingRequestValidation.NoScheduleDurationErrorMessage) .Should().BeTrue(); } @@ -79,7 +75,7 @@ public async Task Should_return_missing_updated_by_error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == UpdateHearingRequestValidation.NoUpdatedByErrorMessage) + result.Errors.Exists(x => x.ErrorMessage == UpdateHearingRequestValidation.NoUpdatedByErrorMessage) .Should().BeTrue(); } diff --git a/BookingsApi/BookingsApi.UnitTests/Validation/V2/EndpointRequestValidationV2Tests.cs b/BookingsApi/BookingsApi.UnitTests/Validation/V2/EndpointRequestValidationV2Tests.cs index 0bdec7e4e..3c4061dfd 100644 --- a/BookingsApi/BookingsApi.UnitTests/Validation/V2/EndpointRequestValidationV2Tests.cs +++ b/BookingsApi/BookingsApi.UnitTests/Validation/V2/EndpointRequestValidationV2Tests.cs @@ -39,8 +39,7 @@ public async Task Should_return_missing_display_name_error() var result = await _validator.ValidateAsync(request); result.IsValid.Should().BeFalse(); - result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDisplayNameErrorMessage).Should().BeTrue(); + result.Errors.Exists(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDisplayNameErrorMessage).Should().BeTrue(); } [Test] @@ -56,7 +55,7 @@ public async Task Should_return_missing_defence_advocate_contact_email_error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDefenceAdvocateContactEmailError).Should().BeTrue(); + result.Errors.Exists(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDefenceAdvocateContactEmailError).Should().BeTrue(); } [Test] @@ -72,6 +71,6 @@ public async Task Should_return_invalid_defence_advocate_contact_email_error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDefenceAdvocateContactEmailError).Should().BeTrue(); + result.Errors.Exists(x => x.ErrorMessage == EndpointRequestValidationV2.InvalidDefenceAdvocateContactEmailError).Should().BeTrue(); } } \ No newline at end of file diff --git a/BookingsApi/BookingsApi.UnitTests/Validation/V2/LinkedParticipantRequestValidationTests.cs b/BookingsApi/BookingsApi.UnitTests/Validation/V2/LinkedParticipantRequestValidationTests.cs index 0b4d338e6..8b9612e43 100644 --- a/BookingsApi/BookingsApi.UnitTests/Validation/V2/LinkedParticipantRequestValidationTests.cs +++ b/BookingsApi/BookingsApi.UnitTests/Validation/V2/LinkedParticipantRequestValidationTests.cs @@ -34,7 +34,7 @@ public async Task Should_Return_Missing_Participant_Email_Error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.NoParticipantEmail) + result.Errors.Exists(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.NoParticipantEmail) .Should().BeTrue(); } @@ -47,20 +47,20 @@ public async Task Should_Return_Missing_LinkedParticipant_Email_Error() result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.NoLinkedParticipantEmail) + result.Errors.Exists(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.NoLinkedParticipantEmail) .Should().BeTrue(); } [Test] public async Task Should_Return_Invalid_LinkedParticipant_Type_Error() { - _requestV2.TypeV2 = (LinkedParticipantTypeV2)456789; + _requestV2.Type = (LinkedParticipantTypeV2)456789; var result = await _validator.ValidateAsync(_requestV2); result.IsValid.Should().BeFalse(); result.Errors.Count.Should().Be(1); - result.Errors.Any(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.InvalidType) + result.Errors.Exists(x => x.ErrorMessage == LinkedParticipantRequestValidationV2.InvalidType) .Should().BeTrue(); } @@ -69,7 +69,7 @@ private LinkedParticipantRequestV2 BuildRequest() return Builder.CreateNew() .With(x => x.ParticipantContactEmail = "interpretee@hmcts.net") .With(x => x.LinkedParticipantContactEmail = "interpreter@hmcts.net") - .With(x => x.TypeV2 = LinkedParticipantTypeV2.Interpreter) + .With(x => x.Type = LinkedParticipantTypeV2.Interpreter) .Build(); } } diff --git a/BookingsApi/BookingsApi/ConfigureServicesExtensions.cs b/BookingsApi/BookingsApi/ConfigureServicesExtensions.cs index 8332eace1..d52b5692c 100644 --- a/BookingsApi/BookingsApi/ConfigureServicesExtensions.cs +++ b/BookingsApi/BookingsApi/ConfigureServicesExtensions.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc.Versioning; using Newtonsoft.Json.Converters; using NSwag.Generation.AspNetCore; +using ZymLabs.NSwag.FluentValidation; namespace BookingsApi @@ -35,30 +36,38 @@ public static IServiceCollection AddApiVersioning(this IServiceCollection servic } public static IServiceCollection AddSwagger(this IServiceCollection services) { + services.AddScoped(provider => + { + var validationRules = provider.GetService>(); + var loggerFactory = provider.GetService(); + + return new FluentValidationSchemaProcessor(provider, validationRules, loggerFactory); + }); + var apiVersionDescription = services.BuildServiceProvider().GetService(); foreach (var groupName in apiVersionDescription.ApiVersionDescriptions.Select(x=> x.GroupName)) { - services.AddOpenApiDocument((configure) => + services.AddOpenApiDocument((configure, servicesProvider) => { - ConfigureSwaggerForVersion(configure, groupName, new[] { groupName }); + ConfigureSwaggerForVersion(configure, groupName, new[] { groupName }, servicesProvider); }); } // to build a single a client for all versions of the api, create one document with all the groups var groupNames = apiVersionDescription.ApiVersionDescriptions.Select(x => x.GroupName).ToArray(); - services.AddOpenApiDocument((configure) => + services.AddOpenApiDocument((configure, servicesProvider) => { - ConfigureSwaggerForVersion(configure, "all", groupNames); + ConfigureSwaggerForVersion(configure, "all", groupNames, servicesProvider); }); return services; } - private static void ConfigureSwaggerForVersion(AspNetCoreOpenApiDocumentGeneratorSettings configure, - string documentName, string[] apiGroupNames) + private static void ConfigureSwaggerForVersion(AspNetCoreOpenApiDocumentGeneratorSettings settings, + string documentName, string[] apiGroupNames, IServiceProvider serviceProvider) { - configure.DocumentName = documentName; - configure.ApiGroupNames = apiGroupNames; - configure.AddSecurity("JWT", Enumerable.Empty(), + settings.DocumentName = documentName; + settings.ApiGroupNames = apiGroupNames; + settings.AddSecurity("JWT", Enumerable.Empty(), new OpenApiSecurityScheme { Type = OpenApiSecuritySchemeType.ApiKey, @@ -67,9 +76,15 @@ private static void ConfigureSwaggerForVersion(AspNetCoreOpenApiDocumentGenerato Description = "Type into the textbox: Bearer {your JWT token}.", Scheme = "bearer" }); - configure.Title = "Bookings API"; - configure.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT")); - configure.OperationProcessors.Add(new AuthResponseOperationProcessor()); + settings.Title = "Bookings API"; + settings.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("JWT")); + settings.OperationProcessors.Add(new AuthResponseOperationProcessor()); + + var fluentValidationSchemaProcessor = serviceProvider.CreateScope().ServiceProvider.GetService(); + + // Add the fluent validations schema processor + settings.SchemaProcessors.Add(fluentValidationSchemaProcessor); + } public static IServiceCollection AddCustomTypes(this IServiceCollection services) diff --git a/BookingsApi/BookingsApi/Controllers/V1/HearingsController.cs b/BookingsApi/BookingsApi/Controllers/V1/HearingsController.cs index e5c9de234..8bb37a295 100644 --- a/BookingsApi/BookingsApi/Controllers/V1/HearingsController.cs +++ b/BookingsApi/BookingsApi/Controllers/V1/HearingsController.cs @@ -409,7 +409,16 @@ public async Task UpdateHearingDetails(Guid hearingId, [FromBody] return NotFound(); } - var result = new UpdateHearingRequestValidation(videoHearing).Validate(request); + var result = new UpdateHearingRequestValidation().Validate(request); + + if (videoHearing.ScheduledDateTime != request.ScheduledDateTime && + request.ScheduledDateTime < DateTime.UtcNow) // ignore if the scheduled date time has not changed + { + ModelState.AddModelError(nameof(request.ScheduledDateTime), + UpdateHearingRequestValidation.ScheduleDateTimeInPastErrorMessage); + + } + if (!result.IsValid) { ModelState.AddFluentValidationErrors(result.Errors); diff --git a/BookingsApi/BookingsApi/Controllers/V2/HearingParticipantsControllerV2.cs b/BookingsApi/BookingsApi/Controllers/V2/HearingParticipantsControllerV2.cs index aaaae733e..5d6c9bcb4 100644 --- a/BookingsApi/BookingsApi/Controllers/V2/HearingParticipantsControllerV2.cs +++ b/BookingsApi/BookingsApi/Controllers/V2/HearingParticipantsControllerV2.cs @@ -56,7 +56,7 @@ public async Task AddParticipantsToHearing(Guid hearingId, [FromB var caseTypeQuery = new GetCaseRolesForCaseServiceQuery(videoHearing.CaseType.ServiceId); var caseType = await _queryHandler.Handle(caseTypeQuery); - var dataValidationResult = await new AddParticipantsToHearingRequestDataValidationV2(caseType).ValidateAsync(request); + var dataValidationResult = await new AddParticipantsToHearingRequestRefDataValidationV2(caseType).ValidateAsync(request); if (!dataValidationResult.IsValid) { ModelState.AddFluentValidationErrors(dataValidationResult.Errors); @@ -124,7 +124,7 @@ public async Task UpdateHearingParticipants(Guid hearingId, [From var caseTypeQuery = new GetCaseRolesForCaseServiceQuery(videoHearing.CaseType.ServiceId); var hearingRoles = await _queryHandler.Handle>(new GetHearingRolesQuery()); var caseType = await _queryHandler.Handle(caseTypeQuery); - var dataValidationResult = await new UpdateHearingParticipantsRequestDataValidationV2(caseType, hearingRoles).ValidateAsync(request); + var dataValidationResult = await new UpdateHearingParticipantsRequestRefDataValidationV2(caseType, hearingRoles).ValidateAsync(request); if (!dataValidationResult.IsValid) { ModelState.AddFluentValidationErrors(dataValidationResult.Errors); diff --git a/BookingsApi/BookingsApi/Controllers/V2/HearingsControllerV2.cs b/BookingsApi/BookingsApi/Controllers/V2/HearingsControllerV2.cs index 974de3ac0..d93d2980d 100644 --- a/BookingsApi/BookingsApi/Controllers/V2/HearingsControllerV2.cs +++ b/BookingsApi/BookingsApi/Controllers/V2/HearingsControllerV2.cs @@ -52,7 +52,7 @@ public async Task BookNewHearingWithCode(BookNewHearingRequestV2 var caseType = await _queryHandler.Handle(new GetCaseRolesForCaseServiceQuery(request.ServiceId)); var hearingVenue = await GetHearingVenue(request.HearingVenueCode); - var dataValidationResult = await new BookNewHearingRequestDataValidationV2(caseType, hearingVenue, hearingRoles).ValidateAsync(request); + var dataValidationResult = await new BookNewHearingRequestRefDataValidationV2(caseType, hearingVenue, hearingRoles).ValidateAsync(request); if (!dataValidationResult.IsValid) { ModelState.AddFluentValidationErrors(dataValidationResult.Errors); diff --git a/BookingsApi/BookingsApi/Mappings/V2/LinkedParticipantRequestV2ToLinkedParticipantDtoMapper.cs b/BookingsApi/BookingsApi/Mappings/V2/LinkedParticipantRequestV2ToLinkedParticipantDtoMapper.cs index fdb9920b3..7e878682d 100644 --- a/BookingsApi/BookingsApi/Mappings/V2/LinkedParticipantRequestV2ToLinkedParticipantDtoMapper.cs +++ b/BookingsApi/BookingsApi/Mappings/V2/LinkedParticipantRequestV2ToLinkedParticipantDtoMapper.cs @@ -17,7 +17,7 @@ public static List MapToDto(List(ServiceLifetime.Scoped, + filter => + { + var valid = !filter.ValidatorType.GetInterfaces().ToList().Contains(typeof(IRefDataInputValidator)); + return valid; + }); + services.AddSwagger(); services.AddCors(options => options.AddPolicy("CorsPolicy", builder => diff --git a/BookingsApi/BookingsApi/Validations/Common/DataInputValidator.cs b/BookingsApi/BookingsApi/Validations/Common/DataInputValidator.cs new file mode 100644 index 000000000..bc6d644cb --- /dev/null +++ b/BookingsApi/BookingsApi/Validations/Common/DataInputValidator.cs @@ -0,0 +1,10 @@ +using FluentValidation; + +namespace BookingsApi.Validations.Common; + +public interface IRefDataInputValidator{} + +public abstract class RefDataInputValidatorValidator : AbstractValidator, IRefDataInputValidator +{ + +} \ No newline at end of file diff --git a/BookingsApi/BookingsApi/Validations/V1/JudiciaryParticipantRequestValidation.cs b/BookingsApi/BookingsApi/Validations/V1/JudiciaryParticipantRequestValidation.cs index 522ebecde..2b8634b3c 100644 --- a/BookingsApi/BookingsApi/Validations/V1/JudiciaryParticipantRequestValidation.cs +++ b/BookingsApi/BookingsApi/Validations/V1/JudiciaryParticipantRequestValidation.cs @@ -12,7 +12,7 @@ public JudiciaryParticipantRequestValidation() { RuleFor(x => x.PersonalCode).NotEmpty().WithMessage(NoPersonalCodeErrorMessage); RuleFor(x => x.DisplayName).NotEmpty().WithMessage(NoDisplayNameErrorMessage); - RuleFor(x => x.HearingRoleCode).IsInEnum(); + RuleFor(x => x.HearingRoleCode).NotEmpty().IsInEnum(); } } } diff --git a/BookingsApi/BookingsApi/Validations/V1/UpdateHearingRequestValidation.cs b/BookingsApi/BookingsApi/Validations/V1/UpdateHearingRequestValidation.cs index ce624503b..825920c91 100644 --- a/BookingsApi/BookingsApi/Validations/V1/UpdateHearingRequestValidation.cs +++ b/BookingsApi/BookingsApi/Validations/V1/UpdateHearingRequestValidation.cs @@ -10,20 +10,19 @@ public class UpdateHearingRequestValidation : AbstractValidator x.HearingVenueName) .NotEmpty().WithMessage(NoHearingVenueNameErrorMessage); RuleFor(x => x.ScheduledDateTime).Custom((dateTime, context) => { - if(videoHearing.ScheduledDateTime == dateTime) return; // ignore if the scheduled date time has not changed - if (dateTime < DateTime.UtcNow) + if (dateTime <= DateTime.MinValue) { context.AddFailure(ScheduleDateTimeInPastErrorMessage); } }); - + RuleFor(x => x.ScheduledDuration) .GreaterThan(0).WithMessage(NoScheduleDurationErrorMessage); diff --git a/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestInputValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestInputValidationV2.cs index 705d0f941..6a54eb186 100644 --- a/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestInputValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestInputValidationV2.cs @@ -1,5 +1,4 @@ using BookingsApi.Contract.V2.Requests; -using BookingsApi.Validations.Common; using FluentValidation; namespace BookingsApi.Validations.V2 @@ -17,19 +16,4 @@ public AddParticipantsToHearingRequestInputValidationV2() .SetValidator(new ParticipantRequestValidationV2()); } } - - public class AddParticipantsToHearingRequestDataValidationV2 : AbstractValidator - { - public AddParticipantsToHearingRequestDataValidationV2(CaseType caseType) - { - if (caseType == null) - { - return; - } - - var representativeRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsRepresentative).Select(x => x.Name).ToList(); - RuleForEach(request => request.Participants).Where(x => representativeRoles.Contains(x.HearingRoleName)) - .SetValidator(new RepresentativeValidation()); - } - } } \ No newline at end of file diff --git a/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestRefDataValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestRefDataValidationV2.cs new file mode 100644 index 000000000..fde3f6714 --- /dev/null +++ b/BookingsApi/BookingsApi/Validations/V2/AddParticipantsToHearingRequestRefDataValidationV2.cs @@ -0,0 +1,20 @@ +using BookingsApi.Contract.V2.Requests; +using BookingsApi.Validations.Common; +using FluentValidation; + +namespace BookingsApi.Validations.V2; + +public class AddParticipantsToHearingRequestRefDataValidationV2 : RefDataInputValidatorValidator +{ + public AddParticipantsToHearingRequestRefDataValidationV2(CaseType caseType) + { + if (caseType == null) + { + return; + } + + var representativeRoles = caseType.CaseRoles.SelectMany(x => x.HearingRoles).Where(x => x.UserRole.IsRepresentative).Select(x => x.Name).ToList(); + RuleForEach(request => request.Participants).Where(x => representativeRoles.Contains(x.HearingRoleName)) + .SetValidator(new RepresentativeValidation()); + } +} \ No newline at end of file diff --git a/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestInputValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestInputValidationV2.cs index 4d7e16119..d33f03711 100644 --- a/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestInputValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestInputValidationV2.cs @@ -1,4 +1,5 @@ using BookingsApi.Contract.V2.Requests; +using BookingsApi.Validations.Common; using BookingsApi.Validations.V1; using Castle.Core.Internal; using FluentValidation; @@ -61,6 +62,7 @@ public BookNewHearingRequestInputValidationV2() .When(x => x.Endpoints.Any()); RuleForEach(request => request.JudiciaryParticipants).SetValidator(new JudiciaryParticipantRequestValidation()); + RuleFor(x => x.CreatedBy).NotEmpty(); } } } \ No newline at end of file diff --git a/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestDataValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestRefDataValidationV2.cs similarity index 90% rename from BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestDataValidationV2.cs rename to BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestRefDataValidationV2.cs index 637361cb8..9651b53a0 100644 --- a/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestDataValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/BookNewHearingRequestRefDataValidationV2.cs @@ -1,11 +1,12 @@ using BookingsApi.Contract.V2.Requests; +using BookingsApi.Validations.Common; using FluentValidation; namespace BookingsApi.Validations.V2; -public class BookNewHearingRequestDataValidationV2 : AbstractValidator +public class BookNewHearingRequestRefDataValidationV2 : RefDataInputValidatorValidator { - public BookNewHearingRequestDataValidationV2(CaseType caseType, HearingVenue hearingVenue, List hearingRoles) + public BookNewHearingRequestRefDataValidationV2(CaseType caseType, HearingVenue hearingVenue, List hearingRoles) { RuleFor(x => x.ServiceId).Custom((_, context) => { diff --git a/BookingsApi/BookingsApi/Validations/V2/EndpointRequestValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/EndpointRequestValidationV2.cs index 666079578..afd561983 100644 --- a/BookingsApi/BookingsApi/Validations/V2/EndpointRequestValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/EndpointRequestValidationV2.cs @@ -13,7 +13,7 @@ public EndpointRequestValidationV2() // regex where only alphanumeric and underscore are allowed and maximum 255 characters var regex = "^([-A-Za-z0-9 ',._]){1,255}$"; - RuleFor(x => x.DisplayName).Matches(regex).WithMessage(InvalidDisplayNameErrorMessage); + RuleFor(x => x.DisplayName).NotEmpty().Matches(regex).WithMessage(InvalidDisplayNameErrorMessage); RuleFor(x => x.DefenceAdvocateContactEmail).Must(x => x.IsValidEmail()).When(x => x.DefenceAdvocateContactEmail != null) .WithMessage(InvalidDefenceAdvocateContactEmailError); } diff --git a/BookingsApi/BookingsApi/Validations/V2/LinkedParticipantRequestValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/LinkedParticipantRequestValidationV2.cs index d16f0d0c8..f12a2f69e 100644 --- a/BookingsApi/BookingsApi/Validations/V2/LinkedParticipantRequestValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/LinkedParticipantRequestValidationV2.cs @@ -13,7 +13,7 @@ public LinkedParticipantRequestValidationV2() { RuleFor(x => x.ParticipantContactEmail).NotEmpty().WithMessage(NoParticipantEmail); RuleFor(x => x.LinkedParticipantContactEmail).NotEmpty().WithMessage(NoLinkedParticipantEmail); - RuleFor(x => x.TypeV2).IsInEnum().WithMessage(InvalidType); + RuleFor(x => x.Type).NotEmpty().IsInEnum().WithMessage(InvalidType); } } } \ No newline at end of file diff --git a/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestInputValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestInputValidationV2.cs index 862fe5edc..20b168c8c 100644 --- a/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestInputValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestInputValidationV2.cs @@ -1,4 +1,5 @@ using BookingsApi.Contract.V2.Requests; +using BookingsApi.Validations.Common; using FluentValidation; namespace BookingsApi.Validations.V2 diff --git a/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestDataValidationV2.cs b/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestRefDataValidationV2.cs similarity index 88% rename from BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestDataValidationV2.cs rename to BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestRefDataValidationV2.cs index b69dc2ce2..68ae706e6 100644 --- a/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestDataValidationV2.cs +++ b/BookingsApi/BookingsApi/Validations/V2/UpdateHearingParticipantsRequestRefDataValidationV2.cs @@ -4,9 +4,9 @@ namespace BookingsApi.Validations.V2; -public class UpdateHearingParticipantsRequestDataValidationV2 : AbstractValidator +public class UpdateHearingParticipantsRequestRefDataValidationV2 : RefDataInputValidatorValidator { - public UpdateHearingParticipantsRequestDataValidationV2(CaseType caseType, List hearingRoles) + public UpdateHearingParticipantsRequestRefDataValidationV2(CaseType caseType, List hearingRoles) { RuleForEach(x=> x.NewParticipants).Custom((participant, context) => {