a6bf8632ce
Typed result structs replace empty envelopes. Equity place sends ref_id only so live additionalProperties:false schemas accept the call.
71 lines
2.5 KiB
Go
71 lines
2.5 KiB
Go
package equity_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
decimal "github.com/alpacahq/alpacadecimal"
|
|
"s1d3sw1ped/robinhood-agentic-mcp/client"
|
|
"s1d3sw1ped/robinhood-agentic-mcp/equity"
|
|
)
|
|
|
|
func TestPositions_parsesEnvelope(t *testing.T) {
|
|
t.Parallel()
|
|
c := equity.New(client.Func(func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"positions":[{"symbol":"MU","quantity":"3","average_buy_price":"99.6"}],"next_cursor":"n1"}`), nil
|
|
}))
|
|
got, err := c.Positions(context.Background(), equity.PositionsRequest{AccountNumber: "acct"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got.NextCursor != "n1" || len(got.Positions) != 1 || got.Positions[0].Symbol != "MU" {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
if !got.Positions[0].Qty.Equal(decimal.NewFromInt(3)) || !got.Positions[0].AvgCost.Equal(decimal.RequireFromString("99.6")) {
|
|
t.Fatalf("money %+v", got.Positions[0])
|
|
}
|
|
}
|
|
|
|
func TestOrders_parsesList(t *testing.T) {
|
|
t.Parallel()
|
|
c := equity.New(client.Func(func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"orders":[{"id":"o1","symbol":"MU","state":"filled","quantity":"2"}]}`), nil
|
|
}))
|
|
got, err := c.Orders(context.Background(), equity.OrdersRequest{AccountNumber: "acct"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got.Orders) != 1 || got.Orders[0].ID != "o1" || !got.Orders[0].Qty.Equal(decimal.NewFromInt(2)) {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
}
|
|
|
|
func TestTradability_parsesFlags(t *testing.T) {
|
|
t.Parallel()
|
|
c := equity.New(client.Func(func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"symbol":"MU","tradable":true,"fractional_tradable":true}`), nil
|
|
}))
|
|
got, err := c.Tradability(context.Background(), equity.TradabilityRequest{AccountNumber: "acct", Symbols: []string{"MU"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(got.Symbols) != 1 || !got.Symbols[0].Tradable || !got.Symbols[0].Fractional {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
}
|
|
|
|
func TestNews_parsesArticles(t *testing.T) {
|
|
t.Parallel()
|
|
c := equity.New(client.Func(func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"results":[{"title":"Hi","url":"https://x","published_at":"2026-01-01T00:00:00Z"}],"next_cursor":"c9"}`), nil
|
|
}))
|
|
got, err := c.News(context.Background(), equity.NewsRequest{Symbol: "MU"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got.NextCursor != "c9" || len(got.Articles) != 1 || got.Articles[0].Title != "Hi" {
|
|
t.Fatalf("%+v", got)
|
|
}
|
|
}
|