From a69d94054bc7d334e3d0b7e0184935bc8a80a16d Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 5 Jun 2023 17:53:41 -0500 Subject: [PATCH] Simplify filters and make cross control slots not show by default (#782) * Simplify filters and make cross control slots not show by default Also sort author levels by oldest levels first rather than newest levels first. * Fix unit test expecting slots to sorted by timestamp descending * Remove errant whitespace --- .../Controllers/Slots/SlotsController.cs | 4 +- .../Extensions/ControllerExtensions.cs | 7 ++- .../Controllers/ControllerExtensionTests.cs | 46 +++++++++++++++++++ .../Unit/Controllers/SlotControllerTests.cs | 6 +-- ProjectLighthouse.Tests/Unit/FilterTests.cs | 28 +++++++++++ .../Filter/Filters/AdventureFilter.cs | 4 +- .../Filter/Filters/CreatorFilter.cs | 4 +- .../Filter/Filters/CrossControlFilter.cs | 4 +- .../Filter/Filters/ExcludeAdventureFilter.cs | 4 +- .../Filters/ExcludeCrossControlFilter.cs | 11 +++++ .../Filter/Filters/ExcludeLBP1OnlyFilter.cs | 9 +--- .../Filter/Filters/ExcludeMovePackFilter.cs | 4 +- .../Filter/Filters/GameVersionFilter.cs | 14 ++---- .../Filter/Filters/HiddenSlotFilter.cs | 4 +- .../Filter/Filters/MovePackFilter.cs | 4 +- .../Filter/Filters/ResultTypeFilter.cs | 6 +-- .../Filter/Filters/SlotTypeFilter.cs | 4 +- .../Filter/Filters/SubLevelFilter.cs | 4 +- .../Filter/Filters/TeamPickFilter.cs | 4 +- .../Helpers/LastContactHelper.cs | 1 - 20 files changed, 114 insertions(+), 58 deletions(-) create mode 100644 ProjectLighthouse/Filter/Filters/ExcludeCrossControlFilter.cs diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SlotsController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SlotsController.cs index e9ec67a5..7afaf6a1 100644 --- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SlotsController.cs +++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/SlotsController.cs @@ -49,7 +49,9 @@ public class SlotsController : ControllerBase SlotQueryBuilder queryBuilder = this.FilterFromRequest(token).AddFilter(new CreatorFilter(targetUserId)); - SlotSortBuilder sortBuilder = new SlotSortBuilder().AddSort(new FirstUploadedSort()); + SlotSortBuilder sortBuilder = new SlotSortBuilder() + .AddSort(new FirstUploadedSort()) + .SortDescending(false); List slots = await this.database.GetSlots(token, queryBuilder, pageData, sortBuilder); diff --git a/ProjectLighthouse.Servers.GameServer/Extensions/ControllerExtensions.cs b/ProjectLighthouse.Servers.GameServer/Extensions/ControllerExtensions.cs index 035d61d6..18f9dba3 100644 --- a/ProjectLighthouse.Servers.GameServer/Extensions/ControllerExtensions.cs +++ b/ProjectLighthouse.Servers.GameServer/Extensions/ControllerExtensions.cs @@ -92,8 +92,8 @@ public static class ControllerExtensions } } - if (bool.TryParse(controller.Request.Query["crosscontrol"], out bool crossControl) && crossControl) - queryBuilder.AddFilter(new CrossControlFilter()); + bool _ = bool.TryParse(controller.Request.Query["crosscontrol"], out bool showCrossControl); + if (showCrossControl) queryBuilder.AddFilter(new CrossControlFilter()); GameVersion targetVersion = token.GameVersion; @@ -171,6 +171,9 @@ public static class ControllerExtensions if (token.GameVersion != GameVersion.LittleBigPlanet1) queryBuilder.AddFilter(new ExcludeLBP1OnlyFilter(token.UserId, token.GameVersion)); + if (!queryBuilder.GetFilters(typeof(CrossControlFilter)).Any()) + queryBuilder.AddFilter(new ExcludeCrossControlFilter()); + queryBuilder.AddFilter(new SubLevelFilter(token.UserId)); queryBuilder.AddFilter(new HiddenSlotFilter()); queryBuilder.AddFilter(new SlotTypeFilter(SlotType.User)); diff --git a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ControllerExtensionTests.cs b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ControllerExtensionTests.cs index e02fc1da..15a30b49 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ControllerExtensionTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/ControllerExtensionTests.cs @@ -271,6 +271,52 @@ public class ControllerExtensionTests Assert.NotEmpty(queryBuilder.GetFilters(typeof(CrossControlFilter))); } + [Fact] + public void FilterFromRequest_ShouldAddExcludeCrossControlFilter_WhenCrossControlNotTrue() + { + GameTokenEntity token = MockHelper.GetUnitTestToken(); + token.GameVersion = GameVersion.LittleBigPlanet2; + SlotsController controller = new(null!) + { + ControllerContext = + { + HttpContext = new DefaultHttpContext + { + Request = + { + QueryString = new QueryString("?crosscontrol=false"), + }, + }, + }, + }; + + SlotQueryBuilder queryBuilder = controller.FilterFromRequest(token); + Assert.NotEmpty(queryBuilder.GetFilters(typeof(ExcludeCrossControlFilter))); + } + + [Fact] + public void FilterFromRequest_ShouldAddExcludeCrossControlFilter_WhenCrossControlMissing() + { + GameTokenEntity token = MockHelper.GetUnitTestToken(); + token.GameVersion = GameVersion.LittleBigPlanet2; + SlotsController controller = new(null!) + { + ControllerContext = + { + HttpContext = new DefaultHttpContext + { + Request = + { + QueryString = new QueryString(), + }, + }, + }, + }; + + SlotQueryBuilder queryBuilder = controller.FilterFromRequest(token); + Assert.NotEmpty(queryBuilder.GetFilters(typeof(ExcludeCrossControlFilter))); + } + [Fact] public void FilterFromRequest_ShouldAddAdventureFilter_WhenAdventureEqualsAllMust() { diff --git a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/SlotControllerTests.cs b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/SlotControllerTests.cs index da500021..5bf2a342 100644 --- a/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/SlotControllerTests.cs +++ b/ProjectLighthouse.Tests.GameApiTests/Unit/Controllers/SlotControllerTests.cs @@ -77,7 +77,7 @@ public class SlotControllerTests } [Fact] - public async Task SlotsBy_ResultsAreOrderedByFirstUploadedTimestampDescending() + public async Task SlotsBy_ResultsAreOrderedByFirstUploadedTimestampAscending() { List slots = new() { @@ -119,9 +119,9 @@ public class SlotControllerTests IActionResult result = await slotsController.SlotsBy("bytest"); const int expectedElements = 3; - const int expectedFirstSlotId = 1; + const int expectedFirstSlotId = 2; const int expectedSecondSlotId = 3; - const int expectedThirdSlotId = 2; + const int expectedThirdSlotId = 1; GenericSlotResponse slotResponse = result.CastTo(); Assert.Equal(expectedElements, slotResponse.Slots.Count); diff --git a/ProjectLighthouse.Tests/Unit/FilterTests.cs b/ProjectLighthouse.Tests/Unit/FilterTests.cs index e73d64dc..2e8941fa 100644 --- a/ProjectLighthouse.Tests/Unit/FilterTests.cs +++ b/ProjectLighthouse.Tests/Unit/FilterTests.cs @@ -208,6 +208,34 @@ public class FilterTests Assert.True(adventureFunc(slot)); } + [Fact] + public void ExcludeCrossControlFilter_ShouldAccept_WhenNotCrossControl() + { + ExcludeCrossControlFilter crossControlFilter = new(); + Func crossControlFunc = crossControlFilter.GetPredicate().Compile(); + + SlotEntity slot = new() + { + CrossControllerRequired = false, + }; + + Assert.True(crossControlFunc(slot)); + } + + [Fact] + public void ExcludeCrossControlFilter_ShouldReject_WhenCrossControl() + { + ExcludeCrossControlFilter crossControlFilter = new(); + Func crossControlFunc = crossControlFilter.GetPredicate().Compile(); + + SlotEntity slot = new() + { + CrossControllerRequired = true, + }; + + Assert.False(crossControlFunc(slot)); + } + [Fact] public void ExcludeLBP1OnlyFilter_ShouldReject_WhenLbp1Only_AndTokenNotLbp1_AndNotCreator() { diff --git a/ProjectLighthouse/Filter/Filters/AdventureFilter.cs b/ProjectLighthouse/Filter/Filters/AdventureFilter.cs index a233074e..c7756361 100644 --- a/ProjectLighthouse/Filter/Filters/AdventureFilter.cs +++ b/ProjectLighthouse/Filter/Filters/AdventureFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class AdventureFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.IsAdventurePlanet); + public Expression> GetPredicate() => s => s.IsAdventurePlanet; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/CreatorFilter.cs b/ProjectLighthouse/Filter/Filters/CreatorFilter.cs index ba7f4da8..a3283b54 100644 --- a/ProjectLighthouse/Filter/Filters/CreatorFilter.cs +++ b/ProjectLighthouse/Filter/Filters/CreatorFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -15,6 +14,5 @@ public class CreatorFilter : ISlotFilter this.creatorId = creatorId; } - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.CreatorId == this.creatorId); + public Expression> GetPredicate() => s => s.CreatorId == this.creatorId; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/CrossControlFilter.cs b/ProjectLighthouse/Filter/Filters/CrossControlFilter.cs index 5e98187e..37a8bd81 100644 --- a/ProjectLighthouse/Filter/Filters/CrossControlFilter.cs +++ b/ProjectLighthouse/Filter/Filters/CrossControlFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class CrossControlFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.CrossControllerRequired); + public Expression> GetPredicate() => s => s.CrossControllerRequired; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/ExcludeAdventureFilter.cs b/ProjectLighthouse/Filter/Filters/ExcludeAdventureFilter.cs index c6a1dae0..6d6510d6 100644 --- a/ProjectLighthouse/Filter/Filters/ExcludeAdventureFilter.cs +++ b/ProjectLighthouse/Filter/Filters/ExcludeAdventureFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class ExcludeAdventureFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => !s.IsAdventurePlanet); + public Expression> GetPredicate() => s => !s.IsAdventurePlanet; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/ExcludeCrossControlFilter.cs b/ProjectLighthouse/Filter/Filters/ExcludeCrossControlFilter.cs new file mode 100644 index 00000000..069eb345 --- /dev/null +++ b/ProjectLighthouse/Filter/Filters/ExcludeCrossControlFilter.cs @@ -0,0 +1,11 @@ +using System; +using System.Linq.Expressions; +using LBPUnion.ProjectLighthouse.Types.Entities.Level; +using LBPUnion.ProjectLighthouse.Types.Filter; + +namespace LBPUnion.ProjectLighthouse.Filter.Filters; + +public class ExcludeCrossControlFilter : ISlotFilter +{ + public Expression> GetPredicate() => s => !s.CrossControllerRequired; +} \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/ExcludeLBP1OnlyFilter.cs b/ProjectLighthouse/Filter/Filters/ExcludeLBP1OnlyFilter.cs index f1a464bb..5d813008 100644 --- a/ProjectLighthouse/Filter/Filters/ExcludeLBP1OnlyFilter.cs +++ b/ProjectLighthouse/Filter/Filters/ExcludeLBP1OnlyFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; using LBPUnion.ProjectLighthouse.Types.Users; @@ -18,10 +17,6 @@ public class ExcludeLBP1OnlyFilter : ISlotFilter this.targetGameVersion = targetGameVersion; } - public Expression> GetPredicate() - { - Expression> predicate = PredicateExtensions.True(); - predicate = predicate.And(s => !s.Lbp1Only || s.CreatorId == this.userId || this.targetGameVersion == GameVersion.LittleBigPlanet1); - return predicate; - } + public Expression> GetPredicate() => + s => !s.Lbp1Only || s.CreatorId == this.userId || this.targetGameVersion == GameVersion.LittleBigPlanet1; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/ExcludeMovePackFilter.cs b/ProjectLighthouse/Filter/Filters/ExcludeMovePackFilter.cs index 85d9ccde..2b03fab7 100644 --- a/ProjectLighthouse/Filter/Filters/ExcludeMovePackFilter.cs +++ b/ProjectLighthouse/Filter/Filters/ExcludeMovePackFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class ExcludeMovePackFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => !s.MoveRequired); + public Expression> GetPredicate() => s => !s.MoveRequired; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/GameVersionFilter.cs b/ProjectLighthouse/Filter/Filters/GameVersionFilter.cs index 298abefa..b3444739 100644 --- a/ProjectLighthouse/Filter/Filters/GameVersionFilter.cs +++ b/ProjectLighthouse/Filter/Filters/GameVersionFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; using LBPUnion.ProjectLighthouse.Types.Users; @@ -18,12 +17,9 @@ public class GameVersionFilter : ISlotFilter this.matchExactly = matchExactly; } - public Expression> GetPredicate() - { - Expression> predicate = PredicateExtensions.True(); - predicate = this.matchExactly || this.targetVersion is GameVersion.LittleBigPlanetVita or GameVersion.LittleBigPlanetPSP or GameVersion.Unknown - ? predicate.And(s => s.GameVersion == this.targetVersion) - : predicate.And(s => s.GameVersion <= this.targetVersion); - return predicate; - } + public Expression> GetPredicate() => + this.matchExactly || + this.targetVersion is GameVersion.LittleBigPlanetVita or GameVersion.LittleBigPlanetPSP or GameVersion.Unknown + ? s => s.GameVersion == this.targetVersion + : s => s.GameVersion <= this.targetVersion; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/HiddenSlotFilter.cs b/ProjectLighthouse/Filter/Filters/HiddenSlotFilter.cs index f722c50f..eab9820b 100644 --- a/ProjectLighthouse/Filter/Filters/HiddenSlotFilter.cs +++ b/ProjectLighthouse/Filter/Filters/HiddenSlotFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class HiddenSlotFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => !s.Hidden); + public Expression> GetPredicate() => s => !s.Hidden; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/MovePackFilter.cs b/ProjectLighthouse/Filter/Filters/MovePackFilter.cs index 65658a8d..5c29834a 100644 --- a/ProjectLighthouse/Filter/Filters/MovePackFilter.cs +++ b/ProjectLighthouse/Filter/Filters/MovePackFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class MovePackFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.MoveRequired); + public Expression> GetPredicate() => s => s.MoveRequired; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/ResultTypeFilter.cs b/ProjectLighthouse/Filter/Filters/ResultTypeFilter.cs index 5e8ce64c..3460fb57 100644 --- a/ProjectLighthouse/Filter/Filters/ResultTypeFilter.cs +++ b/ProjectLighthouse/Filter/Filters/ResultTypeFilter.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -16,8 +15,5 @@ public class ResultTypeFilter : ISlotFilter this.results = results; } - public Expression> GetPredicate() => - this.results.Contains("slot") - ? PredicateExtensions.True() - : PredicateExtensions.False(); + public Expression> GetPredicate() => this.results.Contains("slot") ? s => true : s => false; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/SlotTypeFilter.cs b/ProjectLighthouse/Filter/Filters/SlotTypeFilter.cs index 34cfd5b0..96ea578d 100644 --- a/ProjectLighthouse/Filter/Filters/SlotTypeFilter.cs +++ b/ProjectLighthouse/Filter/Filters/SlotTypeFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; using LBPUnion.ProjectLighthouse.Types.Levels; @@ -16,6 +15,5 @@ public class SlotTypeFilter : ISlotFilter this.slotType = slotType; } - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.Type == this.slotType); + public Expression> GetPredicate() => s => s.Type == this.slotType; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/SubLevelFilter.cs b/ProjectLighthouse/Filter/Filters/SubLevelFilter.cs index 4ca2a0f8..2116ae66 100644 --- a/ProjectLighthouse/Filter/Filters/SubLevelFilter.cs +++ b/ProjectLighthouse/Filter/Filters/SubLevelFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -15,6 +14,5 @@ public class SubLevelFilter : ISlotFilter this.userId = userId; } - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => !s.SubLevel || s.CreatorId == this.userId); + public Expression> GetPredicate() => s => !s.SubLevel || s.CreatorId == this.userId; } \ No newline at end of file diff --git a/ProjectLighthouse/Filter/Filters/TeamPickFilter.cs b/ProjectLighthouse/Filter/Filters/TeamPickFilter.cs index 01ec2c4c..7a80d050 100644 --- a/ProjectLighthouse/Filter/Filters/TeamPickFilter.cs +++ b/ProjectLighthouse/Filter/Filters/TeamPickFilter.cs @@ -1,6 +1,5 @@ using System; using System.Linq.Expressions; -using LBPUnion.ProjectLighthouse.Extensions; using LBPUnion.ProjectLighthouse.Types.Entities.Level; using LBPUnion.ProjectLighthouse.Types.Filter; @@ -8,6 +7,5 @@ namespace LBPUnion.ProjectLighthouse.Filter.Filters; public class TeamPickFilter : ISlotFilter { - public Expression> GetPredicate() => - PredicateExtensions.True().And(s => s.TeamPick); + public Expression> GetPredicate() => s => s.TeamPick; } \ No newline at end of file diff --git a/ProjectLighthouse/Helpers/LastContactHelper.cs b/ProjectLighthouse/Helpers/LastContactHelper.cs index c1da7e54..7264e4f7 100644 --- a/ProjectLighthouse/Helpers/LastContactHelper.cs +++ b/ProjectLighthouse/Helpers/LastContactHelper.cs @@ -10,7 +10,6 @@ namespace LBPUnion.ProjectLighthouse.Helpers; public static class LastContactHelper { - public static async Task SetLastContact(DatabaseContext database, UserEntity user, GameVersion gameVersion, Platform platform) { LastContactEntity? lastContact = await database.LastContacts.Where(l => l.UserId == user.UserId).FirstOrDefaultAsync();