@@ -342,9 +342,12 @@ func TestSyncBalancesBatch_ScheduleCleanupFailure(t *testing.T) {
342342 assert .Equal (t , int64 (0 ), result .KeysRemoved ) // cleanup failed
343343}
344344
345- // TestSyncBalancesBatch_AggregationKeepsHighestVersion verifies that when multiple
346- // updates for the same balance exist (same composite key), only the highest version
347- // is synced to the database. This tests US-02 requirement for version-based deduplication.
345+ // TestSyncBalancesBatch_AggregationKeepsHighestVersion verifies idempotent handling
346+ // when the same Redis key appears multiple times in a batch. With the Sorted Set
347+ // scheduling mechanism, duplicate keys map to the same balance data, and the
348+ // aggregator deduplicates them to a single entry. Version-based deduplication
349+ // is thoroughly tested in aggregation_test.go where inputs are constructed
350+ // directly without Redis layer constraints.
348351func TestSyncBalancesBatch_AggregationKeepsHighestVersion (t * testing.T ) {
349352 ctrl := gomock .NewController (t )
350353 defer ctrl .Finish ()
@@ -353,28 +356,28 @@ func TestSyncBalancesBatch_AggregationKeepsHighestVersion(t *testing.T) {
353356 ledgerID := libCommons .GenerateUUIDv7 ()
354357 balanceID := libCommons .GenerateUUIDv7 ()
355358
356- // Two keys for the SAME account but different partition timestamps
357- // (simulating multiple updates within the batch window)
359+ // Same Redis key appearing twice in the batch (simulates duplicate scheduling).
360+ // With Sorted Set architecture, identical keys return the same balance from Redis.
358361 key1 := "balance:{transactions}:" + organizationID .String () + ":" + ledgerID .String () + ":@acc1#default"
359362 key2 := "balance:{transactions}:" + organizationID .String () + ":" + ledgerID .String () + ":@acc1#default"
360363
361364 keys := []string {key1 , key2 }
362365
363- // Same balance ID, same asset code, but different versions
364- // The aggregator should keep only version 10 ( the higher one)
366+ // Since key1 == key2, this map has a single entry (Go map semantics).
367+ // Both iterations in the loop retrieve the same balance data.
365368 balanceData := map [string ]* mmodel.BalanceRedis {
366369 key1 : {
367370 ID : balanceID .String (),
368371 Alias : "@acc1" ,
369372 AssetCode : "USD" ,
370- Version : 5 , // Lower version
373+ Version : 5 , // This entry is overwritten by key2 (same key)
371374 Available : decimal .NewFromInt (1000 ),
372375 },
373376 key2 : {
374377 ID : balanceID .String (),
375378 Alias : "@acc1" ,
376379 AssetCode : "USD" ,
377- Version : 10 , // Higher version - this should be synced
380+ Version : 10 , // Only this entry exists in the map
378381 Available : decimal .NewFromInt (2000 ),
379382 },
380383 }
@@ -387,13 +390,12 @@ func TestSyncBalancesBatch_AggregationKeepsHighestVersion(t *testing.T) {
387390 Return (balanceData , nil ).
388391 Times (1 )
389392
390- // Verify that only 1 balance is synced (the deduplicated result)
391- // and that it has the higher version
393+ // Verify that only 1 balance is synced after deduplication of identical keys
392394 mockBalance .EXPECT ().
393395 SyncBatch (gomock .Any (), organizationID , ledgerID , gomock .Any ()).
394396 DoAndReturn (func (_ context.Context , _ , _ uuid.UUID , balances []mmodel.BalanceRedis ) (int64 , error ) {
395397 assert .Len (t , balances , 1 , "Expected exactly 1 balance after deduplication" )
396- assert .Equal (t , int64 (10 ), balances [0 ].Version , "Expected higher version to be kept " )
398+ assert .Equal (t , int64 (10 ), balances [0 ].Version , "Expected the single map entry's version " )
397399 assert .Equal (t , decimal .NewFromInt (2000 ), balances [0 ].Available , "Expected balance with higher version" )
398400 return 1 , nil
399401 }).
@@ -413,8 +415,8 @@ func TestSyncBalancesBatch_AggregationKeepsHighestVersion(t *testing.T) {
413415
414416 assert .NoError (t , err )
415417 assert .NotNil (t , result )
416- assert .Equal (t , 2 , result .KeysProcessed , "Both keys were processed" )
417- assert .Equal (t , 1 , result .BalancesAggregated , "Only 1 balance after deduplication " )
418+ assert .Equal (t , 2 , result .KeysProcessed , "Both key entries in slice were processed" )
419+ assert .Equal (t , 1 , result .BalancesAggregated , "Deduplicated to 1 balance (same composite key) " )
418420 assert .Equal (t , int64 (1 ), result .BalancesSynced )
419421}
420422
0 commit comments