Files
bank/harness_test.go
zeekayandHanzo Dev 8d7457cdf0 Lux ID is the only way in
Base v1.5.72 closed the door this depended on, and closed it deliberately:
"IAM IS THE ONLY AUTH. There is no second way in... _superusers is not an
exception: it reaches schema, settings, backups and logs, and one process
serves many orgs' Bases, so two independently-keyed doors to it would be
one more than can be reasoned about."

The sandbox login was the second door. It kept a bcrypt hash in its own
collection and minted a _superusers token, and until that release Base
honoured such a token as a fallback. After it, the route still answered
200 with a token and the very next request answered 401 — a login that
succeeds and authenticates nothing. Every authed route was refusing, and
the suite could not see it: the test harness never registers the org
plugin, so 141 tests passed green against a binary whose demo login was
broken.

It was also the custom auth this estate does not build. Gone: the route,
the credentials collection, the token minting, the demo password that was
a constant in a file every browser downloads, and the merged hook shape
that let one path stand in for the other. The SPA already had the PKCE
flow it needed.

What this costs: [email protected] must exist in Lux IAM under org lux, app
lux-bank. The demo cannot sign in until it does. That is an IAM seeding
task, not a code one, and it is the same identity convention every other
surface already follows.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-26 15:16:53 -07:00

97 lines
3.0 KiB
Go

package bank
import (
"os"
"testing"
"github.com/hanzoai/base/core"
"github.com/hanzoai/base/tests"
"github.com/luxfi/bank/collections"
"github.com/luxfi/bank/hooks"
)
// newBankApp returns a live, in-process bank app on a temp SQLite: every
// collection ensured, every hook and route registered, exactly as cmd/bankd
// wires them — so a test exercises the real ledger, not a mock. Sandbox mode
// (default on) keeps the seeded demo path available. Caller-scoped cleanup.
func newBankApp(t testing.TB) *tests.TestApp {
t.Helper()
t.Setenv("hz_test_env", "0123456789abcdef0123456789abcdef")
app, err := tests.NewTestApp()
if err != nil {
t.Fatalf("new test app: %v", err)
}
t.Cleanup(app.Cleanup)
for _, ensure := range []func(core.App) error{
collections.EnsureAccountCollection,
collections.EnsureBalanceCollection,
collections.EnsureBeneficiaryCollection,
collections.EnsureTransactionCollection,
collections.EnsureFeeCollection,
collections.EnsureCardCollection,
collections.EnsureWalletCollection,
collections.EnsureConversionCollection,
collections.EnsureAuditCollection,
collections.EnsureSessionCollection,
collections.EnsureDocumentCollection,
collections.EnsurePositionCollection,
} {
if err := ensure(app); err != nil {
t.Fatalf("ensure collection: %v", err)
}
}
// Register every hook exactly as cmd/bankd does, so tests exercise the
// same wiring — including the webhook routes and the document/wallet hooks.
hooks.RegisterCurrencyCloudWebhooks(app)
hooks.RegisterComplianceHooks(app)
hooks.RegisterPaymentHooks(app)
hooks.RegisterAccountHooks(app)
hooks.RegisterFeeHooks(app)
hooks.RegisterAuditHooks(app)
hooks.RegisterDocumentHooks(app)
hooks.RegisterWalletHooks(app)
hooks.RegisterEmailHooks(app)
hooks.RegisterCronJobs(app)
RegisterRoutes(app)
return app
}
// seedPrincipal creates a superuser (the shape the sandbox login mints), opens
// its account via ProvisionCustomer, and returns the principal id plus a bearer
// token that satisfies apis.RequireAuth on the /v1/bank routes.
func seedPrincipal(t testing.TB, app core.App) (id, token string) {
t.Helper()
su, err := app.FindAuthRecordByEmail(core.CollectionNameSuperusers, "[email protected]")
if err != nil || su == nil {
col, cerr := app.FindCollectionByNameOrId(core.CollectionNameSuperusers)
if cerr != nil {
t.Fatalf("superusers collection: %v", cerr)
}
su = core.NewRecord(col)
su.SetEmail("[email protected]")
su.Set("password", "test-password-1234")
if serr := app.Save(su); serr != nil {
t.Fatalf("save superuser: %v", serr)
}
}
if _, err := ProvisionCustomer(app, su, KYC{Name: "Test User", Country: "US", EntityType: "individual"}); err != nil {
t.Fatalf("provision: %v", err)
}
tok, err := su.NewAuthToken()
if err != nil {
t.Fatalf("auth token: %v", err)
}
return su.Id, tok
}
// TestMain guards against a stray BANK_SANDBOX in the environment flipping the
// suite into production behavior.
func TestMain(m *testing.M) {
_ = os.Unsetenv("BANK_SANDBOX")
os.Exit(m.Run())
}