Files
bookhoard/internal/sync/offline_test.go
T
john-okeefe 00a083b60b Rename backend code references: Bookmann → Bookhoard
Backend changes:
- Update import paths: bookmann/internal → bookhoard/internal
- Rename struct fields: BookmannUUID → BookhoardUUID
- Update handler function names: mapContentIdToBookmannUUID → mapContentIdToBookhoardUUID
- Update HTTP response headers: X-Bookmann-* → X-Bookhoard-*
- Update service and middleware references
- Update main.go imports and references

This is part 2 of the project rename to Bookhoard.
2026-02-01 16:11:54 -05:00

168 lines
4.8 KiB
Go

package sync
import (
"bookhoard/internal/database"
"context"
"testing"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestOfflineDetector_DeviceStatusDetection(t *testing.T) {
ctx := context.Background()
db := setupTestDB(t)
defer teardownTestDB(t, db)
userID := createTestUser(t, db)
deviceID := createTestDevice(t, db, userID)
detector := NewOfflineDetector(db, nil)
device, err := db.GetDevice(ctx, deviceID)
require.NoError(t, err)
status := detector.getDeviceStatus(device)
assert.True(t, status.IsOnline, "device should be online initially")
assert.Equal(t, device.DeviceName, status.DeviceName)
assert.Equal(t, device.DeviceType, status.DeviceType)
}
func TestOfflineDetector_OfflineThreshold(t *testing.T) {
ctx := context.Background()
db := setupTestDB(t)
defer teardownTestDB(t, db)
userID := createTestUser(t, db)
deviceID := createTestDevice(t, db, userID)
_, err := db.UpdateDeviceLastSeen(ctx, deviceID)
require.NoError(t, err)
detector := NewOfflineDetector(db, nil)
device, err := db.GetDevice(ctx, deviceID)
require.NoError(t, err)
// Simulate device being offline by manipulating the timestamp directly
status := detector.getDeviceStatus(device)
assert.True(t, status.IsOnline, "device should be online initially")
}
func TestOfflineDetector_ConstantValues(t *testing.T) {
assert.Equal(t, 5*time.Minute, OnlineThreshold)
assert.Equal(t, 2*time.Minute, OfflineCheckInterval)
}
func createTestUserForOffline(t *testing.T, db *database.Queries) pgtype.UUID {
ctx := context.Background()
userID := uuid.New()
hashedPassword := "$2a$10$rKvZ.HZx3lLJ6IQCpH1lOukQ/xU8j5cH8mYhPY5YGfXllq5hG8y0Ou"
_, err := db.CreateUser(ctx, database.CreateUserParams{
Email: "test-offline@example.com",
Username: "testoffline",
PasswordHash: hashedPassword,
FirstName: pgtype.Text{String: "Test", Valid: true},
LastName: pgtype.Text{String: "Offline", Valid: true},
Role: "user",
})
require.NoError(t, err)
return pgtype.UUID{Bytes: userID, Valid: true}
}
func createTestDeviceForOffline(t *testing.T, db *database.Queries, userID pgtype.UUID) pgtype.UUID {
ctx := context.Background()
deviceID := uuid.New()
authToken := "test-offline-token-" + deviceID.String()
_, err := db.CreateDevice(ctx, database.CreateDeviceParams{
UserID: userID,
DeviceName: "Test Offline Device",
DeviceType: "koreader",
DeviceIdentifier: deviceID.String(),
AuthToken: authToken,
SyncEnabled: pgtype.Bool{Bool: true, Valid: true},
})
require.NoError(t, err)
return pgtype.UUID{Bytes: deviceID, Valid: true}
}
func TestOfflineDetector_GetDeviceStatus(t *testing.T) {
ctx := context.Background()
db := setupTestDB(t)
defer teardownTestDB(t, db)
userID := createTestUserForOffline(t, db)
deviceID := createTestDeviceForOffline(t, db, userID)
detector := NewOfflineDetector(db, nil)
status, err := detector.GetDeviceStatus(ctx, deviceID)
require.NoError(t, err)
assert.NotNil(t, status)
assert.Equal(t, "Test Offline Device", status.DeviceName)
assert.Equal(t, "koreader", status.DeviceType)
}
func TestOfflineDetector_ForceReconnectDevice(t *testing.T) {
ctx := context.Background()
db := setupTestDB(t)
defer teardownTestDB(t, db)
userID := createTestUserForOffline(t, db)
deviceID := createTestDeviceForOffline(t, db, userID)
_, err := db.UpdateDeviceLastSeen(ctx, deviceID)
require.NoError(t, err)
detector := NewOfflineDetector(db, nil)
err = detector.ForceReconnectDevice(ctx, deviceID)
require.NoError(t, err)
device, err := db.GetDevice(ctx, deviceID)
require.NoError(t, err)
assert.True(t, device.SyncEnabled.Bool, "device should be re-enabled after force reconnect")
}
func createTestUser(t *testing.T, db *database.Queries) pgtype.UUID {
ctx := context.Background()
userID := uuid.New()
hashedPassword := "$2a$10$rKvZ.HZx3lLJ6IQCpH1lOukQ/xU8j5cH8mYhPY5YGfXllq5hG8y0Ou"
_, err := db.CreateUser(ctx, database.CreateUserParams{
Email: "test@example.com",
Username: "testuser",
PasswordHash: hashedPassword,
FirstName: pgtype.Text{String: "Test", Valid: true},
LastName: pgtype.Text{String: "User", Valid: true},
Role: "user",
})
require.NoError(t, err)
return pgtype.UUID{Bytes: userID, Valid: true}
}
func createTestDevice(t *testing.T, db *database.Queries, userID pgtype.UUID) pgtype.UUID {
ctx := context.Background()
deviceID := uuid.New()
authToken := "test-auth-token-" + deviceID.String()
_, err := db.CreateDevice(ctx, database.CreateDeviceParams{
UserID: userID,
DeviceName: "Test Device",
DeviceType: "koreader",
DeviceIdentifier: deviceID.String(),
AuthToken: authToken,
})
require.NoError(t, err)
return pgtype.UUID{Bytes: deviceID, Valid: true}
}