diff --git a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/MyAccount/MyAccountPageViewModelTests.cs b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/MyAccount/MyAccountPageViewModelTests.cs index db94dd3f..fc38d32f 100644 --- a/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/MyAccount/MyAccountPageViewModelTests.cs +++ b/TransactionProcessor.Mobile.BusinessLogic.Tests/ViewModelTests/MyAccount/MyAccountPageViewModelTests.cs @@ -57,6 +57,19 @@ public async Task MyAccountPageViewModel_Initialise_IsInitialised() { this.ViewModel.IsDarkThemeEnabled.ShouldBeTrue(); } + [Fact] + public async Task MyAccountPageViewModel_Initialise_WhenMerchantDetailsAreCached_UsesCachedMerchantDetails() { + this.ApplicationCache.Setup(a => a.GetMerchantDetails()).Returns(TestData.MerchantDetailsModel); + this.ApplicationCache.Setup(a => a.GetLastLoginDate()).Returns(DateTime.Now); + this.ApplicationThemeService.Setup(s => s.GetDarkThemeEnabled()).ReturnsAsync(false); + this.Mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())).ReturnsAsync(Result.Success(TestData.MerchantDetailsModel)); + + await this.ViewModel.Initialise(CancellationToken.None); + + this.ViewModel.MerchantName.ShouldBe(TestData.MerchantDetailsModel.MerchantName); + this.Mediator.Verify(m => m.Send(It.IsAny(), It.IsAny()), Times.Never); + } + [Fact] public async Task MyAccountPageViewModel_SetDarkTheme_ThemeStoredAndPropertyUpdated() { await this.ViewModel.SetDarkTheme(true); diff --git a/TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs b/TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs index 483926d5..768a4cd4 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs @@ -1,10 +1,11 @@ -using System; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; -using Microsoft.Extensions.Caching.Memory; using TransactionProcessor.Mobile.BusinessLogic.Models; namespace TransactionProcessor.Mobile.BusinessLogic.Services @@ -35,8 +36,12 @@ public interface IApplicationCache void SetAccessToken(TokenResponseModel value, MemoryCacheEntryOptions options = default); + void ClearAccessToken(); + MerchantDetailsModel GetMerchantDetails(); + void ClearMerchantDetails(); + void SetMerchantDetails(MerchantDetailsModel value, MemoryCacheEntryOptions options = default); Decimal GetMerchantBalance(); @@ -114,6 +119,10 @@ public void SetAccessToken(TokenResponseModel value, this.Set("AccessToken", value, options); } + public void ClearAccessToken() { + this.MemoryCache.Remove("AccessToken"); + } + public void SetConfiguration(Configuration value, MemoryCacheEntryOptions options = default) { @@ -137,6 +146,10 @@ public MerchantDetailsModel GetMerchantDetails() return this.TryGetValue("MerchantDetails"); } + public void ClearMerchantDetails() { + this.MemoryCache.Remove("MerchantDetails"); + } + public void SetMerchantDetails(MerchantDetailsModel value, MemoryCacheEntryOptions options = default) { diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/ExtendedBaseViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/ExtendedBaseViewModel.cs index e36f6228..b8f0abe9 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/ExtendedBaseViewModel.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/ExtendedBaseViewModel.cs @@ -84,7 +84,8 @@ private async Task ShowLoginPage() { if (leave) { Logger.LogInformation("LogoutCommand called"); this.ApplicationCache.SetIsLoggedIn(false); - this.ApplicationCache.SetAccessToken(null); + this.ApplicationCache.ClearAccessToken(); + this.ApplicationCache.ClearMerchantDetails(); await this.NavigationService.GoToLoginPage(); } diff --git a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/MyAccount/MyAccountPageViewModel.cs b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/MyAccount/MyAccountPageViewModel.cs index bd39d293..411ce9ca 100644 --- a/TransactionProcessor.Mobile.BusinessLogic/ViewModels/MyAccount/MyAccountPageViewModel.cs +++ b/TransactionProcessor.Mobile.BusinessLogic/ViewModels/MyAccount/MyAccountPageViewModel.cs @@ -103,8 +103,9 @@ public async Task SetDarkTheme(Boolean isEnabled) { private async Task LogoutCommandExecute() { Logger.LogInformation("LogoutCommand called"); - this.ApplicationCache.SetAccessToken(null); + this.ApplicationCache.ClearAccessToken(); this.ApplicationCache.SetIsLoggedIn(false); + this.ApplicationCache.ClearMerchantDetails(); await this.NavigationService.GoToLoginPage(); } diff --git a/TransactionProcessor.Mobile.UITests/Drivers/AppiumDriver.cs b/TransactionProcessor.Mobile.UITests/Drivers/AppiumDriver.cs index d3425a04..6d8942b9 100644 --- a/TransactionProcessor.Mobile.UITests/Drivers/AppiumDriver.cs +++ b/TransactionProcessor.Mobile.UITests/Drivers/AppiumDriver.cs @@ -499,6 +499,7 @@ private static void SetupAndroidDriver(Uri? appiumServerUri, TestAppConfig testA driverOptions.AddAdditionalAppiumOption("appPackage", "com.transactionprocessor.mobile"); driverOptions.AddAdditionalAppiumOption("enforceAppInstall", true); driverOptions.AddAdditionalAppiumOption("uiautomator2ServerInstallTimeout", "40000"); + driverOptions.AddAdditionalAppiumOption("uiautomator2ServerLaunchTimeout", "120000"); driverOptions.AddAdditionalAppiumOption(MobileCapabilityType.NewCommandTimeout, 6000); driverOptions.App = testAppConfig.AndroidAppPath; diff --git a/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature b/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature new file mode 100644 index 00000000..7ebfe9d7 --- /dev/null +++ b/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature @@ -0,0 +1,136 @@ +@background @login @toolbar @profile @base @sharedapp @shared +Feature: LogoutLoginMerchantDetails + +Background: + + Given the following security roles exist + | Role Name | + | Merchant | + + Given I create the following api scopes + | Name | DisplayName | Description | + | transactionProcessor | Transaction Processor REST Scope | A scope for Transaction Processor REST | + | transactionProcessorACL | Transaction Processor ACL REST Scope | A scope for Transaction Processor ACL REST | + + Given the following api resources exist + | Name | DisplayName | Secret | Scopes | UserClaims | + | transactionProcessor | Transaction Processor REST | Secret1 | transactionProcessor | merchantId, estateId, role | + | transactionProcessorACL | Transaction Processor ACL REST | Secret1 | transactionProcessorACL | merchantId, estateId, role | + + Given the following clients exist + | ClientId | ClientName | Secret | Scopes | GrantTypes | + | serviceClient | Service Client | Secret1 | transactionProcessor,transactionProcessorACL | client_credentials | + | mobileAppClient | Mobile App Client | Secret1 | transactionProcessorACL,transactionProcessor | password | + + Given I have a token to access the estate management and transaction processor acl resources + | ClientId | + | serviceClient | + + Given I have created the following estates + | EstateName | + | Test Estate 1 | + + Given I have created the following operators + | EstateName | OperatorName | RequireCustomMerchantNumber | RequireCustomTerminalNumber | + | Test Estate 1 | Safaricom | True | True | + | Test Estate 1 | Voucher | True | True | + | Test Estate 1 | PataPawa PostPay | True | True | + | Test Estate 1 | PataPawa PrePay | True | True | + + And I have assigned the following operators to the estates + | EstateName | OperatorName | + | Test Estate 1 | Safaricom | + | Test Estate 1 | Voucher | + | Test Estate 1 | PataPawa PostPay | + | Test Estate 1 | PataPawa PrePay | + + Given I create a contract with the following values + | EstateName | OperatorName | ContractDescription | + | Test Estate 1 | Safaricom | Safaricom Contract | + | Test Estate 1 | Voucher | Hospital 1 Contract | + | Test Estate 1 | PataPawa PostPay | PataPawa PostPay Contract | + | Test Estate 1 | PataPawa PrePay | PataPawa PrePay Contract | + + When I create the following Products + | EstateName | OperatorName | ContractDescription | ProductName | DisplayText | Value | ProductType | + | Test Estate 1 | Safaricom | Safaricom Contract | Variable Topup | Custom | | MobileTopup | + | Test Estate 1 | Voucher | Hospital 1 Contract | 10 KES | 10 KES | 10.00 | Voucher | + | Test Estate 1 | PataPawa PostPay | PataPawa PostPay Contract | Post Pay Bill Pay | Bill Pay (Post) | | BillPayment | + | Test Estate 1 | PataPawa PrePay | PataPawa PrePay Contract | Pre Pay Bill Pay | Bill Pay (Pre) | | BillPayment | + + Given I create the following merchants + | MerchantName | AddressLine1 | AddressLine2 | AddressLine3 | AddressLine4 | Town | Region | PostalCode | Country | ContactName | EmailAddress | EstateName | + | Test Merchant 1 | test address line 1 | test address line 2 | test address line 3 | test address line 4 | TestTown | Test Region | TE57 1NG | United Kingdom | Test Contact 1 | testcontact1@merchant1.co.uk | Test Estate 1 | + | Test Merchant 2 | test address line 1 | test address line 2 | test address line 3 | test address line 4 | TestTown | Test Region | TE57 1NG | United Kingdom | Test Contact 2 | testcontact2@merchant2.co.uk | Test Estate 1 | + + Given I have assigned the following operator to the merchants + | OperatorName | MerchantName | MerchantNumber | TerminalNumber | EstateName | + | Safaricom | Test Merchant 1 | 00000001 | 10000001 | Test Estate 1 | + | Voucher | Test Merchant 1 | 00000001 | 10000001 | Test Estate 1 | + | PataPawa PostPay | Test Merchant 1 | 00000001 | 10000001 | Test Estate 1 | + | PataPawa PrePay | Test Merchant 1 | 00000001 | 10000001 | Test Estate 1 | + | Safaricom | Test Merchant 2 | 00000002 | 10000002 | Test Estate 1 | + | Voucher | Test Merchant 2 | 00000002 | 10000002 | Test Estate 1 | + | PataPawa PostPay | Test Merchant 2 | 00000002 | 10000002 | Test Estate 1 | + | PataPawa PrePay | Test Merchant 2 | 00000002 | 10000002 | Test Estate 1 | + + Given I have assigned the following devices to the merchants + | MerchantName | EstateName | + | Test Merchant 1 | Test Estate 1 | + | Test Merchant 2 | Test Estate 1 | + + When I add the following contracts to the following merchants + | EstateName | MerchantName | ContractDescription | + | Test Estate 1 | Test Merchant 1 | Safaricom Contract | + | Test Estate 1 | Test Merchant 1 | Hospital 1 Contract | + | Test Estate 1 | Test Merchant 1 | PataPawa PostPay Contract | + | Test Estate 1 | Test Merchant 1 | PataPawa PrePay Contract | + | Test Estate 1 | Test Merchant 2 | Safaricom Contract | + | Test Estate 1 | Test Merchant 2 | Hospital 1 Contract | + | Test Estate 1 | Test Merchant 2 | PataPawa PostPay Contract | + | Test Estate 1 | Test Merchant 2 | PataPawa PrePay Contract | + + Given I have created the following security users + | EmailAddress | Password | GivenName | FamilyName | EstateName | MerchantName | + | user1 | 123456 | TestMerchant | User1 | Test Estate 1 | Test Merchant 1 | + | user2 | 123456 | TestMerchant | User2 | Test Estate 1 | Test Merchant 2 | + + Given I have created a config for my device + +@PRTest +Scenario: Logout and relogin with a different merchant + Given I am on the Login Screen + And my device is registered + When I enter 'user1' as the Email Address + And I enter '123456' as the Password + And I tap on Login + Then the Merchant Home Page is displayed + When I tap on Profile + Then the My Profile Page is displayed + When I tap on the Account Info button + Then the Account Info Page is displayed + And the Account Info is displayed + | Name | Balance | AvailableBalance | + | Test Merchant 1 | 0 | 0 | + When I click on the back button + Then the My Profile Page is displayed + When I click on the back button + Then the Merchant Home Page is displayed + When I tap on Logout + Then A message is displayed confirming I want to log out + When I click yes + Then the Login Page is displayed + And I replace the merchants with the following merchants + | MerchantName | AddressLine1 | AddressLine2 | AddressLine3 | AddressLine4 | Town | Region | PostalCode | Country | ContactName | EmailAddress | EstateName | + | Test Merchant 2 | test address line 1 | test address line 2 | test address line 3 | test address line 4 | TestTown | Test Region | TE57 1NG | United Kingdom | Test Contact 2 | testcontact2@merchant2.co.uk | Test Estate 1 | + When I enter 'user2' as the Email Address + And I enter '123456' as the Password + And I tap on Login + Then the Merchant Home Page is displayed + When I tap on Profile + Then the My Profile Page is displayed + When I tap on the Account Info button + Then the Account Info Page is displayed + And the Account Info is displayed + | Name | Balance | AvailableBalance | + | Test Merchant 2 | 0 | 0 | diff --git a/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature.cs b/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature.cs new file mode 100644 index 00000000..2b2704a7 --- /dev/null +++ b/TransactionProcessor.Mobile.UITests/Features/LogoutLoginMerchantDetails.feature.cs @@ -0,0 +1,659 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by Reqnroll (https://reqnroll.net/). +// Reqnroll Version:3.0.0.0 +// Reqnroll Generator Version:3.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +#region Designer generated code +#pragma warning disable +using Reqnroll; +namespace TransactionProcessor.Mobile.UITests.Features +{ + + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Reqnroll", "3.0.0.0")] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::NUnit.Framework.TestFixtureAttribute()] + [global::NUnit.Framework.DescriptionAttribute("LogoutLoginMerchantDetails")] + [global::NUnit.Framework.FixtureLifeCycleAttribute(global::NUnit.Framework.LifeCycle.InstancePerTestCase)] + [global::NUnit.Framework.CategoryAttribute("background")] + [global::NUnit.Framework.CategoryAttribute("login")] + [global::NUnit.Framework.CategoryAttribute("toolbar")] + [global::NUnit.Framework.CategoryAttribute("profile")] + [global::NUnit.Framework.CategoryAttribute("base")] + [global::NUnit.Framework.CategoryAttribute("sharedapp")] + [global::NUnit.Framework.CategoryAttribute("shared")] + public partial class LogoutLoginMerchantDetailsFeature + { + + private global::Reqnroll.ITestRunner testRunner; + + private static string[] featureTags = new string[] { + "background", + "login", + "toolbar", + "profile", + "base", + "sharedapp", + "shared"}; + + private static global::Reqnroll.FeatureInfo featureInfo = new global::Reqnroll.FeatureInfo(new global::System.Globalization.CultureInfo("en-US"), "Features", "LogoutLoginMerchantDetails", null, global::Reqnroll.ProgrammingLanguage.CSharp, featureTags, InitializeCucumberMessages()); + +#line 1 "LogoutLoginMerchantDetails.feature" +#line hidden + + [global::NUnit.Framework.OneTimeSetUpAttribute()] + public static async global::System.Threading.Tasks.Task FeatureSetupAsync() + { + } + + [global::NUnit.Framework.OneTimeTearDownAttribute()] + public static async global::System.Threading.Tasks.Task FeatureTearDownAsync() + { + await global::Reqnroll.TestRunnerManager.ReleaseFeatureAsync(featureInfo); + } + + [global::NUnit.Framework.SetUpAttribute()] + public async global::System.Threading.Tasks.Task TestInitializeAsync() + { + testRunner = global::Reqnroll.TestRunnerManager.GetTestRunnerForAssembly(featureHint: featureInfo); + try + { + if (((testRunner.FeatureContext != null) + && (testRunner.FeatureContext.FeatureInfo.Equals(featureInfo) == false))) + { + await testRunner.OnFeatureEndAsync(); + } + } + finally + { + if (((testRunner.FeatureContext != null) + && testRunner.FeatureContext.BeforeFeatureHookFailed)) + { + throw new global::Reqnroll.ReqnrollException("Scenario skipped because of previous before feature hook error"); + } + if ((testRunner.FeatureContext == null)) + { + await testRunner.OnFeatureStartAsync(featureInfo); + } + } + } + + [global::NUnit.Framework.TearDownAttribute()] + public async global::System.Threading.Tasks.Task TestTearDownAsync() + { + if ((testRunner == null)) + { + return; + } + try + { + await testRunner.OnScenarioEndAsync(); + } + finally + { + global::Reqnroll.TestRunnerManager.ReleaseTestRunner(testRunner); + testRunner = null; + } + } + + public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, global::Reqnroll.RuleInfo ruleInfo) + { + testRunner.OnScenarioInitialize(scenarioInfo, ruleInfo); + testRunner.ScenarioContext.ScenarioContainer.RegisterInstanceAs(global::NUnit.Framework.TestContext.CurrentContext); + } + + public async global::System.Threading.Tasks.Task ScenarioStartAsync() + { + await testRunner.OnScenarioStartAsync(); + } + + public async global::System.Threading.Tasks.Task ScenarioCleanupAsync() + { + await testRunner.CollectScenarioErrorsAsync(); + } + + public virtual async global::System.Threading.Tasks.Task FeatureBackgroundAsync() + { +#line 4 +#line hidden + global::Reqnroll.Table table1 = new global::Reqnroll.Table(new string[] { + "Role Name"}); + table1.AddRow(new string[] { + "Merchant"}); +#line 6 + await testRunner.GivenAsync("the following security roles exist", ((string)(null)), table1, "Given "); +#line hidden + global::Reqnroll.Table table2 = new global::Reqnroll.Table(new string[] { + "Name", + "DisplayName", + "Description"}); + table2.AddRow(new string[] { + "transactionProcessor", + "Transaction Processor REST Scope", + "A scope for Transaction Processor REST"}); + table2.AddRow(new string[] { + "transactionProcessorACL", + "Transaction Processor ACL REST Scope", + "A scope for Transaction Processor ACL REST"}); +#line 10 + await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table2, "Given "); +#line hidden + global::Reqnroll.Table table3 = new global::Reqnroll.Table(new string[] { + "Name", + "DisplayName", + "Secret", + "Scopes", + "UserClaims"}); + table3.AddRow(new string[] { + "transactionProcessor", + "Transaction Processor REST", + "Secret1", + "transactionProcessor", + "merchantId, estateId, role"}); + table3.AddRow(new string[] { + "transactionProcessorACL", + "Transaction Processor ACL REST", + "Secret1", + "transactionProcessorACL", + "merchantId, estateId, role"}); +#line 15 + await testRunner.GivenAsync("the following api resources exist", ((string)(null)), table3, "Given "); +#line hidden + global::Reqnroll.Table table4 = new global::Reqnroll.Table(new string[] { + "ClientId", + "ClientName", + "Secret", + "Scopes", + "GrantTypes"}); + table4.AddRow(new string[] { + "serviceClient", + "Service Client", + "Secret1", + "transactionProcessor,transactionProcessorACL", + "client_credentials"}); + table4.AddRow(new string[] { + "mobileAppClient", + "Mobile App Client", + "Secret1", + "transactionProcessorACL,transactionProcessor", + "password"}); +#line 20 + await testRunner.GivenAsync("the following clients exist", ((string)(null)), table4, "Given "); +#line hidden + global::Reqnroll.Table table5 = new global::Reqnroll.Table(new string[] { + "ClientId"}); + table5.AddRow(new string[] { + "serviceClient"}); +#line 25 + await testRunner.GivenAsync("I have a token to access the estate management and transaction processor acl reso" + + "urces", ((string)(null)), table5, "Given "); +#line hidden + global::Reqnroll.Table table6 = new global::Reqnroll.Table(new string[] { + "EstateName"}); + table6.AddRow(new string[] { + "Test Estate 1"}); +#line 29 + await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table6, "Given "); +#line hidden + global::Reqnroll.Table table7 = new global::Reqnroll.Table(new string[] { + "EstateName", + "OperatorName", + "RequireCustomMerchantNumber", + "RequireCustomTerminalNumber"}); + table7.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "True", + "True"}); + table7.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "True", + "True"}); + table7.AddRow(new string[] { + "Test Estate 1", + "PataPawa PostPay", + "True", + "True"}); + table7.AddRow(new string[] { + "Test Estate 1", + "PataPawa PrePay", + "True", + "True"}); +#line 33 + await testRunner.GivenAsync("I have created the following operators", ((string)(null)), table7, "Given "); +#line hidden + global::Reqnroll.Table table8 = new global::Reqnroll.Table(new string[] { + "EstateName", + "OperatorName"}); + table8.AddRow(new string[] { + "Test Estate 1", + "Safaricom"}); + table8.AddRow(new string[] { + "Test Estate 1", + "Voucher"}); + table8.AddRow(new string[] { + "Test Estate 1", + "PataPawa PostPay"}); + table8.AddRow(new string[] { + "Test Estate 1", + "PataPawa PrePay"}); +#line 40 + await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table8, "And "); +#line hidden + global::Reqnroll.Table table9 = new global::Reqnroll.Table(new string[] { + "EstateName", + "OperatorName", + "ContractDescription"}); + table9.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "Safaricom Contract"}); + table9.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "Hospital 1 Contract"}); + table9.AddRow(new string[] { + "Test Estate 1", + "PataPawa PostPay", + "PataPawa PostPay Contract"}); + table9.AddRow(new string[] { + "Test Estate 1", + "PataPawa PrePay", + "PataPawa PrePay Contract"}); +#line 47 + await testRunner.GivenAsync("I create a contract with the following values", ((string)(null)), table9, "Given "); +#line hidden + global::Reqnroll.Table table10 = new global::Reqnroll.Table(new string[] { + "EstateName", + "OperatorName", + "ContractDescription", + "ProductName", + "DisplayText", + "Value", + "ProductType"}); + table10.AddRow(new string[] { + "Test Estate 1", + "Safaricom", + "Safaricom Contract", + "Variable Topup", + "Custom", + "", + "MobileTopup"}); + table10.AddRow(new string[] { + "Test Estate 1", + "Voucher", + "Hospital 1 Contract", + "10 KES", + "10 KES", + "10.00", + "Voucher"}); + table10.AddRow(new string[] { + "Test Estate 1", + "PataPawa PostPay", + "PataPawa PostPay Contract", + "Post Pay Bill Pay", + "Bill Pay (Post)", + "", + "BillPayment"}); + table10.AddRow(new string[] { + "Test Estate 1", + "PataPawa PrePay", + "PataPawa PrePay Contract", + "Pre Pay Bill Pay", + "Bill Pay (Pre)", + "", + "BillPayment"}); +#line 54 + await testRunner.WhenAsync("I create the following Products", ((string)(null)), table10, "When "); +#line hidden + global::Reqnroll.Table table11 = new global::Reqnroll.Table(new string[] { + "MerchantName", + "AddressLine1", + "AddressLine2", + "AddressLine3", + "AddressLine4", + "Town", + "Region", + "PostalCode", + "Country", + "ContactName", + "EmailAddress", + "EstateName"}); + table11.AddRow(new string[] { + "Test Merchant 1", + "test address line 1", + "test address line 2", + "test address line 3", + "test address line 4", + "TestTown", + "Test Region", + "TE57 1NG", + "United Kingdom", + "Test Contact 1", + "testcontact1@merchant1.co.uk", + "Test Estate 1"}); + table11.AddRow(new string[] { + "Test Merchant 2", + "test address line 1", + "test address line 2", + "test address line 3", + "test address line 4", + "TestTown", + "Test Region", + "TE57 1NG", + "United Kingdom", + "Test Contact 2", + "testcontact2@merchant2.co.uk", + "Test Estate 1"}); +#line 61 + await testRunner.GivenAsync("I create the following merchants", ((string)(null)), table11, "Given "); +#line hidden + global::Reqnroll.Table table12 = new global::Reqnroll.Table(new string[] { + "OperatorName", + "MerchantName", + "MerchantNumber", + "TerminalNumber", + "EstateName"}); + table12.AddRow(new string[] { + "Safaricom", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table12.AddRow(new string[] { + "Voucher", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table12.AddRow(new string[] { + "PataPawa PostPay", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table12.AddRow(new string[] { + "PataPawa PrePay", + "Test Merchant 1", + "00000001", + "10000001", + "Test Estate 1"}); + table12.AddRow(new string[] { + "Safaricom", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); + table12.AddRow(new string[] { + "Voucher", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); + table12.AddRow(new string[] { + "PataPawa PostPay", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); + table12.AddRow(new string[] { + "PataPawa PrePay", + "Test Merchant 2", + "00000002", + "10000002", + "Test Estate 1"}); +#line 66 + await testRunner.GivenAsync("I have assigned the following operator to the merchants", ((string)(null)), table12, "Given "); +#line hidden + global::Reqnroll.Table table13 = new global::Reqnroll.Table(new string[] { + "MerchantName", + "EstateName"}); + table13.AddRow(new string[] { + "Test Merchant 1", + "Test Estate 1"}); + table13.AddRow(new string[] { + "Test Merchant 2", + "Test Estate 1"}); +#line 77 + await testRunner.GivenAsync("I have assigned the following devices to the merchants", ((string)(null)), table13, "Given "); +#line hidden + global::Reqnroll.Table table14 = new global::Reqnroll.Table(new string[] { + "EstateName", + "MerchantName", + "ContractDescription"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "Safaricom Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "Hospital 1 Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "PataPawa PostPay Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 1", + "PataPawa PrePay Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "Safaricom Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "Hospital 1 Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "PataPawa PostPay Contract"}); + table14.AddRow(new string[] { + "Test Estate 1", + "Test Merchant 2", + "PataPawa PrePay Contract"}); +#line 82 + await testRunner.WhenAsync("I add the following contracts to the following merchants", ((string)(null)), table14, "When "); +#line hidden + global::Reqnroll.Table table15 = new global::Reqnroll.Table(new string[] { + "EmailAddress", + "Password", + "GivenName", + "FamilyName", + "EstateName", + "MerchantName"}); + table15.AddRow(new string[] { + "user1", + "123456", + "TestMerchant", + "User1", + "Test Estate 1", + "Test Merchant 1"}); + table15.AddRow(new string[] { + "user2", + "123456", + "TestMerchant", + "User2", + "Test Estate 1", + "Test Merchant 2"}); +#line 93 + await testRunner.GivenAsync("I have created the following security users", ((string)(null)), table15, "Given "); +#line hidden +#line 98 + await testRunner.GivenAsync("I have created a config for my device", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden + } + + private static global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages InitializeCucumberMessages() + { + return new global::Reqnroll.Formatters.RuntimeSupport.FeatureLevelCucumberMessages("Features/LogoutLoginMerchantDetails.feature.ndjson", 3); + } + + [global::NUnit.Framework.TestAttribute()] + [global::NUnit.Framework.DescriptionAttribute("Logout and relogin with a different merchant")] + [global::NUnit.Framework.CategoryAttribute("PRTest")] + public async global::System.Threading.Tasks.Task LogoutAndReloginWithADifferentMerchant() + { + string[] tagsOfScenario = new string[] { + "PRTest"}; + global::System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new global::System.Collections.Specialized.OrderedDictionary(); + string pickleIndex = "0"; + global::Reqnroll.ScenarioInfo scenarioInfo = new global::Reqnroll.ScenarioInfo("Logout and relogin with a different merchant", null, tagsOfScenario, argumentsOfScenario, featureTags, pickleIndex); + string[] tagsOfRule = ((string[])(null)); + global::Reqnroll.RuleInfo ruleInfo = null; +#line 101 +this.ScenarioInitialize(scenarioInfo, ruleInfo); +#line hidden + if ((global::Reqnroll.TagHelper.ContainsIgnoreTag(scenarioInfo.CombinedTags) || global::Reqnroll.TagHelper.ContainsIgnoreTag(featureTags))) + { + await testRunner.SkipScenarioAsync(); + } + else + { + await this.ScenarioStartAsync(); +#line 4 +await this.FeatureBackgroundAsync(); +#line hidden +#line 102 + await testRunner.GivenAsync("I am on the Login Screen", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); +#line hidden +#line 103 + await testRunner.AndAsync("my device is registered", ((string)(null)), ((global::Reqnroll.Table)(null)), "And "); +#line hidden +#line 104 + await testRunner.WhenAsync("I enter \'user1\' as the Email Address", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 105 + await testRunner.AndAsync("I enter \'123456\' as the Password", ((string)(null)), ((global::Reqnroll.Table)(null)), "And "); +#line hidden +#line 106 + await testRunner.AndAsync("I tap on Login", ((string)(null)), ((global::Reqnroll.Table)(null)), "And "); +#line hidden +#line 107 + await testRunner.ThenAsync("the Merchant Home Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 108 + await testRunner.WhenAsync("I tap on Profile", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 109 + await testRunner.ThenAsync("the My Profile Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 110 + await testRunner.WhenAsync("I tap on the Account Info button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 111 + await testRunner.ThenAsync("the Account Info Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + global::Reqnroll.Table table16 = new global::Reqnroll.Table(new string[] { + "Name", + "Balance", + "AvailableBalance"}); + table16.AddRow(new string[] { + "Test Merchant 1", + "0", + "0"}); +#line 112 + await testRunner.AndAsync("the Account Info is displayed", ((string)(null)), table16, "And "); +#line hidden +#line 115 + await testRunner.WhenAsync("I click on the back button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 116 + await testRunner.ThenAsync("the My Profile Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 117 + await testRunner.WhenAsync("I click on the back button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 118 + await testRunner.ThenAsync("the Merchant Home Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 119 + await testRunner.WhenAsync("I tap on Logout", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 120 + await testRunner.ThenAsync("A message is displayed confirming I want to log out", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 121 + await testRunner.WhenAsync("I click yes", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 122 + await testRunner.ThenAsync("the Login Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + global::Reqnroll.Table table17 = new global::Reqnroll.Table(new string[] { + "MerchantName", + "AddressLine1", + "AddressLine2", + "AddressLine3", + "AddressLine4", + "Town", + "Region", + "PostalCode", + "Country", + "ContactName", + "EmailAddress", + "EstateName"}); + table17.AddRow(new string[] { + "Test Merchant 2", + "test address line 1", + "test address line 2", + "test address line 3", + "test address line 4", + "TestTown", + "Test Region", + "TE57 1NG", + "United Kingdom", + "Test Contact 2", + "testcontact2@merchant2.co.uk", + "Test Estate 1"}); +#line 123 + await testRunner.AndAsync("I replace the merchants with the following merchants", ((string)(null)), table17, "And "); +#line hidden +#line 126 + await testRunner.WhenAsync("I enter \'user2\' as the Email Address", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 127 + await testRunner.AndAsync("I enter \'123456\' as the Password", ((string)(null)), ((global::Reqnroll.Table)(null)), "And "); +#line hidden +#line 128 + await testRunner.AndAsync("I tap on Login", ((string)(null)), ((global::Reqnroll.Table)(null)), "And "); +#line hidden +#line 129 + await testRunner.ThenAsync("the Merchant Home Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 130 + await testRunner.WhenAsync("I tap on Profile", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 131 + await testRunner.ThenAsync("the My Profile Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden +#line 132 + await testRunner.WhenAsync("I tap on the Account Info button", ((string)(null)), ((global::Reqnroll.Table)(null)), "When "); +#line hidden +#line 133 + await testRunner.ThenAsync("the Account Info Page is displayed", ((string)(null)), ((global::Reqnroll.Table)(null)), "Then "); +#line hidden + global::Reqnroll.Table table18 = new global::Reqnroll.Table(new string[] { + "Name", + "Balance", + "AvailableBalance"}); + table18.AddRow(new string[] { + "Test Merchant 2", + "0", + "0"}); +#line 134 + await testRunner.AndAsync("the Account Info is displayed", ((string)(null)), table18, "And "); +#line hidden + } + await this.ScenarioCleanupAsync(); + } + } +} +#pragma warning restore +#endregion diff --git a/TransactionProcessor.Mobile.UITests/Features/Reporting.feature.cs b/TransactionProcessor.Mobile.UITests/Features/Reporting.feature.cs index 1a541b3a..c32d1a5c 100644 --- a/TransactionProcessor.Mobile.UITests/Features/Reporting.feature.cs +++ b/TransactionProcessor.Mobile.UITests/Features/Reporting.feature.cs @@ -125,119 +125,119 @@ public void ScenarioInitialize(global::Reqnroll.ScenarioInfo scenarioInfo, globa { #line 4 #line hidden - global::Reqnroll.Table table25 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table43 = new global::Reqnroll.Table(new string[] { "Role Name"}); - table25.AddRow(new string[] { + table43.AddRow(new string[] { "Merchant"}); #line 6 - await testRunner.GivenAsync("the following security roles exist", ((string)(null)), table25, "Given "); + await testRunner.GivenAsync("the following security roles exist", ((string)(null)), table43, "Given "); #line hidden - global::Reqnroll.Table table26 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table44 = new global::Reqnroll.Table(new string[] { "Name", "DisplayName", "Description"}); - table26.AddRow(new string[] { + table44.AddRow(new string[] { "transactionProcessor", "Transaction Processor REST Scope", "A scope for Transaction Processor REST"}); - table26.AddRow(new string[] { + table44.AddRow(new string[] { "transactionProcessorACL", "Transaction Processor ACL REST Scope", "A scope for Transaction Processor ACL REST"}); #line 10 - await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table26, "Given "); + await testRunner.GivenAsync("I create the following api scopes", ((string)(null)), table44, "Given "); #line hidden - global::Reqnroll.Table table27 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table45 = new global::Reqnroll.Table(new string[] { "Name", "DisplayName", "Secret", "Scopes", "UserClaims"}); - table27.AddRow(new string[] { + table45.AddRow(new string[] { "transactionProcessor", "Transaction Processor REST", "Secret1", "transactionProcessor", "merchantId, estateId, role"}); - table27.AddRow(new string[] { + table45.AddRow(new string[] { "transactionProcessorACL", "Transaction Processor ACL REST", "Secret1", "transactionProcessorACL", "merchantId, estateId, role"}); #line 15 - await testRunner.GivenAsync("the following api resources exist", ((string)(null)), table27, "Given "); + await testRunner.GivenAsync("the following api resources exist", ((string)(null)), table45, "Given "); #line hidden - global::Reqnroll.Table table28 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table46 = new global::Reqnroll.Table(new string[] { "ClientId", "ClientName", "Secret", "Scopes", "GrantTypes"}); - table28.AddRow(new string[] { + table46.AddRow(new string[] { "serviceClient", "Service Client", "Secret1", "transactionProcessor,transactionProcessorACL", "client_credentials"}); - table28.AddRow(new string[] { + table46.AddRow(new string[] { "mobileAppClient", "Mobile App Client", "Secret1", "transactionProcessorACL,transactionProcessor", "password"}); #line 20 - await testRunner.GivenAsync("the following clients exist", ((string)(null)), table28, "Given "); + await testRunner.GivenAsync("the following clients exist", ((string)(null)), table46, "Given "); #line hidden - global::Reqnroll.Table table29 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table47 = new global::Reqnroll.Table(new string[] { "ClientId"}); - table29.AddRow(new string[] { + table47.AddRow(new string[] { "serviceClient"}); #line 25 await testRunner.GivenAsync("I have a token to access the estate management and transaction processor acl reso" + - "urces", ((string)(null)), table29, "Given "); + "urces", ((string)(null)), table47, "Given "); #line hidden - global::Reqnroll.Table table30 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table48 = new global::Reqnroll.Table(new string[] { "EstateName"}); - table30.AddRow(new string[] { + table48.AddRow(new string[] { "Test Estate 1"}); #line 29 - await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table30, "Given "); + await testRunner.GivenAsync("I have created the following estates", ((string)(null)), table48, "Given "); #line hidden - global::Reqnroll.Table table31 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table49 = new global::Reqnroll.Table(new string[] { "EstateName", "OperatorName", "RequireCustomMerchantNumber", "RequireCustomTerminalNumber"}); - table31.AddRow(new string[] { + table49.AddRow(new string[] { "Test Estate 1", "Safaricom", "True", "True"}); #line 33 - await testRunner.GivenAsync("I have created the following operators", ((string)(null)), table31, "Given "); + await testRunner.GivenAsync("I have created the following operators", ((string)(null)), table49, "Given "); #line hidden - global::Reqnroll.Table table32 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table50 = new global::Reqnroll.Table(new string[] { "EstateName", "OperatorName"}); - table32.AddRow(new string[] { + table50.AddRow(new string[] { "Test Estate 1", "Safaricom"}); #line 37 - await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table32, "And "); + await testRunner.AndAsync("I have assigned the following operators to the estates", ((string)(null)), table50, "And "); #line hidden - global::Reqnroll.Table table33 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table51 = new global::Reqnroll.Table(new string[] { "EstateName", "OperatorName", "ContractDescription"}); - table33.AddRow(new string[] { + table51.AddRow(new string[] { "Test Estate 1", "Safaricom", "Safaricom Contract"}); #line 41 - await testRunner.GivenAsync("I create a contract with the following values", ((string)(null)), table33, "Given "); + await testRunner.GivenAsync("I create a contract with the following values", ((string)(null)), table51, "Given "); #line hidden - global::Reqnroll.Table table34 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table52 = new global::Reqnroll.Table(new string[] { "EstateName", "OperatorName", "ContractDescription", @@ -245,7 +245,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "DisplayText", "Value", "ProductType"}); - table34.AddRow(new string[] { + table52.AddRow(new string[] { "Test Estate 1", "Safaricom", "Safaricom Contract", @@ -254,9 +254,9 @@ await testRunner.GivenAsync("I have a token to access the estate management and "", "MobileTopup"}); #line 45 - await testRunner.WhenAsync("I create the following Products", ((string)(null)), table34, "When "); + await testRunner.WhenAsync("I create the following Products", ((string)(null)), table52, "When "); #line hidden - global::Reqnroll.Table table35 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table53 = new global::Reqnroll.Table(new string[] { "EstateName", "OperatorName", "ContractDescription", @@ -264,7 +264,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "CalculationType", "FeeDescription", "Value"}); - table35.AddRow(new string[] { + table53.AddRow(new string[] { "Test Estate 1", "Safaricom", "Safaricom Contract", @@ -273,9 +273,9 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Merchant Commission", "2.50"}); #line 49 - await testRunner.WhenAsync("I add the following Transaction Fees", ((string)(null)), table35, "When "); + await testRunner.WhenAsync("I add the following Transaction Fees", ((string)(null)), table53, "When "); #line hidden - global::Reqnroll.Table table36 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table54 = new global::Reqnroll.Table(new string[] { "MerchantName", "AddressLine1", "AddressLine2", @@ -288,7 +288,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "ContactName", "EmailAddress", "EstateName"}); - table36.AddRow(new string[] { + table54.AddRow(new string[] { "Test Merchant 1", "test address line 1", "test address line 2", @@ -302,51 +302,51 @@ await testRunner.GivenAsync("I have a token to access the estate management and "testcontact1@merchant1.co.uk", "Test Estate 1"}); #line 53 - await testRunner.GivenAsync("I create the following merchants", ((string)(null)), table36, "Given "); + await testRunner.GivenAsync("I create the following merchants", ((string)(null)), table54, "Given "); #line hidden - global::Reqnroll.Table table37 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table55 = new global::Reqnroll.Table(new string[] { "OperatorName", "MerchantName", "MerchantNumber", "TerminalNumber", "EstateName"}); - table37.AddRow(new string[] { + table55.AddRow(new string[] { "Safaricom", "Test Merchant 1", "00000001", "10000001", "Test Estate 1"}); #line 57 - await testRunner.GivenAsync("I have assigned the following operator to the merchants", ((string)(null)), table37, "Given "); + await testRunner.GivenAsync("I have assigned the following operator to the merchants", ((string)(null)), table55, "Given "); #line hidden - global::Reqnroll.Table table38 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table56 = new global::Reqnroll.Table(new string[] { "MerchantName", "EstateName"}); - table38.AddRow(new string[] { + table56.AddRow(new string[] { "Test Merchant 1", "Test Estate 1"}); #line 61 - await testRunner.GivenAsync("I have assigned the following devices to the merchants", ((string)(null)), table38, "Given "); + await testRunner.GivenAsync("I have assigned the following devices to the merchants", ((string)(null)), table56, "Given "); #line hidden - global::Reqnroll.Table table39 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table57 = new global::Reqnroll.Table(new string[] { "EstateName", "MerchantName", "ContractDescription"}); - table39.AddRow(new string[] { + table57.AddRow(new string[] { "Test Estate 1", "Test Merchant 1", "Safaricom Contract"}); #line 65 - await testRunner.WhenAsync("I add the following contracts to the following merchants", ((string)(null)), table39, "When "); + await testRunner.WhenAsync("I add the following contracts to the following merchants", ((string)(null)), table57, "When "); #line hidden - global::Reqnroll.Table table40 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table58 = new global::Reqnroll.Table(new string[] { "EmailAddress", "Password", "GivenName", "FamilyName", "EstateName", "MerchantName"}); - table40.AddRow(new string[] { + table58.AddRow(new string[] { "user1", "123456", "TestMerchant", @@ -354,12 +354,12 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Test Estate 1", "Test Merchant 1"}); #line 69 - await testRunner.GivenAsync("I have created the following security users", ((string)(null)), table40, "Given "); + await testRunner.GivenAsync("I have created the following security users", ((string)(null)), table58, "Given "); #line hidden #line 73 await testRunner.GivenAsync("I have created a config for my device", ((string)(null)), ((global::Reqnroll.Table)(null)), "Given "); #line hidden - global::Reqnroll.Table table41 = new global::Reqnroll.Table(new string[] { + global::Reqnroll.Table table59 = new global::Reqnroll.Table(new string[] { "Reference", "TransactionType", "Product", @@ -367,7 +367,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Status", "Amount", "TransactionDateTime"}); - table41.AddRow(new string[] { + table59.AddRow(new string[] { "TXN-10001", "Mobile Topup", "Custom", @@ -375,7 +375,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Success", "100.00", "Today"}); - table41.AddRow(new string[] { + table59.AddRow(new string[] { "TXN-10002", "Bill Payment", "Bill Pay (Post)", @@ -383,7 +383,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "Success", "250.00", "Today"}); - table41.AddRow(new string[] { + table59.AddRow(new string[] { "TXN-10003", "Voucher Issue", "10 KES", @@ -392,7 +392,7 @@ await testRunner.GivenAsync("I have a token to access the estate management and "0.00", "Today"}); #line 75 - await testRunner.GivenAsync("the following transaction mix report transactions exist", ((string)(null)), table41, "Given "); + await testRunner.GivenAsync("the following transaction mix report transactions exist", ((string)(null)), table59, "Given "); #line hidden } diff --git a/TransactionProcessor.Mobile.UITests/Pages/MainPage.cs b/TransactionProcessor.Mobile.UITests/Pages/MainPage.cs index 9d390da8..0a677b89 100644 --- a/TransactionProcessor.Mobile.UITests/Pages/MainPage.cs +++ b/TransactionProcessor.Mobile.UITests/Pages/MainPage.cs @@ -83,6 +83,11 @@ public async Task ClickSupportButton() await this.ClickTopLevelButtonAsync(this.SupportButton, "Support").ConfigureAwait(false); } + public async Task ClickLogoutButton() + { + await this.ClickTopLevelButtonAsync("BackButton", "Log Out").ConfigureAwait(false); + } + private async Task ClickTopLevelButtonAsync(String automationId, String title) { await Retry.For(async () => diff --git a/TransactionProcessor.Mobile.UITests/SmokeTests/LogoutLoginMerchantDetailsSmokeTests.cs b/TransactionProcessor.Mobile.UITests/SmokeTests/LogoutLoginMerchantDetailsSmokeTests.cs new file mode 100644 index 00000000..9082c2e0 --- /dev/null +++ b/TransactionProcessor.Mobile.UITests/SmokeTests/LogoutLoginMerchantDetailsSmokeTests.cs @@ -0,0 +1,178 @@ +using NLog; +using NUnit.Framework; +using Shared.Logger; +using Shouldly; +using TransactionProcessor.Mobile.UiTestBackend; +using TransactionProcessor.Mobile.UITests.Common; +using TransactionProcessor.Mobile.UITests.Drivers; +using TransactionProcessor.Mobile.UITests.Pages; + +namespace TransactionProcessor.Mobile.UITests.SmokeTests; + +[TestFixture(MobileTestPlatform.Android, Category = "Android")] +[TestFixture(MobileTestPlatform.Windows, Category = "Windows")] +[NonParallelizable] +public class LogoutLoginMerchantDetailsSmokeTests : BaseTestFixture +{ + private TestingContext testingContext = null!; + private TestHostHelper testHostHelper = null!; + private AppiumDriverWrapper appiumDriver = null!; + private LoginPage loginPage = null!; + private MainPage mainPage = null!; + private ProfileAccountInfoPage profileAccountInfoPage = null!; + private SharedPage sharedPage = null!; + + public LogoutLoginMerchantDetailsSmokeTests(MobileTestPlatform mobileTestPlatform) : base(mobileTestPlatform) + { + } + + [Test] + public async Task LogoutThenRelogin_WithDifferentMerchant_ShowsFreshMerchantDetails() + { + await SetupHarnessAsync("LogoutThenReloginWithDifferentMerchant").ConfigureAwait(false); + + try + { + await this.loginPage.AssertOnPage().ConfigureAwait(false); + await this.loginPage.SetConfigHostUrl(this.testHostHelper.ConfigHostUrlForCurrentPlatform()).ConfigureAwait(false); + await this.loginPage.EnterEmailAddress("user1").ConfigureAwait(false); + await this.loginPage.EnterPassword("123456").ConfigureAwait(false); + await this.loginPage.ClickLoginButton().ConfigureAwait(false); + + await this.mainPage.AssertOnPage().ConfigureAwait(false); + await this.mainPage.ClickProfileButton().ConfigureAwait(false); + var profilePage = new ProfilePage(this.testingContext); + await profilePage.AssertOnPage().ConfigureAwait(false); + await profilePage.ClickAccountInfoButton().ConfigureAwait(false); + await this.profileAccountInfoPage.AssertOnPage().ConfigureAwait(false); + + string merchantName = await this.profileAccountInfoPage.GetMerchantNameValue().ConfigureAwait(false); + merchantName.ShouldBe("Test Merchant 1"); + + await this.sharedPage.ClickBackButton().ConfigureAwait(false); + await profilePage.AssertOnPage().ConfigureAwait(false); + await this.sharedPage.ClickBackButton().ConfigureAwait(false); + await this.mainPage.AssertOnPage().ConfigureAwait(false); + await this.mainPage.ClickLogoutButton().ConfigureAwait(false); + await this.sharedPage.LogoutMessageIsDisplayed("Title", "Logout Message").ConfigureAwait(false); + await this.sharedPage.AcceptAlert().ConfigureAwait(false); + await this.loginPage.AssertOnPage().ConfigureAwait(false); + + this.testHostHelper.ApplySeed(BuildMerchantSeed("Test Merchant 2", "user2")); + + await this.loginPage.EnterEmailAddress("user2").ConfigureAwait(false); + await this.loginPage.EnterPassword("123456").ConfigureAwait(false); + await this.loginPage.ClickLoginButton().ConfigureAwait(false); + + await this.mainPage.AssertOnPage().ConfigureAwait(false); + await this.mainPage.ClickProfileButton().ConfigureAwait(false); + var reloginProfilePage = new ProfilePage(this.testingContext); + await reloginProfilePage.AssertOnPage().ConfigureAwait(false); + await reloginProfilePage.ClickAccountInfoButton().ConfigureAwait(false); + await this.profileAccountInfoPage.AssertOnPage().ConfigureAwait(false); + + string reloginMerchantName = await this.profileAccountInfoPage.GetMerchantNameValue().ConfigureAwait(false); + reloginMerchantName.ShouldBe("Test Merchant 2"); + } + finally + { + await this.CleanupHarnessAsync().ConfigureAwait(false); + } + } + + private async Task SetupHarnessAsync(string scenarioName) + { + await Setup.GlobalSetup().ConfigureAwait(false); + + NlogLogger logger = new(); + logger.Initialise(LogManager.GetLogger(scenarioName), scenarioName); + LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly); + + this.testingContext = new TestingContext(); + this.testingContext.Logger = logger; + this.testHostHelper = new TestHostHelper(this.testingContext) + { + Logger = logger + }; + this.testingContext.TestHostHelper = this.testHostHelper; + + this.appiumDriver = new AppiumDriverWrapper(); + + await this.testHostHelper.StartTestHostForScenarioRun(scenarioName).ConfigureAwait(false); + this.testHostHelper.ApplySeed(BuildMerchantSeed("Test Merchant 1", "user1")); + await this.appiumDriver.StartAppAsync().ConfigureAwait(false); + + this.loginPage = new LoginPage(this.testingContext); + this.mainPage = new MainPage(this.testingContext); + this.profileAccountInfoPage = new ProfileAccountInfoPage(this.testingContext); + this.sharedPage = new SharedPage(this.testingContext); + } + + private async Task CleanupHarnessAsync() + { + if (this.appiumDriver != null) + { + await this.appiumDriver.StopAppAsync().ConfigureAwait(false); + } + + if (this.testHostHelper != null) + { + await this.testHostHelper.StopTestHostForScenarioRun().ConfigureAwait(false); + } + } + + private static BackendSeed BuildMerchantSeed(string merchantName, string userName) + { + return new BackendSeed + { + Clients = + [ + new ClientSeed + { + ClientId = "mobileAppClient", + ClientName = "Mobile App Client", + Secret = "Secret1", + GrantTypes = ["password", "client_credentials"], + IsAppClient = true + } + ], + Estates = + [ + new EstateSeed + { + EstateName = "Test Estate 1", + EstateReference = "Test Estate 1" + } + ], + Merchants = + [ + new MerchantSeed + { + EstateName = "Test Estate 1", + MerchantName = merchantName, + AddressLine1 = "test address line 1", + AddressLine2 = "test address line 2", + AddressLine3 = "test address line 3", + AddressLine4 = "test address line 4", + Town = "TestTown", + Region = "Test Region", + PostalCode = "TE57 1NG", + Country = "United Kingdom", + ContactName = merchantName, + ContactEmailAddress = $"{merchantName.Replace(" ", string.Empty).ToLowerInvariant()}@merchant.example.com", + ContactPhoneNumber = "123456789" + } + ], + Users = + [ + new UserSeed + { + UserName = userName, + Password = "123456", + GivenName = "TestMerchant", + FamilyName = userName + } + ] + }; + } +} diff --git a/TransactionProcessor.Mobile.UITests/Steps/ProfileSteps.cs b/TransactionProcessor.Mobile.UITests/Steps/ProfileSteps.cs index 58f19d32..61dcd41b 100644 --- a/TransactionProcessor.Mobile.UITests/Steps/ProfileSteps.cs +++ b/TransactionProcessor.Mobile.UITests/Steps/ProfileSteps.cs @@ -12,6 +12,7 @@ public class ProfileSteps{ private readonly TestingContext TestingContext; private ProfilePage profilePage; + private MainPage mainPage; private ProfileAddressesPage profileAddressesPage; @@ -21,6 +22,7 @@ public class ProfileSteps{ public ProfileSteps(TestingContext testingContext){ this.TestingContext = testingContext; this.profilePage = new ProfilePage(testingContext); + this.mainPage = new MainPage(testingContext); this.profileAccountInfoPage = new ProfileAccountInfoPage(testingContext); this.profileContactsPage = new ProfileContactsPage(testingContext); this.profileAddressesPage = new ProfileAddressesPage(testingContext); @@ -35,7 +37,7 @@ public async Task ThenTheMyProfilePageIsDisplayed() [When(@"I tap on Logout")] public async Task WhenITapOnLogout() { - await this.profilePage.ClickLogoutButton(); + await this.mainPage.ClickLogoutButton(); } [When(@"I tap on the Addresses button")] @@ -166,4 +168,4 @@ public async Task ThenTheAccountInfoIsDisplayed(DataTable table) //settlementSchedule.ShouldBe(expectedSettlementSchedule); } -} \ No newline at end of file +} diff --git a/TransactionProcessor.Mobile.UITests/Steps/SharedSteps.cs b/TransactionProcessor.Mobile.UITests/Steps/SharedSteps.cs index 500651b8..3b698d0b 100644 --- a/TransactionProcessor.Mobile.UITests/Steps/SharedSteps.cs +++ b/TransactionProcessor.Mobile.UITests/Steps/SharedSteps.cs @@ -269,6 +269,47 @@ public Task GivenICreateTheFollowingMerchants(DataTable table) return Task.CompletedTask; } + [Given(@"I replace the merchants with the following merchants")] + [Then(@"I replace the merchants with the following merchants")] + public Task GivenIReplaceTheMerchantsWithTheFollowingMerchants(DataTable table) + { + this.testingContext.ScenarioSeed.Merchants.Clear(); + + foreach (DataTableRow row in table.Rows) + { + string estateName = GetString(row, "EstateName"); + string estateReference = GetOptionalString(row, "EstateReference") ?? estateName; + string merchantName = GetString(row, "MerchantName"); + string emailAddress = GetOptionalString(row, "EmailAddress", "ContactEmailAddress") ?? $"{merchantName.Replace(" ", string.Empty).ToLowerInvariant()}@example.com"; + string contactName = GetOptionalString(row, "ContactName", "MerchantContactName") ?? merchantName; + + this.testingContext.ScenarioSeed.Merchants.Add(new MerchantSeed + { + EstateName = estateName, + MerchantName = merchantName, + AddressLine1 = GetString(row, "AddressLine1"), + AddressLine2 = GetString(row, "AddressLine2"), + AddressLine3 = GetString(row, "AddressLine3"), + AddressLine4 = GetString(row, "AddressLine4"), + Town = GetString(row, "Town"), + Region = GetString(row, "Region"), + PostalCode = GetString(row, "PostalCode"), + Country = GetString(row, "Country"), + ContactName = contactName, + ContactEmailAddress = emailAddress, + ContactPhoneNumber = GetOptionalString(row, "ContactPhoneNumber", "PhoneNumber") ?? "123456789", + SettlementSchedule = GetOptionalString(row, "SettlementSchedule") + }); + + EstateDetails estate = EnsureEstate(CreateGuid($"estate:{estateName}"), estateName, estateReference); + MerchantResponse merchantResponse = CreateMerchantResponse(estateName, merchantName, row); + estate.AddMerchant(merchantResponse); + } + + this.testingContext.TestHostHelper.ApplySeed(this.testingContext.ScenarioSeed); + return Task.CompletedTask; + } + [Given(@"I have assigned the following operator to the merchants")] public Task GivenIHaveAssignedTheFollowingOperatorToTheMerchants(DataTable table) { diff --git a/TransactionProcessor.Mobile/Pages/Common/NoBackWithoutLogoutPage.cs b/TransactionProcessor.Mobile/Pages/Common/NoBackWithoutLogoutPage.cs index 48eec44b..1ad5b97e 100644 --- a/TransactionProcessor.Mobile/Pages/Common/NoBackWithoutLogoutPage.cs +++ b/TransactionProcessor.Mobile/Pages/Common/NoBackWithoutLogoutPage.cs @@ -42,7 +42,8 @@ private async Task ShowLoginPage() if (leave) { applicationCache.SetIsLoggedIn(false); - applicationCache.SetAccessToken(null); + applicationCache.ClearAccessToken(); + applicationCache.ClearMerchantDetails(); await navigationService.GoToLoginPage(); }