180 lines
6.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|