Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactoring of the domain and writing tests

  • Loading branch information...
commit 3d392c0397194a168aeafed937c379c424db4229 1 parent 21b7bc5
@bettiolo authored
View
21 src/PassFruit.Client.InMemoryRepository/InMemoryRepository.cs
@@ -8,7 +8,16 @@ namespace PassFruit.Client.InMemoryRepository {
public class InMemoryRepository : RepositoryBase {
- private readonly Dictionary<Guid, Dictionary<string, string>> _passwords = new Dictionary<Guid, Dictionary<string, string>>();
+ public InMemoryRepository(InMemoryRepositoryConfiguration configuration) : base(configuration) {
+
+ }
+
+ public new InMemoryRepositoryConfiguration Configuration {
+ get { return (InMemoryRepositoryConfiguration)base.Configuration; }
+ }
+
+ private readonly Dictionary<Guid, Dictionary<string, string>> _passwords =
+ new Dictionary<Guid, Dictionary<string, string>>();
public override string Name {
get { return "In Memory Repository"; }
@@ -45,21 +54,21 @@ public class InMemoryRepository : RepositoryBase {
}
protected override void InternalSave(IAccount account) {
- // Nothing to do as the account is already changed in memory;
+ throw new NotImplementedException();
}
protected override IAccount GetAccount(Guid accountId) {
- // The accounts are not persisted
- return null;
+ throw new NotImplementedException();
}
protected override IEnumerable<Guid> GetAllAccountIds(bool includingDeleted = false) {
- return new List<Guid>();
+ throw new NotImplementedException();
}
protected override void LoadAllFieldTypes() {
- // FieldTypes.Add(FieldTypes.Create());
+ throw new NotImplementedException();
}
+
}
}
View
19 src/PassFruit.Client.InMemoryRepository/InMemoryRepositoryConfiguration.cs
@@ -0,0 +1,19 @@
+using PassFruit.Contracts;
+
+namespace PassFruit.Client.InMemoryRepository {
+
+ public class InMemoryRepositoryConfiguration : IRepositoryConfiguration {
+
+ public InMemoryRepositoryConfiguration(string serializedFilePath) {
+ _serializedFilePath = serializedFilePath;
+ }
+
+ private readonly string _serializedFilePath;
+
+ public string SerializedFilePath {
+ get { return _serializedFilePath; }
+ }
+
+ }
+
+}
View
1  src/PassFruit.Client.InMemoryRepository/PassFruit.Client.InMemoryRepository.csproj
@@ -41,6 +41,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="InMemoryRepository.cs" />
+ <Compile Include="InMemoryRepositoryConfiguration.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
View
20 src/PassFruit.Client.XmlRepository.Tests/PassFruit.Client.XmlRepository.Tests.csproj
@@ -30,6 +30,26 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+ <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=1.7.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.1.7.0\Lib\net40\FluentAssertions.dll</HintPath>
View
5 src/PassFruit.Client.XmlRepository.Tests/XmlRepositoryTests.cs
@@ -25,7 +25,8 @@ public class XmlRepositoryTests : RepositoryTests {
// Given
var repository = (XmlRepository)GetRepositoryWithFakeData();
XmlRepository reloadedRepository = null;
- var account = repository.Accounts.GetByUserName("tWiTTeRUsEr").First();
+ var userName = "tWiTTeRUsEr";
+ var account = repository.Accounts.GetByUserName(userName).First();
IAccount reloadedAccount = null;
var originalDefaultPassword = account.GetPassword();
var originalCustomPassword = account.GetPassword("custom");
@@ -40,7 +41,7 @@ public class XmlRepositoryTests : RepositoryTests {
var actSave = new Action(account.Save);
var actReloadRepository = new Action(() => reloadedRepository = new XmlRepository(repository.XmlFilePath));
var actReloadAccount = new Action(() =>
- reloadedAccount = reloadedRepository.Accounts.GetByUserName("tWiTTeRUsEr").First()
+ reloadedAccount = reloadedRepository.Accounts.GetByUserName(userName.ToLowerInvariant()).First()
);
// Then
View
2  src/PassFruit.Client.XmlRepository/PassFruit.Client.XmlRepository.csproj
@@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -42,6 +43,7 @@
<ItemGroup>
<Compile Include="XmlRepository.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="XmlRepositoryConfiguration.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PassFruit.Contracts\PassFruit.Contracts.csproj">
View
63 src/PassFruit.Client.XmlRepository/XmlRepository.cs
@@ -25,21 +25,19 @@ public class XmlRepository : RepositoryBase {
* </passfruit>
*/
- public XmlRepository(string xmlFilePath) {
- _xmlFilePath = xmlFilePath;
+ public XmlRepository(XmlRepositoryConfiguration configuration) : base(configuration) {
LoadXDocument();
}
+ public new XmlRepositoryConfiguration Configuration {
+ get { return (XmlRepositoryConfiguration) base.Configuration; }
+ }
+
private const string AccountIdPrefix = "id-";
+ private const string TagPrefix = "tag-";
private XDocument _xDoc;
- private readonly string _xmlFilePath;
-
- public string XmlFilePath {
- get { return _xmlFilePath; }
- }
-
public override string Name {
get { return "XML Repository"; }
}
@@ -71,16 +69,24 @@ public class XmlRepository : RepositoryBase {
accountId = accountId.Remove(0, AccountIdPrefix.Length);
Guid guid;
if (Guid.TryParse(accountId, out guid)) {
- accountIds.Add(guid);
+ accountIds.Add(guid);
}
}
return accountIds;
}
protected override IAccount GetAccount(Guid accountId) {
- var accountElement = GetAccountElement(accountId);
- // var account = Accounts.Add()
- return null;
+ var accountFieldsElement = GetAccountFieldsElement(accountId);
+ IAccount account = null;
+ foreach (var fieldElement in accountFieldsElement.Elements()) {
+ if (account == null) {
+ account = Accounts.Create("", accountId);
+ }
+ var fieldTypeKey = (FieldTypeKey)Enum.Parse(typeof (FieldTypeKey), fieldElement.Name.LocalName, true);
+ account.SetField(fieldTypeKey, fieldElement.Value);
+ account.SetClean();
+ }
+ return account;
}
protected override void LoadAllFieldTypes() {
@@ -88,10 +94,10 @@ public class XmlRepository : RepositoryBase {
}
private void LoadXDocument() {
- var xmlFile = new FileInfo(_xmlFilePath);
+ var xmlFile = new FileInfo(Configuration.XmlFilePath);
if (xmlFile.Exists && xmlFile.Length > 0) {
- _xDoc = XDocument.Load(_xmlFilePath);
+ _xDoc = XDocument.Load(xmlFile.FullName);
} else {
_xDoc = new XDocument();
}
@@ -114,15 +120,31 @@ public class XmlRepository : RepositoryBase {
}
private XElement GetAccountsElement() {
- return GetOrCreateElement("accounts", GetPasswordsElement());
+ return GetOrCreateElement("accounts", GetPassfruitElement());
}
private XElement GetAccountElement(Guid accountId) {
return GetOrCreateElement(AccountIdPrefix + accountId, GetAccountsElement());
}
+ private XElement GetAccountFieldsElement(Guid accountId) {
+ return GetOrCreateElement("fields", GetAccountElement(accountId));
+ }
+
+ private XElement GetProviderField(Guid accountId) {
+ return GetOrCreateElement("provider", GetAccountElement(accountId));
+ }
+
+ private XElement GetTagsElement() {
+ return GetOrCreateElement("tags", GetPassfruitElement());
+ }
+
+ private XElement GetTagElement(string tagName) {
+ return GetOrCreateElement(TagPrefix + tagName, GetPassfruitElement());
+ }
+
private XElement GetAccountField(IField field, Guid accountId) {
- return GetOrCreateElement(field.FieldType.Key.ToString(), GetAccountElement(accountId));
+ return GetOrCreateElement(field.FieldType.Key.ToString(), GetAccountFieldsElement(accountId));
}
private XElement GetOrCreateElement(string elementName, XContainer parentElement) {
@@ -136,13 +158,20 @@ public class XmlRepository : RepositoryBase {
}
private void SaveXml() {
- _xDoc.Save(_xmlFilePath);
+ _xDoc.Save(Configuration.XmlFilePath);
}
protected override void InternalSave(IAccount account) {
+ if (account.Provider != null) {
+ GetProviderField(account.Id).Value = account.Provider.Key;
+ }
foreach (var field in account.Fields) {
GetAccountField(field, account.Id).Value = field.Value.ToString();
}
+ foreach (var tag in account.Tags) {
+ // var tagElement = GetTagElement(tag.Key);
+ // ToDo: Should handle adding, removing and changing tags
+ }
SaveXml();
}
View
23 src/PassFruit.Client.XmlRepository/XmlRepositoryConfiguration.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PassFruit.Contracts;
+
+namespace PassFruit.Client.XmlRepository {
+
+ public class XmlRepositoryConfiguration : IRepositoryConfiguration {
+
+ public XmlRepositoryConfiguration(string xmlFilePath) {
+ _xmlFilePath = xmlFilePath;
+ }
+
+ private readonly string _xmlFilePath;
+
+ public string XmlFilePath {
+ get { return _xmlFilePath; }
+ }
+
+ }
+
+}
View
2  src/PassFruit.Contracts/IAccounts.cs
@@ -13,7 +13,7 @@ public interface IAccounts : IList<IAccount> {
IEnumerable<IAccount> GetByUserName(string userName);
- IAccount Create(string providerKey);
+ IAccount Create(string providerKey, Guid? id = null);
}
View
12 src/PassFruit.Contracts/IRepositoryConfiguration.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PassFruit.Contracts {
+
+ public interface IRepositoryConfiguration {
+
+ }
+
+}
View
1  src/PassFruit.Contracts/PassFruit.Contracts.csproj
@@ -46,6 +46,7 @@
<Compile Include="IFieldType.cs" />
<Compile Include="IProvider.cs" />
<Compile Include="IProviders.cs" />
+ <Compile Include="IRepositoryConfiguration.cs" />
<Compile Include="ITag.cs" />
<Compile Include="ITags.cs" />
<Compile Include="IAccounts.cs" />
View
28 src/PassFruit.Tests.FakeData/FakeDataGenerator.cs
@@ -5,37 +5,47 @@ namespace PassFruit.Tests.FakeData {
public class FakeDataGenerator {
+ public const string FacebookEmail = @"testFacebook@example.com";
+ public const string FacebookPassword = @"Password1";
+ public const string TwitterEmail = @"testTwitter@example.com";
+ public const string TwitterUserName = @"TwitterUser";
+ public const string TwitterPassword = @"Password2!£!$!$%!$&!£&!";
+ public const string Google1Email = @"user.name.example@gmail.com";
+ public const string Goggle1Password = @"Password3";
+ public const string Google2Email = @"example2@gmail.com";
+ public const string Google2Password = @"Password4";
+
public void GenerateFakeData(IRepository repository) {
var facebookAccount = repository.Accounts.Create("facebook");
facebookAccount.Notes = @"Example test note 1";
- facebookAccount.SetField(FieldTypeKey.Email, @"testFacebook@example.com");
+ facebookAccount.SetField(FieldTypeKey.Email, FacebookEmail);
facebookAccount.AddTag("Tag 1");
facebookAccount.AddTag("Tag 2");
- facebookAccount.SetPassword("Password1");
+ facebookAccount.SetPassword(FacebookPassword);
repository.Accounts.Add(facebookAccount);
var twitterAccount = repository.Accounts.Create("twitter");
twitterAccount.Notes = @"Example test note 2 blah blah blah\nBlah blah blah\nLorem ipsun dolor sit amet";
- twitterAccount.SetField(FieldTypeKey.Email, @"testTwitter@example.com");
- twitterAccount.SetField(FieldTypeKey.UserName, @"TwitterUser");
+ twitterAccount.SetField(FieldTypeKey.Email, TwitterEmail);
+ twitterAccount.SetField(FieldTypeKey.UserName, TwitterUserName);
twitterAccount.AddTag("Tag 1");
- twitterAccount.SetPassword("Password2!£!$!$%!$&!£&!");
+ twitterAccount.SetPassword(TwitterPassword);
repository.Accounts.Add(twitterAccount);
var googleAccount = repository.Accounts.Create("google");
- googleAccount.SetField(FieldTypeKey.Email, "user.name.example@gmail.com");
+ googleAccount.SetField(FieldTypeKey.Email, Google1Email);
googleAccount.AddTag("Tag 1");
googleAccount.AddTag("Tag 2");
googleAccount.AddTag("Tag 3");
- googleAccount.SetPassword("Password3");
+ googleAccount.SetPassword(Goggle1Password);
repository.Accounts.Add(googleAccount);
var googleAccount2 = repository.Accounts.Create("google");
- googleAccount2.SetField(FieldTypeKey.Email, "example2@gmail.com");
+ googleAccount2.SetField(FieldTypeKey.Email, Google2Email);
googleAccount2.AddTag("Tag 2");
googleAccount2.AddTag("Tag 3");
- googleAccount2.SetPassword("Password4");
+ googleAccount2.SetPassword(Google2Password);
repository.Accounts.Add(googleAccount2);
repository.SaveAll();
View
4 src/PassFruit.Tests.sln
@@ -43,8 +43,8 @@ Global
{EF5C1406-CD43-46C7-A5C3-DBC74770585F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF5C1406-CD43-46C7-A5C3-DBC74770585F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF5C1406-CD43-46C7-A5C3-DBC74770585F}.Release|Any CPU.Build.0 = Release|Any CPU
- {94587E6F-E2F6-4394-AB7C-F4037B726425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {94587E6F-E2F6-4394-AB7C-F4037B726425}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94587E6F-E2F6-4394-AB7C-F4037B726425}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {94587E6F-E2F6-4394-AB7C-F4037B726425}.Debug|Any CPU.Build.0 = Debug|x86
{94587E6F-E2F6-4394-AB7C-F4037B726425}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94587E6F-E2F6-4394-AB7C-F4037B726425}.Release|Any CPU.Build.0 = Release|Any CPU
{02D15B96-AD18-466A-88D7-454652E8347A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
View
27 src/PassFruit.Tests/RepositoryTests.cs
@@ -3,6 +3,7 @@
using FluentAssertions;
using NUnit.Framework;
using PassFruit.Contracts;
+using PassFruit.Tests.FakeData;
namespace PassFruit.Tests {
@@ -11,21 +12,25 @@ public abstract class RepositoryTests {
protected abstract IRepository GetRepositoryWithFakeData();
+ protected abstract IRepository GetReloadedRepository();
+
[Test]
public void When_An_Account_Is_Loaded_The_Correct_One_Should_Be_Returned() {
// Given
var repository = GetRepositoryWithFakeData();
- var testFacebookEmail = "testFacebook@example.com";
- var testTwitterAccount = "TwitterUser";
- var testTwitterEmail = "testTwitter@example.com";
- var testGoogleEmail = "user.name.example@gmail.com";
+ var testFacebookEmail = FakeDataGenerator.FacebookEmail;
+ var testTwitterAccount = FakeDataGenerator.TwitterUserName;
+ var testTwitterEmail = FakeDataGenerator.TwitterEmail;
+ var testGoogleEmail = FakeDataGenerator.Google1Email;
+ IRepository reloadedRepository = null;
// When
var facebookAccount = repository.Accounts.GetByEmail(testFacebookEmail).FirstOrDefault();
var twitterAccountByUserName = repository.Accounts.GetByUserName(testTwitterAccount).FirstOrDefault();
var twitterAccountByEmail = repository.Accounts.GetByEmail(testTwitterEmail).FirstOrDefault();
var gmailAccount = repository.Accounts.GetByEmail(testGoogleEmail).FirstOrDefault();
+ Action actReloadRepository = () => reloadedRepository = GetReloadedRepository();
// Then
facebookAccount.Should().NotBeNull();
@@ -44,6 +49,9 @@ public abstract class RepositoryTests {
gmailAccount.GetDefaultField(FieldTypeKey.Email).Value.Should().Be(testGoogleEmail);
gmailAccount.Provider.Key.Should().Be("google");
+ actReloadRepository();
+ reloadedRepository.Should().NotBeNull();
+
}
[Test]
@@ -137,6 +145,17 @@ public abstract class RepositoryTests {
}
[Test]
+ public void When_A_Tag_Is_Deleted_Then_The_Number_Of_Tags_Should_Decrease() {
+ throw new NotImplementedException();
+ }
+
+
+ [Test]
+ public void When_A_Tag_Is_Changed_Then_The_Change_Should_Be_Persisted() {
+ throw new NotImplementedException();
+ }
+
+ [Test]
public void When_A_Password_Is_Changed_Then_The_Account_Should_Not_Be_Dirty_And_The_Password_Shold_Be_Saved() {
// Given
View
2  src/PassFruit/Account.cs
@@ -60,7 +60,7 @@ public class Account : IAccount {
return GetAccountName() + " | " + Provider.Name;
}
- private IProvider _provider;
+ private readonly IProvider _provider;
public IProvider Provider {
get { return _provider; }
}
View
8 src/PassFruit/Accounts.cs
@@ -19,16 +19,16 @@ public class Accounts : Collection<IAccount>, IAccounts {
}
public IEnumerable<IAccount> GetByEmail(string email) {
- return this.Where(account => FindField(account, Contracts.FieldTypeKey.Email, email));
+ return this.Where(account => FindField(account, FieldTypeKey.Email, email));
}
public IEnumerable<IAccount> GetByUserName(string userName) {
- return this.Where(account => FindField(account, Contracts.FieldTypeKey.UserName, userName));
+ return this.Where(account => FindField(account, FieldTypeKey.UserName, userName));
}
- public IAccount Create(string providerKey) {
+ public IAccount Create(string providerKey, Guid? id) {
var provider = _repository.Providers.GetByKey(providerKey);
- return new Account(_repository, provider);
+ return new Account(_repository, provider, id);
}
private static bool FindField(IAccount account, FieldTypeKey fieldTypeKey, string fieldValue) {
View
13 src/PassFruit/Providers.cs
@@ -27,12 +27,13 @@ public class Providers : IProviders {
}
public void Add(string key, string name, bool hasEmail, bool hasUserName, bool hasPassword, string url) {
- var provider = new Provider(key);
- provider.Name = name;
- provider.HasEmail = hasEmail;
- provider.HasPassword = hasPassword;
- provider.HasUserName = hasUserName;
- provider.Url = url;
+ var provider = new Provider(key) {
+ Name = name,
+ HasEmail = hasEmail,
+ HasPassword = hasPassword,
+ HasUserName = hasUserName,
+ Url = url
+ };
_providers.Add(provider);
}
View
6 src/PassFruit/RepositoryBase.cs
@@ -10,6 +10,12 @@ public abstract class RepositoryBase : IRepository {
public const string DefaultPasswordKey = "default";
+ public RepositoryBase(IRepositoryConfiguration configuration) {
+ Configuration = configuration;
+ }
+
+ protected IRepositoryConfiguration Configuration { get; set; }
+
private IAccounts _accounts;
private ITags _tags;
Please sign in to comment.
Something went wrong with that request. Please try again.