| package ledger_test |
|
|
| import ( |
| "testing" |
| "time" |
|
|
| "github.com/alpacahq/alpacadecimal" |
| "github.com/stretchr/testify/require" |
|
|
| "github.com/openmeterio/openmeter/openmeter/ledger" |
| "github.com/openmeterio/openmeter/openmeter/ledger/transactions/testutils" |
| "github.com/openmeterio/openmeter/pkg/currencyx" |
| "github.com/openmeterio/openmeter/pkg/models" |
| ) |
|
|
| |
|
|
| type exampleEntryInput struct { |
| account ledger.PostingAddress |
| amount alpacadecimal.Decimal |
| } |
|
|
| func (e exampleEntryInput) PostingAddress() ledger.PostingAddress { |
| return e.account |
| } |
|
|
| func (e exampleEntryInput) Amount() alpacadecimal.Decimal { |
| return e.amount |
| } |
|
|
| func (e exampleEntryInput) IdentityKey() string { |
| return "" |
| } |
|
|
| func (e exampleEntryInput) SchemaVersion() ledger.EntrySchemaVersion { |
| return ledger.EntrySchemaVersionCurrent |
| } |
|
|
| func (e exampleEntryInput) SourceChargeID() *string { |
| return nil |
| } |
|
|
| func (e exampleEntryInput) SpendChargeID() *string { |
| return nil |
| } |
|
|
| func (e exampleEntryInput) Annotations() models.Annotations { |
| return nil |
| } |
|
|
| var _ ledger.EntryInput = exampleEntryInput{} |
|
|
| func TestTwoAccountTransaction(t *testing.T) { |
| t.Skipf("This is just to assert the types, it would fail on unimplemented") |
|
|
| var l ledger.Ledger |
| var a1, a2 ledger.SubAccount |
|
|
| |
| txInput := &testutils.AnyTransactionInput{ |
| BookedAtValue: time.Now(), |
| EntryInputsValues: []*testutils.AnyEntryInput{ |
| { |
| Address: a1.Address(), |
| AmountValue: alpacadecimal.NewFromInt(-100), |
| }, |
| { |
| Address: a2.Address(), |
| AmountValue: alpacadecimal.NewFromInt(100), |
| }, |
| }, |
| } |
|
|
| _, err := l.CommitGroup(t.Context(), txInput.AsGroupInput("namespace", nil)) |
| require.NoError(t, err) |
| } |
|
|
| func TestMultiAccountTransaction(t *testing.T) { |
| t.Skipf("This is just to assert the types, it would fail on unimplemented") |
|
|
| var a1, a2, a3 ledger.SubAccount |
|
|
| |
| txInput := &testutils.AnyTransactionInput{ |
| BookedAtValue: time.Now(), |
| EntryInputsValues: []*testutils.AnyEntryInput{ |
| { |
| Address: a1.Address(), |
| AmountValue: alpacadecimal.NewFromInt(-100), |
| }, |
| { |
| Address: a2.Address(), |
| AmountValue: alpacadecimal.NewFromInt(50), |
| }, |
| { |
| Address: a3.Address(), |
| AmountValue: alpacadecimal.NewFromInt(49), |
| }, |
| }, |
| } |
|
|
| err := ledger.ValidateTransactionInput(t.Context(), txInput) |
| require.NoError(t, err) |
|
|
| |
| found := false |
| if issues, err := models.AsValidationIssues(err); err != nil { |
| for _, issue := range issues { |
| if issue.Code() == ledger.ErrCodeInvalidTransactionTotal { |
| |
| found = true |
| } |
| } |
| } |
| require.True(t, found, "expected validation issue not found, got %v", err) |
| } |
|
|
| func TestGetAccountBalance(t *testing.T) { |
| t.Skipf("This is just to assert the types, it would fail on unimplemented") |
|
|
| var acc ledger.Account |
| var querier ledger.BalanceQuerier |
|
|
| balance, err := querier.GetAccountBalance(t.Context(), acc, ledger.RouteFilter{ |
| Currency: currencyx.Code("USD"), |
| }, ledger.BalanceQuery{}) |
| require.NoError(t, err) |
| require.NotNil(t, balance) |
| } |
|
|
| func TestBalanceBucketQueryValidateGroupBy(t *testing.T) { |
| require.NoError(t, ledger.BalanceBucketQuery{ |
| Namespace: "namespace", |
| GroupBy: []string{ |
| ledger.BalanceBucketGroupBySourceChargeID, |
| ledger.BalanceBucketGroupBySpendChargeID, |
| }, |
| }.Validate()) |
|
|
| require.Error(t, ledger.BalanceBucketQuery{ |
| Namespace: "namespace", |
| GroupBy: []string{"unsupported"}, |
| }.Validate()) |
|
|
| require.Error(t, ledger.BalanceBucketQuery{ |
| Namespace: "namespace", |
| GroupBy: []string{ |
| ledger.BalanceBucketGroupBySourceChargeID, |
| ledger.BalanceBucketGroupBySourceChargeID, |
| }, |
| }.Validate()) |
| } |
|
|