117 lines
3.5 KiB
Go
117 lines
3.5 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
|
|
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
|
|
oraclev1 "github.com/tech/sendico/pkg/proto/oracle/v1"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
type stubOracle struct {
|
|
latestResp *oraclev1.LatestRateResponse
|
|
latestErr error
|
|
|
|
quoteResp *oraclev1.GetQuoteResponse
|
|
quoteErr error
|
|
|
|
lastLatest *oraclev1.LatestRateRequest
|
|
lastQuote *oraclev1.GetQuoteRequest
|
|
}
|
|
|
|
func (s *stubOracle) LatestRate(ctx context.Context, in *oraclev1.LatestRateRequest, _ ...grpc.CallOption) (*oraclev1.LatestRateResponse, error) {
|
|
s.lastLatest = in
|
|
return s.latestResp, s.latestErr
|
|
}
|
|
|
|
func (s *stubOracle) GetQuote(ctx context.Context, in *oraclev1.GetQuoteRequest, _ ...grpc.CallOption) (*oraclev1.GetQuoteResponse, error) {
|
|
s.lastQuote = in
|
|
return s.quoteResp, s.quoteErr
|
|
}
|
|
|
|
func TestLatestRate(t *testing.T) {
|
|
expectedTime := time.Date(2024, 1, 1, 15, 0, 0, 0, time.UTC)
|
|
stub := &stubOracle{
|
|
latestResp: &oraclev1.LatestRateResponse{
|
|
Rate: &oraclev1.RateSnapshot{
|
|
Pair: &fxv1.CurrencyPair{Base: "USD", Quote: "EUR"},
|
|
Mid: &moneyv1.Decimal{Value: "1.1000"},
|
|
Bid: &moneyv1.Decimal{Value: "1.0995"},
|
|
Ask: &moneyv1.Decimal{Value: "1.1005"},
|
|
SpreadBps: &moneyv1.Decimal{Value: "5"},
|
|
Provider: "ECB",
|
|
RateRef: "ECB-20240101",
|
|
AsofUnixMs: expectedTime.UnixMilli(),
|
|
},
|
|
},
|
|
}
|
|
|
|
client := NewWithClient(Config{}, stub)
|
|
resp, err := client.LatestRate(context.Background(), LatestRateParams{
|
|
Meta: RequestMeta{
|
|
TenantRef: "tenant",
|
|
OrganizationRef: "org",
|
|
},
|
|
Pair: &fxv1.CurrencyPair{Base: "USD", Quote: "EUR"},
|
|
Provider: "ECB",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("LatestRate returned error: %v", err)
|
|
}
|
|
|
|
if stub.lastLatest.GetProvider() != "ECB" {
|
|
t.Fatalf("expected provider to propagate, got %s", stub.lastLatest.GetProvider())
|
|
}
|
|
if resp.Provider != "ECB" || resp.RateRef != "ECB-20240101" {
|
|
t.Fatalf("unexpected response: %+v", resp)
|
|
}
|
|
if !resp.AsOf.Equal(expectedTime) {
|
|
t.Fatalf("expected as-of %s, got %s", expectedTime, resp.AsOf)
|
|
}
|
|
}
|
|
|
|
func TestGetQuote(t *testing.T) {
|
|
expiresAt := time.Date(2024, 2, 2, 12, 0, 0, 0, time.UTC)
|
|
stub := &stubOracle{
|
|
quoteResp: &oraclev1.GetQuoteResponse{
|
|
Quote: &oraclev1.Quote{
|
|
QuoteRef: "quote-123",
|
|
Pair: &fxv1.CurrencyPair{Base: "GBP", Quote: "USD"},
|
|
Side: fxv1.Side_BUY_BASE_SELL_QUOTE,
|
|
Price: &moneyv1.Decimal{Value: "1.2500"},
|
|
BaseAmount: &moneyv1.Money{Amount: "100.00", Currency: "GBP"},
|
|
QuoteAmount: &moneyv1.Money{Amount: "125.00", Currency: "USD"},
|
|
ExpiresAtUnixMs: expiresAt.UnixMilli(),
|
|
Provider: "Test",
|
|
RateRef: "test-ref",
|
|
Firm: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
client := NewWithClient(Config{}, stub)
|
|
resp, err := client.GetQuote(context.Background(), GetQuoteParams{
|
|
Pair: &fxv1.CurrencyPair{Base: "GBP", Quote: "USD"},
|
|
Side: fxv1.Side_BUY_BASE_SELL_QUOTE,
|
|
BaseAmount: &moneyv1.Money{Amount: "100.00", Currency: "GBP"},
|
|
Firm: true,
|
|
TTL: 2 * time.Second,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("GetQuote returned error: %v", err)
|
|
}
|
|
|
|
if stub.lastQuote.GetFirm() != true {
|
|
t.Fatalf("expected firm flag to propagate")
|
|
}
|
|
if stub.lastQuote.GetTtlMs() == 0 {
|
|
t.Fatalf("expected ttl to be populated")
|
|
}
|
|
if resp.QuoteRef != "quote-123" || resp.Price != "1.2500" || !resp.ExpiresAt.Equal(expiresAt) {
|
|
t.Fatalf("unexpected quote response: %+v", resp)
|
|
}
|
|
}
|