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) =>
{