package service import ( "testing" "filefast/backend/internal/model" "filefast/backend/internal/store" ) func TestRegisterReusesKnownDeviceOnlyWithValidToken(t *testing.T) { memStore := store.NewMemoryStore(model.RuntimeConfig{}) deviceService := NewDeviceService(memStore, nil, nil) device, session := deviceService.Register(RegisterDeviceInput{ DeviceID: "known-device", Name: "Alpha", Type: "desktop", }, "ua/1.0", "") if device.ID != "known-device" { t.Fatalf("expected first registration to keep requested device id, got %q", device.ID) } if !deviceService.ValidateSession(device.ID, session.Token) { t.Fatal("expected issued device token to validate") } hijacked, hijackedSession := deviceService.Register(RegisterDeviceInput{ DeviceID: "known-device", Name: "Mallory", Type: "desktop", }, "ua/1.0", "") if hijacked.ID == device.ID { t.Fatal("expected registration without token to receive a new device id") } if !deviceService.ValidateSession(hijacked.ID, hijackedSession.Token) { t.Fatal("expected replacement device token to validate") } restored, rotatedSession := deviceService.Register(RegisterDeviceInput{ DeviceID: "known-device", Name: "Alpha", Type: "desktop", }, "ua/1.0", session.Token) if restored.ID != device.ID { t.Fatalf("expected valid token to reclaim original device id, got %q", restored.ID) } if rotatedSession.Token == session.Token { t.Fatal("expected registration to rotate the device token") } if deviceService.ValidateSession(restored.ID, session.Token) { t.Fatal("expected rotated token to invalidate the old token") } if !deviceService.ValidateSession(restored.ID, rotatedSession.Token) { t.Fatal("expected rotated device token to validate") } } func TestListCandidatesOnlyReturnsSameNetworkDevices(t *testing.T) { memStore := store.NewMemoryStore(model.RuntimeConfig{}) deviceService := NewDeviceService(memStore, nil, nil) current, _ := deviceService.Register(RegisterDeviceInput{ DeviceID: "current", Name: "Current", Type: "desktop", NetworkGroupKey: "192.168.1.10", }, "ua/1.0", "") sameNetwork, _ := deviceService.Register(RegisterDeviceInput{ DeviceID: "same-network", Name: "Same Network", Type: "phone", NetworkGroupKey: "192.168.1.10", }, "ua/1.0", "") _, _ = deviceService.Register(RegisterDeviceInput{ DeviceID: "other-network", Name: "Other Network", Type: "phone", NetworkGroupKey: "10.0.0.5", }, "ua/1.0", "") candidates := deviceService.ListCandidates(current.ID) if len(candidates) != 1 { t.Fatalf("expected 1 same-network candidate, got %d", len(candidates)) } if candidates[0].ID != sameNetwork.ID { t.Fatalf("expected candidate %q, got %q", sameNetwork.ID, candidates[0].ID) } } func TestListCandidatesReturnsEmptyWithoutNetworkGroupKey(t *testing.T) { memStore := store.NewMemoryStore(model.RuntimeConfig{}) deviceService := NewDeviceService(memStore, nil, nil) current, _ := deviceService.Register(RegisterDeviceInput{ DeviceID: "current", Name: "Current", Type: "desktop", }, "ua/1.0", "") _, _ = deviceService.Register(RegisterDeviceInput{ DeviceID: "same-network", Name: "Same Network", Type: "phone", NetworkGroupKey: "192.168.1.10", }, "ua/1.0", "") candidates := deviceService.ListCandidates(current.ID) if len(candidates) != 0 { t.Fatalf("expected no candidates without a local network group key, got %d", len(candidates)) } }