diff --git a/EUniversity.Tests/Filters/GradesFilterTests.cs b/EUniversity.Tests/Filters/GradesFilterTests.cs new file mode 100644 index 00000000..fcb9c38b --- /dev/null +++ b/EUniversity.Tests/Filters/GradesFilterTests.cs @@ -0,0 +1,105 @@ +using EUniversity.Core.Models.University.Grades; +using EUniversity.Infrastructure.Filters; + +namespace EUniversity.Tests.Filters; + +public class GradesFilterTests +{ + private readonly Grade[] TestGrades = + { + new Grade() {Id = 1, Name = "1", Score = 500}, + new Grade() {Id = 3, Name = "3", Score = 700}, + new Grade() {Id = 2, Name = "2", Score = 600}, + new Grade() {Id = 4, Name = "10", Score = 800}, + }; + + [Test] + public void EmptyFilter_ReturnsEntireQuery() + { + // Arrange + GradesFilterProperties properties = new(); + GradesFilter filter = new(properties); + + // Act + var result = filter.Apply(TestGrades.AsQueryable()); + + // Assert + Assert.That(result, Is.EquivalentTo(TestGrades)); + } + + [Test] + public void NameSpecified_ReturnsFilteredQuery() + { + // Arrange + GradesFilterProperties properties = new(Name: "1"); + GradesFilter filter = new(properties); + int[] expectedIds = { 1, 4 }; + + // Act + var actualIds = filter.Apply(TestGrades.AsQueryable()) + .Select(g => g.Id); + + // Assert + Assert.That(actualIds, Is.EquivalentTo(expectedIds)); + } + + [Test] + public void SortByName_ReturnsOrderedByNameQuery() + { + // Arrange + GradesFilterProperties properties = new(SortingMode: GradesSortingMode.Name); + GradesFilter filter = new(properties); + + // Act + var result = filter.Apply(TestGrades.AsQueryable()); + + // Assert + Assert.That(result, Is.EquivalentTo(TestGrades)); + Assert.That(result, Is.Ordered.Ascending.By("Name")); + } + + [Test] + public void SortByNameDescending_ReturnsOrderedByNameQuery() + { + // Arrange + GradesFilterProperties properties = new(SortingMode: GradesSortingMode.NameDescending); + GradesFilter filter = new(properties); + + // Act + var result = filter.Apply(TestGrades.AsQueryable()); + + // Assert + Assert.That(result, Is.EquivalentTo(TestGrades)); + Assert.That(result, Is.Ordered.Descending.By("Name")); + } + + [Test] + public void SortByScore_ReturnsOrderedByScoreQuery() + { + // Arrange + GradesFilterProperties properties = new(SortingMode: GradesSortingMode.Score); + GradesFilter filter = new(properties); + + // Act + var result = filter.Apply(TestGrades.AsQueryable()); + + // Assert + Assert.That(result, Is.EquivalentTo(TestGrades)); + Assert.That(result, Is.Ordered.Ascending.By("Score")); + } + + [Test] + public void SortByScoreDescending_ReturnsOrderedByScoreQuery() + { + // Arrange + GradesFilterProperties properties = new(SortingMode: GradesSortingMode.ScoreDescending); + GradesFilter filter = new(properties); + + // Act + var result = filter.Apply(TestGrades.AsQueryable()); + + // Assert + Assert.That(result, Is.EquivalentTo(TestGrades)); + Assert.That(result, Is.Ordered.Descending.By("Score")); + } +} diff --git a/EUniversity.Tests/Filters/GroupsFilterTests.cs b/EUniversity.Tests/Filters/GroupsFilterTests.cs index 12f03791..da4b695c 100644 --- a/EUniversity.Tests/Filters/GroupsFilterTests.cs +++ b/EUniversity.Tests/Filters/GroupsFilterTests.cs @@ -1,11 +1,6 @@ using EUniversity.Core.Models; using EUniversity.Core.Models.University; using EUniversity.Infrastructure.Filters; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace EUniversity.Tests.Filters; diff --git a/EUniversity/Controllers/University/Grades/GradesController.cs b/EUniversity/Controllers/University/Grades/GradesController.cs index 64ee07ff..2b3c2240 100644 --- a/EUniversity/Controllers/University/Grades/GradesController.cs +++ b/EUniversity/Controllers/University/Grades/GradesController.cs @@ -30,23 +30,19 @@ public GradesController(IGradesService gradesService) /// Gets a page with grades. /// /// - /// If there is no items in the requested page, then empty page will be returned. - /// - /// Pagination properties. - /// An optional name to filter grades by. - /// - /// An optional sorting mode. - /// - /// Possible values: + /// If there is no items in the requested page, then empty page will be returned. + /// Possible sortingMode values: /// /// - /// + /// + /// Pagination properties. + /// /// Returns requested page with grades. /// Bad request /// Unauthorized user call @@ -57,10 +53,9 @@ public GradesController(IGradesService gradesService) [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task GetGradesPageAsync( [FromQuery] PaginationProperties properties, - [FromQuery] string? name, - [FromQuery] DefaultFilterSortingMode sortingMode = DefaultFilterSortingMode.Name) + [FromQuery] GradesFilterProperties filterProperties) { - DefaultFilter filter = new(name ?? string.Empty, sortingMode); + GradesFilter filter = new(filterProperties); return Ok(await _gradesService.GetPageAsync(properties, filter)); } diff --git a/Infrastructure/Filters/GradesFilter.cs b/Infrastructure/Filters/GradesFilter.cs new file mode 100644 index 00000000..5b9ed88c --- /dev/null +++ b/Infrastructure/Filters/GradesFilter.cs @@ -0,0 +1,75 @@ +using Bogus.DataSets; +using EUniversity.Core.Filters; +using EUniversity.Core.Models; +using EUniversity.Core.Models.University.Grades; + +namespace EUniversity.Infrastructure.Filters; + +/// +/// Represents a sorting mode for . +/// +public enum GradesSortingMode +{ + /// + /// Default sorting mode, grades will not be sorted. + /// + Default = 0, + /// + /// Sort grades by name alphabetically from a to z. + /// + Name = 1, + /// + /// Sort grades by name alphabetically from z to a. + /// + NameDescending = 2, + /// + /// Sort grades by its score. + /// + Score = 3, + /// + /// Sort grades by its score descending. + /// + ScoreDescending = 4 +} + +/// +/// Filter for grades. +/// +public class GradesFilter : IFilter +{ + /// + /// Properties used for filtering grades. + /// + public GradesFilterProperties Properties { get; set; } + + public GradesFilter(GradesFilterProperties properties) + { + Properties = properties; + } + + /// + public virtual IQueryable Apply(IQueryable query) + { + // Filter by name + query = query.Where(g => g.Name.Contains(Properties.Name)); + + // Apply sort + switch (Properties.SortingMode) + { + case GradesSortingMode.Name: + query = query.OrderBy(g => g.Name); + break; + case GradesSortingMode.NameDescending: + query = query.OrderByDescending(g => g.Name); + break; + case GradesSortingMode.Score: + query = query.OrderBy(g => g.Score); + break; + case GradesSortingMode.ScoreDescending: + query = query.OrderByDescending(g => g.Score); + break; + } + + return query; + } +} diff --git a/Infrastructure/Filters/GradesFilterProperties.cs b/Infrastructure/Filters/GradesFilterProperties.cs new file mode 100644 index 00000000..085a1a2a --- /dev/null +++ b/Infrastructure/Filters/GradesFilterProperties.cs @@ -0,0 +1,8 @@ +namespace EUniversity.Infrastructure.Filters; + +/// +/// Represents properties for filtering grades. +/// +/// Optional name to filter by. +/// Sorting mode for grades. +public record GradesFilterProperties(string Name = "", GradesSortingMode SortingMode = GradesSortingMode.ScoreDescending); diff --git a/IntegrationTests/Controllers/University/Grades/GradesControllerTests.cs b/IntegrationTests/Controllers/University/Grades/GradesControllerTests.cs index 2cb8a09c..7fec116a 100644 --- a/IntegrationTests/Controllers/University/Grades/GradesControllerTests.cs +++ b/IntegrationTests/Controllers/University/Grades/GradesControllerTests.cs @@ -20,7 +20,7 @@ public class GradesControllerTestsAdminCrudControllersTest : public override int DefaultId => 1; - public override string GetPageFilter => "name=testfilter&sortingMode=name"; + public override string GetPageFilter => "name=1&sortingMode=score"; public override void SetUpService() { @@ -59,8 +59,8 @@ protected override GradeCreateDto GetValidUpdateDto() protected override bool AssertThatFilterWasApplied(IFilter filter) { - return filter is DefaultFilter defaultFilter && - defaultFilter.Name == "testfilter" && - defaultFilter.SortingMode == DefaultFilterSortingMode.Name; + return filter is GradesFilter defaultFilter && + defaultFilter.Properties.Name == "1" && + defaultFilter.Properties.SortingMode == GradesSortingMode.Score; } }