2022-07-07 15:42:48 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2022-07-13 15:43:39 +08:00
using System ;
2022-07-07 15:42:48 +08:00
using System.Linq ;
using NUnit.Framework ;
2022-07-08 17:59:08 +08:00
using osu.Framework.Allocation ;
using osu.Framework.Audio ;
using osu.Framework.Extensions ;
2022-07-09 00:02:46 +08:00
using osu.Framework.Extensions.ObjectExtensions ;
2022-07-15 19:14:58 +08:00
using osu.Framework.Graphics.Containers ;
2022-07-08 17:59:08 +08:00
using osu.Framework.Platform ;
2022-07-07 15:42:48 +08:00
using osu.Framework.Screens ;
2022-07-15 19:14:58 +08:00
using osu.Framework.Testing ;
2022-07-08 17:59:08 +08:00
using osu.Game.Beatmaps ;
2022-07-15 19:14:58 +08:00
using osu.Game.Graphics.Containers ;
2022-07-07 15:42:48 +08:00
using osu.Game.Rulesets ;
2022-09-19 10:31:38 +08:00
using osu.Game.Rulesets.Mods ;
2022-07-07 15:42:48 +08:00
using osu.Game.Rulesets.Objects ;
using osu.Game.Rulesets.Osu ;
2022-09-19 10:31:38 +08:00
using osu.Game.Rulesets.Osu.Mods ;
2022-07-08 18:17:51 +08:00
using osu.Game.Rulesets.Scoring ;
2022-07-07 15:42:48 +08:00
using osu.Game.Scoring ;
2022-07-15 19:14:58 +08:00
using osu.Game.Screens.Play ;
2022-07-07 15:42:48 +08:00
using osu.Game.Screens.Ranking ;
2022-07-08 17:59:08 +08:00
using osu.Game.Tests.Resources ;
2022-07-07 15:42:48 +08:00
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestScenePlayerLocalScoreImport : PlayerTestScene
{
2022-07-08 17:59:08 +08:00
private BeatmapManager beatmaps = null ! ;
private RulesetStore rulesets = null ! ;
private BeatmapSetInfo ? importedSet ;
2022-07-07 15:42:48 +08:00
2022-07-08 17:59:08 +08:00
[BackgroundDependencyLoader]
private void load ( GameHost host , AudioManager audio )
{
Dependencies . Cache ( rulesets = new RealmRulesetStore ( Realm ) ) ;
2022-07-28 15:19:05 +08:00
Dependencies . Cache ( beatmaps = new BeatmapManager ( LocalStorage , Realm , null , audio , Resources , host , Beatmap . Default ) ) ;
2022-08-22 20:31:30 +08:00
Dependencies . Cache ( new ScoreManager ( rulesets , ( ) = > beatmaps , LocalStorage , Realm , API ) ) ;
2022-07-08 17:59:08 +08:00
Dependencies . Cache ( Realm ) ;
}
public override void SetUpSteps ( )
{
base . SetUpSteps ( ) ;
AddStep ( "import beatmap" , ( ) = >
{
beatmaps . Import ( TestResources . GetQuickTestBeatmapForImport ( ) ) . WaitSafely ( ) ;
importedSet = beatmaps . GetAllUsableBeatmapSets ( ) . First ( ) ;
} ) ;
}
protected override IBeatmap CreateBeatmap ( RulesetInfo ruleset ) = > beatmaps . GetWorkingBeatmap ( importedSet ? . Beatmaps . First ( ) ) . Beatmap ;
private Ruleset ? customRuleset ;
2022-07-07 15:42:48 +08:00
protected override Ruleset CreatePlayerRuleset ( ) = > customRuleset ? ? new OsuRuleset ( ) ;
protected override TestPlayer CreatePlayer ( Ruleset ruleset ) = > new TestPlayer ( false ) ;
protected override bool HasCustomSteps = > true ;
2022-07-15 19:14:58 +08:00
protected override bool AllowFail = > allowFail ;
private bool allowFail ;
2022-07-16 03:09:54 +08:00
[SetUp]
public void SetUp ( )
{
allowFail = false ;
customRuleset = null ;
}
2022-07-15 19:14:58 +08:00
[Test]
public void TestSaveFailedReplay ( )
{
2022-07-16 03:09:54 +08:00
AddStep ( "allow fail" , ( ) = > allowFail = true ) ;
2022-07-15 19:14:58 +08:00
CreateTest ( ) ;
AddUntilStep ( "fail screen displayed" , ( ) = > Player . ChildrenOfType < FailOverlay > ( ) . First ( ) . State . Value = = Visibility . Visible ) ;
2022-09-08 15:48:43 +08:00
AddUntilStep ( "wait for button clickable" , ( ) = > Player . ChildrenOfType < SaveFailedScoreButton > ( ) . First ( ) . ChildrenOfType < OsuClickableContainer > ( ) . First ( ) . Enabled . Value ) ;
2022-07-15 19:14:58 +08:00
AddUntilStep ( "score not in database" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) = = null ) ) ;
AddStep ( "click save button" , ( ) = > Player . ChildrenOfType < SaveFailedScoreButton > ( ) . First ( ) . ChildrenOfType < OsuClickableContainer > ( ) . First ( ) . TriggerClick ( ) ) ;
2022-09-08 15:48:43 +08:00
AddUntilStep ( "score in database" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) ! = null ) ) ;
2022-07-15 19:14:58 +08:00
}
2022-07-07 15:42:48 +08:00
2022-07-13 15:43:39 +08:00
[Test]
public void TestLastPlayedUpdated ( )
{
DateTimeOffset ? getLastPlayed ( ) = > Realm . Run ( r = > r . Find < BeatmapInfo > ( Beatmap . Value . BeatmapInfo . ID ) ? . LastPlayed ) ;
AddAssert ( "last played is null" , ( ) = > getLastPlayed ( ) = = null ) ;
CreateTest ( ) ;
AddUntilStep ( "wait for track to start running" , ( ) = > Beatmap . Value . Track . IsRunning ) ;
AddUntilStep ( "wait for last played to update" , ( ) = > getLastPlayed ( ) ! = null ) ;
}
2022-09-19 10:31:38 +08:00
[Test]
public void TestModReferenceNotRetained ( )
{
AddStep ( "allow fail" , ( ) = > allowFail = false ) ;
Mod [ ] originalMods = { new OsuModDaycore { SpeedChange = { Value = 0.8 } } } ;
Mod [ ] playerMods = null ! ;
2022-09-19 20:51:54 +08:00
AddStep ( "load player with mods" , ( ) = > LoadPlayer ( originalMods ) ) ;
2022-09-19 10:31:38 +08:00
AddUntilStep ( "player loaded" , ( ) = > Player . IsLoaded & & Player . Alpha = = 1 ) ;
AddStep ( "get mods at start of gameplay" , ( ) = > playerMods = Player . Score . ScoreInfo . Mods . ToArray ( ) ) ;
// Player creates new instance of mods during load.
AddAssert ( "player score has copied mods" , ( ) = > playerMods . First ( ) , ( ) = > Is . Not . SameAs ( originalMods . First ( ) ) ) ;
AddAssert ( "player score has matching mods" , ( ) = > playerMods . First ( ) , ( ) = > Is . EqualTo ( originalMods . First ( ) ) ) ;
AddUntilStep ( "wait for track to start running" , ( ) = > Beatmap . Value . Track . IsRunning ) ;
AddStep ( "seek to completion" , ( ) = > Player . GameplayClockContainer . Seek ( Player . DrawableRuleset . Objects . Last ( ) . GetEndTime ( ) ) ) ;
AddUntilStep ( "results displayed" , ( ) = > Player . GetChildScreen ( ) is ResultsScreen ) ;
// Player creates new instance of mods after gameplay to ensure any runtime references to drawables etc. are not retained.
AddAssert ( "results screen score has copied mods" , ( ) = > ( Player . GetChildScreen ( ) as ResultsScreen ) ? . Score . Mods . First ( ) , ( ) = > Is . Not . SameAs ( playerMods . First ( ) ) ) ;
AddAssert ( "results screen score has matching" , ( ) = > ( Player . GetChildScreen ( ) as ResultsScreen ) ? . Score . Mods . First ( ) , ( ) = > Is . EqualTo ( playerMods . First ( ) ) ) ;
AddUntilStep ( "score in database" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) ! = null ) ) ;
AddUntilStep ( "databased score has correct mods" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) ) . Mods . First ( ) , ( ) = > Is . EqualTo ( playerMods . First ( ) ) ) ;
}
2022-07-07 15:42:48 +08:00
[Test]
public void TestScoreStoredLocally ( )
{
CreateTest ( ) ;
AddUntilStep ( "wait for track to start running" , ( ) = > Beatmap . Value . Track . IsRunning ) ;
AddStep ( "seek to completion" , ( ) = > Player . GameplayClockContainer . Seek ( Player . DrawableRuleset . Objects . Last ( ) . GetEndTime ( ) ) ) ;
AddUntilStep ( "results displayed" , ( ) = > Player . GetChildScreen ( ) is ResultsScreen ) ;
AddUntilStep ( "score in database" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) ! = null ) ) ;
}
[Test]
public void TestScoreStoredLocallyCustomRuleset ( )
{
2022-07-08 18:17:51 +08:00
Ruleset createCustomRuleset ( ) = > new CustomRuleset ( ) ;
2022-07-07 15:42:48 +08:00
AddStep ( "import custom ruleset" , ( ) = > Realm . Write ( r = > r . Add ( createCustomRuleset ( ) . RulesetInfo ) ) ) ;
AddStep ( "set custom ruleset" , ( ) = > customRuleset = createCustomRuleset ( ) ) ;
CreateTest ( ) ;
2022-07-09 00:02:46 +08:00
AddAssert ( "score has custom ruleset" , ( ) = > Player . Score . ScoreInfo . Ruleset . Equals ( customRuleset . AsNonNull ( ) . RulesetInfo ) ) ;
2022-07-07 15:42:48 +08:00
AddUntilStep ( "wait for track to start running" , ( ) = > Beatmap . Value . Track . IsRunning ) ;
AddStep ( "seek to completion" , ( ) = > Player . GameplayClockContainer . Seek ( Player . DrawableRuleset . Objects . Last ( ) . GetEndTime ( ) ) ) ;
AddUntilStep ( "results displayed" , ( ) = > Player . GetChildScreen ( ) is ResultsScreen ) ;
2022-07-08 17:59:08 +08:00
AddUntilStep ( "score in database" , ( ) = > Realm . Run ( r = > r . Find < ScoreInfo > ( Player . Score . ScoreInfo . ID ) ! = null ) ) ;
2022-07-07 15:42:48 +08:00
}
2022-07-08 18:17:51 +08:00
private class CustomRuleset : OsuRuleset , ILegacyRuleset
{
public override string Description = > "custom" ;
public override string ShortName = > "custom" ;
2022-07-09 00:01:21 +08:00
int ILegacyRuleset . LegacyID = > - 1 ;
2022-07-08 18:17:51 +08:00
public override ScoreProcessor CreateScoreProcessor ( ) = > new ScoreProcessor ( this ) ;
}
2022-07-07 15:42:48 +08:00
}
}