Skip to content

Commit

Permalink
Add Filter for Grades (#59)
Browse files Browse the repository at this point in the history
* Implement grades filter

* Apply grades filter to the endpoint
  • Loading branch information
romandykyi authored Dec 17, 2023
1 parent d3d6a33 commit 82da81b
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 24 deletions.
105 changes: 105 additions & 0 deletions EUniversity.Tests/Filters/GradesFilterTests.cs
Original file line number Diff line number Diff line change
@@ -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"));
}
}
5 changes: 0 additions & 5 deletions EUniversity.Tests/Filters/GroupsFilterTests.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
25 changes: 10 additions & 15 deletions EUniversity/Controllers/University/Grades/GradesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,19 @@ public GradesController(IGradesService gradesService)
/// Gets a page with grades.
/// </summary>
/// <remarks>
/// If there is no items in the requested page, then empty page will be returned.
/// </remarks>
/// <param name="properties">Pagination properties.</param>
/// <param name="name">An optional name to filter grades by.</param>
/// <param name="sortingMode">
/// An optional sorting mode.
/// <para>
/// Possible values:
/// If there is no items in the requested page, then empty page will be returned.<para>
/// Possible sortingMode values:
/// </para>
/// <ul>
/// <li>default(or 0) - no sorting will be applied;</li>
/// <li>name(or 1) - grades will be sorted by their name(from a to z), this mode is applied by default;</li>
/// <li>name(or 1) - grades will be sorted by their name(from a to z)</li>
/// <li>nameDescending(or 2) - grades will be sorted by their name in descending order(from z to a);</li>
/// <li>newest(or 3) - grades will be sorted by their creation date in descending order;</li>
/// <li>oldest(or 4) - grades will be sorted by their creation date in ascending order.</li>
/// <li>score(or 3) - grades will be sorted by their score in ascending order;</li>
/// <li>scoreDescending(or 4) - grades will be sorted by their score in descending order, this mode is applied by default.</li>
/// </ul>
/// </param>
/// </remarks>
/// <param name="properties">Pagination properties.</param>
/// <param name="filterProperties"></param>
/// <response code="200">Returns requested page with grades.</response>
/// <response code="400">Bad request</response>
/// <response code="401">Unauthorized user call</response>
Expand All @@ -57,10 +53,9 @@ public GradesController(IGradesService gradesService)
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> GetGradesPageAsync(
[FromQuery] PaginationProperties properties,
[FromQuery] string? name,
[FromQuery] DefaultFilterSortingMode sortingMode = DefaultFilterSortingMode.Name)
[FromQuery] GradesFilterProperties filterProperties)
{
DefaultFilter<Grade> filter = new(name ?? string.Empty, sortingMode);
GradesFilter filter = new(filterProperties);
return Ok(await _gradesService.GetPageAsync(properties, filter));
}

Expand Down
75 changes: 75 additions & 0 deletions Infrastructure/Filters/GradesFilter.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// Represents a sorting mode for <see cref="GradesFilter" />.
/// </summary>
public enum GradesSortingMode
{
/// <summary>
/// Default sorting mode, grades will not be sorted.
/// </summary>
Default = 0,
/// <summary>
/// Sort grades by name alphabetically from a to z.
/// </summary>
Name = 1,
/// <summary>
/// Sort grades by name alphabetically from z to a.
/// </summary>
NameDescending = 2,
/// <summary>
/// Sort grades by its score.
/// </summary>
Score = 3,
/// <summary>
/// Sort grades by its score descending.
/// </summary>
ScoreDescending = 4
}

/// <summary>
/// Filter for grades.
/// </summary>
public class GradesFilter : IFilter<Grade>
{
/// <summary>
/// Properties used for filtering grades.
/// </summary>
public GradesFilterProperties Properties { get; set; }

public GradesFilter(GradesFilterProperties properties)
{
Properties = properties;
}

/// <inheritdoc />
public virtual IQueryable<Grade> Apply(IQueryable<Grade> 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;
}
}
8 changes: 8 additions & 0 deletions Infrastructure/Filters/GradesFilterProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EUniversity.Infrastructure.Filters;

/// <summary>
/// Represents properties for filtering grades.
/// </summary>
/// <param name="Name">Optional name to filter by.</param>
/// <param name="SortingMode">Sorting mode for grades.</param>
public record GradesFilterProperties(string Name = "", GradesSortingMode SortingMode = GradesSortingMode.ScoreDescending);
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -59,8 +59,8 @@ protected override GradeCreateDto GetValidUpdateDto()

protected override bool AssertThatFilterWasApplied(IFilter<Grade> filter)
{
return filter is DefaultFilter<Grade> defaultFilter &&
defaultFilter.Name == "testfilter" &&
defaultFilter.SortingMode == DefaultFilterSortingMode.Name;
return filter is GradesFilter defaultFilter &&
defaultFilter.Properties.Name == "1" &&
defaultFilter.Properties.SortingMode == GradesSortingMode.Score;
}
}

0 comments on commit 82da81b

Please sign in to comment.