diff --git a/ModernKeePass/Interfaces/IDatabase.cs b/ModernKeePass/Interfaces/IDatabase.cs index e005b46..71e7912 100644 --- a/ModernKeePass/Interfaces/IDatabase.cs +++ b/ModernKeePass/Interfaces/IDatabase.cs @@ -1,20 +1,29 @@ -using ModernKeePass.ViewModels; +using Windows.Storage; +using ModernKeePass.ViewModels; using ModernKeePassLib; +using ModernKeePassLib.Cryptography.KeyDerivation; using ModernKeePassLib.Keys; namespace ModernKeePass.Interfaces { public interface IDatabase { + string Name { get; } bool RecycleBinEnabled { get; set; } int Status { get; set; } GroupVm RootGroup { get; set; } GroupVm RecycleBin { get; set; } + StorageFile DatabaseFile { get; set; } + PwUuid DataCipher { get; set; } + PwCompressionAlgorithm CompressionAlgorithm { get; set; } + KdfParameters KeyDerivation { get; set; } void Open(CompositeKey key, bool createNew); void UpdateCompositeKey(CompositeKey key); bool Save(); + bool Save(StorageFile file); void CreateRecycleBin(); void AddDeletedItem(PwUuid id); + void Close(); } } \ No newline at end of file diff --git a/ModernKeePass/ViewModels/AboutVm.cs b/ModernKeePass/ViewModels/AboutVm.cs index 15efb12..ccdacfe 100644 --- a/ModernKeePass/ViewModels/AboutVm.cs +++ b/ModernKeePass/ViewModels/AboutVm.cs @@ -4,17 +4,24 @@ namespace ModernKeePass.ViewModels { public class AboutVm { - public string Name { get; } = Package.Current.DisplayName; + private readonly Package _package; + + public string Name => _package.DisplayName; public string Version { get { - var package = Package.Current; - var version = package.Id.Version; - + var version = _package.Id.Version; return $"{version.Major}.{version.Minor}"; } } + + public AboutVm() : this(Package.Current) { } + + public AboutVm(Package package) + { + _package = package; + } } } diff --git a/ModernKeePass/ViewModels/EntryVm.cs b/ModernKeePass/ViewModels/EntryVm.cs index 2c2e7f5..59c44ec 100644 --- a/ModernKeePass/ViewModels/EntryVm.cs +++ b/ModernKeePass/ViewModels/EntryVm.cs @@ -14,7 +14,6 @@ namespace ModernKeePass.ViewModels { public class EntryVm : INotifyPropertyChanged, IPwEntity { - public IDatabase Database { get; set; } public GroupVm ParentGroup { get; private set; } public GroupVm PreviousGroup { get; private set; } @@ -151,6 +150,7 @@ namespace ModernKeePass.ViewModels public event PropertyChangedEventHandler PropertyChanged; private readonly PwEntry _pwEntry; + private readonly IDatabase _database; private bool _isEditMode; private bool _isRevealPassword; private double _passwordLength = 25; @@ -160,13 +160,13 @@ namespace ModernKeePass.ViewModels PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - public EntryVm() : this(null, null) { } + public EntryVm() { } internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, (Application.Current as App)?.Database) { } public EntryVm(PwEntry entry, GroupVm parent, IDatabase database) { - Database = database; + _database = database; _pwEntry = entry; ParentGroup = parent; } @@ -212,9 +212,9 @@ namespace ModernKeePass.ViewModels public void MarkForDelete() { - if (Database.RecycleBinEnabled && Database.RecycleBin?.IdUuid == null) - Database.CreateRecycleBin(); - Move(Database.RecycleBinEnabled && !ParentGroup.IsSelected ? Database.RecycleBin : null); + if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null) + _database.CreateRecycleBin(); + Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null); } public void UndoDelete() @@ -229,7 +229,7 @@ namespace ModernKeePass.ViewModels PreviousGroup.RemovePwEntry(_pwEntry); if (destination == null) { - Database.AddDeletedItem(IdUuid); + _database.AddDeletedItem(IdUuid); return; } ParentGroup = destination; @@ -240,13 +240,13 @@ namespace ModernKeePass.ViewModels public void CommitDelete() { _pwEntry.ParentGroup.Entries.Remove(_pwEntry); - if (Database.RecycleBinEnabled && !PreviousGroup.IsSelected) Database.RecycleBin.AddPwEntry(_pwEntry); - else Database.AddDeletedItem(IdUuid); + if (_database.RecycleBinEnabled && !PreviousGroup.IsSelected) _database.RecycleBin.AddPwEntry(_pwEntry); + else _database.AddDeletedItem(IdUuid); } public void Save() { - Database.Save(); + _database.Save(); } } } diff --git a/ModernKeePass/ViewModels/GroupVm.cs b/ModernKeePass/ViewModels/GroupVm.cs index d0ca935..9570892 100644 --- a/ModernKeePass/ViewModels/GroupVm.cs +++ b/ModernKeePass/ViewModels/GroupVm.cs @@ -32,16 +32,10 @@ namespace ModernKeePass.ViewModels /// public bool IsSelected { - get { return _app.Database.RecycleBinEnabled && _app.Database.RecycleBin?.Id == Id; } + get { return _database.RecycleBinEnabled && _database.RecycleBin?.Id == Id; } set { - if (value && _pwGroup != null) _app.Database.RecycleBin = this; - /*else if (value && _pwGroup == null) - { - var recycleBin = _app.Database.RootGroup.AddNewGroup("Recycle bin"); - recycleBin.IsSelected = true; - recycleBin.IconSymbol = Symbol.Delete; - }*/ + if (value && _pwGroup != null) _database.RecycleBin = this; } } @@ -86,17 +80,22 @@ namespace ModernKeePass.ViewModels } private readonly PwGroup _pwGroup; - private readonly App _app = Application.Current as App; + private readonly IDatabase _database; private bool _isEditMode; public GroupVm() {} - public GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) + internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent, + (Application.Current as App)?.Database, recycleBinId) + { } + + public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabase database, PwUuid recycleBinId = null) { _pwGroup = pwGroup; + _database = database; ParentGroup = parent; - if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _app.Database.RecycleBin = this; + if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _database.RecycleBin = this; Entries = new ObservableCollection(pwGroup.Entries.Select(e => new EntryVm(e, this)).OrderBy(e => e.Name)); Entries.Insert(0, new EntryVm ()); Groups = new ObservableCollection(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)).OrderBy(g => g.Name)); @@ -133,9 +132,9 @@ namespace ModernKeePass.ViewModels public void MarkForDelete() { - if (_app.Database.RecycleBinEnabled && _app.Database.RecycleBin?.IdUuid == null) - _app.Database.CreateRecycleBin(); - Move(_app.Database.RecycleBinEnabled && !IsSelected ? _app.Database.RecycleBin : null); + if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null) + _database.CreateRecycleBin(); + Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null); } @@ -151,7 +150,7 @@ namespace ModernKeePass.ViewModels PreviousGroup._pwGroup.Groups.Remove(_pwGroup); if (destination == null) { - _app.Database.AddDeletedItem(IdUuid); + _database.AddDeletedItem(IdUuid); return; } ParentGroup = destination; @@ -162,13 +161,13 @@ namespace ModernKeePass.ViewModels public void CommitDelete() { _pwGroup.ParentGroup.Groups.Remove(_pwGroup); - if (_app.Database.RecycleBinEnabled && !PreviousGroup.IsSelected) _app.Database.RecycleBin._pwGroup.AddGroup(_pwGroup, true); - else _app.Database.AddDeletedItem(IdUuid); + if (_database.RecycleBinEnabled && !PreviousGroup.IsSelected) _database.RecycleBin._pwGroup.AddGroup(_pwGroup, true); + else _database.AddDeletedItem(IdUuid); } public void Save() { - _app.Database.Save(); + _database.Save(); } public override string ToString() diff --git a/ModernKeePass/ViewModels/Items/SettingsDatabaseVm.cs b/ModernKeePass/ViewModels/Items/SettingsDatabaseVm.cs index 6b097de..5967172 100644 --- a/ModernKeePass/ViewModels/Items/SettingsDatabaseVm.cs +++ b/ModernKeePass/ViewModels/Items/SettingsDatabaseVm.cs @@ -14,16 +14,16 @@ namespace ModernKeePass.ViewModels { public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject { - private readonly App _app = Application.Current as App; + private readonly IDatabase _database; private readonly ApplicationDataContainer _localSettings = ApplicationData.Current.LocalSettings; private GroupVm _selectedItem; public bool HasRecycleBin { - get { return _app.Database.RecycleBinEnabled; } + get { return _database.RecycleBinEnabled; } set { - _app.Database.RecycleBinEnabled = value; + _database.RecycleBinEnabled = value; OnPropertyChanged(); } } @@ -47,26 +47,26 @@ namespace ModernKeePass.ViewModels { for (var inx = 0; inx < CipherPool.GlobalPool.EngineCount; ++inx) { - if (CipherPool.GlobalPool[inx].CipherUuid.Equals(_app.Database.DataCipher)) return inx; + if (CipherPool.GlobalPool[inx].CipherUuid.Equals(_database.DataCipher)) return inx; } return -1; } - set { _app.Database.DataCipher = CipherPool.GlobalPool[value].CipherUuid; } + set { _database.DataCipher = CipherPool.GlobalPool[value].CipherUuid; } } public IEnumerable Compressions => Enum.GetNames(typeof(PwCompressionAlgorithm)).Take((int)PwCompressionAlgorithm.Count); public string CompressionName { - get { return Enum.GetName(typeof(PwCompressionAlgorithm), _app.Database.CompressionAlgorithm); } - set { _app.Database.CompressionAlgorithm = (PwCompressionAlgorithm)Enum.Parse(typeof(PwCompressionAlgorithm), value); } + get { return Enum.GetName(typeof(PwCompressionAlgorithm), _database.CompressionAlgorithm); } + set { _database.CompressionAlgorithm = (PwCompressionAlgorithm)Enum.Parse(typeof(PwCompressionAlgorithm), value); } } public IEnumerable KeyDerivations => KdfPool.Engines.Select(e => e.Name); public string KeyDerivationName { - get { return KdfPool.Get(_app.Database.KeyDerivation.KdfUuid).Name; } - set { _app.Database.KeyDerivation = KdfPool.Engines.FirstOrDefault(e => e.Name == value)?.GetDefaultParameters(); } + get { return KdfPool.Get(_database.KeyDerivation.KdfUuid).Name; } + set { _database.KeyDerivation = KdfPool.Engines.FirstOrDefault(e => e.Name == value)?.GetDefaultParameters(); } } public ISelectableModel SelectedItem @@ -89,9 +89,12 @@ namespace ModernKeePass.ViewModels } } - public SettingsDatabaseVm() + public SettingsDatabaseVm() : this((Application.Current as App)?.Database) { } + + public SettingsDatabaseVm(IDatabase database) { - Groups = _app?.Database.RootGroup.Groups; + _database = database; + Groups = _database.RootGroup.Groups; } // TODO: Move to another setting class (or a static class) diff --git a/ModernKeePass/ViewModels/MainVm.cs b/ModernKeePass/ViewModels/MainVm.cs index ae18a81..4e72c21 100644 --- a/ModernKeePass/ViewModels/MainVm.cs +++ b/ModernKeePass/ViewModels/MainVm.cs @@ -45,18 +45,19 @@ namespace ModernKeePass.ViewModels public MainVm() {} - public MainVm(Frame referenceFrame, Frame destinationFrame) + internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame, (Application.Current as App)?.Database) { } + + public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database) { - var app = (App)Application.Current; var mru = StorageApplicationPermissions.MostRecentlyUsedList; - var isDatabaseOpen = app.Database != null && app.Database.Status == (int) DatabaseHelper.DatabaseStatus.Opened; + var isDatabaseOpen = database != null && database.Status == (int) DatabaseHelper.DatabaseStatus.Opened; var mainMenuItems = new ObservableCollection { new MainMenuItemVm { Title = "Open", PageType = typeof(OpenDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Page2, - IsSelected = app.Database.Status == (int) DatabaseHelper.DatabaseStatus.Opening + IsSelected = database != null && database.Status == (int) DatabaseHelper.DatabaseStatus.Opening }, new MainMenuItemVm { @@ -69,7 +70,7 @@ namespace ModernKeePass.ViewModels }, new MainMenuItemVm { Title = "Recent" , PageType = typeof(RecentDatabasesPage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Copy, - IsSelected = (app.Database == null || app.Database.Status == (int) DatabaseHelper.DatabaseStatus.Closed) && mru.Entries.Count > 0, IsEnabled = mru.Entries.Count > 0 + IsSelected = (database == null || database.Status == (int) DatabaseHelper.DatabaseStatus.Closed) && mru.Entries.Count > 0, IsEnabled = mru.Entries.Count > 0 }, new MainMenuItemVm { @@ -78,13 +79,13 @@ namespace ModernKeePass.ViewModels }; // Auto-select the Recent Items menu item if the conditions are met SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected); - if (app.Database != null && app.Database.Status == (int) DatabaseHelper.DatabaseStatus.Opened) + if (database != null && database.Status == (int) DatabaseHelper.DatabaseStatus.Opened) mainMenuItems.Add(new MainMenuItemVm { - Title = app.Database.Name, + Title = database.Name, PageType = typeof(GroupDetailPage), Destination = referenceFrame, - Parameter = app.Database.RootGroup, + Parameter = database.RootGroup, Group = 1, SymbolIcon = Symbol.ProtectedDocument }); diff --git a/ModernKeePass/ViewModels/OpenVm.cs b/ModernKeePass/ViewModels/OpenVm.cs index 2987237..1b30fae 100644 --- a/ModernKeePass/ViewModels/OpenVm.cs +++ b/ModernKeePass/ViewModels/OpenVm.cs @@ -3,26 +3,25 @@ using Windows.Storage; using Windows.Storage.AccessCache; using Windows.UI.Xaml; using ModernKeePass.Common; +using ModernKeePass.Interfaces; namespace ModernKeePass.ViewModels { public class OpenVm: INotifyPropertyChanged { - public bool ShowPasswordBox - { - get { return ((App)Application.Current).Database.Status == (int) DatabaseHelper.DatabaseStatus.Opening; } - } + public bool ShowPasswordBox => _database?.Status == (int) DatabaseHelper.DatabaseStatus.Opening; - public string Name - { - get { return ((App)Application.Current).Database.Name; } - } + public string Name => _database?.Name; - public OpenVm() + private readonly IDatabase _database; + + public OpenVm() : this((Application.Current as App)?.Database) { } + + public OpenVm(IDatabase database) { - var app = Application.Current as App; - if (app?.Database == null || app.Database.Status != (int) DatabaseHelper.DatabaseStatus.Opening) return; - OpenFile(app.Database.DatabaseFile); + _database = database; + if (database == null || database.Status != (int) DatabaseHelper.DatabaseStatus.Opening) return; + OpenFile(database.DatabaseFile); } public event PropertyChangedEventHandler PropertyChanged; @@ -34,8 +33,7 @@ namespace ModernKeePass.ViewModels public void OpenFile(StorageFile file) { - var database = ((App)Application.Current).Database; - database.DatabaseFile = file; + _database.DatabaseFile = file; NotifyPropertyChanged("Name"); NotifyPropertyChanged("ShowPasswordBox"); AddToRecentList(file); diff --git a/ModernKeePass/ViewModels/SaveVm.cs b/ModernKeePass/ViewModels/SaveVm.cs index 26b6502..7dd1b48 100644 --- a/ModernKeePass/ViewModels/SaveVm.cs +++ b/ModernKeePass/ViewModels/SaveVm.cs @@ -1,20 +1,27 @@ using Windows.Storage; using Windows.UI.Xaml; +using ModernKeePass.Interfaces; namespace ModernKeePass.ViewModels { public class SaveVm { + private readonly IDatabase _database; + public SaveVm() : this((Application.Current as App)?.Database) { } + + public SaveVm(IDatabase database) + { + _database = database; + } + public void Save(bool close = true) { - var app = (App)Application.Current; - if (close && app.Database.Save()) app.Database.Close(); + if (close && _database.Save()) _database.Close(); } internal void Save(StorageFile file) { - var app = (App)Application.Current; - app.Database.Save(file); + _database.Save(file); } } } \ No newline at end of file diff --git a/ModernKeePassApp.Test/DatabaseTests.cs b/ModernKeePassApp.Test/DatabaseTests.cs index 3ca6687..d765370 100644 --- a/ModernKeePassApp.Test/DatabaseTests.cs +++ b/ModernKeePassApp.Test/DatabaseTests.cs @@ -4,7 +4,6 @@ using Windows.Storage; using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using ModernKeePass.Common; using ModernKeePass.ViewModels; -using ModernKeePassLib.Keys; namespace ModernKeePassApp.Test { @@ -16,20 +15,20 @@ namespace ModernKeePassApp.Test [TestMethod] public void TestCreate() { - Assert.AreEqual(_database.Status, (int) DatabaseHelper.DatabaseStatus.Closed); + Assert.AreEqual((int) DatabaseHelper.DatabaseStatus.Closed, _database.Status); _database.DatabaseFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync("NewDatabase.kdbx").GetAwaiter().GetResult(); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Opening); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Opening, _database.Status); OpenOrCreateDatabase(true); _database.Close(); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Closed); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Closed, _database.Status); } [TestMethod] public void TestOpen() { - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Closed); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Closed, _database.Status); _database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx").GetAwaiter().GetResult(); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Opening); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Opening, _database.Status); OpenOrCreateDatabase(false); } @@ -39,26 +38,21 @@ namespace ModernKeePassApp.Test TestOpen(); Assert.IsTrue(_database.Save(ApplicationData.Current.TemporaryFolder.CreateFileAsync("SaveDatabase.kdbx").GetAwaiter().GetResult())); _database.Close(); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Closed); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Closed, _database.Status); TestOpen(); } private void OpenOrCreateDatabase(bool createNew) { _database.Open(null, createNew); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.NoCompositeKey); - var compositeKey = new CompositeKey(); - if (!createNew) + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.NoCompositeKey, _database.Status); + var compositeKey = new CompositeKeyVm(_database) { - _database.Open(compositeKey); - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.CompositeKeyError); - } - compositeKey.AddUserKey(new KcpPassword("test")); - - _database.Open(compositeKey, createNew); - /*var compositeKey = new CompositeKeyVm(_database); - compositeKey.OpenDatabase(createNew);*/ - Assert.AreEqual(_database.Status, (int)DatabaseHelper.DatabaseStatus.Opened); + HasPassword = true, + Password = "test" + }; + compositeKey.OpenDatabase(createNew); + Assert.AreEqual((int)DatabaseHelper.DatabaseStatus.Opened, _database.Status); } } } diff --git a/ModernKeePassApp.Test/Mock/DatabaseHelperMock.cs b/ModernKeePassApp.Test/Mock/DatabaseHelperMock.cs new file mode 100644 index 0000000..82604b6 --- /dev/null +++ b/ModernKeePassApp.Test/Mock/DatabaseHelperMock.cs @@ -0,0 +1,66 @@ +using System; +using ModernKeePass.Interfaces; +using ModernKeePass.ViewModels; +using ModernKeePassLib; +using ModernKeePassLib.Cryptography.KeyDerivation; +using ModernKeePassLib.Keys; +using Windows.Storage; + +namespace ModernKeePassApp.Test.Mock +{ + public class DatabaseHelperMock : IDatabase + { + public PwCompressionAlgorithm CompressionAlgorithm { get; set; } + + public StorageFile DatabaseFile { get; set; } + + public PwUuid DataCipher { get; set; } + + public KdfParameters KeyDerivation { get; set; } + + public string Name => "MockDatabase"; + + public GroupVm RecycleBin { get; set; } + + public bool RecycleBinEnabled { get; set; } + + public GroupVm RootGroup { get; set; } + + public int Status { get; set; } + + public void AddDeletedItem(PwUuid id) + { + throw new NotImplementedException(); + } + + public void Close() + { + throw new NotImplementedException(); + } + + public void CreateRecycleBin() + { + throw new NotImplementedException(); + } + + public void Open(CompositeKey key, bool createNew) + { + throw new NotImplementedException(); + } + + public bool Save() + { + throw new NotImplementedException(); + } + + public bool Save(StorageFile file) + { + throw new NotImplementedException(); + } + + public void UpdateCompositeKey(CompositeKey key) + { + throw new NotImplementedException(); + } + } +} diff --git a/ModernKeePassApp.Test/ModernKeePassApp.Test.csproj b/ModernKeePassApp.Test/ModernKeePassApp.Test.csproj index e052ff7..e1671a0 100644 --- a/ModernKeePassApp.Test/ModernKeePassApp.Test.csproj +++ b/ModernKeePassApp.Test/ModernKeePassApp.Test.csproj @@ -118,7 +118,9 @@ + + diff --git a/ModernKeePassApp.Test/ViewModelsTests.cs b/ModernKeePassApp.Test/ViewModelsTests.cs new file mode 100644 index 0000000..c68cd15 --- /dev/null +++ b/ModernKeePassApp.Test/ViewModelsTests.cs @@ -0,0 +1,40 @@ +using System.Linq; +using Windows.ApplicationModel; +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using ModernKeePass.ViewModels; +using ModernKeePassApp.Test.Mock; + +namespace ModernKeePassApp.Test +{ + [TestClass] + public class ViewModelsTests + { + [TestMethod] + public void TestAboutVm() + { + var aboutVm = new AboutVm(Package.Current); + Assert.AreEqual("1.0", aboutVm.Version); + } + + [TestMethod] + public void TestMainVm() + { + var database = new DatabaseHelperMock(); + var mainVm = new MainVm(null, null, database); + Assert.AreEqual(1, mainVm.MainMenuItems.Count()); + var firstGroup = mainVm.MainMenuItems.FirstOrDefault(); + Assert.AreEqual(5, firstGroup.Count()); + + database.Status = 1; + mainVm = new MainVm(null, null, database); + Assert.IsNotNull(mainVm.SelectedItem); + Assert.AreEqual("Open", ((MainMenuItemVm)mainVm.SelectedItem).Title); + + database.Status = 2; + mainVm = new MainVm(null, null, database); + Assert.IsNotNull(mainVm.SelectedItem); + Assert.AreEqual(2, mainVm.MainMenuItems.Count()); + Assert.AreEqual("Save", ((MainMenuItemVm)mainVm.SelectedItem).Title); + } + } +}