Skip to content

Commit ba1efaa

Browse files
committed
Add and use sort direction enum
1 parent 224bf91 commit ba1efaa

6 files changed

Lines changed: 194 additions & 11 deletions

File tree

SabreTools.RedumpLib.Test/Data/ExtensionsTests.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,113 @@ public void SortCategory_ToSortCategory(SortCategory? sortCategory, bool expectN
11981198

11991199
#endregion
12001200

1201+
#region SortDirection
1202+
1203+
/// <summary>
1204+
/// Check that every SortDirection has a long name provided
1205+
/// </summary>
1206+
/// <param name="sortDirection">SortDirection value to check</param>
1207+
/// <param name="expectNull">True to expect a null value, false otherwise</param>
1208+
[Theory]
1209+
[MemberData(nameof(GenerateSortDirectionTestData))]
1210+
public void SortDirection_LongName(SortDirection? sortDirection, bool expectNull)
1211+
{
1212+
var actual = sortDirection.LongName();
1213+
1214+
if (expectNull)
1215+
Assert.Null(actual);
1216+
else
1217+
Assert.NotNull(actual);
1218+
}
1219+
1220+
/// <summary>
1221+
/// Check that every SortDirection has a short name provided
1222+
/// </summary>
1223+
/// <param name="sortDirection">SortDirection value to check</param>
1224+
/// <param name="expectNull">True to expect a null value, false otherwise</param>
1225+
[Theory]
1226+
[MemberData(nameof(GenerateSortDirectionTestData))]
1227+
public void SortDirection_ShortName(SortDirection? sortDirection, bool expectNull)
1228+
{
1229+
var actual = sortDirection.ShortName();
1230+
1231+
if (expectNull)
1232+
Assert.Null(actual);
1233+
else
1234+
Assert.NotNull(actual);
1235+
}
1236+
1237+
/// <summary>
1238+
/// Ensure that every SortDirection that has a short name that is unique
1239+
/// </summary>
1240+
[Fact]
1241+
public void SortDirection_ShortName_NoDuplicates()
1242+
{
1243+
var fullSortDirections = Enum.GetValues<SortDirection>().Cast<SortDirection>().ToList();
1244+
var filteredSortDirections = new Dictionary<string, SortDirection?>();
1245+
1246+
int totalCount = 0;
1247+
foreach (SortDirection? sortDirection in fullSortDirections)
1248+
{
1249+
var code = sortDirection.ShortName();
1250+
if (string.IsNullOrEmpty(code))
1251+
continue;
1252+
1253+
// Throw if the code already exists
1254+
if (filteredSortDirections.ContainsKey(code))
1255+
throw new DuplicateNameException($"Code {code} already in dictionary");
1256+
1257+
filteredSortDirections[code] = sortDirection;
1258+
totalCount++;
1259+
}
1260+
1261+
Assert.Equal(totalCount, filteredSortDirections.Count);
1262+
}
1263+
1264+
/// <summary>
1265+
/// Check that every SortDirection can be mapped from a string
1266+
/// </summary>
1267+
/// <param name="sortDirection">SortDirection value to check</param>
1268+
/// <param name="expectNull">True to expect a null value, false otherwise</param>
1269+
[Theory]
1270+
[MemberData(nameof(GenerateSortDirectionTestData))]
1271+
public void SortDirection_ToSortDirection(SortDirection? sortDirection, bool expectNull)
1272+
{
1273+
string? longName = sortDirection.LongName();
1274+
string? longNameSpaceless = longName?.Replace(" ", string.Empty);
1275+
1276+
var actualNormal = longName.ToSortDirection();
1277+
var actualSpaceless = longNameSpaceless.ToSortDirection();
1278+
1279+
if (expectNull)
1280+
{
1281+
Assert.Null(actualNormal);
1282+
Assert.Null(actualSpaceless);
1283+
}
1284+
else
1285+
{
1286+
Assert.Equal(sortDirection, actualNormal);
1287+
Assert.Equal(sortDirection, actualSpaceless);
1288+
}
1289+
}
1290+
1291+
/// <summary>
1292+
/// Generate a test set of SortDirection values
1293+
/// </summary>
1294+
/// <returns>MemberData-compatible list of SortDirection values</returns>
1295+
public static TheoryData<SortDirection?, bool> GenerateSortDirectionTestData()
1296+
{
1297+
var testData = new TheoryData<SortDirection?, bool>() { { null, true } };
1298+
foreach (SortDirection? sortDirection in Enum.GetValues<SortDirection>().Cast<SortDirection?>())
1299+
{
1300+
testData.Add(sortDirection, false);
1301+
}
1302+
1303+
return testData;
1304+
}
1305+
1306+
#endregion
1307+
12011308
#region System
12021309

12031310
/// <summary>

SabreTools.RedumpLib.Test/Web/UrlBuilderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public void BuildDiscsUrl_DumperWithPages_Builds()
5050
[Fact]
5151
public void BuildDiscsUrl_DumperLastModifiedWithPages_Builds()
5252
{
53-
string actual = UrlBuilder.BuildDiscsUrl(dumper: "user", sort: SortCategory.Modified, sortDir: "desc", page: 3);
53+
string actual = UrlBuilder.BuildDiscsUrl(dumper: "user", sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: 3);
5454
Assert.Equal("http://redump.org/discs/dumper/user/sort/modified/dir/desc/?page=3", actual);
5555
}
5656

5757
[Fact]
5858
public void BuildDiscsUrl_LastModifiedWithPages_Builds()
5959
{
60-
string actual = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: "desc", page: 3);
60+
string actual = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: 3);
6161
Assert.Equal("http://redump.org/discs/sort/modified/dir/desc/?page=3", actual);
6262
}
6363

SabreTools.RedumpLib/Data/Enumerations.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3858,6 +3858,18 @@ public enum SortCategory
38583858
Modified,
38593859
}
38603860

3861+
/// <summary>
3862+
/// List of all recognized sort directions
3863+
/// </summary>
3864+
public enum SortDirection
3865+
{
3866+
[HumanReadable(LongName = "Ascending", ShortName = "asc")]
3867+
Ascending,
3868+
3869+
[HumanReadable(LongName = "Descending", ShortName = "desc")]
3870+
Descending,
3871+
}
3872+
38613873
/// <summary>
38623874
/// List of system categories
38633875
/// </summary>

SabreTools.RedumpLib/Data/Extensions.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,70 @@ public static bool IsMultiLine(this SiteCode? siteCode)
15851585

15861586
#endregion
15871587

1588+
#region SortDirection
1589+
1590+
/// <summary>
1591+
/// Get the human readable name for a SortDirection
1592+
/// </summary>
1593+
/// <param name="sortDirection"></param>
1594+
/// <returns></returns>
1595+
public static string? LongName(this SortDirection sortDirection)
1596+
=> AttributeHelper<SortDirection>.GetAttribute(sortDirection)?.LongName;
1597+
1598+
/// <summary>
1599+
/// Get the human readable name for a SortDirection
1600+
/// </summary>
1601+
/// <param name="sortDirection"></param>
1602+
/// <returns></returns>
1603+
public static string? LongName(this SortDirection? sortDirection)
1604+
=> AttributeHelper<SortDirection?>.GetAttribute(sortDirection)?.LongName;
1605+
1606+
/// <summary>
1607+
/// Get the URL path part for a SortDirection
1608+
/// </summary>
1609+
/// <param name="sortDirection"></param>
1610+
/// <returns></returns>
1611+
public static string? ShortName(this SortDirection sortDirection)
1612+
=> AttributeHelper<SortDirection>.GetAttribute(sortDirection)?.ShortName;
1613+
1614+
/// <summary>
1615+
/// Get the URL path part for a SortDirection
1616+
/// </summary>
1617+
/// <param name="sortDirection"></param>
1618+
/// <returns></returns>
1619+
public static string? ShortName(this SortDirection? sortDirection)
1620+
=> AttributeHelper<SortDirection?>.GetAttribute(sortDirection)?.ShortName;
1621+
1622+
/// <summary>
1623+
/// Get the Region enum value for a given string
1624+
/// </summary>
1625+
/// <param name="sortDirection">String value to convert</param>
1626+
/// <returns>Region represented by the string, if possible</returns>
1627+
public static SortDirection? ToSortDirection(this string? sortDirection)
1628+
{
1629+
// No value means no match
1630+
if (sortDirection is null || sortDirection.Length == 0)
1631+
return null;
1632+
1633+
sortDirection = sortDirection.ToLowerInvariant();
1634+
var sortCategories = (SortDirection[])Enum.GetValues(typeof(SortDirection));
1635+
1636+
// Check short names
1637+
int index = Array.FindIndex(sortCategories, s => sortDirection == s.ShortName()?.ToLowerInvariant());
1638+
if (index > -1)
1639+
return sortCategories[index];
1640+
1641+
// Check long names
1642+
index = Array.FindIndex(sortCategories, s => sortDirection == s.LongName()?.ToLowerInvariant()
1643+
|| sortDirection == s.LongName()?.Replace(" ", string.Empty)?.ToLowerInvariant());
1644+
if (index > -1)
1645+
return sortCategories[index];
1646+
1647+
return null;
1648+
}
1649+
1650+
#endregion
1651+
15881652
#region System
15891653

15901654
/// <summary>

SabreTools.RedumpLib/Web/RedumpClient.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ public RedumpClient()
406406
/// <returns>List of IDs from the page, empty on none, null on error</returns>
407407
public async Task<List<int>?> CheckSingleDiscsLastModifiedPage(int pageNumber)
408408
{
409-
string url = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: "desc", page: pageNumber);
409+
string url = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: pageNumber);
410410
return await CheckSingleSitePage(url);
411411
}
412412

@@ -418,7 +418,7 @@ public RedumpClient()
418418
/// <returns>List of IDs from the page, empty on none, null on error</returns>
419419
public async Task<List<int>?> CheckSingleDiscsLastModifiedPage(int pageNumber, string? outDir)
420420
{
421-
string url = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: "desc", page: pageNumber);
421+
string url = UrlBuilder.BuildDiscsUrl(sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: pageNumber);
422422
return await CheckSingleSitePage(url, outDir);
423423
}
424424

@@ -461,7 +461,7 @@ public RedumpClient()
461461
public async Task<List<int>?> CheckSingleUserPage(string username, int pageNumber, bool lastModified)
462462
{
463463
string url = lastModified
464-
? UrlBuilder.BuildDiscsUrl(dumper: username, sort: SortCategory.Modified, sortDir: "desc", page: pageNumber)
464+
? UrlBuilder.BuildDiscsUrl(dumper: username, sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: pageNumber)
465465
: UrlBuilder.BuildDiscsUrl(dumper: username, page: pageNumber);
466466
return await CheckSingleSitePage(url);
467467
}
@@ -477,7 +477,7 @@ public RedumpClient()
477477
public async Task<List<int>?> CheckSingleUserPage(string username, int pageNumber, string? outDir, bool lastModified)
478478
{
479479
string url = lastModified
480-
? UrlBuilder.BuildDiscsUrl(dumper: username, sort: SortCategory.Modified, sortDir: "desc", page: pageNumber)
480+
? UrlBuilder.BuildDiscsUrl(dumper: username, sort: SortCategory.Modified, sortDir: SortDirection.Descending, page: pageNumber)
481481
: UrlBuilder.BuildDiscsUrl(dumper: username, page: pageNumber);
482482
return await CheckSingleSitePage(url, outDir);
483483
}

SabreTools.RedumpLib/Web/UrlBuilder.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public static string BuildDiscsUrl(bool? antimodchip = null,
256256
Region? region = null,
257257
string? ringcode = null,
258258
SortCategory? sort = null,
259-
string? sortDir = null,
259+
SortDirection? sortDir = null,
260260
DumpStatus? status = null,
261261
RedumpSystem? system = null,
262262
int? tracks = null)
@@ -389,11 +389,11 @@ public static string BuildDiscsUrl(bool? antimodchip = null,
389389
}
390390

391391
// Sort Direction
392-
switch (sortDir?.ToLowerInvariant())
392+
switch (sortDir)
393393
{
394-
case "asc":
395-
case "desc":
396-
sb.Append($"dir/{sortDir}/");
394+
case SortDirection.Ascending:
395+
case SortDirection.Descending:
396+
sb.Append($"dir/{sortDir.ShortName()}/");
397397
break;
398398

399399
default: break;

0 commit comments

Comments
 (0)