Skip to content

Commit 4d8a960

Browse files
Merge pull request #898 from TransactionProcessing/bug/#887_file_import_log_duplicate_handling
handle import log created duplicates
2 parents 4294cd4 + 50e6c27 commit 4d8a960

5 files changed

Lines changed: 49 additions & 20 deletions

File tree

TransactionProcessor.DatabaseTests/ContractEventTests.cs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,47 +55,41 @@ public async Task AddContract_ContractIsAdded_EventReplayHandled() {
5555
}
5656

5757
[Fact]
58-
public async Task AddContractProduct_ContractProductIsAdded()
59-
{
58+
public async Task AddContractProduct_ContractProductIsAdded() {
6059
Result result = await this.Repository.AddContractProduct(TestData.DomainEvents.FixedValueProductAddedToContractEvent, CancellationToken.None);
6160
result.IsSuccess.ShouldBeTrue();
6261
EstateManagementContext context = this.GetContext();
63-
ContractProduct? fixedContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ContractId &&
64-
c.ContractProductId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ProductId);
62+
ContractProduct? fixedContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ContractId && c.ContractProductId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ProductId);
6563
fixedContractProduct.ShouldNotBeNull();
6664

6765
result = await this.Repository.AddContractProduct(TestData.DomainEvents.VariableValueProductAddedToContractEvent, CancellationToken.None);
6866
result.IsSuccess.ShouldBeTrue();
6967
context = this.GetContext();
70-
ContractProduct? variableContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ContractId &&
71-
c.ContractProductId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ProductId);
68+
ContractProduct? variableContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ContractId && c.ContractProductId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ProductId);
7269
variableContractProduct.ShouldNotBeNull();
7370
}
7471

7572
[Fact]
76-
public async Task AddContractProduct_ContractProductIsAdded_EventReplayHandled()
77-
{
73+
public async Task AddContractProduct_ContractProductIsAdded_EventReplayHandled() {
7874
Result result = await this.Repository.AddContractProduct(TestData.DomainEvents.FixedValueProductAddedToContractEvent, CancellationToken.None);
7975
result.IsSuccess.ShouldBeTrue();
8076
EstateManagementContext context = this.GetContext();
81-
ContractProduct? fixedContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ContractId &&
82-
c.ContractProductId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ProductId);
77+
ContractProduct? fixedContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ContractId && c.ContractProductId == TestData.DomainEvents.FixedValueProductAddedToContractEvent.ProductId);
8378
fixedContractProduct.ShouldNotBeNull();
8479

8580
result = await this.Repository.AddContractProduct(TestData.DomainEvents.VariableValueProductAddedToContractEvent, CancellationToken.None);
8681
result.IsSuccess.ShouldBeTrue();
8782
context = this.GetContext();
88-
ContractProduct? variableContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ContractId &&
89-
c.ContractProductId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ProductId);
83+
ContractProduct? variableContractProduct = await context.ContractProducts.SingleOrDefaultAsync(c => c.ContractId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ContractId && c.ContractProductId == TestData.DomainEvents.VariableValueProductAddedToContractEvent.ProductId);
9084
variableContractProduct.ShouldNotBeNull();
9185

9286
result = await this.Repository.AddContractProduct(TestData.DomainEvents.FixedValueProductAddedToContractEvent, CancellationToken.None);
9387
result.IsSuccess.ShouldBeTrue();
94-
88+
9589
result = await this.Repository.AddContractProduct(TestData.DomainEvents.VariableValueProductAddedToContractEvent, CancellationToken.None);
9690
result.IsSuccess.ShouldBeTrue();
9791
}
98-
92+
9993
[Fact]
10094
public async Task AddContractProductTransactionFee_ContractIsAdded()
10195
{
@@ -116,5 +110,25 @@ public async Task AddContractProductTransactionFee_ContractIsAdded_EventReplayHa
116110
result = await this.Repository.AddContractProductTransactionFee(TestData.DomainEvents.TransactionFeeForProductAddedToContractEvent, CancellationToken.None);
117111
result.IsSuccess.ShouldBeTrue();
118112
}
119-
}
113+
114+
[Fact]
115+
public async Task AddFileImportLog_FileImportLogIsAdded()
116+
{
117+
Result result = await this.Repository.AddFileImportLog(TestData.DomainEvents.ImportLogCreatedEvent, CancellationToken.None);
118+
result.IsSuccess.ShouldBeTrue();
119+
EstateManagementContext context = this.GetContext();
120+
var fileImportLog = await context.FileImportLogs.SingleOrDefaultAsync(f => f.FileImportLogId == TestData.DomainEvents.ImportLogCreatedEvent.FileImportLogId);
121+
fileImportLog.ShouldNotBeNull();
122+
}
123+
124+
[Fact]
125+
public async Task AddFileImportLog_FileImportLogIsAdded_EventReplayHandled()
126+
{
127+
Result result = await this.Repository.AddFileImportLog(TestData.DomainEvents.ImportLogCreatedEvent, CancellationToken.None);
128+
result.IsSuccess.ShouldBeTrue();
129+
130+
result = await this.Repository.AddFileImportLog(TestData.DomainEvents.ImportLogCreatedEvent, CancellationToken.None);
131+
result.IsSuccess.ShouldBeTrue();
132+
}
133+
}
120134
}

TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ public async Task<Result> AddFileImportLog(ImportLogCreatedEvent domainEvent,
18371837

18381838
await context.FileImportLogs.AddAsync(fileImportLog, cancellationToken);
18391839

1840-
return await context.SaveChangesAsync(cancellationToken);
1840+
return await context.SaveChangesWithDuplicateHandling(cancellationToken);
18411841
}
18421842

18431843
public async Task<Result> AddFileLineToFile(FileLineAddedEvent domainEvent,

TransactionProcessor.Testing/TestData.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Text;
2+
using FileProcessor.FileImportLog.DomainEvents;
23
using Microsoft.IdentityModel.Tokens;
34
using Newtonsoft.Json;
45
using Shared.EventStore.ProjectionEngine;
@@ -451,6 +452,14 @@ public class TestData
451452

452453
public static Decimal TransactionAmount = 1000.00m;
453454

455+
public static Guid FileImportLogId = Guid.Parse("2250C12E-B617-4012-8145-33ADD6E8E848");
456+
public static Guid FileId = Guid.Parse("3F2A50DE-FD72-4D50-87B0-8F97D1688EFD");
457+
public static Guid FileProfileId = Guid.Parse("E1FF239B-908B-497D-AB5B-6BA3148CE80D");
458+
public static String FileName = "TestFile1.csv";
459+
public static String FilePath = "/uploads/TestFile1.csv";
460+
public static DateTime FileUploadedDateTime = new DateTime(2023, 1, 1, 10, 0, 0);
461+
public static DateTime ImportLogDateTime = new DateTime(2023, 1, 1, 10, 5, 0);
462+
454463
public static OperatorResponse OperatorResponse =>
455464
new OperatorResponse
456465
{
@@ -2764,6 +2773,11 @@ public static class DomainEvents {
27642773
public static OperatorDomainEvents.OperatorNameUpdatedEvent OperatorNameUpdatedEvent => new(TestData.OperatorId, TestData.EstateId, TestData.OperatorName2);
27652774
public static OperatorDomainEvents.OperatorRequireCustomMerchantNumberChangedEvent OperatorRequireCustomMerchantNumberChangedEvent => new(TestData.OperatorId, TestData.EstateId, TestData.RequireCustomMerchantNumberFalse);
27662775
public static OperatorDomainEvents.OperatorRequireCustomTerminalNumberChangedEvent OperatorRequireCustomTerminalNumberChangedEvent => new(TestData.OperatorId, TestData.EstateId, TestData.RequireCustomTerminalNumberFalse);
2776+
2777+
public static ImportLogCreatedEvent ImportLogCreatedEvent => new ImportLogCreatedEvent(FileImportLogId, EstateId, ImportLogDateTime);
2778+
public static FileAddedToImportLogEvent FileAddedToImportLogEvent => new FileAddedToImportLogEvent(FileImportLogId, FileId, EstateId, MerchantId, EstateSecurityUserId,
2779+
FileProfileId, FileName, FilePath, FileUploadedDateTime );
2780+
27672781
}
27682782
}
27692783

TransactionProcessor.Testing/TransactionProcessor.Testing.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
<ItemGroup>
99
<PackageReference Include="ClientProxyBase" Version="2025.7.13" />
10+
<PackageReference Include="FileProcessor.FileImportLog.DomainEvents" Version="2025.8.1" />
1011
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.7" />
1112
<PackageReference Include="SecurityService.Client" Version="2025.7.2" />
1213
<PackageReference Include="System.ServiceModel.Federation" Version="8.1.2" />

TransactionProcessor/appsettings.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,29 +186,29 @@
186186
}
187187
},
188188
"ConnectionStrings": {
189-
"TransactionProcessorReadModel": "server=192.168.1.167;user id=sa;password=Sc0tland;database=TransactionProcessorReadModel;Encrypt=false"
189+
"TransactionProcessorReadModel": "server=192.168.1.163;user id=sa;password=Sc0tland;database=TransactionProcessorReadModel;Encrypt=false"
190190
},
191191
"SecurityConfiguration": {
192192
"ApiName": "transactionProcessor"
193193
//"Authority": "https://127.0.0.1:5001"
194194
},
195195
"OperatorConfiguration": {
196196
"Safaricom": {
197-
"Url": "http://192.168.1.167:9000/api/safaricom",
197+
"Url": "http://192.168.1.163:9000/api/safaricom",
198198
"LoginId": "D-S136",
199199
"MSISDN": "700945625",
200200
"Pin": "0322",
201201
"Password": "@SafePay33",
202202
"ExtCode": "SA"
203203
},
204204
"PataPawaPostPay": {
205-
"Url": "http://192.168.1.167:9000/PataPawaPostPayService/basichttp",
205+
"Url": "http://192.168.1.163:9000/PataPawaPostPayService/basichttp",
206206
"Username": "testuser1",
207207
"Password": "password1",
208208
"ApiLogonRequired": true
209209
},
210210
"PataPawaPrePay": {
211-
"Url": "http://192.168.1.167:9000/api/patapawaprepay",
211+
"Url": "http://192.168.1.163:9000/api/patapawaprepay",
212212
"Username": "operatora",
213213
"Password": "1234567898",
214214
"ApiLogonRequired": true

0 commit comments

Comments
 (0)