77using ECommerce . Contracts . DTOs ;
88using ECommerce . Contracts . Interfaces ;
99using ECommerce . BusinessEvents . Infrastructure ;
10+ using ECommerce . Common ;
11+ using Newtonsoft . Json . Linq ;
12+ using JsonFlatten ;
1013
1114namespace ECommerce . BusinessEvents . Tests . Services
1215{
@@ -16,7 +19,6 @@ public class EventTrackingServiceTests : IDisposable
1619 private readonly SchemaRegistryService _schemaRegistry ;
1720 private readonly Mock < IJsonSchemaValidator > _schemaValidatorMock ;
1821 private readonly EventTrackingService _eventTracker ;
19- private readonly ITransactionManager _transactionManager ;
2022
2123 public EventTrackingServiceTests ( )
2224 {
@@ -28,8 +30,8 @@ public EventTrackingServiceTests()
2830 _schemaRegistry = new SchemaRegistryService ( _context ) ;
2931 _schemaValidatorMock = new Mock < IJsonSchemaValidator > ( ) ;
3032 var loggerMock = new Mock < Microsoft . Extensions . Logging . ILogger < EventTrackingService > > ( ) ;
31- _transactionManager = new NoOpTransactionManager ( ) ;
32- _eventTracker = new EventTrackingService ( _context , _schemaRegistry , _schemaValidatorMock . Object , loggerMock . Object , _transactionManager ) ;
33+ ITransactionManager transactionManager = new NoOpTransactionManager ( ) ;
34+ _eventTracker = new EventTrackingService ( _context , _schemaRegistry , _schemaValidatorMock . Object , loggerMock . Object , transactionManager ) ;
3335
3436 InitializeTestSchema ( ) . Wait ( ) ;
3537 }
@@ -59,7 +61,7 @@ public async Task TrackEventAsync_ValidData_SavesEventToDatabase()
5961 Customer customer = new Customer ( "John Doe" , "john.doe@example.com" ) ;
6062 _schemaValidatorMock
6163 . Setup ( v => v . Validate ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
62- . Returns ( ECommerce . Common . Result < ECommerce . Common . Unit , string > . Success ( new ECommerce . Common . Unit ( ) ) ) ;
64+ . Returns ( Result < Unit , string > . Success ( new Unit ( ) ) ) ;
6365
6466 var dto = new BusinessEventDto
6567 {
@@ -98,7 +100,7 @@ public async Task TrackEventAsync_InvalidData_ReturnsFailure()
98100 var invalidCustomer = new Customer ( "john doe" , "wrong-email-format" ) ;
99101 _schemaValidatorMock
100102 . Setup ( v => v . Validate ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
101- . Returns ( ECommerce . Common . Result < ECommerce . Common . Unit , string > . Failure ( "Entity data does not match schema" ) ) ;
103+ . Returns ( Result < Unit , string > . Failure ( "Entity data does not match schema" ) ) ;
102104
103105 var dto = new BusinessEventDto
104106 {
@@ -158,7 +160,7 @@ public async Task GetAllEventsAsync_ReturnsAllEvents()
158160 Customer customer1 = new Customer ( "Alice" , "alice@example.com" ) ;
159161 Customer customer2 = new Customer ( "Bob" , "bob@example.com" ) ;
160162 _schemaValidatorMock . Setup ( v => v . Validate ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
161- . Returns ( ECommerce . Common . Result < ECommerce . Common . Unit , string > . Success ( new ECommerce . Common . Unit ( ) ) ) ;
163+ . Returns ( Result < Unit , string > . Success ( new Unit ( ) ) ) ;
162164
163165 var dto1 = new BusinessEventDto
164166 {
@@ -267,7 +269,7 @@ public async Task TrackEventAsync_WithNullAndEmptyFields_OnlySavesMetadataForFie
267269
268270 _schemaValidatorMock
269271 . Setup ( v => v . Validate ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
270- . Returns ( ECommerce . Common . Result < ECommerce . Common . Unit , string > . Success ( new ECommerce . Common . Unit ( ) ) ) ;
272+ . Returns ( Result < Unit , string > . Success ( new Unit ( ) ) ) ;
271273
272274 var dto = new BusinessEventDto
273275 {
@@ -354,6 +356,14 @@ public async Task TrackEventAsync_WithEmbeddedPhoneNumbers_ExtractsMetadataCorre
354356
355357 await _schemaRegistry . AddSchemaAsync ( "CustomerWithPhones" , 1 , customerSchemaWithPhones ) ;
356358
359+ // Debug: Test metadata config parsing directly
360+ var metadataConfig = _schemaRegistry . ParseMetadataConfig ( customerSchemaWithPhones ) ;
361+ Assert . Equal ( 2 , metadataConfig . FieldsToExtract . Count ) ; // Should have Id and Name
362+ Assert . Single ( metadataConfig . ArrayPathsToExtract ) ; // Should have PhoneNumbers array
363+ Assert . Contains ( "Id" , metadataConfig . FieldsToExtract ) ;
364+ Assert . Contains ( "Name" , metadataConfig . FieldsToExtract ) ;
365+ Assert . Contains ( "PhoneNumbers" , metadataConfig . ArrayPathsToExtract . Keys ) ;
366+
357367 var customerData = new {
358368 Id = "cust-001" ,
359369 Name = "Ent" ,
@@ -365,7 +375,7 @@ public async Task TrackEventAsync_WithEmbeddedPhoneNumbers_ExtractsMetadataCorre
365375
366376 _schemaValidatorMock
367377 . Setup ( v => v . Validate ( It . IsAny < string > ( ) , It . IsAny < string > ( ) ) )
368- . Returns ( ECommerce . Common . Result < ECommerce . Common . Unit , string > . Success ( new ECommerce . Common . Unit ( ) ) ) ;
378+ . Returns ( Result < Unit , string > . Success ( new Unit ( ) ) ) ;
369379
370380 var dto = new BusinessEventDto
371381 {
@@ -392,6 +402,12 @@ public async Task TrackEventAsync_WithEmbeddedPhoneNumbers_ExtractsMetadataCorre
392402 . Where ( m => m . EventId == savedEvent . EventId )
393403 . ToListAsync ( ) ;
394404
405+ // Debug: Check what we actually got vs what we expected
406+ Assert . True ( metadataRecords . Count > 0 , "No metadata records were extracted at all!" ) ;
407+
408+ // Should have 6 total: Id, Name, PhoneNumbers[0].Number, PhoneNumbers[0].Prefix, PhoneNumbers[1].Number, PhoneNumbers[1].Prefix
409+ Assert . Equal ( 6 , metadataRecords . Count ) ;
410+
395411 // Should have Id and Name
396412 Assert . Contains ( metadataRecords , m => m . MetadataKey == "Id" && m . MetadataValue == "cust-001" ) ;
397413 Assert . Contains ( metadataRecords , m => m . MetadataKey == "Name" && m . MetadataValue == "Ent" ) ;
@@ -405,6 +421,35 @@ public async Task TrackEventAsync_WithEmbeddedPhoneNumbers_ExtractsMetadataCorre
405421 Assert . Contains ( metadataRecords , m => m . MetadataKey == "PhoneNumbers[1].Prefix" && m . MetadataValue == "+1" ) ;
406422 }
407423
424+ [ Fact ]
425+ public void JsonFlatten_BasicTest_ShouldFlattenCorrectly ( )
426+ {
427+ // Arrange
428+ var testJson = @"{
429+ ""Id"": ""cust-001"",
430+ ""Name"": ""Ent"",
431+ ""PhoneNumbers"": [
432+ {""Number"": ""123456789"", ""Prefix"": ""+44""},
433+ {""Number"": ""987654321"", ""Prefix"": ""+1""}
434+ ]
435+ }" ;
436+
437+ // Act
438+ var jObject = JObject . Parse ( testJson ) ;
439+ var flattened = jObject . Flatten ( ) ;
440+
441+ // Assert - Let's see what keys JsonFlatten actually produces
442+ var keys = flattened . Keys . ToList ( ) ;
443+ Assert . Contains ( "Id" , keys ) ;
444+ Assert . Contains ( "Name" , keys ) ;
445+
446+ // Check if JsonFlatten produces the expected array keys
447+ Assert . Contains ( "PhoneNumbers[0].Number" , keys ) ;
448+ Assert . Contains ( "PhoneNumbers[0].Prefix" , keys ) ;
449+ Assert . Contains ( "PhoneNumbers[1].Number" , keys ) ;
450+ Assert . Contains ( "PhoneNumbers[1].Prefix" , keys ) ;
451+ }
452+
408453 public void Dispose ( )
409454 {
410455 _context . Dispose ( ) ;
0 commit comments