diff --git a/Api/Api.csproj b/Api/Api.csproj index ca1d4b8..b97550a 100644 --- a/Api/Api.csproj +++ b/Api/Api.csproj @@ -26,4 +26,8 @@ + + + + diff --git a/Api/Controllers/UserController.cs b/Api/Controllers/UserController.cs index dac9501..d8cad93 100644 --- a/Api/Controllers/UserController.cs +++ b/Api/Controllers/UserController.cs @@ -45,22 +45,21 @@ public IActionResult GetAllCourses() [HttpPut("RateCourse")] public async Task RateCourse(RateCourseRequest request) { - try - { - return Ok(await _userService.RateCourseAsync(request)); - } - catch (Exception exception) - { - return BadRequest(exception.Message); - } + return Ok(await _userService.RateCourseAsync(request)); } [HttpPost("MakeComment")] public async Task MakeComment(MakeCommentRequest request) + { + return Ok(await _userService.MakeCommentAsync(request)); + } + + [HttpGet("GetMyComments")] + public IActionResult GetMyComments(string userId) { try { - return Ok(await _userService.MakeCommentAsync(request)); + return Ok(_userService.GetMyComments(userId)); } catch (Exception exception) { @@ -68,13 +67,12 @@ public async Task MakeComment(MakeCommentRequest request) } } - - [HttpGet("GetMyComments")] - public IActionResult GetMyComments(string userId) + [HttpPut("AddCourseToFavourites")] + public IActionResult AddCourseToFavourites(AddCourseToFavRequest request) { try { - return Ok(_userService.GetMyComments(userId)); + return Ok(_userService.AddCourseToFavourites(request)); } catch (Exception exception) { diff --git a/Api/GlobalException/GlobalExceptionHandler.cs b/Api/GlobalException/GlobalExceptionHandler.cs new file mode 100644 index 0000000..52626f4 --- /dev/null +++ b/Api/GlobalException/GlobalExceptionHandler.cs @@ -0,0 +1,22 @@ +using Application.Exceptions; +using Microsoft.AspNetCore.Diagnostics; + +namespace Api.GlobalException; + +public class GlobalExceptionHandler : IExceptionHandler +{ + public async ValueTask TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) + { + (int statusCode, string errorMessage) = exception switch + { + InvalidRatingException => (StatusCodes.Status406NotAcceptable, "Rating must be between 1 and 5, Please provide correct number"), + UserNotFoundException => (StatusCodes.Status404NotFound, "Cannot find user, check user credentials"), + CourseNotFoundException => (StatusCodes.Status404NotFound, "Cannot find course, check course credentials"), + _ => (500, "Error occured, Try again.") + }; ; + + httpContext.Response.StatusCode = statusCode; + await httpContext.Response.WriteAsJsonAsync(errorMessage); + return true; + } +} diff --git a/Api/Program.cs b/Api/Program.cs index df94bba..0fa44fd 100644 --- a/Api/Program.cs +++ b/Api/Program.cs @@ -1,4 +1,5 @@ using Api.Extensions; +using Api.GlobalException; using Application.Models.Configurations; using Microsoft.EntityFrameworkCore; using Persistence.Context; @@ -15,6 +16,7 @@ builder.Services.AddRepositories(); builder.Services.AddAuthenticationAndAuthorization(builder.Configuration); builder.Services.AddSwagger(); +builder.Services.AddExceptionHandler(); var cosmos = new CosmosConfiguration(); builder.Configuration.GetSection("Cosmos").Bind(cosmos); builder.Services.Configure(builder.Configuration.GetSection("BlobStorage")); @@ -31,6 +33,8 @@ app.UseHttpsRedirection(); +app.UseExceptionHandler("/err"); + app.UseAuthorization(); app.MapControllers(); diff --git a/Core/Application/Application.csproj b/Core/Application/Application.csproj index 34ff80f..34320df 100644 --- a/Core/Application/Application.csproj +++ b/Core/Application/Application.csproj @@ -8,6 +8,8 @@ + + diff --git a/Core/Application/Exceptions/CourseNotFoundException.cs b/Core/Application/Exceptions/CourseNotFoundException.cs new file mode 100644 index 0000000..9e9dbce --- /dev/null +++ b/Core/Application/Exceptions/CourseNotFoundException.cs @@ -0,0 +1,9 @@ +namespace Application.Exceptions; + +public class CourseNotFoundException : Exception +{ + public CourseNotFoundException():base() + { + + } +} diff --git a/Core/Application/Exceptions/InvalidRatingException.cs b/Core/Application/Exceptions/InvalidRatingException.cs index f878df7..46b5140 100644 --- a/Core/Application/Exceptions/InvalidRatingException.cs +++ b/Core/Application/Exceptions/InvalidRatingException.cs @@ -2,11 +2,8 @@ public class InvalidRatingException : Exception { - public InvalidRatingException(string? message) : base(message) - { - } - - public InvalidRatingException(string? message, Exception? innerException) : base(message, innerException) + public InvalidRatingException() { + } } diff --git a/Core/Application/Exceptions/UserNotFoundException.cs b/Core/Application/Exceptions/UserNotFoundException.cs new file mode 100644 index 0000000..60e88c3 --- /dev/null +++ b/Core/Application/Exceptions/UserNotFoundException.cs @@ -0,0 +1,12 @@ +namespace Application.Exceptions; + +public class UserNotFoundException : Exception +{ + public UserNotFoundException(string? message) : base(message) + { + } + + public UserNotFoundException(string? message, Exception? innerException) : base(message, innerException) + { + } +} diff --git a/Core/Application/Models/Requests/AddCourseToFavRequest.cs b/Core/Application/Models/Requests/AddCourseToFavRequest.cs new file mode 100644 index 0000000..f78bcc4 --- /dev/null +++ b/Core/Application/Models/Requests/AddCourseToFavRequest.cs @@ -0,0 +1,8 @@ +namespace Application.Models.Requests; + +public class AddCourseToFavRequest +{ + public string CourseId { get; set; } + public string UserId { get; set; } + +} diff --git a/Core/Application/Services/IHostService.cs b/Core/Application/Services/IHostService.cs index 4818c3a..49e3f99 100644 --- a/Core/Application/Services/IHostService.cs +++ b/Core/Application/Services/IHostService.cs @@ -11,6 +11,5 @@ public interface IHostService Task RemoveCourseAsync(string courseId); Task BanUser(string userId); - Task ConfirmAndRemoveAccount(RemoveMyAccountRequest request); } diff --git a/Core/Application/Services/IUserService.cs b/Core/Application/Services/IUserService.cs index 4300ab0..b796c01 100644 --- a/Core/Application/Services/IUserService.cs +++ b/Core/Application/Services/IUserService.cs @@ -10,4 +10,5 @@ public interface IUserService IEnumerable GetAllBooks(); Task RateCourseAsync(RateCourseRequest request); Task MakeCommentAsync(MakeCommentRequest request); + Task AddCourseToFavourites(AddCourseToFavRequest request); } diff --git a/Infrastructure/Infrastructure/Services/UserService.cs b/Infrastructure/Infrastructure/Services/UserService.cs index 1284755..cbc9e62 100644 --- a/Infrastructure/Infrastructure/Services/UserService.cs +++ b/Infrastructure/Infrastructure/Services/UserService.cs @@ -89,7 +89,7 @@ public async Task MakeCommentAsync(MakeCommentRequest request) var course = await _unitOfWork.ReadCourseRepository.GetAsync(request.CourseId); if (user == null || course == null) - return false; + throw new UserNotFoundException("Cannot find user"); var newComment = CreateNewComment(request); @@ -111,16 +111,10 @@ private async Task AddNewComment(Comment newComment) public async Task RateCourseAsync(RateCourseRequest request) { if (request.Rate > 5 || request.Rate < 1) - { - throw new InvalidRatingException("The rating value must be between 1 and 5. Please provide a valid rating."); - } - - var course = await _unitOfWork.ReadCourseRepository.GetAsync(request.CourseId); + throw new InvalidRatingException(); - if (course is null) - { - throw new ArgumentNullException(nameof(course)); - } + var course = await _unitOfWork.ReadCourseRepository.GetAsync(request.CourseId)?? + throw new CourseNotFoundException(); course.Rating = course.RatingsCount == 0 ? request.Rate : (course.Rating + request.Rate) / course.RatingsCount++; var result = _unitOfWork.WriteCourseRepository.Update(course); @@ -128,6 +122,23 @@ public async Task RateCourseAsync(RateCourseRequest request) return result; } + public async Task AddCourseToFavourites(AddCourseToFavRequest request) + { + var course = await _unitOfWork.ReadCourseRepository.GetAsync(request.CourseId) ?? throw new NullReferenceException(); + course.FavCount++; + + var user = await _unitOfWork.ReadUserRepository.GetAsync(request.UserId); + user.FavouritesIds.Add(course.Id); + + await _unitOfWork.WriteUserRepository.UpdateAsync(user.Id); + await _unitOfWork.WriteCourseRepository.UpdateAsync(course.Id); + + await _unitOfWork.WriteUserRepository.SaveChangesAsync(); + + return true; + } + + // Helper Methods private Comment CreateNewComment(MakeCommentRequest request) @@ -147,5 +158,4 @@ private void UpdateUserAndCourseComments(User user, Course course, Comment newCo user.CommentIds.Add(newComment.Id); course.CommentIds.Add(newComment.Id); } - }