Files
apocapoc-api/internal/infrastructure/http/habit_entries_integration_test.go
T
david 1b69bec12f
CI/CD Pipeline / Test (push) Has been cancelled
CI/CD Pipeline / Lint (push) Has been cancelled
CI/CD Pipeline / Build and Push Docker Image (push) Has been cancelled
Fix integration tests to comply with password requirements
Update test passwords from 'password123' to 'Password123!' to meet security requirements (uppercase, lowercase, digit, special char).

Fix migrations test to match actual habit_entries schema (removed non-existent deleted_at column).
2025-11-27 23:38:36 +01:00

128 lines
3.4 KiB
Go

package http
import (
"net/http"
"testing"
"time"
)
func TestHabitEntriesFlow(t *testing.T) {
ts := setupTestServer(t)
defer ts.Close()
registerBody := RegisterRequest{
Email: "entryuser@example.com",
Password: "Password123!",
Timezone: "UTC",
}
rr := makeRequest(t, *ts.Router, "POST", "/api/v1/auth/register", registerBody, "")
var authResp AuthResponse
decodeResponse(t, rr, &authResp)
token := authResp.Token
habitBody := CreateHabitRequest{
Name: "Reading",
Type: "BOOLEAN",
Frequency: "DAILY",
}
rr = makeRequest(t, *ts.Router, "POST", "/api/v1/habits", habitBody, token)
var habitResp map[string]string
decodeResponse(t, rr, &habitResp)
habitID := habitResp["id"]
today := time.Now().UTC().Format("2006-01-02")
t.Run("Mark habit as complete", func(t *testing.T) {
reqBody := MarkHabitRequest{
ScheduledDate: today,
}
rr := makeRequest(t, *ts.Router, "POST", "/api/v1/habits/"+habitID+"/mark", reqBody, token)
if rr.Code != http.StatusOK {
t.Fatalf("Expected status 200, got %d. Body: %s", rr.Code, rr.Body.String())
}
})
t.Run("Mark habit twice returns conflict", func(t *testing.T) {
reqBody := MarkHabitRequest{
ScheduledDate: today,
}
rr := makeRequest(t, *ts.Router, "POST", "/api/v1/habits/"+habitID+"/mark", reqBody, token)
if rr.Code != http.StatusConflict {
t.Errorf("Expected status 409, got %d", rr.Code)
}
})
t.Run("Get habit entries", func(t *testing.T) {
rr := makeRequest(t, *ts.Router, "GET", "/api/v1/habits/"+habitID+"/entries?page=1&limit=10", nil, token)
if rr.Code != http.StatusOK {
t.Fatalf("Expected status 200, got %d", rr.Code)
}
var resp HabitEntriesResponse
decodeResponse(t, rr, &resp)
if resp.Total != 1 {
t.Errorf("Expected 1 entry, got %d", resp.Total)
}
if len(resp.Entries) != 1 {
t.Errorf("Expected 1 entry in array, got %d", len(resp.Entries))
}
})
t.Run("Unmark habit", func(t *testing.T) {
rr := makeRequest(t, *ts.Router, "DELETE", "/api/v1/habits/"+habitID+"/entries/"+today, nil, token)
if rr.Code != http.StatusOK {
t.Fatalf("Expected status 200, got %d. Body: %s", rr.Code, rr.Body.String())
}
rr = makeRequest(t, *ts.Router, "GET", "/api/v1/habits/"+habitID+"/entries?page=1&limit=10", nil, token)
var resp HabitEntriesResponse
decodeResponse(t, rr, &resp)
if resp.Total != 0 {
t.Errorf("Expected 0 entries after unmark, got %d", resp.Total)
}
})
t.Run("Mark with value for counter habit", func(t *testing.T) {
counterHabitBody := CreateHabitRequest{
Name: "Steps",
Type: "COUNTER",
Frequency: "DAILY",
}
rr := makeRequest(t, *ts.Router, "POST", "/api/v1/habits", counterHabitBody, token)
var counterResp map[string]string
decodeResponse(t, rr, &counterResp)
counterHabitID := counterResp["id"]
value := 10000.0
reqBody := MarkHabitRequest{
ScheduledDate: today,
Value: &value,
}
rr = makeRequest(t, *ts.Router, "POST", "/api/v1/habits/"+counterHabitID+"/mark", reqBody, token)
if rr.Code != http.StatusOK {
t.Fatalf("Expected status 200, got %d", rr.Code)
}
rr = makeRequest(t, *ts.Router, "GET", "/api/v1/habits/"+counterHabitID+"/entries?page=1&limit=10", nil, token)
var resp HabitEntriesResponse
decodeResponse(t, rr, &resp)
if resp.Entries[0].Value == nil {
t.Error("Expected value in entry")
} else if *resp.Entries[0].Value != 10000.0 {
t.Errorf("Expected value 10000, got %f", *resp.Entries[0].Value)
}
})
}