mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
- go.mod module path + all self-imports: github.com/formancehq/payments -> github.com/hanzo-fi/payments (1590 .go files / 3152 refs; 20 modules: root, pkg/client, pkg/domain, 18 ce/plugins). External dep kept: formancehq/go-libs. - plugins: each ce/plugins/* consumed a *published* pkg/domain; added local 'replace .../pkg/domain => ../../../pkg/domain' (consistent with root) so every standalone plugin module builds in-monorepo. compile-plugin.sh MOD var rebranded too. - branding: README, LICENSE (dual MIT+EE; upstream copyright retained + Hanzo added), goreleaser (release images -> registry.hanzo.ai/hanzo-fi, OCI labels, homepage), proto go_package, renovate, speakeasy gen.yaml, connector-template *.gotpl. - CI: removed Numary/Formance workflows + composite action; added canonical hanzo.yml + cicd.yml (hanzoai/ci, gated HANZO_CI_ENABLED) + secretless ci.yml (go build/vet). - kept as data/compat keys: wire capability enums ALLOW_FORMANCE_*, generated SDK type client.Formance, domain field FormanceRedirectURL, OTEL_SERVICE_NAME, upstream base image. - verified: go build ./... (default + -tags ee) + all 20 nested modules green.
256 lines
7.4 KiB
Go
256 lines
7.4 KiB
Go
package client_test
|
|
|
|
import (
|
|
"math"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/hanzo-fi/payments/ce/plugins/plaid/client"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
func TestAmountUtils(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "Amount Utils Suite")
|
|
}
|
|
|
|
var _ = Describe("Amount Utils", func() {
|
|
Describe("TranslatePlaidAmount", func() {
|
|
Context("with valid currency codes", func() {
|
|
It("should convert USD amounts correctly", func() {
|
|
amount := 123.45
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(12345))) // 123.45 * 100 (2 decimal places)
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
})
|
|
|
|
It("should convert JPY amounts correctly (no decimal places)", func() {
|
|
amount := 1000.0
|
|
currencyCode := "JPY"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(1000))) // 1000 * 1 (0 decimal places)
|
|
Expect(assetName).To(Equal("JPY/0"))
|
|
})
|
|
|
|
It("should convert BHD amounts correctly (3 decimal places)", func() {
|
|
amount := 1.234
|
|
currencyCode := "BHD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(1234))) // 1.234 * 1000 (3 decimal places)
|
|
Expect(assetName).To(Equal("BHD/3"))
|
|
})
|
|
|
|
It("should handle zero amounts", func() {
|
|
amount := 0.0
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(0)))
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
})
|
|
|
|
It("should handle negative amounts", func() {
|
|
amount := -123.45
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(-12345))) // -123.45 * 100
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
})
|
|
|
|
It("should handle very small amounts", func() {
|
|
amount := 0.01
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(1))) // 0.01 * 100
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
})
|
|
|
|
It("should handle large amounts", func() {
|
|
amount := 999999.99
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(99999999))) // 999999.99 * 100
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
})
|
|
|
|
It("should handle amounts with many decimal places", func() {
|
|
amount := 123.456789
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
// This should FAIL because 123.456789 has more than 2 decimal places for USD
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
|
|
It("should handle EUR amounts correctly", func() {
|
|
amount := 50.75
|
|
currencyCode := "EUR"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(5075))) // 50.75 * 100
|
|
Expect(assetName).To(Equal("EUR/2"))
|
|
})
|
|
|
|
It("should handle GBP amounts correctly", func() {
|
|
amount := 25.50
|
|
currencyCode := "GBP"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(2550))) // 25.50 * 100
|
|
Expect(assetName).To(Equal("GBP/2"))
|
|
})
|
|
})
|
|
|
|
Context("with invalid currency codes", func() {
|
|
It("should return error for unsupported currency", func() {
|
|
amount := 100.0
|
|
currencyCode := "INVALID"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
|
|
It("should return error for empty currency code", func() {
|
|
amount := 100.0
|
|
currencyCode := ""
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
})
|
|
|
|
Context("with special float values", func() {
|
|
It("should handle NaN values", func() {
|
|
amount := math.NaN()
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
|
|
It("should handle positive infinity", func() {
|
|
amount := math.Inf(1)
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
|
|
It("should handle negative infinity", func() {
|
|
amount := math.Inf(-1)
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
})
|
|
|
|
Context("with various precision currencies", func() {
|
|
It("should handle KWD (3 decimal places)", func() {
|
|
amount := 1.234
|
|
currencyCode := "KWD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(1234))) // 1.234 * 1000
|
|
Expect(assetName).To(Equal("KWD/3"))
|
|
})
|
|
|
|
It("should handle OMR (3 decimal places)", func() {
|
|
amount := 5.678
|
|
currencyCode := "OMR"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(5678))) // 5.678 * 1000
|
|
Expect(assetName).To(Equal("OMR/3"))
|
|
})
|
|
|
|
It("should handle JOD (3 decimal places)", func() {
|
|
amount := 10.123
|
|
currencyCode := "JOD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).To(Equal(big.NewInt(10123))) // 10.123 * 1000
|
|
Expect(assetName).To(Equal("JOD/3"))
|
|
})
|
|
})
|
|
|
|
Context("with boundary values", func() {
|
|
It("should handle maximum float64 value", func() {
|
|
amount := 1.7976931348623157e+308
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
// This should SUCCEED with a very large number (max float64 is valid)
|
|
Expect(err).To(BeNil())
|
|
Expect(resultAmount).ToNot(BeNil())
|
|
Expect(assetName).To(Equal("USD/2"))
|
|
// The result should be a very large number representing the max float64 in cents
|
|
Expect(resultAmount.Cmp(big.NewInt(0))).To(Equal(1)) // Should be positive
|
|
})
|
|
|
|
It("should handle minimum positive float64 value", func() {
|
|
amount := 4.9406564584124654e-324
|
|
currencyCode := "USD"
|
|
|
|
resultAmount, assetName, err := client.TranslatePlaidAmount(amount, currencyCode)
|
|
|
|
Expect(err).ToNot(BeNil())
|
|
Expect(err).To(MatchError("invalid precision"))
|
|
Expect(resultAmount).To(BeNil())
|
|
Expect(assetName).To(Equal(""))
|
|
})
|
|
})
|
|
})
|
|
})
|