hsa-app/internal/auth/pkce_test.go
Jean-Michel Tremblay 8b7252dad4 Initial commit: HSA receipt tracker
Go app for capturing and archiving HSA-eligible receipts: OIDC/PKCE auth
against Authelia, SQLite storage with dual-write (filesystem + DB blob),
mobile-first upload, and DB export.

Adds AI receipt classification: a config.json catalog of people and
categories (seeded into the DB on startup), a prompt builder that derives
name-order/initial variants from the data (with same-surname ambiguity
handling), and an Anthropic tool-use client behind POST /classify. Tests
run against a mock endpoint; a live integration test is env-gated to the
cheapest model.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 21:40:12 -04:00

54 lines
1.3 KiB
Go

package auth
import (
"strings"
"testing"
)
// RFC 7636 Appendix B known vector.
// verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
// expected challenge (S256) = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
const (
rfcVerifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
rfcChallenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
)
func TestChallengeS256_RFCVector(t *testing.T) {
got := ChallengeS256(rfcVerifier)
if got != rfcChallenge {
t.Errorf("ChallengeS256(%q) = %q, want %q", rfcVerifier, got, rfcChallenge)
}
}
func TestGenerateVerifier_Length(t *testing.T) {
v, err := GenerateVerifier()
if err != nil {
t.Fatal(err)
}
if len(v) < 43 || len(v) > 128 {
t.Errorf("verifier length %d outside [43,128]", len(v))
}
}
func TestGenerateVerifier_URLSafe(t *testing.T) {
for range 20 {
v, err := GenerateVerifier()
if err != nil {
t.Fatal(err)
}
for _, c := range v {
if !strings.ContainsRune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~", c) {
t.Errorf("verifier %q contains non-URL-safe char %q", v, c)
break
}
}
}
}
func TestGenerateVerifier_Unique(t *testing.T) {
a, _ := GenerateVerifier()
b, _ := GenerateVerifier()
if a == b {
t.Error("two calls returned the same verifier")
}
}