func TestOneToOneReconciliation(t *testing.T) { cnf := &config.Configuration{ Transaction: config.TransactionConfig{ BatchSize: 100000, MaxWorkers: 1, }, Queue: config.QueueConfig{ TransactionQueue: "transaction_queue", }, } config.ConfigStore.Store(cnf) mockDS := new(mocks.Moc
(t *testing.T)
| 83 | |
| 84 | // TestOneToManyReconciliation tests the one-to-many reconciliation strategy |
| 85 | func TestOneToManyReconciliation(t *testing.T) { |
| 86 | cnf := &config.Configuration{ |
| 87 | Transaction: config.TransactionConfig{ |
| 88 | BatchSize: 100000, |
| 89 | MaxWorkers: 1, |
| 90 | }, |
| 91 | } |
| 92 | config.ConfigStore.Store(cnf) |
| 93 | mockDS := new(mocks.MockDataSource) |
| 94 | ledgerforge := &LedgerForge{datasource: mockDS} |
| 95 | |
| 96 | ctx := context.Background() |
| 97 | externalTxns := []*model.Transaction{ |
| 98 | {TransactionID: "ext1", Amount: 300, CreatedAt: time.Now(), Description: "External 1 Internal 1 2 3", Reference: "REF1", Currency: "USD"}, |
| 99 | } |
| 100 | internalTxns := []*model.Transaction{ |
| 101 | {TransactionID: "int1", Amount: 100, CreatedAt: time.Now().Add(-1 * time.Hour), Description: "Internal 1", Reference: "REF1-A", Currency: "USD"}, |
| 102 | {TransactionID: "int2", Amount: 150, CreatedAt: time.Now(), Description: "Internal 2", Reference: "REF1-B", Currency: "USD"}, |
| 103 | {TransactionID: "int3", Amount: 53, CreatedAt: time.Now().Add(1 * time.Hour), Description: "Internal 3", Reference: "REF1-C", Currency: "USD"}, |
| 104 | } |
| 105 | |
| 106 | groupedInternalTxns := map[string][]*model.Transaction{ |
| 107 | "parent_transaction": internalTxns, |
| 108 | } |
| 109 | |
| 110 | emptyGroup := map[string][]*model.Transaction{} |
| 111 | |
| 112 | mockDS.On("GroupTransactions", mock.Anything, mock.Anything, 100000, int64(0)).Return(groupedInternalTxns, nil) |
| 113 | mockDS.On("GroupTransactions", mock.Anything, mock.Anything, 100000, int64(100000)).Return(emptyGroup, nil) |
| 114 | |
| 115 | matchingRules := []model.MatchingRule{ |
| 116 | { |
| 117 | RuleID: "parent_transaction", |
| 118 | Criteria: []model.MatchingCriteria{ |
| 119 | {Field: "amount", Operator: "equals", AllowableDrift: 0.01}, // 1% drift allowed |
| 120 | {Field: "description", Operator: "contains"}, |
| 121 | {Field: "reference", Operator: "contains"}, |
| 122 | {Field: "currency", Operator: "equals"}, |
| 123 | }, |
| 124 | }, |
| 125 | } |
| 126 | |
| 127 | matches, unmatched := ledgerforge.oneToManyReconciliation(ctx, externalTxns, "parent_transaction", matchingRules, false) |
| 128 | |
| 129 | assert.Equal(t, 3, len(matches), "Expected 3 matches") |
| 130 | assert.Equal(t, 0, len(unmatched), "Expected 0 unmatched transactions") |
| 131 | |
| 132 | assert.Equal(t, "ext1", matches[0].ExternalTransactionID) |
| 133 | assert.Equal(t, "int1", matches[0].InternalTransactionID) |
| 134 | assert.Equal(t, "ext1", matches[1].ExternalTransactionID) |
| 135 | assert.Equal(t, "int2", matches[1].InternalTransactionID) |
| 136 | assert.Equal(t, "ext1", matches[2].ExternalTransactionID) |
| 137 | assert.Equal(t, "int3", matches[2].InternalTransactionID) |
| 138 | mockDS.AssertExpectations(t) |
| 139 | } |
| 140 | |
| 141 | func TestOneToManyReconciliationNoMatches(t *testing.T) { |
| 142 | cnf := &config.Configuration{ |
nothing calls this directly
no test coverage detected