-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed Playnite crash when StartPage settings are loaded slower than UI
- Loading branch information
1 parent
9197280
commit 06a9667
Showing
5 changed files
with
483 additions
and
474 deletions.
There are no files selected for viewing
274 changes: 137 additions & 137 deletions
274
PlayNext.IntegrationTests/Extensions/GameActivity/GameActivityExtensionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,147 +1,147 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Moq; | ||
using Moq; | ||
using PlayNext.Extensions.GameActivity; | ||
using PlayNext.Infrastructure.Services; | ||
using PlayNext.Settings; | ||
using Playnite.SDK.Models; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using TestTools.Shared; | ||
using Xunit; | ||
|
||
namespace PlayNext.IntegrationTests.Extensions.GameActivity | ||
{ | ||
public class GameActivityExtensionTests | ||
{ | ||
private const string TestDataPath = @"Extensions\GameActivity\TestData"; | ||
private const string ExtensionsDataPath = @"Extensions\GameActivity\ExtensionsData"; | ||
|
||
public GameActivityExtensionTests() | ||
{ | ||
Utils.CopyDirectory(TestDataPath, ExtensionsDataPath, true); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public void GameActivityPathExists_ReturnsFalse_WhenPathDoesNotExist( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
CleanUpExtensionsDataPath(); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.False(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public void GameActivityPathExists_ReturnsTrue_WhenPathExists( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.True(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsTrue_WhenPathExists( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.True(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsAllGamesWithZeroTime_WhenNoActivityFilesExistsForGames( | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
Assert.Equal(games.Count(), gamesWithRecentPlaytime.Count()); | ||
Assert.All(gamesWithRecentPlaytime, x => Assert.Equal(0d, x.Playtime)); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsGameWithPlaytime_WhenActivityWasWithinRecentTime( | ||
int recentDays, | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var gameId = Guid.Parse("f1044699-4b97-4968-868b-e871e37ae1f3"); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
var gameWithActivity = games.First(); | ||
gameWithActivity.Id = gameId; | ||
settings.RecentDays = recentDays; | ||
dateTimeProviderMock | ||
.Setup(x => x.GetNow()) | ||
.Returns(DateTime.Parse("2023-02-12T13:40:18.2429471Z") + TimeSpan.FromDays(recentDays / 2)); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
var game = gamesWithRecentPlaytime.First(x => x.Id == gameId); | ||
Assert.Equal(67, (int)game.Playtime); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsGameWithZeroTime_WhenActivityWasNotWithinRecentTime( | ||
int recentDays, | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var gameId = Guid.Parse("f1044699-4b97-4968-868b-e871e37ae1f3"); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
var gameWithActivity = games.First(); | ||
gameWithActivity.Id = gameId; | ||
settings.RecentDays = recentDays; | ||
dateTimeProviderMock | ||
.Setup(x => x.GetNow()) | ||
.Returns(DateTime.Parse("2023-02-12T13:40:18.2429471Z") + TimeSpan.FromDays(recentDays * 2)); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
var game = gamesWithRecentPlaytime.First(x => x.Id == gameId); | ||
Assert.Equal(0d, game.Playtime); | ||
} | ||
|
||
private static void CleanUpExtensionsDataPath() | ||
{ | ||
foreach (var dir in Directory.GetDirectories(ExtensionsDataPath)) | ||
{ | ||
Directory.Delete(dir, true); | ||
} | ||
} | ||
} | ||
public class GameActivityExtensionTests | ||
{ | ||
private const string TestDataPath = @"Extensions\GameActivity\TestData"; | ||
private const string ExtensionsDataPath = @"Extensions\GameActivity\ExtensionsData"; | ||
|
||
public GameActivityExtensionTests() | ||
{ | ||
Utils.CopyDirectory(TestDataPath, ExtensionsDataPath, true); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public void GameActivityPathExists_ReturnsFalse_WhenPathDoesNotExist( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
CleanUpExtensionsDataPath(); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.False(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public void GameActivityPathExists_ReturnsTrue_WhenPathExists( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.True(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public void GetRecentPlaytime_ReturnsTrue_WhenPathExists( | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
var pathExists = sut.GameActivityPathExists(); | ||
|
||
// Assert | ||
Assert.True(pathExists); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsAllGamesWithZeroTime_WhenNoActivityFilesExistsForGames( | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
Assert.Equal(games.Count(), gamesWithRecentPlaytime.Count()); | ||
Assert.All(gamesWithRecentPlaytime, x => Assert.Equal(0d, x.Playtime)); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsGameWithPlaytime_WhenActivityWasWithinRecentTime( | ||
int recentDays, | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var gameId = Guid.Parse("f1044699-4b97-4968-868b-e871e37ae1f3"); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
var gameWithActivity = games.First(); | ||
gameWithActivity.Id = gameId; | ||
settings.RecentDays = recentDays; | ||
dateTimeProviderMock | ||
.Setup(x => x.GetNow()) | ||
.Returns(DateTime.Parse("2023-02-12T13:40:18.2429471Z") + TimeSpan.FromDays(recentDays / 2)); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
var game = gamesWithRecentPlaytime.First(x => x.Id == gameId); | ||
Assert.Equal(67, (int)game.Playtime); | ||
} | ||
|
||
[Theory, AutoMoqData] | ||
public async Task GetRecentPlaytime_ReturnsGameWithZeroTime_WhenActivityWasNotWithinRecentTime( | ||
int recentDays, | ||
IEnumerable<Game> games, | ||
PlayNextSettings settings, | ||
Mock<IDateTimeProvider> dateTimeProviderMock) | ||
{ | ||
// Arrange | ||
var gameId = Guid.Parse("f1044699-4b97-4968-868b-e871e37ae1f3"); | ||
var sut = GameActivityExtension.Create(dateTimeProviderMock.Object, ExtensionsDataPath); | ||
var gameWithActivity = games.First(); | ||
gameWithActivity.Id = gameId; | ||
settings.RecentDays = recentDays; | ||
dateTimeProviderMock | ||
.Setup(x => x.GetNow()) | ||
.Returns(DateTime.Parse("2023-02-12T13:40:18.2429471Z") + TimeSpan.FromDays(recentDays * 2)); | ||
|
||
// Act | ||
await sut.ParseGameActivity(games); | ||
var gamesWithRecentPlaytime = sut.GetRecentPlaytime(games, settings); | ||
|
||
// Assert | ||
var game = gamesWithRecentPlaytime.First(x => x.Id == gameId); | ||
Assert.Equal(0d, game.Playtime); | ||
} | ||
|
||
private static void CleanUpExtensionsDataPath() | ||
{ | ||
foreach (var dir in Directory.GetDirectories(ExtensionsDataPath)) | ||
{ | ||
Directory.Delete(dir, true); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,50 @@ | ||
using System; | ||
using PlayNext.Extensions.StartPage.Settings; | ||
using Playnite.SDK; | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using PlayNext.Extensions.StartPage.Settings; | ||
using Playnite.SDK; | ||
|
||
namespace PlayNext.Extensions.StartPage | ||
{ | ||
public class LandingPageExtension | ||
{ | ||
private static readonly ILogger Logger = LogManager.GetLogger(nameof(LandingPageExtension)); | ||
|
||
private LandingPageExtension(LandingPageSettings settings) | ||
{ | ||
Settings = settings; | ||
} | ||
|
||
public LandingPageSettings Settings { get; set; } | ||
|
||
public static LandingPageExtension Instance { get; set; } | ||
|
||
public static void CreateInstance(IPlayniteAPI api) | ||
{ | ||
new Task(() => | ||
{ | ||
try | ||
{ | ||
var plugin = api.Addons.Plugins.FirstOrDefault(x => | ||
x.Id == Guid.Parse("a6a3dcf6-9bfe-426c-afb0-9f49409ae0c5")); | ||
if (plugin == null) | ||
{ | ||
Logger.Debug("Did not find start page plugin"); | ||
return; | ||
} | ||
var settings = plugin.LoadPluginSettings<LandingPageSettings>(); | ||
var landingPageExtension = new LandingPageExtension(settings); | ||
Instance = landingPageExtension; | ||
Logger.Debug("Settings loaded: " + settings); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Logger.Error(ex, "Error loading start page settings"); | ||
} | ||
}).Start(); | ||
} | ||
} | ||
public class LandingPageExtension | ||
{ | ||
private static readonly ILogger Logger = LogManager.GetLogger(nameof(LandingPageExtension)); | ||
|
||
private LandingPageExtension(LandingPageSettings settings) | ||
{ | ||
Settings = settings; | ||
} | ||
|
||
public LandingPageSettings Settings { get; set; } | ||
|
||
public static LandingPageExtension Instance { get; set; } | ||
|
||
public static void CreateInstance(IPlayniteAPI api) | ||
{ | ||
new Task(() => | ||
{ | ||
try | ||
{ | ||
var plugin = api.Addons.Plugins.FirstOrDefault(x => | ||
x.Id == Guid.Parse("a6a3dcf6-9bfe-426c-afb0-9f49409ae0c5")); | ||
if (plugin == null) | ||
{ | ||
Logger.Debug("Did not find start page plugin"); | ||
return; | ||
} | ||
var settings = plugin.LoadPluginSettings<LandingPageSettings>(); | ||
var landingPageExtension = new LandingPageExtension(settings); | ||
Instance = landingPageExtension; | ||
Logger.Debug("Settings loaded: " + settings); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Logger.Error(ex, "Error loading start page settings"); | ||
} | ||
}).Start(); | ||
} | ||
} | ||
} |
Oops, something went wrong.