Some checks failed
Deploy to NAS / deploy (push) Failing after 14s
- Introduce store interfaces (TrackpointStorer, StopStorer, SuggestionStorer) in internal/db/interfaces.go so handlers can be tested without a real DB. - Refactor HandleSingleTrackpoint, HandleBatchTrackpoints, HandleListDays, HandleListTrackpoints, HandleListStops, HandleListSuggestions to accept the new interfaces instead of concrete *db.*Store pointers (no behaviour change; concrete types satisfy the interfaces implicitly). - internal/api/ingest_test.go: 13 handler tests covering happy path, invalid JSON, invalid timestamp, missing event_id/device_id, out-of-range lat/lon, empty/oversized batch, store errors, and idempotency (single + batch). - internal/api/query_test.go: 14 handler tests covering missing query params (400) and empty-result-is-array guarantees for all four query endpoints. - internal/auth/auth_test.go: 5 unit tests for HashPassword / VerifyPassword (correct password, wrong password, empty password, malformed hash, salt uniqueness). - internal/db/trackpoints_test.go: 6 unit tests for the validateTrackpoint helper (happy path, missing fields, coordinate bounds, invalid source). - .gitea/workflows/deploy.yml: add "Test" step (go test ./...) before "Build & Deploy" so a failing test aborts the deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
1.6 KiB
Go
66 lines
1.6 KiB
Go
package auth
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestHashPassword_ProducesVerifiableHash(t *testing.T) {
|
|
hash, err := HashPassword("secret")
|
|
if err != nil {
|
|
t.Fatalf("HashPassword returned error: %v", err)
|
|
}
|
|
if hash == "" {
|
|
t.Fatal("HashPassword returned empty string")
|
|
}
|
|
if !VerifyPassword("secret", hash) {
|
|
t.Error("VerifyPassword returned false for correct password")
|
|
}
|
|
}
|
|
|
|
func TestHashPassword_TwoCallsProduceDifferentHashes(t *testing.T) {
|
|
h1, err1 := HashPassword("secret")
|
|
h2, err2 := HashPassword("secret")
|
|
if err1 != nil || err2 != nil {
|
|
t.Fatalf("HashPassword error: %v / %v", err1, err2)
|
|
}
|
|
// Different salts → different hashes
|
|
if h1 == h2 {
|
|
t.Error("expected distinct hashes for same password (due to random salt), got identical")
|
|
}
|
|
}
|
|
|
|
func TestVerifyPassword_WrongPassword(t *testing.T) {
|
|
hash, err := HashPassword("correct")
|
|
if err != nil {
|
|
t.Fatalf("HashPassword error: %v", err)
|
|
}
|
|
if VerifyPassword("wrong", hash) {
|
|
t.Error("VerifyPassword returned true for wrong password")
|
|
}
|
|
}
|
|
|
|
func TestVerifyPassword_EmptyPassword(t *testing.T) {
|
|
hash, err := HashPassword("notempty")
|
|
if err != nil {
|
|
t.Fatalf("HashPassword error: %v", err)
|
|
}
|
|
if VerifyPassword("", hash) {
|
|
t.Error("VerifyPassword returned true for empty password against non-empty hash")
|
|
}
|
|
}
|
|
|
|
func TestVerifyPassword_MalformedHash(t *testing.T) {
|
|
cases := []string{
|
|
"",
|
|
"notahash",
|
|
"$wrongalgo$aabb$ccdd",
|
|
"$argon2id$nothex$ccdd",
|
|
"$argon2id$aabb$nothex",
|
|
}
|
|
for _, h := range cases {
|
|
if VerifyPassword("secret", h) {
|
|
t.Errorf("VerifyPassword should return false for malformed hash %q", h)
|
|
}
|
|
}
|
|
}
|