Documentation
¶
Overview ¶
Package testing provides utilities for testing JOSE-protected handlers in go-bricks applications without requiring real counterparty credentials.
The primary use case is unit-testing handlers whose request/response types carry jose: tags (e.g., a Visa Token Services integration). Test code generates an in-memory key pair, registers it under the kids the handler expects, and uses SealForTest / OpenForTest to produce and consume nested JWE-of-JWS payloads.
Basic Usage ¶
priv, pub := jositest.GenerateTestKeyPair(t)
resolver := jositest.NewTestResolver(map[string]any{
"our-key": priv, // played as both the decrypt key (us) and sign key (peer in test)
"peer-key": pub, // verify key
})
inboundPolicy := &jose.Policy{
Direction: jose.DirectionInbound,
DecryptKid: "our-key", VerifyKid: "peer-key",
SigAlg: jose.DefaultSigAlg, KeyAlg: jose.DefaultKeyAlg,
Enc: jose.DefaultEnc, Cty: jose.DefaultCty,
}
outboundPolicy := &jose.Policy{
Direction: jose.DirectionOutbound,
SignKid: "peer-key", EncryptKid: "our-key",
SigAlg: jose.DefaultSigAlg, KeyAlg: jose.DefaultKeyAlg,
Enc: jose.DefaultEnc, Cty: jose.DefaultCty,
}
compact := jositest.SealForTest(t, []byte(`{"pan":"..."}`), outboundPolicy, resolver)
plaintext, claims := jositest.OpenForTest(t, compact, inboundPolicy, resolver)
Why a separate package ¶
jose/testing/ depends on jose/ but jose/ does not depend on jose/testing/, keeping production binaries free of test-only key-generation code (the rsa.GenerateKey call is heavy enough to matter for cold-start budgets).
Index ¶
- func GenerateTestKeyPair(t testing.TB) (*rsa.PrivateKey, *rsa.PublicKey)
- func NewTestResolver(keys map[string]any) jose.KeyResolver
- func OpenForTest(t testing.TB, compact string, p *jose.Policy, r jose.KeyResolver) (plaintext []byte, claims *jose.Claims)
- func SealForTest(t testing.TB, payload []byte, p *jose.Policy, r jose.KeyResolver) string
- type BidirectionalFixture
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenerateTestKeyPair ¶
GenerateTestKeyPair returns a freshly-minted 2048-bit RSA key pair suitable for JOSE round-trip tests. The smaller key size is chosen for test speed — production keystores should use 3072+ bits.
func NewTestResolver ¶
func NewTestResolver(keys map[string]any) jose.KeyResolver
NewTestResolver builds a jose.KeyResolver from a flat kid → key map. Values may be *rsa.PrivateKey (used for both PrivateKey and PublicKey lookups via the embedded public key) or *rsa.PublicKey (used only for PublicKey lookups; PrivateKey lookup against a public-only entry returns ErrKidUnknown).
Unknown kids return a *jose.Error wrapping jose.ErrKidUnknown — the same behavior as the production KeyStoreResolver — so tests exercise the same error paths as production code.
func OpenForTest ¶
func OpenForTest(t testing.TB, compact string, p *jose.Policy, r jose.KeyResolver) (plaintext []byte, claims *jose.Claims)
OpenForTest is a convenience wrapper over jose.Open that fails the test on error. Use it in assertions when consuming a JOSE response from the system under test (e.g., decrypting + verifying a response body to assert on its plaintext shape).
Returns the verified plaintext and the extracted claims; the diagnostic header is dropped because tests rarely care about it. If you need the header, call jose.Open directly.
func SealForTest ¶
SealForTest is a convenience wrapper over jose.Seal that fails the test on error. Use it in test setup when producing a JOSE-wrapped payload to feed into the system under test (e.g., posting to an httptest server with a JOSE-tagged handler).
Types ¶
type BidirectionalFixture ¶
type BidirectionalFixture struct {
ClientPrivate *rsa.PrivateKey
PeerPrivate *rsa.PrivateKey
Resolver jose.KeyResolver
ClientOutbound *jose.Policy // client signs with client-key, encrypts to peer-key
ClientInbound *jose.Policy // client decrypts with client-key, verifies with peer-key
PeerOutbound *jose.Policy // peer signs with peer-key, encrypts to client-key
PeerInbound *jose.Policy // peer decrypts with peer-key, verifies with client-key
}
BidirectionalFixture is the test-scoped state for exercising both ends of a JOSE channel — typical for VTS-style integrations where one side is the system under test and the other side is replayed by an in-process httptest server. The fixture holds two key pairs and the four matching policies (client outbound/inbound + peer outbound/inbound) so a test can seal and open in either direction without rebuilding the kid namespace.
func NewBidirectionalFixture ¶
func NewBidirectionalFixture(t testing.TB) *BidirectionalFixture
NewBidirectionalFixture returns a fixture with two freshly generated 2048-bit RSA pairs and matching client/peer policies. Kid strings are fixed ("client-key" and "peer-key") because production VTS-style integrations use matching kid names on both ends — header kids on a sealed payload must match the receiver's expected kid for ExpectedKid validation to pass.