Merged lloyds/get-accounts into main

This commit is contained in:
AaronJamesY 2017-02-10 20:48:36 +00:00
commit 414de1008d
15 changed files with 159 additions and 34 deletions

View file

@ -1,23 +1,35 @@
using BankingBot.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BankingBot.Models;
using BankingBot.Enums;
using BankingBot.ScriptManagement;
namespace BankingBot.ActionManagers.AccountManagers
{
public class AccountManager : ActionManager, IAccountManager
{
protected IProviderAccountManager providerAccountManager;
private Provider _provider;
public AccountManager(IBrowserBot 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()
{
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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingBot.ActionManagers
{
@ -18,22 +16,38 @@ namespace BankingBot.ActionManagers
BrowserBot = browserBot;
}
protected Type GetActionTypeFromInterface(object identifyingType, Type interfaceType)
protected ActionDetail GetActionDetailFromInterface(object identifyingType, Type interfaceType)
{
var provider = ProviderIdentifier.GetProviderFromType(identifyingType.GetType());
var type = GetTypeAssociatedWithProvider(provider, interfaceType);
// Get all types implementing the given interface
var typesImplementingInterface = AppDomain.CurrentDomain.GetAssemblies()
return new ActionDetail { Provider = provider, Type = type };
}
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())
.Where(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)
{
var typeProvider = ProviderIdentifier.GetProviderFromType(type);
if (typeProvider == provider)
{
return type;
}
}
return null;

View file

@ -8,19 +8,13 @@ using OpenQA.Selenium;
using BankingBot.Responses;
using BankingBot.Enums;
using BankingBot.ScriptManagement;
using BankingBot.Urls;
namespace BankingBot.ActionManagers.LoginManagers
{
[ProviderIdentifier(Provider.Lloyds)]
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 IScriptManager _scriptManager;
@ -41,12 +35,12 @@ namespace BankingBot.ActionManagers.LoginManagers
{
LoginStep1(lloydsCreds);
if (!_browserBot.WebDriver.Url.Contains(Urls.MemorableInfo))
if (!_browserBot.WebDriver.Url.Contains(LloydsUrls.MemorableInfo))
throw new InvalidOperationException("Invalid login credentials");
LoginStep2(lloydsCreds);
if (!_browserBot.WebDriver.Url.Contains(Urls.AccountOverview))
if (!_browserBot.WebDriver.Url.Contains(LloydsUrls.AccountOverview))
throw new InvalidOperationException("Invalid passphrase for account");
response.Status = ResponseStatus.Success;
@ -62,7 +56,7 @@ namespace BankingBot.ActionManagers.LoginManagers
private void LoginStep1(LloydsLoginCredentials credentials)
{
_browserBot.WebDriver.Url = Urls.Login;
_browserBot.WebDriver.Url = LloydsUrls.Login;
_browserBot.WebDriver.Navigate();
_browserBot.WebDriver.FindElement(By.Id("frmLogin:strCustomerLogin_userID")).SendKeys(credentials.Username);
@ -93,7 +87,7 @@ namespace BankingBot.ActionManagers.LoginManagers
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");
var charIndexes = new int[3];

View file

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

View file

@ -12,7 +12,7 @@ namespace BankingBot.Attributes
Provider = provider;
}
public static Provider? GetProviderFromType(Type t)
public static Provider GetProviderFromType(Type t)
{
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>
<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\LoginManagers\BarclaysLoginManager.cs" />
<Compile Include="Attributes\ProviderIdentifier.cs" />
@ -59,6 +61,7 @@
<Compile Include="Contracts\IClient.cs" />
<Compile Include="Contracts\ILoginCredentials.cs" />
<Compile Include="Contracts\ILoginManager.cs" />
<Compile Include="Contracts\IProviderAccountManager.cs" />
<Compile Include="Contracts\IProviderLoginManager.cs" />
<Compile Include="Contracts\IResponse.cs" />
<Compile Include="Contracts\IScriptManager.cs" />
@ -77,6 +80,7 @@
<Compile Include="Responses\Response.cs" />
<Compile Include="ScriptManagement\ScriptBundles.cs" />
<Compile Include="ScriptManagement\ScriptManager.cs" />
<Compile Include="Urls\LloydsUrls.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

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

View file

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

View file

@ -4,6 +4,6 @@ namespace BankingBot.Contracts
{
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 Provider? GetProvider()
public Provider GetProvider()
{
return ProviderIdentifier.GetProviderFromType(GetType());
}

View file

@ -13,5 +13,7 @@ namespace BankingBot.Models
public string AccountNumber { 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/";
}
}