Documentation
¶
Overview ¶
Package test provides mock implementations of the auth service for testing.
Overview ¶
This package contains mock implementations of auth.AuthClient and auth.AuthServer that can be used in unit tests to simulate authentication behavior without requiring a real auth service. The mocks support configurable responses for all auth operations.
Features ¶
- MockAuthClient: A configurable mock implementation of auth.AuthClient
- MockAuthServer: A mock server that wraps MockAuthClient for gRPC testing
- Flexible response configuration using slice-based matchers
- Context-aware validation matching via FromContextFn
- Protocol buffer comparison using protocmp for request matching
Usage ¶
The mock client is configured by populating slices of response configurations. Each operation (Validate, Register, GetHeadlessSession, Delete) has a corresponding slice that defines the expected inputs and desired outputs.
Basic mock setup:
mock := test.MockAuthClient{
OnValidate: []test.AuthOnValidate{{
Given: func(ctx context.Context) bool { return true },
Validate: &auth.WhoAmI{
Identity: &auth.Identity{Id: "user-123"},
},
}},
}
whoami, err := mock.Validate(ctx, &emptypb.Empty{})
Request matching:
mock := test.MockAuthClient{
OnRegister: []test.AuthOnRegister{{
Given: &auth.RegistrationRequest{
Email: "user@example.com",
},
Created: &auth.Session{
Token: "session-token",
},
}},
}
session, err := mock.Register(ctx, &auth.RegistrationRequest{
Email: "user@example.com",
})
Error simulation:
mock := test.MockAuthClient{
OnDelete: []test.AuthOnDelete{{
Given: &auth.DeletionRequest{Id: "session-123"},
Error: errors.New("deletion failed"),
}},
}
_, err := mock.Delete(ctx, &auth.DeletionRequest{Id: "session-123"})
// err will be "deletion failed"
Integration Patterns ¶
For testing gRPC servers, use MockAuthServer:
server := test.MockAuthServer{
Client: test.MockAuthClient{
OnValidate: []test.AuthOnValidate{{
Given: func(ctx context.Context) bool { return true },
Validate: &auth.WhoAmI{
Identity: &auth.Identity{Id: "user-123"},
},
}},
},
}
// Register with grpc.Server
auth.RegisterAuthServer(grpcServer, server)
The mock uses protocol buffer comparison (protocmp.Transform()) for matching requests, ensuring that semantically equivalent messages match even if they differ in internal representation.
Index ¶
- type AuthOnDelete
- type AuthOnGetHeadlessSession
- type AuthOnRegister
- type AuthOnValidate
- type FromContextFn
- type MockAuthClient
- func (m MockAuthClient) Delete(_ context.Context, given *auth.DeletionRequest, _ ...grpc.CallOption) (*emptypb.Empty, error)
- func (m MockAuthClient) GetHeadlessSession(_ context.Context, given *auth.GetHeadlessSessionRequest, _ ...grpc.CallOption) (*auth.HeadlessSession, error)
- func (m MockAuthClient) Register(ctx context.Context, given *auth.RegistrationRequest, _ ...grpc.CallOption) (*auth.Session, error)
- func (m MockAuthClient) Validate(ctx context.Context, _ *emptypb.Empty, _ ...grpc.CallOption) (*auth.WhoAmI, error)
- type MockAuthServer
- func (m MockAuthServer) Delete(ctx context.Context, req *auth.DeletionRequest) (*emptypb.Empty, error)
- func (m MockAuthServer) GetHeadlessSession(ctx context.Context, req *auth.GetHeadlessSessionRequest) (*auth.HeadlessSession, error)
- func (m MockAuthServer) Register(ctx context.Context, req *auth.RegistrationRequest) (*auth.Session, error)
- func (m MockAuthServer) Validate(ctx context.Context, empty *emptypb.Empty) (*auth.WhoAmI, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthOnDelete ¶ added in v0.1.42
type AuthOnDelete struct {
Given *auth.DeletionRequest
Error error
}
type AuthOnGetHeadlessSession ¶ added in v0.1.25
type AuthOnGetHeadlessSession struct {
Given *auth.GetHeadlessSessionRequest
Found *auth.HeadlessSession
Error error
}
type AuthOnRegister ¶
type AuthOnRegister struct {
Given *auth.RegistrationRequest
Created *auth.Session
CheckContext FromContextFn
Error error
}
type AuthOnValidate ¶
type AuthOnValidate struct {
Given FromContextFn
Validate *auth.WhoAmI
Error error
}
type FromContextFn ¶
type MockAuthClient ¶
type MockAuthClient struct {
OnValidate []AuthOnValidate
OnRegister []AuthOnRegister
OnGetHeadlessSession []AuthOnGetHeadlessSession
OnDelete []AuthOnDelete
}
func (MockAuthClient) Delete ¶ added in v0.1.42
func (m MockAuthClient) Delete(_ context.Context, given *auth.DeletionRequest, _ ...grpc.CallOption) (*emptypb.Empty, error)
Example ¶
package main
import (
"context"
"fmt"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
mock := test.MockAuthClient{
OnDelete: []test.AuthOnDelete{{
Given: &auth.DeletionRequest{
Id: "session-456",
},
}},
}
_, err := mock.Delete(context.Background(), &auth.DeletionRequest{
Id: "session-456",
})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Println("deleted successfully")
}
Output: deleted successfully
Example (Error) ¶
package main
import (
"context"
"errors"
"fmt"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
mock := test.MockAuthClient{
OnDelete: []test.AuthOnDelete{{
Given: &auth.DeletionRequest{
Id: "session-789",
},
Error: errors.New("session not found"),
}},
}
_, err := mock.Delete(context.Background(), &auth.DeletionRequest{
Id: "session-789",
})
if err != nil {
fmt.Printf("error: %v\n", err)
}
}
Output: error: session not found
func (MockAuthClient) GetHeadlessSession ¶ added in v0.1.25
func (m MockAuthClient) GetHeadlessSession(_ context.Context, given *auth.GetHeadlessSessionRequest, _ ...grpc.CallOption) (*auth.HeadlessSession, error)
Example ¶
package main
import (
"context"
"fmt"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
mock := test.MockAuthClient{
OnGetHeadlessSession: []test.AuthOnGetHeadlessSession{{
Given: &auth.GetHeadlessSessionRequest{
Code: "headless-code-123",
},
Found: &auth.HeadlessSession{
EcdhPublicKey: []byte("public-key-data"),
EncryptedIdtoken: []byte("encrypted-token-data"),
},
}},
}
session, err := mock.GetHeadlessSession(context.Background(), &auth.GetHeadlessSessionRequest{
Code: "headless-code-123",
})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("session has public key: %v\n", len(session.EcdhPublicKey) > 0)
}
Output: session has public key: true
func (MockAuthClient) Register ¶
func (m MockAuthClient) Register(ctx context.Context, given *auth.RegistrationRequest, _ ...grpc.CallOption) (*auth.Session, error)
Example ¶
package main
import (
"context"
"fmt"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
mock := test.MockAuthClient{
OnRegister: []test.AuthOnRegister{{
Given: &auth.RegistrationRequest{
Code: "invite-code-123",
},
Created: &auth.Session{
Identity: "user-identity-abc",
Group: "group-123",
},
}},
}
session, err := mock.Register(context.Background(), &auth.RegistrationRequest{
Code: "invite-code-123",
})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("identity: %s\n", session.Identity)
}
Output: identity: user-identity-abc
Example (WithContextCheck) ¶
package main
import (
"context"
"fmt"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
type contextKey string
const authKey contextKey = "authorized"
mock := test.MockAuthClient{
OnRegister: []test.AuthOnRegister{{
Given: &auth.RegistrationRequest{
Code: "invite-code-456",
},
CheckContext: func(ctx context.Context) bool {
return ctx.Value(authKey) == true
},
Created: &auth.Session{
Identity: "user-identity-xyz",
Group: "group-456",
},
}},
}
ctx := context.WithValue(context.Background(), authKey, true)
session, err := mock.Register(ctx, &auth.RegistrationRequest{
Code: "invite-code-456",
})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("identity: %s\n", session.Identity)
}
Output: identity: user-identity-xyz
func (MockAuthClient) Validate ¶
func (m MockAuthClient) Validate(ctx context.Context, _ *emptypb.Empty, _ ...grpc.CallOption) (*auth.WhoAmI, error)
Example ¶
package main
import (
"context"
"fmt"
"google.golang.org/protobuf/types/known/emptypb"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
mock := test.MockAuthClient{
OnValidate: []test.AuthOnValidate{{
Given: func(_ context.Context) bool { return true },
Validate: &auth.WhoAmI{
Subject: "user-123",
},
}},
}
whoami, err := mock.Validate(context.Background(), &emptypb.Empty{})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("identity: %s\n", whoami.Subject)
}
Output: identity: user-123
Example (ContextMatching) ¶
package main
import (
"context"
"fmt"
"google.golang.org/protobuf/types/known/emptypb"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
type contextKey string
const userKey contextKey = "user"
mock := test.MockAuthClient{
OnValidate: []test.AuthOnValidate{{
Given: func(ctx context.Context) bool {
return ctx.Value(userKey) == "admin"
},
Validate: &auth.WhoAmI{
Subject: "admin-456",
},
}, {
Given: func(ctx context.Context) bool {
return ctx.Value(userKey) == "user"
},
Validate: &auth.WhoAmI{
Subject: "user-789",
},
}},
}
ctx := context.WithValue(context.Background(), userKey, "admin")
whoami, err := mock.Validate(ctx, &emptypb.Empty{})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("identity: %s\n", whoami.Subject)
}
Output: identity: admin-456
type MockAuthServer ¶
type MockAuthServer struct {
auth.UnimplementedAuthServer
Client MockAuthClient
}
Example ¶
package main
import (
"context"
"fmt"
"google.golang.org/protobuf/types/known/emptypb"
auth "chainguard.dev/sdk/proto/platform/auth/v1"
"chainguard.dev/sdk/proto/platform/auth/v1/test"
)
func main() {
server := test.MockAuthServer{
Client: test.MockAuthClient{
OnValidate: []test.AuthOnValidate{{
Given: func(_ context.Context) bool { return true },
Validate: &auth.WhoAmI{
Subject: "server-user-123",
},
}},
},
}
whoami, err := server.Validate(context.Background(), &emptypb.Empty{})
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
fmt.Printf("identity: %s\n", whoami.Subject)
}
Output: identity: server-user-123
func (MockAuthServer) Delete ¶ added in v0.1.42
func (m MockAuthServer) Delete(ctx context.Context, req *auth.DeletionRequest) (*emptypb.Empty, error)
func (MockAuthServer) GetHeadlessSession ¶ added in v0.1.25
func (m MockAuthServer) GetHeadlessSession(ctx context.Context, req *auth.GetHeadlessSessionRequest) (*auth.HeadlessSession, error)
func (MockAuthServer) Register ¶
func (m MockAuthServer) Register(ctx context.Context, req *auth.RegistrationRequest) (*auth.Session, error)