From 8db0ee58c43bc3ad634963bcaaf58da3b2b677f4 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Fri, 8 Oct 2021 11:57:20 +0300 Subject: [PATCH 1/8] Initial commit, needs basic testing Add ICourseRules Rewrite validator in AddCourseCommand.cs, RemoveCourseByIdCommand.cs and GetCourseByIdQuery.cs --- .../Commands/AddCourseCommand.cs | 20 +++++++++++++++++++ .../Commands/RemoveCourseByIdCommand.cs | 17 +++++++++++----- .../Queries/GetCourseByIdQuery.cs | 17 +++++++++++----- .../ValidationRules/ICourseRules.cs | 13 ++++++++++++ 4 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs diff --git a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs index f0fd2e6..bf19a4c 100644 --- a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs @@ -1,7 +1,9 @@ using System.Threading; using System.Threading.Tasks; +using FluentValidation; using MediatR; using Microsoft.EntityFrameworkCore; +using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; @@ -15,6 +17,24 @@ public sealed class AddCourseCommand : IRequest public int TeacherId { get; set; } } + public class AddCourseCommandValidator : AbstractValidator + { + public AddCourseCommandValidator(ICourseRules rules) + { + RuleFor(_ => _.Name) + .NotEmpty() + .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.Name))) + .MustAsync((_, token) => rules.IsNameUniqueAsync(_, token)) + .WithMessage(_ => string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), _.Name)); + + RuleFor(_ => _.TeacherId) + .NotEmpty() + .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.TeacherId))) + .MustAsync((_, token) => rules.IsTeacherIdExistAsync(_, token)) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), _.TeacherId)); + } + } + public sealed class AddCourseCommandHandler : IRequestHandler { private readonly StudySharpDbContext _context; diff --git a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs index 0262e8a..a1c7a46 100644 --- a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs @@ -1,6 +1,8 @@ using System.Threading; using System.Threading.Tasks; +using FluentValidation; using MediatR; +using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; @@ -13,6 +15,16 @@ public sealed class RemoveCourseByIdCommand : IRequest public int Id { get; set; } } + public class RemoveCourseByIdCommandValidator : AbstractValidator + { + public RemoveCourseByIdCommandValidator(ICourseRules rules) + { + RuleFor(_ => _.Id) + .MustAsync((_, token) => rules.IsCourseIdExistAsync(_, token)) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); + } + } + public sealed class RemoveCourseByIdCommandHandler : IRequestHandler { private readonly StudySharpDbContext _context; @@ -25,11 +37,6 @@ public RemoveCourseByIdCommandHandler(StudySharpDbContext sharpDbContext) public async Task Handle(RemoveCourseByIdCommand request, CancellationToken cancellationToken) { var course = await _context.Courses.FindAsync(request.Id, cancellationToken); - if (course == null) - { - return OperationResult.Fail(string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Name), request.Id)); - } - _context.Courses.Remove(course); await _context.SaveChangesAsync(cancellationToken); return OperationResult.Ok(); diff --git a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs index ca14897..3ac8e03 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs @@ -1,6 +1,8 @@ using System.Threading; using System.Threading.Tasks; +using FluentValidation; using MediatR; +using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; @@ -13,6 +15,16 @@ public sealed class GetCourseByIdQuery : IRequest> public int Id { get; set; } } + public class GetCourseByIdQueryValidator : AbstractValidator + { + public GetCourseByIdQueryValidator(ICourseRules rules) + { + RuleFor(_ => _.Id) + .MustAsync((_, token) => rules.IsCourseIdExistAsync(_, token)) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); + } + } + public sealed class GetCourseByIdQueryHandler : IRequestHandler> { private readonly StudySharpDbContext _context; @@ -25,11 +37,6 @@ public GetCourseByIdQueryHandler(StudySharpDbContext studySharpDbContext) public async Task> Handle(GetCourseByIdQuery request, CancellationToken cancellationToken) { var course = await _context.Courses.FindAsync(request.Id, cancellationToken); - if (course == null) - { - return OperationResult.Fail(string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), request.Id)); - } - return OperationResult.Ok(course); } } diff --git a/server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs b/server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs new file mode 100644 index 0000000..ee5b557 --- /dev/null +++ b/server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs @@ -0,0 +1,13 @@ +using System.Threading; +using System.Threading.Tasks; +using FluentValidation; + +namespace StudySharp.ApplicationServices.ValidationRules +{ + public interface ICourseRules : IValidationRule + { + Task IsCourseIdExistAsync(int id, CancellationToken cancellationToken); + Task IsTeacherIdExistAsync(int teacherId, CancellationToken cancellationToken); + Task IsNameUniqueAsync(string name, CancellationToken cancellationToken); + } +} \ No newline at end of file From 7351b744d5b750307110e33a0fe67a344a81b388 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Fri, 8 Oct 2021 12:23:22 +0300 Subject: [PATCH 2/8] Little rework of CourseRules --- .../Commands/AddCourseCommand.cs | 1 + .../Commands/RemoveCourseByIdCommand.cs | 1 + .../Queries/GetCourseByIdQuery.cs | 1 + .../ValidationRules/CourseRules.cs | 33 +++++++++++++++++++ .../ValidationRules/ICourseRules.cs | 3 +- 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs rename server/{StudySharp.ApplicationServices => StudySharp.Domain}/ValidationRules/ICourseRules.cs (82%) diff --git a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs index bf19a4c..a7a83be 100644 --- a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs @@ -7,6 +7,7 @@ using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; +using StudySharp.Domain.ValidationRules; using StudySharp.DomainServices; namespace StudySharp.ApplicationServices.Commands diff --git a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs index a1c7a46..0845f59 100644 --- a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs @@ -6,6 +6,7 @@ using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; +using StudySharp.Domain.ValidationRules; using StudySharp.DomainServices; namespace StudySharp.ApplicationServices.Commands diff --git a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs index 3ac8e03..0e7b52e 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs @@ -6,6 +6,7 @@ using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; +using StudySharp.Domain.ValidationRules; using StudySharp.DomainServices; namespace StudySharp.ApplicationServices.Queries diff --git a/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs b/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs new file mode 100644 index 0000000..c877c57 --- /dev/null +++ b/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs @@ -0,0 +1,33 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using StudySharp.Domain.ValidationRules; +using StudySharp.DomainServices; + +namespace StudySharp.ApplicationServices.ValidationRules +{ + public class CourseRules : ICourseRules + { + private readonly StudySharpDbContext _context; + + public CourseRules(StudySharpDbContext context) + { + _context = context; + } + + public async Task IsNameUniqueAsync(string name, CancellationToken cancellationToken) + { + return !await _context.Courses.AnyAsync(_ => _.Name == name, cancellationToken); + } + + public async Task IsCourseIdExistAsync(int id, CancellationToken cancellationToken) + { + return await _context.Courses.AnyAsync(_ => _.Id == id, cancellationToken); + } + + public async Task IsTeacherIdExistAsync(int teacherId, CancellationToken cancellationToken) + { + return await _context.Teachers.AnyAsync(_ => _.Id == teacherId, cancellationToken); + } + } +} \ No newline at end of file diff --git a/server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs b/server/StudySharp.Domain/ValidationRules/ICourseRules.cs similarity index 82% rename from server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs rename to server/StudySharp.Domain/ValidationRules/ICourseRules.cs index ee5b557..09fe0ee 100644 --- a/server/StudySharp.ApplicationServices/ValidationRules/ICourseRules.cs +++ b/server/StudySharp.Domain/ValidationRules/ICourseRules.cs @@ -1,8 +1,7 @@ using System.Threading; using System.Threading.Tasks; -using FluentValidation; -namespace StudySharp.ApplicationServices.ValidationRules +namespace StudySharp.Domain.ValidationRules { public interface ICourseRules : IValidationRule { From 9303b2d8857cbff8b79121241463f26760f5cb1b Mon Sep 17 00:00:00 2001 From: zefirlover Date: Sun, 10 Oct 2021 20:19:55 +0300 Subject: [PATCH 3/8] GetCourseByIdQuery.cs rework --- .../Queries/GetCourseByIdQuery.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs index 0e7b52e..782b99a 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs @@ -21,7 +21,7 @@ public class GetCourseByIdQueryValidator : AbstractValidator public GetCourseByIdQueryValidator(ICourseRules rules) { RuleFor(_ => _.Id) - .MustAsync((_, token) => rules.IsCourseIdExistAsync(_, token)) + .MustAsync(rules.IsCourseIdExistAsync) .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); } } @@ -37,7 +37,7 @@ public GetCourseByIdQueryHandler(StudySharpDbContext studySharpDbContext) public async Task> Handle(GetCourseByIdQuery request, CancellationToken cancellationToken) { - var course = await _context.Courses.FindAsync(request.Id, cancellationToken); + var course = await _context.Courses.FindAsync(request.Id); return OperationResult.Ok(course); } } From 3df906e8c1c9f3951ab55d6f52a1c4240d2d4a59 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Sun, 10 Oct 2021 23:18:58 +0300 Subject: [PATCH 4/8] Validation rewrite for Update and GetByTeacherId --- .../Controllers/CourseController.cs | 1 + .../Commands/AddCourseCommand.cs | 8 ++--- .../Commands/RemoveCourseByIdCommand.cs | 4 +-- .../Commands/UpdateCourseCommand.cs | 35 +++++++++++++------ .../Queries/GetCourseByIdQuery.cs | 2 +- .../Queries/GetCoursesByTeacherIdQuery.cs | 18 ++++++---- 6 files changed, 43 insertions(+), 25 deletions(-) diff --git a/server/StudySharp.API/Controllers/CourseController.cs b/server/StudySharp.API/Controllers/CourseController.cs index 9c60e5d..39b27ae 100644 --- a/server/StudySharp.API/Controllers/CourseController.cs +++ b/server/StudySharp.API/Controllers/CourseController.cs @@ -47,6 +47,7 @@ public async Task> GetCourseById([FromRou return OperationResult.Ok(response); } + // did not work because of mapper exception (wtf) [HttpGet] [Route("~/api/teachers/{teacherId:int}/courses")] public async Task> GetCoursesByTeacherId([FromRoute] GetCoursesByTeacherIdRequest getCoursesByTeacherIdRequest) diff --git a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs index a7a83be..7f34400 100644 --- a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs @@ -25,13 +25,13 @@ public AddCourseCommandValidator(ICourseRules rules) RuleFor(_ => _.Name) .NotEmpty() .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.Name))) - .MustAsync((_, token) => rules.IsNameUniqueAsync(_, token)) + .MustAsync(rules.IsNameUniqueAsync) .WithMessage(_ => string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), _.Name)); RuleFor(_ => _.TeacherId) .NotEmpty() .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.TeacherId))) - .MustAsync((_, token) => rules.IsTeacherIdExistAsync(_, token)) + .MustAsync(rules.IsTeacherIdExistAsync) .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), _.TeacherId)); } } @@ -47,9 +47,7 @@ public AddCourseCommandHandler(StudySharpDbContext sharpDbContext) public async Task Handle(AddCourseCommand request, CancellationToken cancellationToken) { - if (await _context.Courses.AnyAsync( - _ => _.Name.ToLower().Equals(request.Name.ToLower()) && _.TeacherId == request.TeacherId, - cancellationToken)) + if (await _context.Courses.AnyAsync(_ => _.Name.ToLower().Equals(request.Name.ToLower()) && _.TeacherId == request.TeacherId)) { return OperationResult.Fail(string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), request.Name)); } diff --git a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs index 0845f59..92f129b 100644 --- a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs @@ -21,7 +21,7 @@ public class RemoveCourseByIdCommandValidator : AbstractValidator _.Id) - .MustAsync((_, token) => rules.IsCourseIdExistAsync(_, token)) + .MustAsync(rules.IsCourseIdExistAsync) .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); } } @@ -37,7 +37,7 @@ public RemoveCourseByIdCommandHandler(StudySharpDbContext sharpDbContext) public async Task Handle(RemoveCourseByIdCommand request, CancellationToken cancellationToken) { - var course = await _context.Courses.FindAsync(request.Id, cancellationToken); + var course = await _context.Courses.FindAsync(request.Id); _context.Courses.Remove(course); await _context.SaveChangesAsync(cancellationToken); return OperationResult.Ok(); diff --git a/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs index 4b0d390..39bc893 100644 --- a/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs @@ -1,10 +1,12 @@ using System.Threading; using System.Threading.Tasks; +using FluentValidation; using MediatR; using Microsoft.EntityFrameworkCore; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; +using StudySharp.Domain.ValidationRules; using StudySharp.DomainServices; namespace StudySharp.ApplicationServices.Commands @@ -16,6 +18,28 @@ public class UpdateCourseCommand : IRequest public int TeacherId { get; set; } } + public partial class UpdateCourseCommandValidator : AbstractValidator + { + public UpdateCourseCommandValidator(ICourseRules rules) + { + RuleFor(_ => _.Id) + .MustAsync(rules.IsCourseIdExistAsync) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); + + RuleFor(_ => _.Name) + .NotEmpty() + .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.Name))) + .MustAsync(rules.IsNameUniqueAsync) + .WithMessage(_ => string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), _.Name)); + + RuleFor(_ => _.TeacherId) + .NotEmpty() + .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.TeacherId))) + .MustAsync(rules.IsTeacherIdExistAsync) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), _.TeacherId)); + } + } + public sealed class UpdateCourseCommandHandler : IRequestHandler { private readonly StudySharpDbContext _context; @@ -28,17 +52,6 @@ public UpdateCourseCommandHandler(StudySharpDbContext sharpDbContext) public async Task Handle(UpdateCourseCommand request, CancellationToken cancellationToken) { var course = await _context.Courses.FirstOrDefaultAsync(_ => _.Id == request.Id, cancellationToken); - if (course == null) - { - return OperationResult.Fail(string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), request.Id)); - } - - var teacherExistent = await _context.Teachers.AnyAsync(_ => _.Id == request.TeacherId, cancellationToken); - if (!teacherExistent) - { - return OperationResult.Fail(string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), request.TeacherId)); - } - course.Name = request.Name; course.TeacherId = request.TeacherId; diff --git a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs index 782b99a..81e5f08 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs @@ -16,7 +16,7 @@ public sealed class GetCourseByIdQuery : IRequest> public int Id { get; set; } } - public class GetCourseByIdQueryValidator : AbstractValidator + public partial class GetCourseByIdQueryValidator : AbstractValidator { public GetCourseByIdQueryValidator(ICourseRules rules) { diff --git a/server/StudySharp.ApplicationServices/Queries/GetCoursesByTeacherIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCoursesByTeacherIdQuery.cs index 8387543..6292319 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCoursesByTeacherIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCoursesByTeacherIdQuery.cs @@ -2,11 +2,13 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using FluentValidation; using MediatR; using Microsoft.EntityFrameworkCore; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; +using StudySharp.Domain.ValidationRules; using StudySharp.DomainServices; namespace StudySharp.ApplicationServices.Queries @@ -16,6 +18,16 @@ public sealed class GetCoursesByTeacherIdQuery : IRequest + { + public GetCoursesByTeacherIdQueryValidator(ICourseRules rules) + { + RuleFor(_ => _.TeacherId) + .MustAsync(rules.IsTeacherIdExistAsync) + .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), _.TeacherId)); + } + } + public sealed class GetCoursesByTeacherIdQueryHandler : IRequestHandler>> { private readonly StudySharpDbContext _context; @@ -27,12 +39,6 @@ public GetCoursesByTeacherIdQueryHandler(StudySharpDbContext studySharpDbContext public async Task>> Handle(GetCoursesByTeacherIdQuery request, CancellationToken cancellationToken) { - var isTeacherExistent = await _context.Teachers.AnyAsync(_ => _.Id == request.TeacherId, cancellationToken); - if (!isTeacherExistent) - { - return OperationResult.Fail>(string.Format(ErrorConstants.EntityNotFound, nameof(Teacher), nameof(Teacher.Id), request.TeacherId)); - } - var courses = await _context.Courses.Where(_ => _.TeacherId == request.TeacherId).ToListAsync(cancellationToken); return OperationResult.Ok(courses); } From 88609c156807adf6d15479497ef73c5093d68959 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Sat, 16 Oct 2021 19:35:23 +0300 Subject: [PATCH 5/8] Pull update from dev --- server/StudySharp.API/Controllers/CourseController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/server/StudySharp.API/Controllers/CourseController.cs b/server/StudySharp.API/Controllers/CourseController.cs index 2942ca4..d2b3641 100644 --- a/server/StudySharp.API/Controllers/CourseController.cs +++ b/server/StudySharp.API/Controllers/CourseController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using AutoMapper; using MediatR; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using StudySharp.API.Requests.Courses; using StudySharp.API.Requests.PracticalBlocks; From e31b49632a7c621350350c4b89db7e3c71094859 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Tue, 19 Oct 2021 00:35:36 +0300 Subject: [PATCH 6/8] Final pre-review changes in CourseController.cs --- server/StudySharp.API/Controllers/CourseController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/StudySharp.API/Controllers/CourseController.cs b/server/StudySharp.API/Controllers/CourseController.cs index d2b3641..7733f56 100644 --- a/server/StudySharp.API/Controllers/CourseController.cs +++ b/server/StudySharp.API/Controllers/CourseController.cs @@ -15,7 +15,7 @@ namespace StudySharp.API.Controllers { - // [Authorize] + [Authorize] [ApiController] [Route("api/courses")] @@ -52,7 +52,6 @@ public async Task> GetCourseById([FromRou return OperationResult.Ok(response); } - // did not work because of mapper exception (wtf) [HttpGet] [Route("~/api/teachers/{teacherId:int}/courses")] public async Task> GetCoursesByTeacherId([FromRoute] GetCoursesByTeacherIdRequest getCoursesByTeacherIdRequest) From 9c69093504a117f07d3e3ef14b717c3811c37e79 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Tue, 19 Oct 2021 00:39:22 +0300 Subject: [PATCH 7/8] Remove unnecessary usings --- .../StudySharp.ApplicationServices/Commands/AddCourseCommand.cs | 1 - .../Commands/RemoveCourseByIdCommand.cs | 1 - .../StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs index 7f34400..404f0a4 100644 --- a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs @@ -3,7 +3,6 @@ using FluentValidation; using MediatR; using Microsoft.EntityFrameworkCore; -using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; diff --git a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs index 92f129b..b77a991 100644 --- a/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/RemoveCourseByIdCommand.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using FluentValidation; using MediatR; -using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; diff --git a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs index 81e5f08..5c06701 100644 --- a/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs +++ b/server/StudySharp.ApplicationServices/Queries/GetCourseByIdQuery.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using FluentValidation; using MediatR; -using StudySharp.ApplicationServices.ValidationRules; using StudySharp.Domain.Constants; using StudySharp.Domain.General; using StudySharp.Domain.Models; From bcf5097eb8b5e2a015a0c7772c393e36359b6175 Mon Sep 17 00:00:00 2001 From: zefirlover Date: Tue, 19 Oct 2021 20:10:01 +0300 Subject: [PATCH 8/8] Rewrite validation for Name in UpdateCourseCommand.cs and AddCourseCommand.cs --- server/StudySharp.API/Controllers/CourseController.cs | 2 +- .../Commands/AddCourseCommand.cs | 4 ++-- .../Commands/UpdateCourseCommand.cs | 4 ++-- .../ValidationRules/CourseRules.cs | 4 ++-- server/StudySharp.Domain/ValidationRules/ICourseRules.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/server/StudySharp.API/Controllers/CourseController.cs b/server/StudySharp.API/Controllers/CourseController.cs index 7733f56..51b4100 100644 --- a/server/StudySharp.API/Controllers/CourseController.cs +++ b/server/StudySharp.API/Controllers/CourseController.cs @@ -15,7 +15,7 @@ namespace StudySharp.API.Controllers { - [Authorize] + // [Authorize] [ApiController] [Route("api/courses")] diff --git a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs index 404f0a4..5cc2a61 100644 --- a/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/AddCourseCommand.cs @@ -21,10 +21,10 @@ public class AddCourseCommandValidator : AbstractValidator { public AddCourseCommandValidator(ICourseRules rules) { - RuleFor(_ => _.Name) + RuleFor(_ => new { _.Name, _.TeacherId }) .NotEmpty() .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.Name))) - .MustAsync(rules.IsNameUniqueAsync) + .MustAsync((courseTeacherAndName, token) => rules.IsNameUniqueAsync(courseTeacherAndName.Name, courseTeacherAndName.TeacherId, token)) .WithMessage(_ => string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), _.Name)); RuleFor(_ => _.TeacherId) diff --git a/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs b/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs index 39bc893..debd962 100644 --- a/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs +++ b/server/StudySharp.ApplicationServices/Commands/UpdateCourseCommand.cs @@ -26,10 +26,10 @@ public UpdateCourseCommandValidator(ICourseRules rules) .MustAsync(rules.IsCourseIdExistAsync) .WithMessage(_ => string.Format(ErrorConstants.EntityNotFound, nameof(Course), nameof(Course.Id), _.Id)); - RuleFor(_ => _.Name) + RuleFor(_ => new { _.Name, _.TeacherId }) .NotEmpty() .WithMessage(string.Format(ErrorConstants.FieldIsRequired, nameof(Course.Name))) - .MustAsync(rules.IsNameUniqueAsync) + .MustAsync((courseTeacherAndName, token) => rules.IsNameUniqueAsync(courseTeacherAndName.Name, courseTeacherAndName.TeacherId, token)) .WithMessage(_ => string.Format(ErrorConstants.EntityAlreadyExists, nameof(Course), nameof(Course.Name), _.Name)); RuleFor(_ => _.TeacherId) diff --git a/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs b/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs index c877c57..353b64c 100644 --- a/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs +++ b/server/StudySharp.ApplicationServices/ValidationRules/CourseRules.cs @@ -15,9 +15,9 @@ public CourseRules(StudySharpDbContext context) _context = context; } - public async Task IsNameUniqueAsync(string name, CancellationToken cancellationToken) + public async Task IsNameUniqueAsync(string name, int teacherId, CancellationToken cancellationToken) { - return !await _context.Courses.AnyAsync(_ => _.Name == name, cancellationToken); + return !await _context.Courses.AnyAsync(_ => _.Name == name && _.TeacherId == teacherId, cancellationToken); } public async Task IsCourseIdExistAsync(int id, CancellationToken cancellationToken) diff --git a/server/StudySharp.Domain/ValidationRules/ICourseRules.cs b/server/StudySharp.Domain/ValidationRules/ICourseRules.cs index 09fe0ee..f9bc374 100644 --- a/server/StudySharp.Domain/ValidationRules/ICourseRules.cs +++ b/server/StudySharp.Domain/ValidationRules/ICourseRules.cs @@ -7,6 +7,6 @@ public interface ICourseRules : IValidationRule { Task IsCourseIdExistAsync(int id, CancellationToken cancellationToken); Task IsTeacherIdExistAsync(int teacherId, CancellationToken cancellationToken); - Task IsNameUniqueAsync(string name, CancellationToken cancellationToken); + Task IsNameUniqueAsync(string name, int teacherId, CancellationToken cancellationToken); } } \ No newline at end of file