Add Go backend unit and handler tests; wire test step into CI
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>
This commit is contained in:
Christoph K.
2026-04-07 19:07:02 +02:00
parent d1649ddfce
commit 034d16e059
8 changed files with 893 additions and 6 deletions

View File

@@ -9,6 +9,9 @@ import (
"github.com/jacek/pamietnik/backend/internal/domain"
)
// Compile-time check: *db.TrackpointStore must satisfy db.TrackpointStorer.
var _ db.TrackpointStorer = (*db.TrackpointStore)(nil)
type trackpointInput struct {
EventID string `json:"event_id"`
DeviceID string `json:"device_id"`
@@ -56,7 +59,7 @@ type batchResponse struct {
}
// HandleSingleTrackpoint handles POST /v1/trackpoints
func HandleSingleTrackpoint(store *db.TrackpointStore) http.HandlerFunc {
func HandleSingleTrackpoint(store db.TrackpointStorer) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var input trackpointInput
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
@@ -86,7 +89,7 @@ func HandleSingleTrackpoint(store *db.TrackpointStore) http.HandlerFunc {
}
// HandleBatchTrackpoints handles POST /v1/trackpoints:batch
func HandleBatchTrackpoints(store *db.TrackpointStore) http.HandlerFunc {
func HandleBatchTrackpoints(store db.TrackpointStorer) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var inputs []trackpointInput
if err := json.NewDecoder(r.Body).Decode(&inputs); err != nil {