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 @@ -5,6 +5,7 @@
using System.Threading;
using System.Threading.Tasks;
using Database;
using Microsoft.Data.Sqlite;
using Moq;
using RequestHandlers;
using Requests;
Expand All @@ -24,7 +25,7 @@ public async Task SupportRequestHandlerTests_UploadLogsRequest_NoLogs_Handle_IsH
});

Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
databaseContext.Setup(d => d.GetLogMessages(It.IsAny<Int32>())).ReturnsAsync(new List<Database.LogMessage>());
databaseContext.Setup(d => d.GetLogMessages(It.IsAny<Int32>(), It.IsAny<Boolean>())).ReturnsAsync(new List<Database.LogMessage>());
Mock<IApplicationCache> applicationCache = new Mock<IApplicationCache>();

SupportRequestHandler handler = new SupportRequestHandler(configurationServiceResolver, databaseContext.Object, applicationCache.Object);
Expand All @@ -45,7 +46,7 @@ public async Task SupportRequestHandlerTests_UploadLogsRequest_LogsToUpload_Only
return configurationService.Object;
});
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
databaseContext.SetupSequence(d => d.GetLogMessages(It.IsAny<Int32>())).ReturnsAsync(new List<Database.LogMessage>()
databaseContext.SetupSequence(d => d.GetLogMessages(It.IsAny<Int32>(), It.IsAny<Boolean>())).ReturnsAsync(new List<Database.LogMessage>()
{
new Database.LogMessage{LogLevel = LogLevel.Debug.ToString()},
new Database.LogMessage{LogLevel = LogLevel.Debug.ToString()},
Expand Down Expand Up @@ -80,7 +81,7 @@ public async Task SupportRequestHandlerTests_UploadLogsRequest_LogsToUpload_15Me
return configurationService.Object;
});
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
databaseContext.SetupSequence(d => d.GetLogMessages(It.IsAny<Int32>())).ReturnsAsync(new List<Database.LogMessage>()
databaseContext.SetupSequence(d => d.GetLogMessages(It.IsAny<Int32>(), It.IsAny<Boolean>())).ReturnsAsync(new List<Database.LogMessage>()
{
new Database.LogMessage{LogLevel = LogLevel.Debug.ToString()},
new Database.LogMessage{LogLevel = LogLevel.Debug.ToString()},
Expand Down Expand Up @@ -112,4 +113,40 @@ public async Task SupportRequestHandlerTests_UploadLogsRequest_LogsToUpload_15Me
response.ShouldBeTrue();
databaseContext.Verify(d => d.RemoveUploadedMessages(It.IsAny<List<Database.LogMessage>>()), Times.Exactly(2));
}

[Theory]
[InlineData(true, 4)]
[InlineData(false, 3)]
public async Task SupportRequestHandlerTests_ViewLogsRequest_Handle_IsHandled(Boolean isTrainingMode, Int32 expectedNumberMessages) {
Mock<IConfigurationService> configurationService = new Mock<IConfigurationService>();
Func<Boolean, IConfigurationService> configurationServiceResolver = new Func<bool, IConfigurationService>((param) =>
{
return configurationService.Object;
});
Func<Database.LogLevel> logLevelFunc = new Func<Database.LogLevel>(() =>
{
return Database.LogLevel.Debug;
});
IDatabaseContext databaseContext = new DatabaseContext(":memory:", logLevelFunc);
await databaseContext.InitialiseDatabase();

List<LogMessage> logMessages = new List<LogMessage>();
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString()});
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString() });
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString() });
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString(), IsTrainingMode = true});
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString(), IsTrainingMode = true });
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString(), IsTrainingMode = true });
logMessages.Add(new LogMessage { LogLevel = LogLevel.Debug.ToString(), IsTrainingMode = true });
await databaseContext.InsertLogMessages(logMessages);

Mock<IApplicationCache> applicationCache = new Mock<IApplicationCache>();
applicationCache.Setup(a => a.GetUseTrainingMode()).Returns(isTrainingMode);
SupportRequestHandler handler = new SupportRequestHandler(configurationServiceResolver, databaseContext, applicationCache.Object);

ViewLogsRequest request = ViewLogsRequest.Create();
List<Models.LogMessage>? result = await handler.Handle(request, CancellationToken.None);

result.Count.ShouldBe(expectedNumberMessages);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public async Task TransactionRequestHandler_PerformReconciliationRequest_NoTrans
Mock<IDatabaseContext> databaseContext = new Mock<IDatabaseContext>();
Mock<IApplicationCache> applicationCache = new Mock<IApplicationCache>();
transactionService.Setup(t => t.PerformReconciliation(It.IsAny<PerformReconciliationRequestModel>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);
databaseContext.Setup(d => d.GetTransactions()).ReturnsAsync(new List<TransactionRecord>());
databaseContext.Setup(d => d.GetTransactions(It.IsAny<Boolean>())).ReturnsAsync(new List<TransactionRecord>());
TransactionRequestHandler handler = new TransactionRequestHandler(transactionServiceResolver, databaseContext.Object, applicationCache.Object);

PerformReconciliationRequest request = PerformReconciliationRequest.Create(TestData.TransactionDateTime,
Expand All @@ -132,7 +132,7 @@ public async Task TransactionRequestHandler_PerformReconciliationRequest_Transac
Mock<IApplicationCache> applicationCache = new Mock<IApplicationCache>();
transactionService.Setup(t => t.PerformReconciliation(It.IsAny<PerformReconciliationRequestModel>(), It.IsAny<CancellationToken>())).ReturnsAsync(true);

databaseContext.Setup(d => d.GetTransactions()).ReturnsAsync(TestData.StoredTransactions);
databaseContext.Setup(d => d.GetTransactions(It.IsAny<Boolean>())).ReturnsAsync(TestData.StoredTransactions);
TransactionRequestHandler handler = new TransactionRequestHandler(transactionServiceResolver, databaseContext.Object, applicationCache.Object);

PerformReconciliationRequest request = PerformReconciliationRequest.Create(TestData.TransactionDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.2-mauipre.1.22102.15" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="Shouldly" Version="4.0.3" />
<PackageReference Include="SQLite" Version="3.13.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
89 changes: 45 additions & 44 deletions TransactionMobile.Maui.BusinessLogic/Database/DatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,86 @@

public class DatabaseContext : IDatabaseContext
{
#region Fields

private readonly SQLiteConnection Connection;

private readonly Func<LogLevel> LogLevelResolver;

public DatabaseContext(String connectionString, Func<LogLevel> logLevelResolver)
{
#endregion

#region Constructors

public DatabaseContext(String connectionString,
Func<LogLevel> logLevelResolver) {
this.Connection = new SQLiteConnection(connectionString);
this.LogLevelResolver = logLevelResolver;
}

public async Task InitialiseDatabase()
{
this.Connection.CreateTable<TransactionRecord>();
this.Connection.CreateTable<LogMessage>();
#endregion

#region Methods

public async Task ClearStoredTransactions(List<TransactionRecord> transactionRecords) {
foreach (var transactionRecord in transactionRecords) {
this.Connection.Delete<TransactionRecord>(transactionRecord.TransactionNumber);
}
}

public async Task<Int64> CreateTransaction(TransactionRecord transactionRecord)
{
public async Task<Int64> CreateTransaction(TransactionRecord transactionRecord) {
this.Connection.Insert(transactionRecord);

return SQLite3.LastInsertRowid(this.Connection.Handle);
}

public async Task UpdateTransaction(TransactionRecord transactionRecord)
{
this.Connection.Update(transactionRecord);
}
public async Task<List<LogMessage>> GetLogMessages(Int32 batchSize,
Boolean isTrainingMode) {
if (this.Connection == null)
return new List<LogMessage>();

public async Task<List<TransactionRecord>> GetTransactions()
{
return this.Connection.Table<TransactionRecord>().ToList();
}
List<LogMessage> messages = this.Connection.Table<LogMessage>().Where(l => l.IsTrainingMode == isTrainingMode).OrderByDescending(l => l.EntryDateTime)
.Take(batchSize).ToList();

public async Task ClearStoredTransactions(List<TransactionRecord> transactionRecords)
{
foreach (var transactionRecord in transactionRecords)
{
this.Connection.Delete<TransactionRecord>(transactionRecord.TransactionNumber);
}
return messages;
}

public async Task<List<LogMessage>> GetLogMessages(int batchSize)
{
if (this.Connection == null)
return new List<LogMessage>();

List<LogMessage> messages = this.Connection.Table<LogMessage>().OrderByDescending(l => l.EntryDateTime).Take(batchSize).ToList();

return messages;
public async Task<List<TransactionRecord>> GetTransactions(Boolean isTrainingMode) {
return this.Connection.Table<TransactionRecord>().Where(t => t.IsTrainingMode == isTrainingMode).ToList();
}

public async Task InitialiseDatabase() {
this.Connection.CreateTable<TransactionRecord>();
this.Connection.CreateTable<LogMessage>();
}

public async Task InsertLogMessage(LogMessage logMessage)
{
public async Task InsertLogMessage(LogMessage logMessage) {
if (this.Connection == null)
return;

LogLevel messageLevel = (LogLevel)Enum.Parse(typeof(LogLevel), logMessage.LogLevel, true);
if (messageLevel <= this.LogLevelResolver())
{
this.Connection.Insert(logMessage);
if (messageLevel <= this.LogLevelResolver()) {
this.Connection.Insert(logMessage);
}
}

public async Task InsertLogMessages(List<LogMessage> logMessages)
{
foreach (LogMessage logMessage in logMessages)
{
public async Task InsertLogMessages(List<LogMessage> logMessages) {
foreach (LogMessage logMessage in logMessages) {
await this.InsertLogMessage(logMessage);
}
}

public async Task RemoveUploadedMessages(List<LogMessage> logMessagesToRemove)
{
public async Task RemoveUploadedMessages(List<LogMessage> logMessagesToRemove) {
if (this.Connection == null)
return;
foreach (LogMessage logMessage in logMessagesToRemove)
{
foreach (LogMessage logMessage in logMessagesToRemove) {
this.Connection.Delete(logMessage);
}
}

public async Task UpdateTransaction(TransactionRecord transactionRecord) {
this.Connection.Update(transactionRecord);
}

#endregion
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ public interface IDatabaseContext

Task UpdateTransaction(TransactionRecord transactionRecord);

Task<List<TransactionRecord>> GetTransactions();
Task<List<TransactionRecord>> GetTransactions(Boolean isTrainingMode);
Task ClearStoredTransactions(List<TransactionRecord> transactionRecords);

Task<List<LogMessage>> GetLogMessages(Int32 batchSize);
Task<List<LogMessage>> GetLogMessages(Int32 batchSize, Boolean isTrainingMode);

Task InsertLogMessage(LogMessage logMessage);

Expand Down
34 changes: 6 additions & 28 deletions TransactionMobile.Maui.BusinessLogic/Database/LogMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,18 @@
public class LogMessage
{
#region Properties

/// <summary>
/// Gets or sets the entry date time.
/// </summary>
/// <value>
/// The entry date time.
/// </value>

public DateTime EntryDateTime { get; set; }

/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>
/// The identifier.
/// </value>

[PrimaryKey, AutoIncrement]
public Int32 Id { get; set; }

/// <summary>
/// Gets or sets the log level.
/// </summary>
/// <value>
/// The log level.
/// </value>

public String LogLevel { get; set; }

/// <summary>
/// Gets or sets the message.
/// </summary>
/// <value>
/// The message.
/// </value>

public String Message { get; set; }

public Boolean IsTrainingMode { get; set; }

#endregion
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ public SupportRequestHandler(Func<Boolean, IConfigurationService> configurationS

public async Task<Boolean> Handle(UploadLogsRequest request, CancellationToken cancellationToken)
{
Boolean useTrainingMode = this.ApplicationCache.GetUseTrainingMode();

while (true)
{
List<LogMessage> logEntries = await this.DatabaseContext.GetLogMessages(10); // TODO: Configurable batch size
List<LogMessage> logEntries = await this.DatabaseContext.GetLogMessages(10, useTrainingMode); // TODO: Configurable batch size

if (logEntries.Any() == false)
{
Expand All @@ -49,7 +51,6 @@ public async Task<Boolean> Handle(UploadLogsRequest request, CancellationToken c
EntryDateTime = l.EntryDateTime,
Id = l.Id
}));
Boolean useTrainingMode = this.ApplicationCache.GetUseTrainingMode();
IConfigurationService configurationService = this.ConfigurationServiceResolver(useTrainingMode);
await configurationService.PostDiagnosticLogs(request.DeviceIdentifier, logMessageModels, CancellationToken.None);

Expand All @@ -62,7 +63,9 @@ public async Task<Boolean> Handle(UploadLogsRequest request, CancellationToken c

public async Task<List<Models.LogMessage>> Handle(ViewLogsRequest request,
CancellationToken cancellationToken) {
List<LogMessage> logEntries = await this.DatabaseContext.GetLogMessages(50); // TODO: Configurable batch size
Boolean useTrainingMode = this.ApplicationCache.GetUseTrainingMode();

List<LogMessage> logEntries = await this.DatabaseContext.GetLogMessages(50, useTrainingMode); // TODO: Configurable batch size

List<Models.LogMessage> logMessageModels = new List<Models.LogMessage>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,17 @@ public async Task<Boolean> Handle(PerformReconciliationRequest request,
{
Boolean useTrainingMode = this.ApplicationCache.GetUseTrainingMode();

List<TransactionRecord> storedTransactions = await this.DatabaseContext.GetTransactions();
List<TransactionRecord> storedTransactions = await this.DatabaseContext.GetTransactions(useTrainingMode);

if (storedTransactions.Any() == false)
{
return true;
}

// Filter based on training mode
storedTransactions = storedTransactions.Where(t => t.IsTrainingMode == useTrainingMode).ToList();


// TODO: convert these to operator totals
List<OperatorTotalModel> operatorTotals = (from t in storedTransactions
where t.IsSuccessful = true &&
t.TransactionType != 1 // Filter out logons
&& t.IsTrainingMode == useTrainingMode
group t by new
{
t.ContractId,
Expand Down
Loading