More refactoring

Added first simple unit test
This commit is contained in:
Philipp Crocoll 2013-06-18 21:12:34 +02:00
parent 8b08baa51a
commit 6588340b2f
23 changed files with 234 additions and 50 deletions

View File

@ -15,21 +15,14 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>. along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
using System.Collections.Generic; 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; using KeePassLib;
namespace keepass2android namespace keepass2android
{ {
/// <summary>
/// EqualityComparer implementation to compare PwGroups based on their Id
/// </summary>
class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup> class PwGroupEqualityFromIdComparer: IEqualityComparer<PwGroup>
{ {
#region IEqualityComparer implementation #region IEqualityComparer implementation

View File

@ -15,22 +15,14 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>. along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
using System.Collections.Generic; 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; using KeePassLib;
namespace keepass2android namespace keepass2android
{ {
/// <summary>
/// EqualityComparer for PwUuid based on their value (instead of reference)
/// </summary>
public class PwUuidEqualityComparer: IEqualityComparer<PwUuid> public class PwUuidEqualityComparer: IEqualityComparer<PwUuid>
{ {
#region IEqualityComparer implementation #region IEqualityComparer implementation

View File

@ -1,5 +1,11 @@
namespace keepass2android namespace keepass2android
{ {
/// <summary>
/// Keys to identify user-displayable strings.
/// </summary>
/// 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 public enum UiStringKey
{ {
AskDeletePermanentlyGroup, AskDeletePermanentlyGroup,

View File

@ -139,7 +139,7 @@ namespace keepass2android
} }
public PwGroup SearchForText(String str) { public PwGroup SearchForText(String str) {
PwGroup group = SearchHelper.searchForText(this, str); PwGroup group = SearchHelper.SearchForText(this, str);
return group; return group;
@ -147,19 +147,19 @@ namespace keepass2android
public PwGroup Search(SearchParameters searchParams) public PwGroup Search(SearchParameters searchParams)
{ {
return SearchHelper.search(this, searchParams); return SearchHelper.Search(this, searchParams);
} }
public PwGroup SearchForExactUrl(String url) { public PwGroup SearchForExactUrl(String url) {
PwGroup group = SearchHelper.searchForExactUrl(this, url); PwGroup group = SearchHelper.SearchForExactUrl(this, url);
return group; return group;
} }
public PwGroup SearchForHost(String url, bool allowSubdomains) { public PwGroup SearchForHost(String url, bool allowSubdomains) {
PwGroup group = SearchHelper.searchForHost(this, url, allowSubdomains); PwGroup group = SearchHelper.SearchForHost(this, url, allowSubdomains);
return group; return group;

View File

@ -110,12 +110,12 @@ namespace keepass2android
{ {
DeletePermanently = true; DeletePermanently = true;
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
pt.run(); pt.Run();
}, },
(dlgSender, dlgEvt) => { (dlgSender, dlgEvt) => {
DeletePermanently = false; DeletePermanently = false;
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
pt.run(); pt.Run();
}, },
(dlgSender, dlgEvt) => {}, (dlgSender, dlgEvt) => {},
Ctx); Ctx);
@ -125,7 +125,7 @@ namespace keepass2android
} else } else
{ {
ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database); ProgressTask pt = new ProgressTask(App, Ctx, this, UiStringKey.saving_database);
pt.run(); pt.Run();
} }
} }

View File

@ -77,7 +77,7 @@ namespace keepass2android
private class AfterSave : OnFinish { private class AfterSave : OnFinish {
private readonly CompositeKey _backup; private readonly CompositeKey _backup;
private readonly DateTime _previousKeyChanged; private readonly DateTime _previousKeyChanged;
private PwDatabase _db; private readonly PwDatabase _db;
public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) { public AfterSave(CompositeKey backup, DateTime previousKeyChanged, PwDatabase db, OnFinish finish): base(finish) {
_previousKeyChanged = previousKeyChanged; _previousKeyChanged = previousKeyChanged;

View File

@ -46,6 +46,8 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="TestDrawableFactory.cs" />
<Compile Include="TestCreateDb.cs" />
<Compile Include="MainActivity.cs" /> <Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" /> <Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
@ -64,6 +66,14 @@
<AndroidResource Include="Resources\Drawable\Icon.png" /> <AndroidResource Include="Resources\Drawable\Icon.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
<Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
<Name>KeePassLib2Android</Name>
</ProjectReference>
<ProjectReference Include="..\Kp2aBusinessLogic\Kp2aBusinessLogic.csproj">
<Project>{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}</Project>
<Name>Kp2aBusinessLogic</Name>
</ProjectReference>
<ProjectReference Include="..\monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj"> <ProjectReference Include="..\monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj">
<Project>{a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48}</Project> <Project>{a5f8fb02-00e0-4335-91ef-aeaa2c2f3c48}</Project>
<Name>MonoDroidUnitTesting</Name> <Name>MonoDroidUnitTesting</Name>

View File

@ -26,6 +26,7 @@ namespace Kp2aUnitTests
public static void UpdateIdValues() public static void UpdateIdValues()
{ {
KeePassLib2Android.Resource.String.library_name = Kp2aUnitTests.Resource.String.library_name;
} }
public partial class Attribute public partial class Attribute
@ -98,6 +99,9 @@ namespace Kp2aUnitTests
// aapt resource value: 0x7f040000 // aapt resource value: 0x7f040000
public const int Hello = 2130968576; public const int Hello = 2130968576;
// aapt resource value: 0x7f040002
public const int library_name = 2130968578;
static String() static String()
{ {
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); global::Android.Runtime.ResourceIdManager.UpdateIdValues();

View File

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
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);
}
}
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<DialogClickEventArgs> yesHandler, EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler, Context ctx)
{
yesHandler(null, null);
}
}
}

View File

@ -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()
{
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using Android.Content;
using KeePassLib.Serialization;
using keepass2android;
namespace Kp2aUnitTests
{
/// <summary>
/// Very simple implementation of the Kp2aApp interface to be used in tests
/// </summary>
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<DialogClickEventArgs> yesHandler, EventHandler<DialogClickEventArgs> noHandler,
EventHandler<DialogClickEventArgs> cancelHandler, Context ctx)
{
yesHandler(null, null);
}
}
}

View File

@ -125,7 +125,7 @@ namespace keepass2android
RequiresRefresh(); RequiresRefresh();
UpdateEntry update = new UpdateEntry(this, App.Kp2a.GetDb(), backupEntry, Entry, null); UpdateEntry update = new UpdateEntry(this, App.Kp2a.GetDb(), backupEntry, Entry, null);
ProgressTask pt = new ProgressTask(App.Kp2a, this, update, UiStringKey.saving_database); ProgressTask pt = new ProgressTask(App.Kp2a, this, update, UiStringKey.saving_database);
pt.run(); pt.Run();
} }
FillData(false); FillData(false);
@ -371,7 +371,7 @@ namespace keepass2android
ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon); ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon);
if (iv != null) 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)); //populateText(Resource.Id.entry_title, _entry.Strings.ReadSafe(PwDefs.TitleField));

View File

@ -388,7 +388,7 @@ namespace keepass2android
runnable = new UpdateEntry(this, App.Kp2a.GetDb(), initialEntry, newEntry, closeOrShowError); runnable = new UpdateEntry(this, App.Kp2a.GetDb(), initialEntry, newEntry, closeOrShowError);
} }
ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable, UiStringKey.saving_database); ProgressTask pt = new ProgressTask(App.Kp2a, act, runnable, UiStringKey.saving_database);
pt.run(); pt.Run();
} }
@ -796,7 +796,7 @@ namespace keepass2android
private void FillData() { private void FillData() {
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button); 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_title, State.Entry.Strings.ReadSafe (PwDefs.TitleField));
PopulateText(Resource.Id.entry_user_name, State.Entry.Strings.ReadSafe (PwDefs.UserNameField)); PopulateText(Resource.Id.entry_user_name, State.Entry.Strings.ReadSafe (PwDefs.UserNameField));

View File

@ -179,7 +179,7 @@ namespace keepass2android
Handler handler = new Handler(); Handler handler = new Handler();
AddGroup task = AddGroup.GetInstance(this, App.Kp2a.GetDb(), groupName, groupIconId, Group, new RefreshTask(handler, this), false); 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); ProgressTask pt = new ProgressTask(App.Kp2a, act, task, UiStringKey.saving_database);
pt.run(); pt.Run();
break; break;
case Result.Canceled: case Result.Canceled:

View File

@ -22,7 +22,9 @@ using Android.Runtime;
namespace keepass2android namespace keepass2android
{ {
/// <summary>
/// Base class for list activities. Notifies the TimeoutHelper whether the app is active or not.
/// </summary>
public class LockingListActivity : ListActivity { public class LockingListActivity : ListActivity {

View File

@ -73,7 +73,7 @@ namespace keepass2android
SetPassword sp = new SetPassword(Context, App.Kp2a.GetDb(), pass, keyfile, new AfterSave(this, _finish, new Handler())); 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); ProgressTask pt = new ProgressTask(App.Kp2a, Context, sp, UiStringKey.saving_database);
pt.run(); pt.Run();
}; };

View File

@ -47,7 +47,9 @@ namespace keepass2android
public const string PackagePart = "keepass2android"; public const string PackagePart = "keepass2android";
} }
#endif #endif
/// <summary>
/// Main implementation of the IKp2aApp interface for usage in the real app.
/// </summary>
public class Kp2aApp: IKp2aApp public class Kp2aApp: IKp2aApp
{ {
public bool IsShutdown() public bool IsShutdown()

View File

@ -162,13 +162,12 @@ namespace keepass2android
return; return;
} }
// Prep an object to collect a password once the database has // Prep an object to collect a password once the database has been created
// been created CollectPassword collectPassword = new CollectPassword(
CollectPassword password = new CollectPassword(
new LaunchGroupActivity(IOConnectionInfo.FromPath(filename), this), this); new LaunchGroupActivity(IOConnectionInfo.FromPath(filename), this), this);
// Create the new database // 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( ProgressTask createTask = new ProgressTask(
App.Kp2a, App.Kp2a,
this, create, this, create,

View File

@ -100,7 +100,7 @@ namespace keepass2android
bitmap = resize (bitmap); bitmap = resize (bitmap);
draw = BitmapDrawableCompat.GetBitmapDrawable (res, bitmap); draw = new BitmapDrawable(res, bitmap);
_customIconMap[icon] = draw; _customIconMap[icon] = draw;
} }

View File

@ -86,11 +86,9 @@
<Compile Include="fileselect\FileSelectActivity.cs" /> <Compile Include="fileselect\FileSelectActivity.cs" />
<Compile Include="fileselect\FileDbHelper.cs" /> <Compile Include="fileselect\FileDbHelper.cs" />
<Compile Include="Utils\Util.cs" /> <Compile Include="Utils\Util.cs" />
<Compile Include="Utils\Interaction.cs" />
<Compile Include="intents\Intents.cs" /> <Compile Include="intents\Intents.cs" />
<Compile Include="fileselect\BrowserDialog.cs" /> <Compile Include="fileselect\BrowserDialog.cs" />
<Compile Include="timeout\TimeoutHelper.cs" /> <Compile Include="timeout\TimeoutHelper.cs" />
<Compile Include="timers\Timeout.cs" />
<Compile Include="GroupActivity.cs" /> <Compile Include="GroupActivity.cs" />
<Compile Include="GroupBaseActivity.cs" /> <Compile Include="GroupBaseActivity.cs" />
<Compile Include="LockCloseListActivity.cs" /> <Compile Include="LockCloseListActivity.cs" />
@ -104,7 +102,6 @@
<Compile Include="settings\PrefsUtil.cs" /> <Compile Include="settings\PrefsUtil.cs" />
<Compile Include="views\PwEntryView.cs" /> <Compile Include="views\PwEntryView.cs" />
<Compile Include="views\GroupHeaderView.cs" /> <Compile Include="views\GroupHeaderView.cs" />
<Compile Include="BitmapDrawableCompat.cs" />
<Compile Include="GroupEditActivity.cs" /> <Compile Include="GroupEditActivity.cs" />
<Compile Include="EntryEditActivity.cs" /> <Compile Include="EntryEditActivity.cs" />
<Compile Include="LockCloseActivity.cs" /> <Compile Include="LockCloseActivity.cs" />

View File

@ -19,6 +19,7 @@ using System;
using Android.App; using Android.App;
using Android.Content; using Android.Content;
using Android.Preferences; using Android.Preferences;
using Android.Util;
using KeePassLib.Serialization; using KeePassLib.Serialization;
namespace keepass2android namespace keepass2android

View File

@ -81,10 +81,10 @@ namespace keepass2android.view
bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now; bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now;
if (isExpired) 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 } 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); String title = pw.Strings.ReadSafe(PwDefs.TitleField);

View File

@ -69,7 +69,7 @@ namespace keepass2android.view
_pwGroup = pw; _pwGroup = pw;
ImageView iv = (ImageView) gv.FindViewById(Resource.Id.group_icon); 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; _textview.Text = pw.Name;
} }