Added functionality to get accounts for Lloyds

This commit is contained in:
AaronJamesY 2017-02-10 20:48:11 +00:00
parent 45064edd5d
commit 8bc5571552
15 changed files with 159 additions and 34 deletions

View file

@ -1,23 +1,35 @@
using BankingBot.Contracts; using BankingBot.Contracts;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BankingBot.Models; using BankingBot.Models;
using BankingBot.Enums;
using BankingBot.ScriptManagement;
namespace BankingBot.ActionManagers.AccountManagers namespace BankingBot.ActionManagers.AccountManagers
{ {
public class AccountManager : ActionManager, IAccountManager public class AccountManager : ActionManager, IAccountManager
{ {
protected IProviderAccountManager providerAccountManager;
private Provider _provider;
public AccountManager(IBrowserBot browserBot) public AccountManager(IBrowserBot browserBot)
: base(browserBot) : base(browserBot)
{ }
public void Init(Provider provider)
{ {
_provider = provider;
// TODO: Implement DI to get rid of this new() crap
var scriptManager = new ScriptManager(BrowserBot);
var providerAccountManagerType = GetTypeFromInterface(provider, typeof(IProviderAccountManager));
providerAccountManager = (IProviderAccountManager)Activator.CreateInstance(providerAccountManagerType, BrowserBot, scriptManager);
} }
public IEnumerable<Account> GetAccounts() public IEnumerable<Account> GetAccounts()
{ {
throw new NotImplementedException(); return providerAccountManager.GetAccounts();
} }
} }
} }

View file

@ -0,0 +1,53 @@
using BankingBot.Attributes;
using BankingBot.Contracts;
using BankingBot.Enums;
using BankingBot.Models;
using BankingBot.Urls;
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingBot.ActionManagers.AccountManagers
{
[ProviderIdentifier(Provider.Lloyds)]
public class LloydsAccountManager : IProviderAccountManager
{
readonly IBrowserBot browserBot;
readonly IScriptManager scriptManager;
public LloydsAccountManager(
IBrowserBot browserBot,
IScriptManager scriptManager)
{
this.browserBot = browserBot;
this.scriptManager = scriptManager;
}
public IEnumerable<Account> GetAccounts()
{
var accounts = new List<Account>();
var accountsContainer = browserBot.WebDriver.FindElements(By.ClassName("des-m-sat-xx-account-information"));
foreach (var container in accountsContainer)
{
var account = new Account();
account.Name = container.FindElement(By.ClassName("account-name")).Text;
account.AccountNumber = container.FindElement(By.ClassName("account-number")).Text;
account.SortCode = container.FindElement(By.CssSelector("dd[aria-label='12 34 56']")).Text;
var balance = 0m;
var balanceTxt = container.FindElement(By.ClassName("balance")).FindElement(By.TagName("span")).Text;
decimal.TryParse(balanceTxt, NumberStyles.Currency, new CultureInfo("en-GB"), out balance);
account.Balance = balance;
accounts.Add(account);
}
return accounts;
}
}
}

View file

@ -0,0 +1,12 @@
using BankingBot.Enums;
using System;
namespace BankingBot.ActionManagers
{
public class ActionDetail
{
public Type Type { get; set; }
public Provider Provider { get; set; }
}
}

View file

@ -4,8 +4,6 @@ using BankingBot.Enums;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingBot.ActionManagers namespace BankingBot.ActionManagers
{ {
@ -18,22 +16,38 @@ namespace BankingBot.ActionManagers
BrowserBot = browserBot; BrowserBot = browserBot;
} }
protected Type GetActionTypeFromInterface(object identifyingType, Type interfaceType) protected ActionDetail GetActionDetailFromInterface(object identifyingType, Type interfaceType)
{ {
var provider = ProviderIdentifier.GetProviderFromType(identifyingType.GetType()); var provider = ProviderIdentifier.GetProviderFromType(identifyingType.GetType());
var type = GetTypeAssociatedWithProvider(provider, interfaceType);
// Get all types implementing the given interface return new ActionDetail { Provider = provider, Type = type };
var typesImplementingInterface = AppDomain.CurrentDomain.GetAssemblies() }
protected Type GetTypeFromInterface(Provider provider, Type interfaceType)
{
return GetTypeAssociatedWithProvider(provider, interfaceType);
}
private static IEnumerable<Type> GetTypesImplementingInterface(Type interfaceType)
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()) .SelectMany(s => s.GetTypes())
.Where(p => .Where(p =>
interfaceType.IsAssignableFrom(p) && interfaceType.IsAssignableFrom(p) &&
p != interfaceType); p != interfaceType).ToList();
}
private static Type GetTypeAssociatedWithProvider(Provider provider, Type interfaceType)
{
var typesImplementingInterface = GetTypesImplementingInterface(interfaceType);
foreach (var type in typesImplementingInterface) foreach (var type in typesImplementingInterface)
{ {
var typeProvider = ProviderIdentifier.GetProviderFromType(type); var typeProvider = ProviderIdentifier.GetProviderFromType(type);
if (typeProvider == provider) if (typeProvider == provider)
{
return type; return type;
}
} }
return null; return null;

View file

@ -8,19 +8,13 @@ using OpenQA.Selenium;
using BankingBot.Responses; using BankingBot.Responses;
using BankingBot.Enums; using BankingBot.Enums;
using BankingBot.ScriptManagement; using BankingBot.ScriptManagement;
using BankingBot.Urls;
namespace BankingBot.ActionManagers.LoginManagers namespace BankingBot.ActionManagers.LoginManagers
{ {
[ProviderIdentifier(Provider.Lloyds)] [ProviderIdentifier(Provider.Lloyds)]
public class LloydsLoginManager : IProviderLoginManager public class LloydsLoginManager : IProviderLoginManager
{ {
private static class Urls
{
public const string Login = "https://online.lloydsbank.co.uk/personal/logon/login.jsp";
public const string MemorableInfo = "https://secure.lloydsbank.co.uk/personal/a/logon/entermemorableinformation.jsp";
public const string AccountOverview = "https://secure.lloydsbank.co.uk/personal/a/account_overview_personal/";
}
private readonly IBrowserBot _browserBot; private readonly IBrowserBot _browserBot;
private readonly IScriptManager _scriptManager; private readonly IScriptManager _scriptManager;
@ -41,12 +35,12 @@ namespace BankingBot.ActionManagers.LoginManagers
{ {
LoginStep1(lloydsCreds); LoginStep1(lloydsCreds);
if (!_browserBot.WebDriver.Url.Contains(Urls.MemorableInfo)) if (!_browserBot.WebDriver.Url.Contains(LloydsUrls.MemorableInfo))
throw new InvalidOperationException("Invalid login credentials"); throw new InvalidOperationException("Invalid login credentials");
LoginStep2(lloydsCreds); LoginStep2(lloydsCreds);
if (!_browserBot.WebDriver.Url.Contains(Urls.AccountOverview)) if (!_browserBot.WebDriver.Url.Contains(LloydsUrls.AccountOverview))
throw new InvalidOperationException("Invalid passphrase for account"); throw new InvalidOperationException("Invalid passphrase for account");
response.Status = ResponseStatus.Success; response.Status = ResponseStatus.Success;
@ -62,7 +56,7 @@ namespace BankingBot.ActionManagers.LoginManagers
private void LoginStep1(LloydsLoginCredentials credentials) private void LoginStep1(LloydsLoginCredentials credentials)
{ {
_browserBot.WebDriver.Url = Urls.Login; _browserBot.WebDriver.Url = LloydsUrls.Login;
_browserBot.WebDriver.Navigate(); _browserBot.WebDriver.Navigate();
_browserBot.WebDriver.FindElement(By.Id("frmLogin:strCustomerLogin_userID")).SendKeys(credentials.Username); _browserBot.WebDriver.FindElement(By.Id("frmLogin:strCustomerLogin_userID")).SendKeys(credentials.Username);
@ -93,7 +87,7 @@ namespace BankingBot.ActionManagers.LoginManagers
private int[] GetPassphraseIndexes() private int[] GetPassphraseIndexes()
{ {
if (_browserBot.WebDriver.Url != Urls.MemorableInfo) if (_browserBot.WebDriver.Url != LloydsUrls.MemorableInfo)
throw new InvalidOperationException("Must be on the memorable info page"); throw new InvalidOperationException("Must be on the memorable info page");
var charIndexes = new int[3]; var charIndexes = new int[3];

View file

@ -18,8 +18,8 @@ namespace BankingBot.ActionManagers.LoginManagers
// TODO: THIS NEEDS TO BE MOVED // TODO: THIS NEEDS TO BE MOVED
var scriptManager = new ScriptManager(BrowserBot); var scriptManager = new ScriptManager(BrowserBot);
var provLoginManagerType = GetActionTypeFromInterface(credentials, typeof(IProviderLoginManager)); var providerLoginManagerType = GetTypeFromInterface(credentials.GetProvider(), typeof(IProviderLoginManager));
var provLoginManager = (IProviderLoginManager)Activator.CreateInstance(provLoginManagerType, BrowserBot, scriptManager); var provLoginManager = (IProviderLoginManager)Activator.CreateInstance(providerLoginManagerType, BrowserBot, scriptManager);
return provLoginManager.Login(credentials); return provLoginManager.Login(credentials);
} }

View file

@ -12,7 +12,7 @@ namespace BankingBot.Attributes
Provider = provider; Provider = provider;
} }
public static Provider? GetProviderFromType(Type t) public static Provider GetProviderFromType(Type t)
{ {
foreach (var attr in t.GetCustomAttributes(false)) foreach (var attr in t.GetCustomAttributes(false))
{ {
@ -22,7 +22,7 @@ namespace BankingBot.Attributes
} }
} }
return null; throw new InvalidOperationException("Could not find associated provider for given type");
} }
} }
} }

View file

@ -49,6 +49,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ActionManagers\AccountManagers\AccountManager.cs" /> <Compile Include="ActionManagers\AccountManagers\AccountManager.cs" />
<Compile Include="ActionManagers\AccountManagers\LloydsAccountManager.cs" />
<Compile Include="ActionManagers\ActionDetail.cs" />
<Compile Include="ActionManagers\ActionManager.cs" /> <Compile Include="ActionManagers\ActionManager.cs" />
<Compile Include="ActionManagers\LoginManagers\BarclaysLoginManager.cs" /> <Compile Include="ActionManagers\LoginManagers\BarclaysLoginManager.cs" />
<Compile Include="Attributes\ProviderIdentifier.cs" /> <Compile Include="Attributes\ProviderIdentifier.cs" />
@ -59,6 +61,7 @@
<Compile Include="Contracts\IClient.cs" /> <Compile Include="Contracts\IClient.cs" />
<Compile Include="Contracts\ILoginCredentials.cs" /> <Compile Include="Contracts\ILoginCredentials.cs" />
<Compile Include="Contracts\ILoginManager.cs" /> <Compile Include="Contracts\ILoginManager.cs" />
<Compile Include="Contracts\IProviderAccountManager.cs" />
<Compile Include="Contracts\IProviderLoginManager.cs" /> <Compile Include="Contracts\IProviderLoginManager.cs" />
<Compile Include="Contracts\IResponse.cs" /> <Compile Include="Contracts\IResponse.cs" />
<Compile Include="Contracts\IScriptManager.cs" /> <Compile Include="Contracts\IScriptManager.cs" />
@ -77,6 +80,7 @@
<Compile Include="Responses\Response.cs" /> <Compile Include="Responses\Response.cs" />
<Compile Include="ScriptManagement\ScriptBundles.cs" /> <Compile Include="ScriptManagement\ScriptBundles.cs" />
<Compile Include="ScriptManagement\ScriptManager.cs" /> <Compile Include="ScriptManagement\ScriptManager.cs" />
<Compile Include="Urls\LloydsUrls.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />

View file

@ -9,6 +9,7 @@ using BankingBot.Models;
using OpenQA.Selenium; using OpenQA.Selenium;
using BankingBot.ActionManagers.AccountManagers; using BankingBot.ActionManagers.AccountManagers;
using BankingBot.Responses; using BankingBot.Responses;
using BankingBot.Enums;
namespace BankingBot namespace BankingBot
{ {
@ -16,13 +17,14 @@ namespace BankingBot
where T : IWebDriver where T : IWebDriver
{ {
#region Dependencies #region Dependencies
private readonly ILoginManager _loginManager; readonly ILoginManager loginManager;
private readonly IAccountManager _accountManager; readonly IAccountManager accountManager;
protected readonly IBrowserBot BrowserBot; protected readonly IBrowserBot BrowserBot;
#endregion #endregion
public ILoginCredentials LoginCredentials { get; private set; } public ILoginCredentials LoginCredentials { get; private set; }
public Provider Provider { get; private set; }
public bool IsLoggedIn public bool IsLoggedIn
{ {
@ -33,8 +35,8 @@ namespace BankingBot
{ {
BrowserBot = new BrowserBot<T>(); BrowserBot = new BrowserBot<T>();
_loginManager = new LoginManager(BrowserBot); loginManager = new LoginManager(BrowserBot);
_accountManager = new AccountManager(BrowserBot); accountManager = new AccountManager(BrowserBot);
} }
#region Actions - Login Manager #region Actions - Login Manager
@ -42,8 +44,15 @@ namespace BankingBot
public Response Login(ILoginCredentials credentials) public Response Login(ILoginCredentials credentials)
{ {
LoginCredentials = credentials; LoginCredentials = credentials;
Provider = credentials.GetProvider();
return _loginManager.Login(credentials); var response = loginManager.Login(credentials);
if (response.Status == ResponseStatus.Success)
{
accountManager.Init(Provider);
}
return response;
} }
#endregion #endregion
@ -57,7 +66,7 @@ namespace BankingBot
public IEnumerable<Account> GetAccounts() public IEnumerable<Account> GetAccounts()
{ {
return _accountManager.GetAccounts(); return accountManager.GetAccounts();
} }
#endregion #endregion

View file

@ -1,10 +1,12 @@
using BankingBot.Models; using BankingBot.Enums;
using BankingBot.Models;
using System.Collections.Generic; using System.Collections.Generic;
namespace BankingBot.Contracts namespace BankingBot.Contracts
{ {
public interface IAccountManager public interface IAccountManager
{ {
void Init(Provider provider);
IEnumerable<Account> GetAccounts(); IEnumerable<Account> GetAccounts();
} }
} }

View file

@ -4,6 +4,6 @@ namespace BankingBot.Contracts
{ {
public interface ILoginCredentials public interface ILoginCredentials
{ {
Provider? GetProvider(); Provider GetProvider();
} }
} }

View file

@ -0,0 +1,14 @@
using BankingBot.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingBot.Contracts
{
public interface IProviderAccountManager
{
IEnumerable<Account> GetAccounts();
}
}

View file

@ -11,7 +11,7 @@ namespace BankingBot.LoginCredentials
{ {
public abstract class LoginCredentials : ILoginCredentials public abstract class LoginCredentials : ILoginCredentials
{ {
public Provider? GetProvider() public Provider GetProvider()
{ {
return ProviderIdentifier.GetProviderFromType(GetType()); return ProviderIdentifier.GetProviderFromType(GetType());
} }

View file

@ -13,5 +13,7 @@ namespace BankingBot.Models
public string AccountNumber { get; set; } public string AccountNumber { get; set; }
public string Name { get; set; } public string Name { get; set; }
public decimal Balance { get; set; }
} }
} }

View file

@ -0,0 +1,9 @@
namespace BankingBot.Urls
{
public static class LloydsUrls
{
public const string Login = "https://online.lloydsbank.co.uk/personal/logon/login.jsp";
public const string MemorableInfo = "https://secure.lloydsbank.co.uk/personal/a/logon/entermemorableinformation.jsp";
public const string AccountOverview = "https://secure.lloydsbank.co.uk/personal/a/account_overview_personal/";
}
}