From 533c6f207e331bb069448391c0e14b5d898e361f Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Tue, 18 Jun 2013 21:12:34 +0200 Subject: [PATCH] More refactoring Added first simple unit test --- .../PwGroupEqualityFromIdComparer.cs | 13 ++--- .../PwUuidEqualityComparer.cs | 14 ++--- src/Kp2aBusinessLogic/UiStringKey.cs | 6 +++ src/Kp2aBusinessLogic/database/Database.cs | 8 +-- .../database/edit/DeleteRunnable.cs | 6 +-- .../database/edit/SetPassword.cs | 2 +- src/Kp2aUnitTests/Kp2aUnitTests.csproj | 10 ++++ .../Resources/Resource.Designer.cs | 4 ++ src/Kp2aUnitTests/TestCreateDb.cs | 51 ++++++++++++++++++ src/Kp2aUnitTests/TestDrawableFactory.cs | 27 ++++++++++ src/Kp2aUnitTests/TestKp2aApp.cs | 54 +++++++++++++++++++ src/keepass2android/EntryActivity.cs | 4 +- src/keepass2android/EntryEditActivity.cs | 4 +- src/keepass2android/GroupActivity.cs | 2 +- src/keepass2android/LockingListActivity.cs | 6 ++- src/keepass2android/SetPasswordDialog.cs | 2 +- src/keepass2android/app/App.cs | 4 +- .../fileselect/FileSelectActivity.cs | 7 ++- src/keepass2android/icons/DrawableFactory.cs | 4 +- src/keepass2android/keepass2android.csproj | 3 -- src/keepass2android/timeout/TimeoutHelper.cs | 1 + src/keepass2android/views/PwEntryView.cs | 4 +- src/keepass2android/views/PwGroupView.cs | 2 +- 23 files changed, 188 insertions(+), 50 deletions(-) create mode 100644 src/Kp2aUnitTests/TestCreateDb.cs create mode 100644 src/Kp2aUnitTests/TestDrawableFactory.cs create mode 100644 src/Kp2aUnitTests/TestKp2aApp.cs diff --git a/src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs b/src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs index 6b86efc4..066e00cf 100644 --- a/src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs +++ b/src/Kp2aBusinessLogic/PwGroupEqualityFromIdComparer.cs @@ -15,21 +15,14 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. along with Keepass2Android. If not, see . */ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Android.App; -using Android.Content; -using Android.OS; -using Android.Runtime; -using Android.Views; -using Android.Widget; using KeePassLib; namespace keepass2android { + /// + /// EqualityComparer implementation to compare PwGroups based on their Id + /// class PwGroupEqualityFromIdComparer: IEqualityComparer { #region IEqualityComparer implementation diff --git a/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs b/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs index b0307ed6..c0aa5419 100644 --- a/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs +++ b/src/Kp2aBusinessLogic/PwUuidEqualityComparer.cs @@ -15,22 +15,14 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. along with Keepass2Android. If not, see . */ -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Android.App; -using Android.Content; -using Android.OS; -using Android.Runtime; -using Android.Views; -using Android.Widget; - using KeePassLib; namespace keepass2android { + /// + /// EqualityComparer for PwUuid based on their value (instead of reference) + /// public class PwUuidEqualityComparer: IEqualityComparer { #region IEqualityComparer implementation diff --git a/src/Kp2aBusinessLogic/UiStringKey.cs b/src/Kp2aBusinessLogic/UiStringKey.cs index f8a7794e..fd6982c0 100644 --- a/src/Kp2aBusinessLogic/UiStringKey.cs +++ b/src/Kp2aBusinessLogic/UiStringKey.cs @@ -1,5 +1,11 @@ namespace keepass2android { + /// + /// Keys to identify user-displayable strings. + /// + /// Do not rename the keys here unless you rename the corresponding keys in the resource file of KP2A. + /// The keys are resolved by reflection to the static Resource class. This kind of duplication is necessary + /// in order to use the Resource mechanism of Android but still decouple the logic layer from the UI. public enum UiStringKey { AskDeletePermanentlyGroup, diff --git a/src/Kp2aBusinessLogic/database/Database.cs b/src/Kp2aBusinessLogic/database/Database.cs index bba66b7c..f22926b8 100644 --- a/src/Kp2aBusinessLogic/database/Database.cs +++ b/src/Kp2aBusinessLogic/database/Database.cs @@ -139,7 +139,7 @@ namespace keepass2android } public PwGroup SearchForText(String str) { - PwGroup group = SearchHelper.searchForText(this, str); + PwGroup group = SearchHelper.SearchForText(this, str); return group; @@ -147,19 +147,19 @@ namespace keepass2android public PwGroup Search(SearchParameters searchParams) { - return SearchHelper.search(this, searchParams); + return SearchHelper.Search(this, searchParams); } public PwGroup SearchForExactUrl(String url) { - PwGroup group = SearchHelper.searchForExactUrl(this, url); + PwGroup group = SearchHelper.SearchForExactUrl(this, url); return group; } public PwGroup SearchForHost(String url, bool allowSubdomains) { - PwGroup group = SearchHelper.searchForHost(this, url, allowSubdomains); + PwGroup group = SearchHelper.SearchForHost(this, url, allowSubdomains); return group; diff --git a/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs index 3494f431..3b07a551 100644 --- a/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs +++ b/src/Kp2aBusinessLogic/database/edit/DeleteRunnable.cs @@ -110,12 +110,12 @@ namespace keepass2android { DeletePermanently = true; ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); - pt.run(); + pt.Run(); }, (dlgSender, dlgEvt) => { DeletePermanently = false; ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); - pt.run(); + pt.Run(); }, (dlgSender, dlgEvt) => {}, Ctx); @@ -125,7 +125,7 @@ namespace keepass2android } else { ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); - pt.run(); + pt.Run(); } } diff --git a/src/Kp2aBusinessLogic/database/edit/SetPassword.cs b/src/Kp2aBusinessLogic/database/edit/SetPassword.cs index d3824d5a..ca238321 100644 --- a/src/Kp2aBusinessLogic/database/edit/SetPassword.cs +++ b/src/Kp2aBusinessLogic/database/edit/SetPassword.cs @@ -77,7 +77,7 @@ namespace keepass2android private class AfterSave : OnFinish { private readonly CompositeKey _backup; private readonly DateTime _previousKeyChanged; - private PwDatabase _db; + private readonly PwDatabase _db; public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) { _previousKeyChanged = previousKeyChanged; diff --git a/src/Kp2aUnitTests/Kp2aUnitTests.csproj b/src/Kp2aUnitTests/Kp2aUnitTests.csproj index 7911fd18..87ccfb1b 100644 --- a/src/Kp2aUnitTests/Kp2aUnitTests.csproj +++ b/src/Kp2aUnitTests/Kp2aUnitTests.csproj @@ -46,6 +46,8 @@ + + @@ -64,6 +66,14 @@ + + {545B4A6B-8BBA-4FBE-92FC-4AC060122A54} + KeePassLib2Android + + + {53A9CB7F-6553-4BC0-B56B-9410BB2E59AA} + Kp2aBusinessLogic + {a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48} MonoDroidUnitTesting diff --git a/src/Kp2aUnitTests/Resources/Resource.Designer.cs b/src/Kp2aUnitTests/Resources/Resource.Designer.cs index 691433d3..88494d33 100644 --- a/src/Kp2aUnitTests/Resources/Resource.Designer.cs +++ b/src/Kp2aUnitTests/Resources/Resource.Designer.cs @@ -26,6 +26,7 @@ namespace Kp2aUnitTests public static void UpdateIdValues() { + KeePassLib2Android.Resource.String.library_name = Kp2aUnitTests.Resource.String.library_name; } public partial class Attribute @@ -98,6 +99,9 @@ namespace Kp2aUnitTests // aapt resource value: 0x7f040000 public const int Hello = 2130968576; + // aapt resource value: 0x7f040002 + public const int library_name = 2130968578; + static String() { global::Android.Runtime.ResourceIdManager.UpdateIdValues(); diff --git a/src/Kp2aUnitTests/TestCreateDb.cs b/src/Kp2aUnitTests/TestCreateDb.cs new file mode 100644 index 00000000..1aa30e60 --- /dev/null +++ b/src/Kp2aUnitTests/TestCreateDb.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Android.App; +using Java.IO; +using KeePassLib; +using KeePassLib.Keys; +using KeePassLib.Serialization; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using keepass2android; + +namespace Kp2aUnitTests +{ + [TestClass] + class TestCreateDb + { + [TestMethod] + public void CreateAndSaveLocal() + { + IKp2aApp app = new TestKp2aApp(); + IOConnectionInfo ioc = new IOConnectionInfo {Path = "/mnt/sdcard/kp2atest/savetest.kdbx"}; + + File outputDir = new File("/mnt/sdcard/kp2atest/"); + outputDir.Mkdirs(); + File targetFile = new File(ioc.Path); + if (targetFile.Exists()) + targetFile.Delete(); + + bool createSuccesful = false; + //create the task: + CreateDb createDb = new CreateDb(app, Application.Context, ioc, new ActionOnFinish((success, message) => + { createSuccesful = success; if (!success) + Assert.Fail(message); + }), false); + //run it: + createDb.Run(); + //check expectations: + Assert.IsTrue(createSuccesful); + Assert.IsNotNull(app.GetDb()); + Assert.IsNotNull(app.GetDb().KpDatabase); + //the create task should create two groups: + Assert.AreEqual(2, app.GetDb().KpDatabase.RootGroup.Groups.Count()); + + //ensure the the database can be loaded from file: + PwDatabase loadedDb = new PwDatabase(); + loadedDb.Open(ioc, new CompositeKey(), null); + + + } + } +} diff --git a/src/Kp2aUnitTests/TestDrawableFactory.cs b/src/Kp2aUnitTests/TestDrawableFactory.cs new file mode 100644 index 00000000..c2c02c9e --- /dev/null +++ b/src/Kp2aUnitTests/TestDrawableFactory.cs @@ -0,0 +1,27 @@ +using System; +using Android.Content.Res; +using Android.Graphics.Drawables; +using Android.Widget; +using KeePassLib; +using keepass2android; + +namespace Kp2aUnitTests +{ + internal class TestDrawableFactory : IDrawableFactory + { + public void AssignDrawableTo(ImageView iv, Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId) + { + + } + + public Drawable GetIconDrawable(Resources res, PwDatabase db, PwIcon icon, PwUuid customIconId) + { + return res.GetDrawable(Resource.Drawable.Icon); + } + + public void Clear() + { + + } + } +} \ No newline at end of file diff --git a/src/Kp2aUnitTests/TestKp2aApp.cs b/src/Kp2aUnitTests/TestKp2aApp.cs new file mode 100644 index 00000000..6533a786 --- /dev/null +++ b/src/Kp2aUnitTests/TestKp2aApp.cs @@ -0,0 +1,54 @@ +using System; +using Android.Content; +using KeePassLib.Serialization; +using keepass2android; + +namespace Kp2aUnitTests +{ + /// + /// Very simple implementation of the Kp2aApp interface to be used in tests + /// + internal class TestKp2aApp : IKp2aApp + { + private Database _db; + + public void SetShutdown() + { + + } + + public Database GetDb() + { + return _db; + } + + public void StoreOpenedFileAsRecent(IOConnectionInfo ioc, string keyfile) + { + + } + + public Database CreateNewDatabase() + { + TestDrawableFactory testDrawableFactory = new TestDrawableFactory(); + _db = new Database(testDrawableFactory, new TestKp2aApp()); + return _db; + + } + + public string GetResourceString(UiStringKey stringKey) + { + return stringKey.ToString(); + } + + public bool GetBooleanPreference(PreferenceKey key) + { + return true; + } + + public void AskYesNoCancel(UiStringKey titleKey, UiStringKey messageKey, EventHandler yesHandler, EventHandler noHandler, + EventHandler cancelHandler, Context ctx) + { + yesHandler(null, null); + } + } +} \ No newline at end of file diff --git a/src/keepass2android/EntryActivity.cs b/src/keepass2android/EntryActivity.cs index e2fb0c29..9b65392f 100644 --- a/src/keepass2android/EntryActivity.cs +++ b/src/keepass2android/EntryActivity.cs @@ -125,7 +125,7 @@ namespace keepass2android RequiresRefresh(); UpdateEntry update = new UpdateEntry(this, App.Kp2a.GetDb(), backupEntry, Entry, null); ProgressTask pt = new ProgressTask(App.Kp2a, this, update, UiStringKey.saving_database); - pt.run(); + pt.Run(); } FillData(false); @@ -371,7 +371,7 @@ namespace keepass2android ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon); if (iv != null) { - App.Kp2a.GetDb().DrawableFactory.assignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, Entry.IconId, Entry.CustomIconUuid); + App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, Entry.IconId, Entry.CustomIconUuid); } //populateText(Resource.Id.entry_title, _entry.Strings.ReadSafe(PwDefs.TitleField)); diff --git a/src/keepass2android/EntryEditActivity.cs b/src/keepass2android/EntryEditActivity.cs index 31cf2c06..3555a55b 100644 --- a/src/keepass2android/EntryEditActivity.cs +++ b/src/keepass2android/EntryEditActivity.cs @@ -388,7 +388,7 @@ namespace keepass2android runnable = new UpdateEntry(this, App.Kp2a.GetDb(), initialEntry, newEntry, closeOrShowError); } ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable, UiStringKey.saving_database); - pt.run(); + pt.Run(); } @@ -796,7 +796,7 @@ namespace keepass2android private void FillData() { ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button); - App.Kp2a.GetDb().DrawableFactory.assignDrawableTo(currIconButton, Resources, App.Kp2a.GetDb().KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid); + App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(currIconButton, Resources, App.Kp2a.GetDb().KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid); PopulateText(Resource.Id.entry_title, State.Entry.Strings.ReadSafe (PwDefs.TitleField)); PopulateText(Resource.Id.entry_user_name, State.Entry.Strings.ReadSafe (PwDefs.UserNameField)); diff --git a/src/keepass2android/GroupActivity.cs b/src/keepass2android/GroupActivity.cs index a40385e4..4eec2ca2 100644 --- a/src/keepass2android/GroupActivity.cs +++ b/src/keepass2android/GroupActivity.cs @@ -179,7 +179,7 @@ namespace keepass2android Handler handler = new Handler(); AddGroup task = AddGroup.GetInstance(this, App.Kp2a.GetDb(), groupName, groupIconId, Group, new RefreshTask(handler, this), false); ProgressTask pt = new ProgressTask(App.Kp2a, act, task, UiStringKey.saving_database); - pt.run(); + pt.Run(); break; case Result.Canceled: diff --git a/src/keepass2android/LockingListActivity.cs b/src/keepass2android/LockingListActivity.cs index e366d23e..cf576b90 100644 --- a/src/keepass2android/LockingListActivity.cs +++ b/src/keepass2android/LockingListActivity.cs @@ -21,8 +21,10 @@ using Android.OS; using Android.Runtime; namespace keepass2android -{ - +{ + /// + /// Base class for list activities. Notifies the TimeoutHelper whether the app is active or not. + /// public class LockingListActivity : ListActivity { diff --git a/src/keepass2android/SetPasswordDialog.cs b/src/keepass2android/SetPasswordDialog.cs index 728ef664..059a0088 100644 --- a/src/keepass2android/SetPasswordDialog.cs +++ b/src/keepass2android/SetPasswordDialog.cs @@ -73,7 +73,7 @@ namespace keepass2android SetPassword sp = new SetPassword(Context, App.Kp2a.GetDb(), pass, keyfile, new AfterSave(this, _finish, new Handler())); ProgressTask pt = new ProgressTask(App.Kp2a, Context, sp, UiStringKey.saving_database); - pt.run(); + pt.Run(); }; diff --git a/src/keepass2android/app/App.cs b/src/keepass2android/app/App.cs index 38944bb3..301554a7 100644 --- a/src/keepass2android/app/App.cs +++ b/src/keepass2android/app/App.cs @@ -47,7 +47,9 @@ namespace keepass2android public const string PackagePart = "keepass2android"; } #endif - + /// + /// Main implementation of the IKp2aApp interface for usage in the real app. + /// public class Kp2aApp: IKp2aApp { public bool IsShutdown() diff --git a/src/keepass2android/fileselect/FileSelectActivity.cs b/src/keepass2android/fileselect/FileSelectActivity.cs index 68fb7cda..b7fe778d 100644 --- a/src/keepass2android/fileselect/FileSelectActivity.cs +++ b/src/keepass2android/fileselect/FileSelectActivity.cs @@ -162,13 +162,12 @@ namespace keepass2android return; } - // Prep an object to collect a password once the database has - // been created - CollectPassword password = new CollectPassword( + // Prep an object to collect a password once the database has been created + CollectPassword collectPassword = new CollectPassword( new LaunchGroupActivity(IOConnectionInfo.FromPath(filename), this), this); // Create the new database - CreateDb create = new CreateDb(App.Kp2a, this, IOConnectionInfo.FromPath(filename), password, true); + CreateDb create = new CreateDb(App.Kp2a, this, IOConnectionInfo.FromPath(filename), collectPassword, true); ProgressTask createTask = new ProgressTask( App.Kp2a, this, create, diff --git a/src/keepass2android/icons/DrawableFactory.cs b/src/keepass2android/icons/DrawableFactory.cs index 1d4ece2c..93028dc8 100644 --- a/src/keepass2android/icons/DrawableFactory.cs +++ b/src/keepass2android/icons/DrawableFactory.cs @@ -99,8 +99,8 @@ namespace keepass2android } bitmap = resize (bitmap); - - draw = BitmapDrawableCompat.GetBitmapDrawable (res, bitmap); + + draw = new BitmapDrawable(res, bitmap); _customIconMap[icon] = draw; } diff --git a/src/keepass2android/keepass2android.csproj b/src/keepass2android/keepass2android.csproj index c480935f..f83df534 100644 --- a/src/keepass2android/keepass2android.csproj +++ b/src/keepass2android/keepass2android.csproj @@ -86,11 +86,9 @@ - - @@ -104,7 +102,6 @@ - diff --git a/src/keepass2android/timeout/TimeoutHelper.cs b/src/keepass2android/timeout/TimeoutHelper.cs index f83c4b23..5075e25f 100644 --- a/src/keepass2android/timeout/TimeoutHelper.cs +++ b/src/keepass2android/timeout/TimeoutHelper.cs @@ -19,6 +19,7 @@ using System; using Android.App; using Android.Content; using Android.Preferences; +using Android.Util; using KeePassLib.Serialization; namespace keepass2android diff --git a/src/keepass2android/views/PwEntryView.cs b/src/keepass2android/views/PwEntryView.cs index b888fd31..07aa1cac 100644 --- a/src/keepass2android/views/PwEntryView.cs +++ b/src/keepass2android/views/PwEntryView.cs @@ -81,10 +81,10 @@ namespace keepass2android.view bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now; if (isExpired) { - App.Kp2a.GetDb().DrawableFactory.assignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, PwIcon.Expired, PwUuid.Zero); + App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, PwIcon.Expired, PwUuid.Zero); } else { - App.Kp2a.GetDb().DrawableFactory.assignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid); + App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid); } String title = pw.Strings.ReadSafe(PwDefs.TitleField); diff --git a/src/keepass2android/views/PwGroupView.cs b/src/keepass2android/views/PwGroupView.cs index f96759f7..34820817 100644 --- a/src/keepass2android/views/PwGroupView.cs +++ b/src/keepass2android/views/PwGroupView.cs @@ -69,7 +69,7 @@ namespace keepass2android.view _pwGroup = pw; ImageView iv = (ImageView) gv.FindViewById(Resource.Id.group_icon); - App.Kp2a.GetDb().DrawableFactory.assignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid); + App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(iv, Resources, App.Kp2a.GetDb().KpDatabase, pw.IconId, pw.CustomIconUuid); _textview.Text = pw.Name; }