diff --git a/.mockery.yaml b/.mockery.yaml new file mode 100644 index 0000000..0df4c1b --- /dev/null +++ b/.mockery.yaml @@ -0,0 +1,11 @@ +with-expecter: true +dir: "{{.InterfaceDir}}/mocks" +mockname: "Mock{{.InterfaceName}}" +outpkg: "{{.PackageName}}" +filename: "mock_{{.InterfaceName | snakecase}}.go" +packages: + github.com/word-of-wisdom/internal/pow: + interfaces: + Generator: + Verifier: + Solver: \ No newline at end of file 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..20b11df --- /dev/null +++ b/internal/pow/test_utils.go @@ -0,0 +1,65 @@ +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) + + return &Config{ + DefaultDifficulty: 4, + MaxDifficulty: 10, + MinDifficulty: 3, + ChallengeTTL: 5 * time.Minute, + HMACSecret: secret, + Resource: "quotes", + LoadAdjustmentBits: 1, + FailurePenaltyBits: 2, + MaxFailurePenaltyBits: 6, + } +} + +// TestChallenge returns a valid challenge for testing +func TestChallenge() *Challenge { + return &Challenge{ + Timestamp: time.Now().Unix(), + Difficulty: 4, + Resource: "quotes", + Random: "a1b2c3d4e5f6", + HMAC: "", // 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 +}