diff --git a/Core b/Core
index fc794b4b..2f7ed7a4 160000
--- a/Core
+++ b/Core
@@ -1 +1 @@
-Subproject commit fc794b4bbe20e099702c93fb75f0b97c651ed819
+Subproject commit 2f7ed7a4b9d588bc6fae41aaf9a0f8b87a909451
diff --git a/Source/Data/AchievementSetType.cs b/Source/Data/AchievementSetType.cs
index 65552bf4..6c3129d2 100644
--- a/Source/Data/AchievementSetType.cs
+++ b/Source/Data/AchievementSetType.cs
@@ -23,6 +23,15 @@ public enum AchievementSetType
///
Bonus,
+ ///
+ /// A unique way to play the game.
+ ///
+ ///
+ /// Allows loading the core set and potentially bonus sets.
+ /// Must be explicitly opted-in by the player.
+ ///
+ Challenge,
+
///
/// A unique way to play the game.
///
diff --git a/Source/Parser/AchievementScriptInterpreter.cs b/Source/Parser/AchievementScriptInterpreter.cs
index 14146533..ad231bf2 100644
--- a/Source/Parser/AchievementScriptInterpreter.cs
+++ b/Source/Parser/AchievementScriptInterpreter.cs
@@ -24,6 +24,7 @@ public AchievementScriptInterpreter()
_achievements = new Dictionary();
_leaderboards = new Dictionary();
_richPresence = new RichPresenceBuilder();
+ Sets = Array.Empty();
_minimumVersion = RATools.Data.Version.MinimumVersion;
}
@@ -55,6 +56,11 @@ internal void AddAchievement(Achievement achievement)
_achievements[achievement] = 0;
}
+ ///
+ /// Gets the sets generated by the script.
+ ///
+ public IEnumerable Sets { get; private set; }
+
///
/// Gets the game identifier from the script.
///
@@ -328,6 +334,7 @@ public bool Run(ExpressionGroupCollection expressionGroups, IScriptInterpreterCa
_achievements.Clear();
_leaderboards.Clear();
_richPresence.Clear();
+ var sets = new List();
foreach (var expressionGroup in expressionGroups.Groups.OfType())
{
@@ -352,7 +359,11 @@ public bool Run(ExpressionGroupCollection expressionGroups, IScriptInterpreterCa
result = false;
}
}
+
+ if (expressionGroup.GeneratedSets != null)
+ sets.AddRange(expressionGroup.GeneratedSets);
}
+ Sets = sets;
SoftwareVersion minimumVersion = scriptContext.SerializationContext.MinimumVersion.OrNewer(_minimumVersion);
uint maxAddress = 0;
diff --git a/Source/Parser/Functions/AchievementSetFunction.cs b/Source/Parser/Functions/AchievementSetFunction.cs
index 9b003546..19df07e5 100644
--- a/Source/Parser/Functions/AchievementSetFunction.cs
+++ b/Source/Parser/Functions/AchievementSetFunction.cs
@@ -79,6 +79,7 @@ public override bool Evaluate(InterpreterScope scope, out ExpressionBase result)
case "BONUS": set.Type = AchievementSetType.Bonus; break;
case "SPECIALTY": set.Type = AchievementSetType.Specialty; break;
case "EXCLUSIVE": set.Type = AchievementSetType.Exclusive; break;
+ case "CHALLENGE": set.Type = AchievementSetType.Challenge; break;
case "CORE":
result = new ErrorExpression("Cannot add CORE set. Only one is allowed, and is provided by default.", type);
diff --git a/Source/Parser/Internal/AssetExpressionGroup.cs b/Source/Parser/Internal/AssetExpressionGroup.cs
index ba130dab..3a59fc6f 100644
--- a/Source/Parser/Internal/AssetExpressionGroup.cs
+++ b/Source/Parser/Internal/AssetExpressionGroup.cs
@@ -16,6 +16,8 @@ public AssetExpressionGroup()
public RichPresenceBuilder GeneratedRichPresence { get; private set; }
+ public AchievementSet[] GeneratedSets { get; private set; }
+
protected override ExpressionGroup CreateGroup()
{
return new AssetExpressionGroup();
@@ -48,6 +50,12 @@ internal void CaptureGeneratedAssets(AchievementScriptContext context)
GeneratedRichPresence = context.RichPresence;
context.RichPresence = null;
}
+
+ if (context.Sets.Count > 0)
+ {
+ GeneratedSets = context.Sets.ToArray();
+ context.Sets.Clear();
+ }
}
internal override void AdjustSourceLines(int adjustment)
diff --git a/Source/ViewModels/AssetViewModelBase.cs b/Source/ViewModels/AssetViewModelBase.cs
index b48ad1a6..03401d77 100644
--- a/Source/ViewModels/AssetViewModelBase.cs
+++ b/Source/ViewModels/AssetViewModelBase.cs
@@ -145,6 +145,20 @@ public int Id
protected set { SetValue(IdProperty, value); }
}
+ public int OwnerSetId
+ {
+ get
+ {
+ if (Generated.Asset != null && Generated.Asset.OwnerSetId != 0)
+ return Generated.Asset.OwnerSetId;
+ if (Local.Asset != null && Local.Asset.OwnerSetId != 0)
+ return Local.Asset.OwnerSetId;
+ if (Published.Asset != null && Published.Asset.OwnerSetId != 0)
+ return Published.Asset.OwnerSetId;
+ return 0;
+ }
+ }
+
public static readonly ModelProperty PointsProperty = ModelProperty.Register(typeof(AssetViewModelBase), "Points", typeof(int), 0);
public int Points
{
@@ -187,6 +201,7 @@ private void UpdateModified()
{
Triggers = Local.TriggerList;
TriggerSource = "Local (Not Generated)";
+ CompareState = GeneratedCompareState.NotGenerated;
}
}
else if (IsModified(Local, true))
diff --git a/Source/ViewModels/GameViewModel.cs b/Source/ViewModels/GameViewModel.cs
index 83c39da6..86eb3518 100644
--- a/Source/ViewModels/GameViewModel.cs
+++ b/Source/ViewModels/GameViewModel.cs
@@ -224,18 +224,8 @@ internal void PopulateEditorList(AchievementScriptInterpreter interpreter)
GeneratedAchievementCount = 0;
}
- if (NavigationNodes == null || !NavigationNodes.Any())
- {
- var navigationNodes = new List();
- navigationNodes.Add(new ScriptFolderNavigationViewModel());
- navigationNodes.Add(new RichPresenceNavigationViewModel(null));
- navigationNodes.Add(new AssetFolderNavigationViewModel("Achievements"));
- navigationNodes.Add(new AssetFolderNavigationViewModel("Leaderboards"));
- NavigationNodes = navigationNodes;
- }
-
var navigation = new NavigationListViewModel(this, _publishedAssets, _localAssets, _editors);
- navigation.Merge(interpreter);
+ NavigationNodes = navigation.Merge(interpreter);
SelectedNavigationNode = FindEditorNavigationNode(NavigationNodes, SelectedEditor);
}
@@ -258,7 +248,7 @@ internal void UpdateCompileProgress(int progress, int line)
}
}
- public static readonly ModelProperty NavigationNodesProperty = ModelProperty.Register(typeof(GameViewModel), "Editors", typeof(IEnumerable), new NavigationViewModelBase[0]);
+ public static readonly ModelProperty NavigationNodesProperty = ModelProperty.Register(typeof(GameViewModel), "NavigationNodes", typeof(IEnumerable), new NavigationViewModelBase[0]);
public IEnumerable NavigationNodes
{
get { return (IEnumerable)GetValue(NavigationNodesProperty); }
@@ -539,7 +529,13 @@ public string Title
private set { SetValue(TitleProperty, value); }
}
- public IEnumerable PublishedSets { get { return _publishedAssets?.Sets ?? new AchievementSet[0]; } }
+ public IEnumerable PublishedSets
+ {
+ get
+ {
+ return _publishedAssets?.Sets ?? new [] { new AchievementSet { OwnerGameId = GameId, Title = Title } };
+ }
+ }
public static readonly ModelProperty GeneratedAchievementCountProperty = ModelProperty.Register(typeof(MainWindowViewModel), "GeneratedAchievementCount", typeof(int), 0);
public int GeneratedAchievementCount
diff --git a/Source/ViewModels/Navigation/AchievementSetFolderNavigationViewModel.cs b/Source/ViewModels/Navigation/AchievementSetFolderNavigationViewModel.cs
new file mode 100644
index 00000000..7d0144a1
--- /dev/null
+++ b/Source/ViewModels/Navigation/AchievementSetFolderNavigationViewModel.cs
@@ -0,0 +1,15 @@
+using RATools.Data;
+
+namespace RATools.ViewModels.Navigation
+{
+ internal class AchievementSetFolderNavigationViewModel : AssetFolderNavigationViewModel
+ {
+ public AchievementSetFolderNavigationViewModel(AchievementSet achievementSet)
+ : base(achievementSet.Title)
+ {
+ AchievementSet = achievementSet;
+ }
+
+ public AchievementSet AchievementSet { get; private set; }
+ }
+}
diff --git a/Source/ViewModels/Navigation/NavigationListViewModel.cs b/Source/ViewModels/Navigation/NavigationListViewModel.cs
index 636c85cb..014f2b19 100644
--- a/Source/ViewModels/Navigation/NavigationListViewModel.cs
+++ b/Source/ViewModels/Navigation/NavigationListViewModel.cs
@@ -31,14 +31,14 @@ public NavigationListViewModel(GameViewModel gameViewModel, PublishedAssets publ
private readonly List _editors;
private readonly IBackgroundWorkerService _backgroundWorkerService;
- private void MergeScript()
+ private void MergeScript(IEnumerable navigationNodes)
{
if (_gameViewModel.Script != null)
{
if (!_editors.Contains(_gameViewModel.Script))
_editors.Add(_gameViewModel.Script);
- var scriptFolder = _gameViewModel.NavigationNodes.OfType().First();
+ var scriptFolder = navigationNodes.OfType().First();
var scriptNode = scriptFolder.Children.OfType().FirstOrDefault();
if (scriptNode == null)
{
@@ -349,21 +349,45 @@ private void MergeLocal()
}
}
- private void UpdateNavigationNodes()
+ private void UpdateNavigationNodes(IEnumerable navigationNodes)
{
- MergeScript();
+ MergeScript(navigationNodes);
var richPresence = _editors.OfType().FirstOrDefault();
if (richPresence != null)
{
- var richPresenceNode = _gameViewModel.NavigationNodes.OfType().First();
+ var richPresenceNode = navigationNodes.OfType().First();
richPresenceNode.Editor = richPresence;
}
- var achievementsFolder = _gameViewModel.NavigationNodes.OfType().First(n => n.Label == "Achievements");
+ bool hasSubsets = false;
+ foreach (var achievementSetNode in navigationNodes.OfType())
+ {
+ var achievementsFolder = achievementSetNode.Children.OfType().First(n => n.Label == "Achievements");
+ var leaderboardsFolder = achievementSetNode.Children.OfType().First(n => n.Label == "Leaderboards");
+ UpdateAchievementSetNodes(achievementsFolder, leaderboardsFolder, achievementSetNode.AchievementSet);
+ hasSubsets = true;
+ }
+
+ if (!hasSubsets)
+ {
+ var achievementsFolder = navigationNodes.OfType().First(n => n.Label == "Achievements");
+ var leaderboardsFolder = navigationNodes.OfType().First(n => n.Label == "Leaderboards");
+ UpdateAchievementSetNodes(achievementsFolder, leaderboardsFolder, null);
+ }
+ }
+
+ private void UpdateAchievementSetNodes(AssetFolderNavigationViewModel achievementsFolder, AssetFolderNavigationViewModel leaderboardsFolder, AchievementSet achievementSet)
+ {
var achievementNodes = achievementsFolder.Children.OfType().ToList();
foreach (var achievement in _editors.OfType())
{
+ if (achievementSet != null && achievement.OwnerSetId != achievementSet.Id)
+ {
+ if (achievement.OwnerSetId != 0 || achievementSet.Type != AchievementSetType.Core)
+ continue;
+ }
+
if (achievement.Generated.Asset == null && achievement.Local.Asset == null && achievement.Published.Asset == null)
{
// nothing keeping this node around, let it get discarded
@@ -387,7 +411,6 @@ private void UpdateNavigationNodes()
foreach (var achievementNode in achievementNodes)
achievementsFolder.Children.Remove(achievementNode);
- var leaderboardsFolder = _gameViewModel.NavigationNodes.OfType().First(n => n.Label == "Leaderboards");
var leaderboardNodes = leaderboardsFolder.Children.OfType().ToList();
foreach (var leaderboard in _editors.OfType())
{
@@ -459,8 +482,54 @@ private static void ApplySort(ObservableCollection node
}
}
- public void Merge(AchievementScriptInterpreter interpreter)
+ public IEnumerable Merge(AchievementScriptInterpreter interpreter)
{
+ var navigationNodes = _gameViewModel.NavigationNodes;
+
+ var previousSubsetCount = navigationNodes != null ? navigationNodes.OfType().Count() : 0;
+ var sets = new List();
+ if (interpreter != null)
+ sets.AddRange(interpreter.Sets);
+ foreach (var set in _gameViewModel.PublishedSets)
+ {
+ if (!sets.Any(s => s.Id == set.Id))
+ sets.Add(set);
+ }
+ if (sets.Count == 0)
+ sets.Add(new AchievementSet { OwnerGameId = _gameViewModel.GameId, Title = _gameViewModel.Title });
+
+ if (sets.Count != previousSubsetCount)
+ {
+ var newNavigationNodes = new List();
+ if (navigationNodes != null && navigationNodes.Any())
+ {
+ newNavigationNodes.AddRange(navigationNodes.Take(2));
+ }
+ else
+ {
+ newNavigationNodes.Add(new ScriptFolderNavigationViewModel());
+ newNavigationNodes.Add(new RichPresenceNavigationViewModel(null));
+ }
+
+ if (sets.Count < 2)
+ {
+ newNavigationNodes.Add(new AssetFolderNavigationViewModel("Achievements"));
+ newNavigationNodes.Add(new AssetFolderNavigationViewModel("Leaderboards"));
+ }
+ else
+ {
+ foreach (var achievementSet in sets)
+ {
+ var setFolderNode = new AchievementSetFolderNavigationViewModel(achievementSet);
+ setFolderNode.AddChild(new AssetFolderNavigationViewModel("Achievements"));
+ setFolderNode.AddChild(new AssetFolderNavigationViewModel("Leaderboards"));
+ newNavigationNodes.Add(setFolderNode);
+ }
+ }
+
+ navigationNodes = newNavigationNodes.ToArray();
+ }
+
foreach (var editor in _editors.OfType())
editor.SortOrder = 0;
@@ -480,11 +549,13 @@ public void Merge(AchievementScriptInterpreter interpreter)
_backgroundWorkerService.InvokeOnUiThread(() =>
{
- UpdateNavigationNodes();
+ UpdateNavigationNodes(navigationNodes);
- foreach (var node in _gameViewModel.NavigationNodes)
+ foreach (var node in navigationNodes)
ApplySort(node.Children);
});
+
+ return navigationNodes;
}
}
}
diff --git a/Source/ViewModels/Navigation/NavigationViewModelBase.cs b/Source/ViewModels/Navigation/NavigationViewModelBase.cs
index 35edd19c..9ca2d11b 100644
--- a/Source/ViewModels/Navigation/NavigationViewModelBase.cs
+++ b/Source/ViewModels/Navigation/NavigationViewModelBase.cs
@@ -77,7 +77,7 @@ protected virtual string GetModificationMessage(GeneratedCompareState state)
case GeneratedCompareState.PublishedDiffers: // ◐
return "Generated asset differs from published";
case GeneratedCompareState.NotGenerated: // ◖
- return "Published asset is not generated";
+ return "Local asset is not generated";
default:
return null;
}
diff --git a/Source/ViewModels/ViewerViewModelBase.cs b/Source/ViewModels/ViewerViewModelBase.cs
index 05b1a507..727b5f09 100644
--- a/Source/ViewModels/ViewerViewModelBase.cs
+++ b/Source/ViewModels/ViewerViewModelBase.cs
@@ -97,27 +97,27 @@ public enum GeneratedCompareState
None = 0,
///
- /// generated matches core and/or local. no icon
+ /// published by not generated or generated matches core and/or local. no icon
///
Same,
///
- /// ◖ not generated (core only). half circle icon
+ /// ◖ not generated (local only). half circle icon
///
NotGenerated,
///
- /// ○ generated but not stored (no core or no local). hollow circle icon
+ /// ○ generated but not stored (no published or no local). hollow circle icon
///
GeneratedOnly,
///
- /// ◐ generated differs from core (local may or may not exist). half filled circle icon
+ /// ◐ generated differs from published (local may or may not exist). half filled circle icon
///
PublishedDiffers,
///
- /// ● generated differs from local (core may or may not exist). fully filled circle icon
+ /// ● generated differs from local (published may or may not exist). fully filled circle icon
///
LocalDiffers,
}
diff --git a/Tests/ViewModels/AssetViewModelBaseTests.cs b/Tests/ViewModels/AssetViewModelBaseTests.cs
index f06f0f62..f8d3d4ce 100644
--- a/Tests/ViewModels/AssetViewModelBaseTests.cs
+++ b/Tests/ViewModels/AssetViewModelBaseTests.cs
@@ -186,7 +186,7 @@ public void TestRefreshLocalNotGenerated()
Assert.That(vmAsset.IsTitleModified, Is.False);
Assert.That(vmAsset.IsDescriptionModified, Is.False);
Assert.That(vmAsset.BadgeName, Is.EqualTo("Badge"));
- Assert.That(vmAsset.CompareState, Is.EqualTo(GeneratedCompareState.None));
+ Assert.That(vmAsset.CompareState, Is.EqualTo(GeneratedCompareState.NotGenerated));
Assert.That(vmAsset.ModificationMessage, Is.EqualTo("Not generated"));
Assert.That(vmAsset.IsGenerated, Is.False);
Assert.That(vmAsset.CanUpdate, Is.False);
diff --git a/Tests/ViewModels/Nagivation/NavigationListViewModelTests.cs b/Tests/ViewModels/Nagivation/NavigationListViewModelTests.cs
index f23c734a..87a6c103 100644
--- a/Tests/ViewModels/Nagivation/NavigationListViewModelTests.cs
+++ b/Tests/ViewModels/Nagivation/NavigationListViewModelTests.cs
@@ -27,13 +27,6 @@ public NavigationListViewModelHarness()
_editors = new List();
- var navigationNodes = new List();
- navigationNodes.Add(new ScriptFolderNavigationViewModel());
- navigationNodes.Add(new RichPresenceNavigationViewModel(null));
- navigationNodes.Add(new AssetFolderNavigationViewModel("Achievements"));
- navigationNodes.Add(new AssetFolderNavigationViewModel("Leaderboards"));
- NavigationNodes = navigationNodes;
-
ServiceRepository.Reset();
ServiceRepository.Instance.RegisterInstance(new Mock().Object);
}
@@ -42,20 +35,29 @@ public void Initialize()
{
if (Game == null)
{
- Game = new MockGameViewModel(_fileSystemService.Object);
- Game.SetValue(GameViewModel.NavigationNodesProperty, NavigationNodes);
-
_publishedAssets = new PublishedAssets("1234.json", _fileSystemService.Object);
_localAssets = new LocalAssets("1234-User.txt", _fileSystemService.Object);
+
+ Game = new MockGameViewModel(_fileSystemService.Object, _publishedAssets, _localAssets);
+ Game.SetValue(GameViewModel.NavigationNodesProperty, NavigationNodes);
}
}
+ public void InitializeSubsets()
+ {
+ Initialize();
+
+ var sets = (List)_publishedAssets.Sets;
+ sets.Add(new AchievementSet { Id = 1111, Title = Game.Title, Type = AchievementSetType.Core });
+ sets.Add(new AchievementSet { Id = 2222, Title = "Bonus", Type = AchievementSetType.Bonus });
+ }
+
public void Merge(AchievementScriptInterpreter interpreter)
{
Initialize();
var viewModel = new NavigationListViewModel(Game, _publishedAssets, _localAssets, _editors, _backgroundWorkerService.Object);
- viewModel.Merge(interpreter);
+ NavigationNodes = viewModel.Merge(interpreter).ToList();
}
public Achievement CreateAchievement(string title, int points = 5, AchievementType type = AchievementType.None)
@@ -105,10 +107,13 @@ public MockScriptViewModel()
class MockGameViewModel : GameViewModel
{
- public MockGameViewModel(IFileSystemService fileSystemService)
+ public MockGameViewModel(IFileSystemService fileSystemService, PublishedAssets publishedAssets, LocalAssets localAssets)
: base(1234, "Game Title", new Mock().Object, fileSystemService)
{
SetRACacheDirectory("C:\\RACache\\");
+
+ _publishedAssets = publishedAssets;
+ _localAssets = localAssets;
}
public void InitScript(string filename)
@@ -170,8 +175,8 @@ public void TestMergeLocalAchievement()
Assert.AreEqual("Test Achievement", achievementNode.Label);
Assert.IsNotNull(achievementNode.Editor);
Assert.AreSame(achievement, ((AchievementViewModel)achievementNode.Editor).Local.Asset);
- Assert.AreEqual(GeneratedCompareState.None, achievementNode.CompareState);
- Assert.IsNull(achievementNode.ModificationMessage);
+ Assert.AreEqual(GeneratedCompareState.NotGenerated, achievementNode.CompareState);
+ Assert.AreEqual("Local asset is not generated", achievementNode.ModificationMessage);
Assert.IsNotNull(achievementNode.ContextMenu);
Assert.AreEqual(1, achievementNode.ContextMenu.Count());
@@ -283,8 +288,8 @@ public void TestMergeLocalAndPublishedAchievementDifferentId()
Assert.IsNotNull(achievementNode.Editor);
Assert.IsNull(((AchievementViewModel)achievementNode.Editor).Published.Asset);
Assert.AreSame(localAchievement, ((AchievementViewModel)achievementNode.Editor).Local.Asset);
- Assert.AreEqual(GeneratedCompareState.None, achievementNode.CompareState);
- Assert.IsNull(achievementNode.ModificationMessage);
+ Assert.AreEqual(GeneratedCompareState.NotGenerated, achievementNode.CompareState);
+ Assert.AreEqual("Local asset is not generated", achievementNode.ModificationMessage);
achievementNode = harness.NavigationNodes[2].Children[1] as AchievementNavigationViewModel;
Assert.IsNotNull(achievementNode);
@@ -421,8 +426,8 @@ public void TestMergeLocalAndGeneratedAchievementDifferentId()
Assert.IsNotNull(achievementNode.Editor);
Assert.AreSame(localAchievement, ((AchievementViewModel)achievementNode.Editor).Local.Asset);
Assert.IsNull(((AchievementViewModel)achievementNode.Editor).Generated.Asset);
- Assert.AreEqual(GeneratedCompareState.None, achievementNode.CompareState);
- Assert.IsNull(achievementNode.ModificationMessage);
+ Assert.AreEqual(GeneratedCompareState.NotGenerated, achievementNode.CompareState);
+ Assert.AreEqual("Local asset is not generated", achievementNode.ModificationMessage);
Assert.IsNotNull(achievementNode.ContextMenu);
Assert.AreEqual(1, achievementNode.ContextMenu.Count());
@@ -538,5 +543,46 @@ public void TestMergePublishedAndGeneratedAchievementDifferentId()
Assert.AreEqual("Update Local", menuItem.Label);
Assert.IsFalse(menuItem.Command.CanExecute(null));
}
+
+
+ [Test]
+ public void TestMergeSubsetGeneratedAchievement()
+ {
+ var harness = new NavigationListViewModelHarness();
+ var achievement = harness.CreateAchievement("Test Achievement");
+ achievement.OwnerSetId = 2222;
+ harness.InitializeSubsets();
+
+ var interpreter = new AchievementScriptInterpreter();
+ interpreter.AddAchievement(achievement);
+ harness.Merge(interpreter);
+
+ Assert.AreEqual("Game Title", harness.NavigationNodes[2].Label);
+ Assert.AreEqual(2, harness.NavigationNodes[2].Children?.Count ?? 0);
+ Assert.AreEqual("Achievements", harness.NavigationNodes[2].Children[0].Label);
+ Assert.AreEqual(0, harness.NavigationNodes[2].Children[0].Children?.Count ?? 0);
+ Assert.AreEqual("Leaderboards", harness.NavigationNodes[2].Children[1].Label);
+ Assert.AreEqual(0, harness.NavigationNodes[2].Children[1].Children?.Count ?? 0);
+
+ Assert.AreEqual("Bonus", harness.NavigationNodes[3].Label);
+ Assert.AreEqual(2, harness.NavigationNodes[3].Children?.Count ?? 0);
+
+ Assert.AreEqual("Achievements", harness.NavigationNodes[3].Children[0].Label);
+ Assert.AreEqual(1, harness.NavigationNodes[3].Children[0].Children?.Count ?? 0);
+
+ var achievementNode = harness.NavigationNodes[3].Children[0].Children[0] as AchievementNavigationViewModel;
+ Assert.IsNotNull(achievementNode);
+ Assert.AreEqual("Test Achievement", achievementNode.Label);
+ Assert.IsNotNull(achievementNode.Editor);
+ Assert.AreSame(achievement, ((AchievementViewModel)achievementNode.Editor).Generated.Asset);
+ Assert.AreEqual(GeneratedCompareState.GeneratedOnly, achievementNode.CompareState);
+ Assert.AreEqual("Generated only", achievementNode.ModificationMessage);
+
+ Assert.IsNotNull(achievementNode.ContextMenu);
+ Assert.AreEqual(1, achievementNode.ContextMenu.Count());
+ var menuItem = achievementNode.ContextMenu.First();
+ Assert.AreEqual("Update Local", menuItem.Label);
+ Assert.IsTrue(menuItem.Command.CanExecute(null));
+ }
}
}
diff --git a/Tests/ViewModels/Nagivation/NavigationViewModelBaseTests.cs b/Tests/ViewModels/Nagivation/NavigationViewModelBaseTests.cs
index 709ab6fc..d53ae942 100644
--- a/Tests/ViewModels/Nagivation/NavigationViewModelBaseTests.cs
+++ b/Tests/ViewModels/Nagivation/NavigationViewModelBaseTests.cs
@@ -78,7 +78,7 @@ public void TestCompareStateAndModificationMessage()
harness.SetCompareState(GeneratedCompareState.NotGenerated);
Assert.That(harness.CompareState, Is.EqualTo(GeneratedCompareState.NotGenerated));
- Assert.That(harness.ModificationMessage, Is.EqualTo("Published asset is not generated"));
+ Assert.That(harness.ModificationMessage, Is.EqualTo("Local asset is not generated"));
harness.SetCompareState(GeneratedCompareState.PublishedDiffers);
Assert.That(harness.CompareState, Is.EqualTo(GeneratedCompareState.PublishedDiffers));