(t *testing.T)
| 654 | } |
| 655 | |
| 656 | func TestLineageIntegration_FullCreditDebitCycle(t *testing.T) { |
| 657 | t.Run("Simulate full cycle: 3 deposits then 1 withdrawal", func(t *testing.T) { |
| 658 | stripeTime := time.Date(2024, 1, 1, 10, 0, 0, 0, time.UTC) |
| 659 | paypalTime := time.Date(2024, 1, 1, 11, 0, 0, 0, time.UTC) |
| 660 | bankTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC) |
| 661 | |
| 662 | stripeDeposit := big.NewInt(5000) |
| 663 | paypalDeposit := big.NewInt(3000) |
| 664 | bankDeposit := big.NewInt(2000) |
| 665 | withdrawAmount := big.NewInt(7000) |
| 666 | |
| 667 | shadowBalances := map[string]*struct { |
| 668 | Debit *big.Int |
| 669 | Credit *big.Int |
| 670 | CreatedAt time.Time |
| 671 | }{ |
| 672 | "stripe": {Debit: new(big.Int).Set(stripeDeposit), Credit: big.NewInt(0), CreatedAt: stripeTime}, |
| 673 | "paypal": {Debit: new(big.Int).Set(paypalDeposit), Credit: big.NewInt(0), CreatedAt: paypalTime}, |
| 674 | "bank": {Debit: new(big.Int).Set(bankDeposit), Credit: big.NewInt(0), CreatedAt: bankTime}, |
| 675 | } |
| 676 | |
| 677 | totalDeposited := new(big.Int).Add(stripeDeposit, paypalDeposit) |
| 678 | totalDeposited.Add(totalDeposited, bankDeposit) |
| 679 | assert.Equal(t, 0, big.NewInt(10000).Cmp(totalDeposited)) |
| 680 | |
| 681 | sources := []LineageSource{ |
| 682 | {BalanceID: "stripe", Balance: new(big.Int).Sub(shadowBalances["stripe"].Debit, shadowBalances["stripe"].Credit), CreatedAt: stripeTime}, |
| 683 | {BalanceID: "paypal", Balance: new(big.Int).Sub(shadowBalances["paypal"].Debit, shadowBalances["paypal"].Credit), CreatedAt: paypalTime}, |
| 684 | {BalanceID: "bank", Balance: new(big.Int).Sub(shadowBalances["bank"].Debit, shadowBalances["bank"].Credit), CreatedAt: bankTime}, |
| 685 | } |
| 686 | |
| 687 | datasource, _, _ := newTestDataSource() |
| 688 | ledgerforge, _ := NewLedgerForge(datasource) |
| 689 | allocations := ledgerforge.calculateAllocation(sources, withdrawAmount, AllocationFIFO) |
| 690 | |
| 691 | for _, alloc := range allocations { |
| 692 | shadowBalances[alloc.BalanceID].Credit.Add(shadowBalances[alloc.BalanceID].Credit, alloc.Amount) |
| 693 | } |
| 694 | |
| 695 | stripeAvailable := new(big.Int).Sub(shadowBalances["stripe"].Debit, shadowBalances["stripe"].Credit) |
| 696 | paypalAvailable := new(big.Int).Sub(shadowBalances["paypal"].Debit, shadowBalances["paypal"].Credit) |
| 697 | bankAvailable := new(big.Int).Sub(shadowBalances["bank"].Debit, shadowBalances["bank"].Credit) |
| 698 | |
| 699 | assert.Equal(t, 0, big.NewInt(0).Cmp(stripeAvailable), "Stripe should be fully depleted") |
| 700 | assert.Equal(t, 0, big.NewInt(1000).Cmp(paypalAvailable), "PayPal should have 1000 remaining") |
| 701 | assert.Equal(t, 0, big.NewInt(2000).Cmp(bankAvailable), "Bank should be untouched") |
| 702 | |
| 703 | totalRemaining := new(big.Int).Add(stripeAvailable, paypalAvailable) |
| 704 | totalRemaining.Add(totalRemaining, bankAvailable) |
| 705 | assert.Equal(t, 0, big.NewInt(3000).Cmp(totalRemaining), "Total remaining should be 3000") |
| 706 | }) |
| 707 | } |
| 708 | |
| 709 | func TestLineageIntegration_EdgeCases(t *testing.T) { |
| 710 | datasource, _, _ := newTestDataSource() |
nothing calls this directly
no test coverage detected