Files
bookhoard/cmd/server/tests/device_test_patterns_test.go
T
john-okeefe 80dcdfdd71 refactor(tests): rename test files and fix broken escalate test
Test file renames for clarity:
- phase1_example_test.go → device_test_patterns_test.go
- universal_progress_integration_test.go → setup_integration_test.go

Fix broken TestConflictsBulkEscalate test:
- Comment out test for non-existent /api/conflicts/bulk-escalate endpoint
- Remove unused imports (context, time, pgtype, httptest)
- Add explanatory comment about why test is disabled

Clean up test helper comment:
- Remove Phase 6 reference from test_helpers.go

These changes remove planning document terminology from filenames and
fix compilation errors caused by tests for unimplemented endpoints.
2026-02-13 21:50:03 -05:00

92 lines
3.4 KiB
Go

package main
import (
"bookhoard/internal/database"
"bookhoard/internal/handlers"
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestWithStructs demonstrates struct-based testing patterns
// BEFORE: map[string]interface{} -> AFTER: handlers.* structs
// BEFORE: No DB verification -> AFTER: Database verification
func TestWithStructs(t *testing.T) {
deviceSetup := setupDeviceTest(t)
token := deviceSetup.UserToken
// Create a device to test listing
device := deviceSetup.CreateDevice(t, "Test Device", "koreader", "test-device-struct-123")
t.Run("ListDevices with struct", func(t *testing.T) {
req := httptest.NewRequest("GET", "/api/devices", nil)
req.Header.Set("Authorization", "Bearer "+token)
rr := httptest.NewRecorder()
deviceSetup.Server.Config.Handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code, "Should list devices")
var response handlers.DeviceListResponse
err := json.Unmarshal(rr.Body.Bytes(), &response)
require.NoError(t, err, "Response should match DeviceListResponse schema")
assert.GreaterOrEqual(t, len(response.Devices), 1, "Should have at least one device")
firstDevice := response.Devices[0]
assert.Equal(t, device.Name, firstDevice.DeviceName, "Should match device name")
assert.Equal(t, device.Type, firstDevice.DeviceType, "Should match device type")
})
t.Run("UpdateDevice with struct and DB verification", func(t *testing.T) {
syncEnabled := false
syncFreq := int32(15)
updateRequest := map[string]interface{}{
"sync_enabled": &syncEnabled,
"sync_frequency_minutes": &syncFreq,
}
updateBody, _ := json.Marshal(updateRequest)
req := httptest.NewRequest("PUT", fmt.Sprintf("/api/devices/%s", device.ID), bytes.NewBuffer(updateBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
rr := httptest.NewRecorder()
deviceSetup.Server.Config.Handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code, "Should update device")
var response map[string]interface{}
err := json.Unmarshal(rr.Body.Bytes(), &response)
require.NoError(t, err, "Response should unmarshal")
assert.True(t, response["device_updated"].(bool), "Device should be updated")
// NEW: Database verification
pgDeviceID := pgtype.UUID{Bytes: [16]byte(device.ID), Valid: true}
updatedDevice, err := deviceSetup.DB.GetDevice(context.Background(), pgDeviceID)
require.NoError(t, err, "Device should exist in database after update")
assert.Equal(t, syncEnabled, updatedDevice.SyncEnabled.Bool, "DB: Sync should be disabled")
assert.Equal(t, syncFreq, updatedDevice.SyncFrequencyMinutes.Int32, "DB: Sync frequency should be updated")
})
}
// verifyDeviceUpdated is a helper function for database verification after device updates
func verifyDeviceUpdated(t *testing.T, db *database.Queries, deviceID uuid.UUID, syncEnabled bool, syncFreq int32) {
pgDeviceID := pgtype.UUID{Bytes: [16]byte(deviceID), Valid: true}
device, err := db.GetDevice(context.Background(), pgDeviceID)
require.NoError(t, err, "Device should exist in database")
assert.Equal(t, syncEnabled, device.SyncEnabled.Bool, "DB: Sync enabled should match")
assert.Equal(t, syncFreq, device.SyncFrequencyMinutes.Int32, "DB: Sync frequency should match")
}