Add integration tests for HTTP layer
- Create test server setup with in-memory SQLite - Add auth flow tests (register, login, validation) - Add habit CRUD tests (create, read, update, archive) - Add habit entries tests (mark, unmark, get entries) - Test authorization and cross-user access control
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user