Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public class LoginPageViewModelTests
private readonly Mock<IDialogService> DialogService;

private readonly Mock<IUpdateService> UpdateService;

private readonly Mock<IBalanceRefresher> BalanceRefresher;
public LoginPageViewModelTests() {
this.Mediator = new Mock<IMediator>();
this.NavigationService = new Mock<INavigationService>();
Expand All @@ -43,11 +45,14 @@ public LoginPageViewModelTests() {
this.ApplicationUpdateLauncherService = new Mock<IApplicationUpdateLauncherService>();
this.DialogService = new Mock<IDialogService>();
this.UpdateService = new Mock<IUpdateService>();
this.BalanceRefresher = new Mock<IBalanceRefresher>();


this.ViewModel = new LoginPageViewModel(this.Mediator.Object, this.NavigationService.Object, this.ApplicationCache.Object,
this.DeviceService.Object, this.ApplicationInfoService.Object,
this.DialogService.Object, this.NavigationParameterService.Object,
this.UpdateService.Object, this.ApplicationUpdateLauncherService.Object);
this.UpdateService.Object, this.ApplicationUpdateLauncherService.Object,
this.BalanceRefresher.Object);
Logger.Initialise(new Logging.NullLogger());
}

Expand All @@ -58,14 +63,12 @@ public void LoginPageViewModel_LoginCommand_Execute_IsExecuted()
this.Mediator.Setup(m => m.Send(It.IsAny<LoginRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.AccessToken));
this.Mediator.Setup(m => m.Send(It.IsAny<LogonTransactionRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.PerformLogonResponseModel));
this.Mediator.Setup(m => m.Send(It.IsAny<GetContractProductsRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.ContractProductList));
this.Mediator.Setup(m => m.Send(It.IsAny<GetMerchantBalanceRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.MerchantBalance));


this.ViewModel.LogonCommand.Execute(null);

this.Mediator.Verify(x => x.Send(It.IsAny<LoginRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<LogonTransactionRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<GetContractProductsRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<GetMerchantBalanceRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.NavigationService.Verify(n => n.GoToHome(), Times.Once);
}

Expand All @@ -79,15 +82,13 @@ public void LoginPageViewModel_LoginCommand_Execute_ConfigUrlSet_IsExecuted(Stri
this.Mediator.Setup(m => m.Send(It.IsAny<LoginRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.AccessToken));
this.Mediator.Setup(m => m.Send(It.IsAny<LogonTransactionRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.PerformLogonResponseModel));
this.Mediator.Setup(m => m.Send(It.IsAny<GetContractProductsRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.ContractProductList));
this.Mediator.Setup(m => m.Send(It.IsAny<GetMerchantBalanceRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(TestData.MerchantBalance));
this.ViewModel.ConfigHostUrl = configUrl;

this.ViewModel.LogonCommand.Execute(null);

this.Mediator.Verify(x => x.Send(It.IsAny<LoginRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<LogonTransactionRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<GetContractProductsRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.Mediator.Verify(x => x.Send(It.IsAny<GetMerchantBalanceRequest>(), It.IsAny<CancellationToken>()), Times.Once);
this.NavigationService.Verify(n => n.GoToHome(), Times.Once);
if (String.IsNullOrEmpty(configUrl) == false){
this.ApplicationCache.Verify(v => v.SetConfigHostUrl(It.IsAny<String>(), It.IsAny<MemoryCacheEntryOptions>()), Times.Once);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
MerchantDetailsModel GetMerchantDetails();

void SetMerchantDetails(MerchantDetailsModel value, MemoryCacheEntryOptions options = default);

Decimal GetMerchantBalance();

void SetMerchantBalance(Decimal value, MemoryCacheEntryOptions options = default);

Check warning on line 52 in TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.Mobile.BusinessLogic/Services/ApplicationCache.cs#L52

Use the overloading mechanism instead of the optional parameters.
}

[ExcludeFromCodeCoverage]
Expand Down Expand Up @@ -165,6 +169,15 @@
this.Set("MerchantDetails", value, options);
}

public Decimal GetMerchantBalance() {
return this.TryGetValue<Decimal>("MerchantBalance");
}

public void SetMerchantBalance(Decimal value,
MemoryCacheEntryOptions options = default) {
this.Set("MerchantBalance", value, options);
}

public void SetUseTrainingMode(Boolean value,
MemoryCacheEntryOptions options = default)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text;
using TransactionProcessor.Mobile.BusinessLogic.Logging;

namespace TransactionProcessor.Mobile.BusinessLogic.Services
{
public interface IBalanceRefresher
{
void StartRefreshing();
void StopRefreshing();
}

public class BalanceRefresher : IBalanceRefresher
{
private readonly IApplicationCache ApplicationCache;
private readonly IMerchantService MerchantService;
private CancellationTokenSource? _cts;

public BalanceRefresher(IApplicationCache applicationCache, IMerchantService merchantService) {
this.ApplicationCache = applicationCache;
this.MerchantService = merchantService;
}

public void StartRefreshing()
{
_cts = new CancellationTokenSource();
_ = RefreshLoopAsync(_cts.Token);
}

public void StopRefreshing()
{
_cts?.Cancel();
}

private async Task RefreshLoopAsync(CancellationToken token)
{
using PeriodicTimer timer = new PeriodicTimer(TimeSpan.FromSeconds(30));

try
{
// Do the first refresh
await RefreshBalanceAsync();

while (await timer.WaitForNextTickAsync(token))
{
await RefreshBalanceAsync();
}
}
catch (OperationCanceledException)
{

Check notice on line 51 in TransactionProcessor.Mobile.BusinessLogic/Services/BalanceRefresher.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.Mobile.BusinessLogic/Services/BalanceRefresher.cs#L51

Either remove or fill this block of code.
}
}

private async Task RefreshBalanceAsync()
{
decimal balance = await GetBalanceFromApi();

this.ApplicationCache.SetMerchantBalance(balance);
}

private async Task<decimal> GetBalanceFromApi()
{
var result = await this.MerchantService.GetMerchantBalance(CancellationToken.None);
if (result.IsSuccess)
{
return result.Data;
}

// Handle the failure case as needed, e.g., log the error or return a default value
Logger.LogWarning($"Failed to refresh merchant balance: {result.Message}");
return 0.0m;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ public async Task<Result<Decimal>> GetMerchantBalance(CancellationToken cancella
TokenResponseModel accessToken = this.ApplicationCache.GetAccessToken();
Guid estateId = this.ApplicationCache.GetEstateId();
Guid merchantId = this.ApplicationCache.GetMerchantId();



Logger.LogInformation("About to request merchant balance");
Logger.LogDebug($"Merchant Balance Request details: Estate Id {estateId} Merchant Id {merchantId} Access Token {accessToken.AccessToken}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
{
private readonly IApplicationInfoService ApplicationInfoService;
private readonly IApplicationUpdateLauncherService ApplicationUpdateLauncherService;
private readonly IBalanceRefresher BalanceRefresher;
private readonly IUpdateService UpdateService;

private String userName;
Expand All @@ -37,10 +38,12 @@
IDialogService dialogService,
INavigationParameterService navigationParameterService,
IUpdateService updateService,
IApplicationUpdateLauncherService applicationUpdateLauncherService) : base(applicationCache,dialogService,navigationService, deviceService, navigationParameterService)
IApplicationUpdateLauncherService applicationUpdateLauncherService,
IBalanceRefresher balanceRefresher) : base(applicationCache,dialogService,navigationService, deviceService, navigationParameterService)
{
this.ApplicationInfoService = applicationInfoService;
this.ApplicationUpdateLauncherService = applicationUpdateLauncherService;
this.BalanceRefresher = balanceRefresher;
this.Mediator = mediator;
this.UpdateService = updateService;
}
Expand Down Expand Up @@ -276,13 +279,15 @@
Result<List<ContractProductModel>> getMerchantContractProductsResult = await this.GetMerchantContractProducts();
this.HandleResult(getMerchantContractProductsResult);

await this.WriteTimingTrace(sw, "After GetMerchantContractProducts");
Result<Decimal> getMerchantBalanceResult = await this.GetMerchantBalance();
this.HandleResult(getMerchantBalanceResult);
//await this.WriteTimingTrace(sw, "After GetMerchantContractProducts");

Check notice on line 282 in TransactionProcessor.Mobile.BusinessLogic/ViewModels/LoginPageViewModel.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

TransactionProcessor.Mobile.BusinessLogic/ViewModels/LoginPageViewModel.cs#L282

Remove this commented out code.
//Result<Decimal> getMerchantBalanceResult = await this.GetMerchantBalance();
//this.HandleResult(getMerchantBalanceResult);

await this.WriteTimingTrace(sw, "After GetMerchantBalance");
//await this.WriteTimingTrace(sw, "After GetMerchantBalance");
this.ApplicationCache.SetIsLoggedIn(true);


this.BalanceRefresher.StartRefreshing();

await this.WriteTimingTrace(sw, "After SetIsLoggedIn");
await this.NavigationService.GoToHome();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static MauiAppBuilder ConfigureAppServices(this MauiAppBuilder builder) {
builder.Services.AddSingleton<ITransactionService, TransactionService>();
builder.Services.AddSingleton<IMerchantService, MerchantService>();
builder.Services.AddSingleton<IUpdateService, UpdateService>();

builder.Services.AddSingleton<IBalanceRefresher,BalanceRefresher>();
builder.RegisterConfigurationService().RegisterAuthenticationService().RegisterTransactionService().RegisterMerchantService();

builder.Services.RegisterHttpClientX<ISecurityServiceClient, SecurityServiceClient>();
Expand Down
Loading