Add Go backend unit and handler tests; wire test step into CI
Some checks failed
Deploy to NAS / deploy (push) Failing after 14s
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:
93
backend/internal/db/trackpoints_test.go
Normal file
93
backend/internal/db/trackpoints_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jacek/pamietnik/backend/internal/domain"
|
||||
)
|
||||
|
||||
func TestValidateTrackpoint_HappyPath(t *testing.T) {
|
||||
p := domain.Trackpoint{
|
||||
EventID: "evt-1",
|
||||
DeviceID: "dev-1",
|
||||
Lat: 52.5,
|
||||
Lon: 13.4,
|
||||
Source: "gps",
|
||||
}
|
||||
if err := validateTrackpoint(p); err != nil {
|
||||
t.Fatalf("expected no error, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTrackpoint_MissingEventID(t *testing.T) {
|
||||
p := domain.Trackpoint{
|
||||
DeviceID: "dev-1",
|
||||
Lat: 52.5,
|
||||
Lon: 13.4,
|
||||
}
|
||||
err := validateTrackpoint(p)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for missing event_id, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTrackpoint_MissingDeviceID(t *testing.T) {
|
||||
p := domain.Trackpoint{
|
||||
EventID: "evt-1",
|
||||
Lat: 52.5,
|
||||
Lon: 13.4,
|
||||
}
|
||||
err := validateTrackpoint(p)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for missing device_id, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTrackpoint_LatOutOfRange(t *testing.T) {
|
||||
cases := []struct {
|
||||
lat float64
|
||||
lon float64
|
||||
}{
|
||||
{91, 0},
|
||||
{-91, 0},
|
||||
{0, 181},
|
||||
{0, -181},
|
||||
}
|
||||
for _, c := range cases {
|
||||
p := domain.Trackpoint{
|
||||
EventID: "evt-1",
|
||||
DeviceID: "dev-1",
|
||||
Lat: c.lat,
|
||||
Lon: c.lon,
|
||||
}
|
||||
if err := validateTrackpoint(p); err == nil {
|
||||
t.Errorf("expected error for lat=%v lon=%v, got nil", c.lat, c.lon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTrackpoint_InvalidSource(t *testing.T) {
|
||||
p := domain.Trackpoint{
|
||||
EventID: "evt-1",
|
||||
DeviceID: "dev-1",
|
||||
Lat: 10,
|
||||
Lon: 10,
|
||||
Source: "satellite",
|
||||
}
|
||||
if err := validateTrackpoint(p); err == nil {
|
||||
t.Fatal("expected error for invalid source, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTrackpoint_EmptySourceIsAllowed(t *testing.T) {
|
||||
p := domain.Trackpoint{
|
||||
EventID: "evt-1",
|
||||
DeviceID: "dev-1",
|
||||
Lat: 10,
|
||||
Lon: 10,
|
||||
Source: "",
|
||||
}
|
||||
if err := validateTrackpoint(p); err != nil {
|
||||
t.Fatalf("empty source should be allowed, got: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user