From 47d1280556f599b40d02335cce7279620c573112 Mon Sep 17 00:00:00 2001 From: Savely Krendelhoff Date: Fri, 22 Aug 2025 16:48:14 +0700 Subject: [PATCH] Set up testing framework and utilities --- docs/IMPLEMENTATION.md | 4 +-- go.mod | 2 ++ go.sum | 2 ++ internal/pow/test_utils.go | 63 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 go.sum create mode 100644 internal/pow/test_utils.go diff --git a/docs/IMPLEMENTATION.md b/docs/IMPLEMENTATION.md index a522ed7..87bab66 100644 --- a/docs/IMPLEMENTATION.md +++ b/docs/IMPLEMENTATION.md @@ -3,10 +3,10 @@ ## Phase 1: Proof of Work Package Implementation **Goal**: Create standalone, testable PoW package with HMAC-signed stateless challenges -- [ ] **Project Setup** +- [X] **Project Setup** - [X] Initialize Go module and basic project structure - [X] Create PoW challenge structure and types - - [ ] Set up testing framework and utilities + - [X] Set up testing framework and utilities - [ ] **Challenge Generation & HMAC Security** - [ ] Implement HMAC-signed challenge generation (stateless) diff --git a/go.mod b/go.mod index 54ac4fd..96cd041 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module word-of-wisdom go 1.24.3 + +require github.com/stretchr/testify v1.10.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7bfdabe --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= diff --git a/internal/pow/test_utils.go b/internal/pow/test_utils.go new file mode 100644 index 0000000..1cbe69a --- /dev/null +++ b/internal/pow/test_utils.go @@ -0,0 +1,63 @@ +package pow + +import ( + "crypto/rand" + "encoding/hex" + "time" +) + +// TestConfig returns a configuration suitable for testing +func TestConfig() *Config { + secret := make([]byte, 32) + rand.Read(secret) + + config, err := NewConfig( + WithHMACSecret(secret), + WithDefaultDifficulty(4), + WithRandomBytes(6), + ) + if err != nil { + panic("Failed to create test config: " + err.Error()) + } + return config +} + +// TestChallenge returns a valid challenge for testing +func TestChallenge() *Challenge { + return &Challenge{ + Timestamp: time.Now().Unix(), + Difficulty: 4, + Resource: "quotes", + Random: []byte{0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6}, + HMAC: nil, // To be filled by generator + } +} + +// TestSolution returns a valid solution for testing +func TestSolution() *Solution { + return &Solution{ + Challenge: *TestChallenge(), + Nonce: 42, + } +} + +// RandomHex generates a random hex string of given length +func RandomHex(length int) string { + bytes := make([]byte, length/2) + rand.Read(bytes) + return hex.EncodeToString(bytes) +} + +// ExpiredChallenge returns a challenge that has expired +func ExpiredChallenge() *Challenge { + challenge := TestChallenge() + challenge.Timestamp = time.Now().Add(-10 * time.Minute).Unix() + return challenge +} + +// FutureChallenge returns a challenge with future timestamp +func FutureChallenge() *Challenge { + challenge := TestChallenge() + challenge.Timestamp = time.Now().Add(10 * time.Minute).Unix() + return challenge +}