Skip to content

Commit

Permalink
Merge pull request #24 from CS3203-SEP-21-Group-22/dev1
Browse files Browse the repository at this point in the history
fluent validation changes
  • Loading branch information
SharadaShehan authored Sep 20, 2024
2 parents 23a2ba9 + 7445a62 commit d311d63
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 42 deletions.
8 changes: 6 additions & 2 deletions IMS.Presentation/Controllers/AdminControllers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ public class AdminController : ControllerBase
private readonly ITokenParser _tokenParser;
private readonly ILogger<AdminController> _logger;
private readonly IValidator<UpdateLabDTO> _updateLabDTOValidator;
private readonly IValidator<CreateLabDTO> _createLabDTOValidator;
private readonly UserService _userService;
private readonly LabService _labService;

public AdminController(
DataBaseContext dbContext,
ILogger<AdminController> logger,
IValidator<UpdateLabDTO> updateLabDTOValidator,
IValidator<CreateLabDTO> createLabDTOValidator,
ITokenParser tokenParser,
UserService userService,
LabService labService
Expand All @@ -32,6 +34,7 @@ LabService labService
_dbContext = dbContext;
_logger = logger;
_updateLabDTOValidator = updateLabDTOValidator;
_createLabDTOValidator = createLabDTOValidator;
_tokenParser = tokenParser;
_userService = userService;
_labService = labService;
Expand Down Expand Up @@ -78,8 +81,9 @@ public async Task<ActionResult<LabDTO>> CreateLab(CreateLabDTO createLabDTO)
try
{
// Validate the DTO
if (!ModelState.IsValid)
BadRequest(ModelState);
var result = await _createLabDTOValidator.ValidateAsync(createLabDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Create the Lab
ResponseDTO<LabDTO> responseDTO = _labService.CreateNewLab(createLabDTO);
if (!responseDTO.success)
Expand Down
52 changes: 39 additions & 13 deletions IMS.Presentation/Controllers/ClerkControllers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Diagnostics;
using FluentValidation;
using IMS.Application.DTO;
using IMS.Application.Services;
using IMS.Presentation.Filters;
Expand All @@ -14,6 +14,12 @@ public class ClerkController : ControllerBase
private readonly ITokenParser _tokenParser;
private readonly IQRTokenProvider _qRTokenProvider;
private readonly ILogger<ClerkController> _logger;
private readonly IValidator<CreateEquipmentDTO> _createEquipmentValidator;
private readonly IValidator<UpdateEquipmentDTO> _updateEquipmentValidator;
private readonly IValidator<CreateItemDTO> _createItemValidator;
private readonly IValidator<CreateMaintenanceDTO> _createMaintenanceValidator;
private readonly IValidator<ReviewMaintenanceDTO> _reviewMaintenanceValidator;
private readonly IValidator<RespondReservationDTO> _respondReservationValidator;
private readonly EquipmentService _equipmentService;
private readonly ItemService _itemService;
private readonly MaintenanceService _maintenanceService;
Expand All @@ -23,6 +29,12 @@ public ClerkController(
ITokenParser tokenParser,
IQRTokenProvider qRTokenProvider,
ILogger<ClerkController> logger,
IValidator<CreateEquipmentDTO> createEquipmentValidator,
IValidator<UpdateEquipmentDTO> updateEquipmentValidator,
IValidator<CreateItemDTO> createItemValidator,
IValidator<CreateMaintenanceDTO> createMaintenanceValidator,
IValidator<ReviewMaintenanceDTO> reviewMaintenanceValidator,
IValidator<RespondReservationDTO> respondReservationValidator,
EquipmentService equipmentService,
ItemService itemService,
MaintenanceService maintenanceService,
Expand All @@ -32,6 +44,12 @@ ReservationService reservationService
_tokenParser = tokenParser;
_qRTokenProvider = qRTokenProvider;
_logger = logger;
_createEquipmentValidator = createEquipmentValidator;
_updateEquipmentValidator = updateEquipmentValidator;
_createItemValidator = createItemValidator;
_createMaintenanceValidator = createMaintenanceValidator;
_reviewMaintenanceValidator = reviewMaintenanceValidator;
_respondReservationValidator = respondReservationValidator;
_equipmentService = equipmentService;
_itemService = itemService;
_maintenanceService = maintenanceService;
Expand All @@ -47,8 +65,9 @@ CreateEquipmentDTO createEquipmentDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _createEquipmentValidator.ValidateAsync(createEquipmentDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Create the Equipment
ResponseDTO<EquipmentDetailedDTO> responseDTO =
_equipmentService.CreateNewEquipment(createEquipmentDTO);
Expand All @@ -72,8 +91,9 @@ UpdateEquipmentDTO updateEquipmentDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _updateEquipmentValidator.ValidateAsync(updateEquipmentDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Update the Equipment
ResponseDTO<EquipmentDetailedDTO> responseDTO = _equipmentService.UpdateEquipment(
id,
Expand Down Expand Up @@ -116,8 +136,9 @@ public async Task<ActionResult<ItemDetailedDTO>> CreateItem(CreateItemDTO create
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _createItemValidator.ValidateAsync(createItemDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Create the Item
ResponseDTO<ItemDetailedDTO> responseDTO = _itemService.CreateNewItem(
createItemDTO
Expand Down Expand Up @@ -159,8 +180,9 @@ CreateMaintenanceDTO createMaintenanceDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _createMaintenanceValidator.ValidateAsync(createMaintenanceDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Get the User from the token
UserDTO? clerkDto = await _tokenParser.getUser(
HttpContext.Request.Headers["Authorization"].FirstOrDefault()
Expand Down Expand Up @@ -190,8 +212,9 @@ ReviewMaintenanceDTO reviewMaintenanceDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _reviewMaintenanceValidator.ValidateAsync(reviewMaintenanceDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Get the User from the token
UserDTO? clerkDto = await _tokenParser.getUser(
HttpContext.Request.Headers["Authorization"].FirstOrDefault()
Expand Down Expand Up @@ -273,8 +296,11 @@ RespondReservationDTO respondReservationDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _respondReservationValidator.ValidateAsync(
respondReservationDTO
);
if (!result.IsValid)
return BadRequest(result.Errors);
// Get the User from the token
UserDTO? clerkDto = await _tokenParser.getUser(
HttpContext.Request.Headers["Authorization"].FirstOrDefault()
Expand Down
21 changes: 15 additions & 6 deletions IMS.Presentation/Controllers/ImgUploadControllers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Text.Json;
using FluentValidation;
using IMS.Application.DTO;
using IMS.Infrastructure.Services;
using IMS.Presentation.Filters;
Expand All @@ -12,14 +12,17 @@ public class ImgUploadControllers : ControllerBase
{
private readonly IBlobStorageClient _blobStorageClient;
private readonly ILogger<ImgUploadControllers> _logger;
private readonly IValidator<PresignedUrlRequestDTO> _presignedUrlRequestValidator;

public ImgUploadControllers(
IBlobStorageClient blobStorageClient,
ILogger<ImgUploadControllers> logger
ILogger<ImgUploadControllers> logger,
IValidator<PresignedUrlRequestDTO> presignedUrlRequestValidator
)
{
_blobStorageClient = blobStorageClient;
_logger = logger;
_presignedUrlRequestValidator = presignedUrlRequestValidator;
}

[HttpPost("lab")]
Expand All @@ -31,8 +34,11 @@ PresignedUrlRequestDTO presignedUrlRequestDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _presignedUrlRequestValidator.ValidateAsync(
presignedUrlRequestDTO
);
if (!result.IsValid)
return BadRequest(result.Errors);
// Generate the presigned URL
string blobName =
"labs/"
Expand Down Expand Up @@ -61,8 +67,11 @@ PresignedUrlRequestDTO presignedUrlRequestDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _presignedUrlRequestValidator.ValidateAsync(
presignedUrlRequestDTO
);
if (!result.IsValid)
return BadRequest(result.Errors);
// Generate the presigned URL
string blobName =
"equipments/"
Expand Down
10 changes: 7 additions & 3 deletions IMS.Presentation/Controllers/StudentControllers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Diagnostics;
using FluentValidation;
using IMS.Application.DTO;
using IMS.Application.Services;
using IMS.Presentation.Filters;
Expand All @@ -14,20 +14,23 @@ public class StudentController : ControllerBase
private readonly ITokenParser _tokenParser;
private readonly IQRTokenProvider _qRTokenProvider;
private readonly ILogger<StudentController> _logger;
private readonly IValidator<RequestEquipmentDTO> _requestEquipmentValidator;
private readonly ReservationService _reservationService;
private readonly UserService _userService;

public StudentController(
ITokenParser tokenParser,
IQRTokenProvider qRTokenProvider,
ILogger<StudentController> logger,
IValidator<RequestEquipmentDTO> requestEquipmentValidator,
ReservationService reservationService,
UserService userService
)
{
_tokenParser = tokenParser;
_qRTokenProvider = qRTokenProvider;
_logger = logger;
_requestEquipmentValidator = requestEquipmentValidator;
_reservationService = reservationService;
_userService = userService;
}
Expand All @@ -41,8 +44,9 @@ RequestEquipmentDTO requestEquipmentDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _requestEquipmentValidator.ValidateAsync(requestEquipmentDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Get the User from auth token
UserDTO? studentDto = await _tokenParser.getUser(
HttpContext.Request.Headers["Authorization"].FirstOrDefault()
Expand Down
11 changes: 8 additions & 3 deletions IMS.Presentation/Controllers/TechnicianControllers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using IMS.Application.DTO;
using FluentValidation;
using IMS.Application.DTO;
using IMS.Application.Services;
using IMS.Presentation.Filters;
using IMS.Presentation.Services;
Expand All @@ -12,16 +13,19 @@ public class TechnicianController : ControllerBase
{
private readonly ITokenParser _tokenParser;
private readonly ILogger<TechnicianController> _logger;
private readonly IValidator<SubmitMaintenanceDTO> _submitMaintenanceValidator;
private readonly MaintenanceService _maintenanceService;

public TechnicianController(
ITokenParser tokenParser,
ILogger<TechnicianController> logger,
IValidator<SubmitMaintenanceDTO> submitMaintenanceValidator,
MaintenanceService maintenanceService
)
{
_tokenParser = tokenParser;
_logger = logger;
_submitMaintenanceValidator = submitMaintenanceValidator;
_maintenanceService = maintenanceService;
}

Expand Down Expand Up @@ -86,8 +90,9 @@ SubmitMaintenanceDTO submitMaintenanceDTO
try
{
// Validate the DTO
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _submitMaintenanceValidator.ValidateAsync(submitMaintenanceDTO);
if (!result.IsValid)
return BadRequest(result.Errors);
// Get the User from auth token
UserDTO? technicianDto = await _tokenParser.getUser(
HttpContext.Request.Headers["Authorization"].FirstOrDefault()
Expand Down
14 changes: 10 additions & 4 deletions IMS.Presentation/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using FluentValidation;
using FluentValidation.AspNetCore;
using IMS.Application.DTO;
using IMS.Application.Interfaces;
using IMS.Application.Services;
Expand Down Expand Up @@ -32,9 +31,16 @@

builder.Services.AddControllers();

builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddFluentValidationClientsideAdapters();
builder.Services.AddValidatorsFromAssemblyContaining<UpdateLabValidator>();
builder.Services.AddScoped<IValidator<CreateEquipmentDTO>, CreateEquipmentValidator>();
builder.Services.AddScoped<IValidator<CreateItemDTO>, CreateItemValidator>();
builder.Services.AddScoped<IValidator<CreateLabDTO>, CreateLabValidator>();
builder.Services.AddScoped<IValidator<CreateMaintenanceDTO>, CreateMaintenanceValidator>();
builder.Services.AddScoped<IValidator<PresignedUrlRequestDTO>, PreSignedUrlGenValidator>();
builder.Services.AddScoped<IValidator<RequestEquipmentDTO>, RequestEquipmentValidator>();
builder.Services.AddScoped<IValidator<RespondReservationDTO>, RespondReservationValidator>();
builder.Services.AddScoped<IValidator<ReviewMaintenanceDTO>, ReviewMaintenanceValidator>();
builder.Services.AddScoped<IValidator<SubmitMaintenanceDTO>, SubmitMaintenanceValidator>();
builder.Services.AddScoped<IValidator<UpdateEquipmentDTO>, UpdateEquipmentValidator>();
builder.Services.AddScoped<IValidator<UpdateLabDTO>, UpdateLabValidator>();

builder.Services.AddEndpointsApiExplorer();
Expand Down
1 change: 0 additions & 1 deletion IMS.Presentation/Validators/CreateItemValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace IMS.Presentation.Validators
public class CreateItemValidator : AbstractValidator<CreateItemDTO>
{
private readonly string textPattern = @"^.{2,20}$";
private readonly string imageUrlPattern = @"^https?:\/\/.*\.(?:png|jpg|jpeg|webp)$";

public CreateItemValidator()
{
Expand Down
4 changes: 2 additions & 2 deletions IMS.Presentation/Validators/CreateLabValidator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using FluentValidation;
using System.Text.RegularExpressions;
using FluentValidation;
using IMS.Application.DTO;
using System.Text.RegularExpressions;

namespace IMS.Presentation.Validators
{
Expand Down
2 changes: 1 addition & 1 deletion IMS.Presentation/Validators/RespondReservationValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public RespondReservationValidator()
RuleFor(x => x.accepted).NotNull().WithMessage("Accepted status is required.");

When(
x => !x.accepted,
x => !(x.accepted),
() =>
{
RuleFor(x => x.rejectNote)
Expand Down
8 changes: 4 additions & 4 deletions IMS.Presentation/Validators/SubmitMaintenanceValidator.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using FluentValidation;
using IMS.Application.DTO;
using System.Text.RegularExpressions;

namespace IMS.Presentation.Validators
{
Expand All @@ -11,16 +12,15 @@ public SubmitMaintenanceValidator()
{
// Validate submitNote (optional)
RuleFor(x => x.submitNote)
.Cascade(CascadeMode.Stop)
.Matches(notePattern)
.Must(x => x == null || Regex.IsMatch(x, notePattern))
.WithMessage("Invalid Submit Note. Must be between 1 and 100 characters.")
.When(x => !string.IsNullOrEmpty(x.submitNote));
.When(x => x != null);

// Validate cost (optional)
RuleFor(x => x.cost)
.GreaterThan(0)
.WithMessage("Invalid Cost Value. Cost must be a positive integer.")
.When(x => x.cost.HasValue);
.When(x => x != null);
}
}
}
6 changes: 3 additions & 3 deletions IMS.Presentation/Validators/UpdateLabValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ public UpdateLabValidator()
{
// Validate labName
RuleFor(x => x.labName)
.Must(x => (x == null) || Regex.IsMatch(x, textPattern))
.Must(x => x == null || Regex.IsMatch(x, textPattern))
.WithMessage("Invalid Lab Name. Must be between 2 and 20 characters.")
.When(x => x != null);

// Validate labCode
RuleFor(x => x.labCode)
.Must(x => (x == null) || Regex.IsMatch(x, textPattern))
.Must(x => x == null || Regex.IsMatch(x, textPattern))
.WithMessage("Invalid Lab Code. Must be between 2 and 20 characters.")
.When(x => x != null);

// Validate imageURL (optional)
RuleFor(x => x.imageURL)
.Must(x => (x == null) || Regex.IsMatch(x, imageUrlPattern))
.Must(x => x == null || Regex.IsMatch(x, imageUrlPattern))
.WithMessage(
"Invalid Image URL. Must be a valid URL ending with png, jpg, jpeg, or webp."
)
Expand Down

0 comments on commit d311d63

Please sign in to comment.