Files
Generic.CL/Generic.Tests/Services/SortExtTests.cs
T

180 lines
6.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Generic.Contracts.Generics;
using Generic.Services;
using Xunit;
namespace Generic.Tests.Services
{
public class SortExtTests
{
private class TestItem
{
public int Id { get; set; }
public string Name { get; set; }
public int Category { get; set; }
}
private readonly IQueryable<TestItem> _data;
public SortExtTests()
{
_data = new List<TestItem>
{
new TestItem { Id = 1, Name = "Apple", Category = 1 },
new TestItem { Id = 2, Name = "Banana", Category = 1 },
new TestItem { Id = 3, Name = "Cherry", Category = 2 },
new TestItem { Id = 4, Name = "Date", Category = 2 },
new TestItem { Id = 5, Name = "Elderberry", Category = 1 }
}.AsQueryable();
}
[Fact]
public void ApplySort_Simple_Ascending_Works()
{
var sortModel = new SortModel { SortBy = "Name", SortDirection = SortDir.Ascending };
var result = _data.ApplySimpleSort(sortModel).ToList();
Assert.Equal("Apple", result[0].Name);
Assert.Equal("Banana", result[1].Name);
Assert.Equal("Elderberry", result[4].Name);
}
[Fact]
public void ApplySort_Simple_Descending_Works()
{
var sortModel = new SortModel { SortBy = "Name", SortDirection = SortDir.Descending };
var result = _data.ApplySimpleSort(sortModel).ToList();
Assert.Equal("Elderberry", result[0].Name);
Assert.Equal("Date", result[1].Name);
Assert.Equal("Apple", result[4].Name);
}
[Fact]
public void ApplySort_Complex_MultiLayer_Works()
{
// Category Descending, then Name Ascending
var sortModels = new List<SortModel>
{
new SortModel { SortBy = "Category", SortDirection = SortDir.Descending },
new SortModel { SortBy = "Name", SortDirection = SortDir.Ascending }
};
var result = _data.ApplyComplexSort(sortModels).ToList();
// First should be Category 2 (Cherry or Date)
// Then Category 1 (Apple, Banana, Elderberry)
// Check Category 2 items are first
Assert.Equal(2, result[0].Category);
Assert.Equal(2, result[1].Category);
// Check secondary sort (Name Ascending) within Category 2
Assert.Equal("Cherry", result[0].Name);
Assert.Equal("Date", result[1].Name);
// Check Category 1 items
Assert.Equal(1, result[2].Category);
Assert.Equal(1, result[3].Category);
Assert.Equal(1, result[4].Category);
// Check secondary sort (Name Ascending) within Category 1
Assert.Equal("Apple", result[2].Name);
Assert.Equal("Banana", result[3].Name);
Assert.Equal("Elderberry", result[4].Name);
}
[Fact]
public void ApplySort_InvalidProperty_ThrowsException()
{
var sortModel = new SortModel { SortBy = "InvalidProp" };
Assert.Throws<ArgumentException>(() => _data.ApplySimpleSort(sortModel));
}
[Fact]
public void ApplySort_EmptySort_ReturnsOriginal()
{
var result = _data.ApplySimpleSort((SortModel)null);
var resultList = result.ToList();
Assert.Equal(_data.Count(), resultList.Count);
// Just verifying it doesn't crash and returns data.
// Order is not guaranteed to be unchanged by contract if AsQueryable is used,
// but for List.AsQueryable it usually is.
Assert.Equal(1, resultList[0].Id);
}
[Fact]
public void ApplySort_Complex_Empty_ReturnsOriginal()
{
var result = _data.ApplyComplexSort(new List<SortModel>());
var resultList = result.ToList();
Assert.Equal(5, resultList.Count);
}
[Fact]
public void ApplySort_CaseInsensitiveProperty_Works()
{
var sortModel = new SortModel { SortBy = "name", SortDirection = SortDir.Ascending };
var result = _data.ApplySimpleSort(sortModel).ToList();
Assert.Equal("Apple", result[0].Name);
Assert.Equal("Banana", result[1].Name);
}
[Fact]
public void ApplySort_Complex_SingleItem_WorksAsSimple()
{
var sortModels = new List<SortModel>
{
new SortModel { SortBy = "Name", SortDirection = SortDir.Descending }
};
var result = _data.ApplyComplexSort(sortModels).ToList();
Assert.Equal("Elderberry", result[0].Name);
Assert.Equal("Date", result[1].Name);
Assert.Equal("Apple", result[4].Name);
}
[Fact]
public void ApplySort_Complex_ThreeLayers_Works()
{
// Add data with 3 layers if needed, or reuse existing if sufficient.
// Extending data locally for this test to prove 3 layers.
// Layers: Category (Desc) -> Id (Desc) -> Name (Asc)
// Not perfect with current data, let's just make sure it doesn't crash
// and logically applies.
// Actually, let's create a specific data set for 3 layers.
var detailedData = new List<TestItem>
{
new TestItem { Id = 1, Name = "A", Category = 1 },
new TestItem { Id = 2, Name = "A", Category = 1 }, // Same Name, Same Cat
new TestItem { Id = 1, Name = "B", Category = 1 }, // Same Id (dup), Same Cat
}.AsQueryable();
// This data isn't great for 3 layers. Let's stick to checking logic execution flow using existing data properties.
// Category Desc (2, 2, 1, 1, 1)
// Then Name Asc (Cherry, Date | Apple, Banana, Elderberry)
// Then Id Desc (Within same Category and Name -- none are same, so 3rd layer is effectively no-op but tests the loop).
var sortModels = new List<SortModel>
{
new SortModel { SortBy = "Category", SortDirection = SortDir.Descending },
new SortModel { SortBy = "Name", SortDirection = SortDir.Ascending },
new SortModel { SortBy = "Id", SortDirection = SortDir.Descending }
};
var result = _data.ApplyComplexSort(sortModels).ToList();
Assert.Equal("Cherry", result[0].Name);
Assert.Equal("Date", result[1].Name);
Assert.Equal("Apple", result[2].Name);
}
}
}