mirror of
https://github.com/rommapp/romm.git
synced 2026-02-18 00:27:41 +01:00
feat(devices): default to returning existing device on duplicate registration
Change allow_existing default to True so duplicate fingerprint matches return the existing device (200) instead of 409 Conflict. Add model validator to force allow_existing=False when allow_duplicate is set.
This commit is contained in:
@@ -2,7 +2,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fastapi import HTTPException, Request, Response, status
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, model_validator
|
||||
|
||||
from decorators.auth import protected_route
|
||||
from endpoints.responses.device import DeviceCreateResponse, DeviceSchema
|
||||
@@ -26,10 +26,16 @@ class DeviceCreatePayload(BaseModel):
|
||||
ip_address: str | None = None
|
||||
mac_address: str | None = None
|
||||
hostname: str | None = None
|
||||
allow_existing: bool = False
|
||||
allow_existing: bool = True
|
||||
allow_duplicate: bool = False
|
||||
reset_syncs: bool = False
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _duplicate_disables_existing(self) -> "DeviceCreatePayload":
|
||||
if self.allow_duplicate:
|
||||
self.allow_existing = False
|
||||
return self
|
||||
|
||||
|
||||
class DeviceUpdatePayload(BaseModel):
|
||||
name: str | None = None
|
||||
|
||||
@@ -282,7 +282,7 @@ class TestDeviceUserIsolation:
|
||||
|
||||
|
||||
class TestDeviceDuplicateHandling:
|
||||
def test_duplicate_mac_address_returns_409(
|
||||
def test_duplicate_mac_address_returns_existing(
|
||||
self, client, access_token: str, admin_user: User
|
||||
):
|
||||
db_device_handler.add_device(
|
||||
@@ -303,12 +303,12 @@ class TestDeviceDuplicateHandling:
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_409_CONFLICT
|
||||
data = response.json()["detail"]
|
||||
assert data["error"] == "device_exists"
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["device_id"] == "existing-mac-device"
|
||||
assert data["name"] == "Existing Device"
|
||||
|
||||
def test_duplicate_hostname_platform_returns_409(
|
||||
def test_duplicate_hostname_platform_returns_existing(
|
||||
self, client, access_token: str, admin_user: User
|
||||
):
|
||||
db_device_handler.add_device(
|
||||
@@ -331,10 +331,37 @@ class TestDeviceDuplicateHandling:
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
data = response.json()
|
||||
assert data["device_id"] == "existing-hostname-device"
|
||||
assert data["name"] == "Existing Device"
|
||||
|
||||
def test_duplicate_with_allow_existing_false_returns_409(
|
||||
self, client, access_token: str, admin_user: User
|
||||
):
|
||||
db_device_handler.add_device(
|
||||
Device(
|
||||
id="reject-duplicate-device",
|
||||
user_id=admin_user.id,
|
||||
name="Existing Device",
|
||||
mac_address="FF:EE:DD:CC:BB:AA",
|
||||
)
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
"/api/devices",
|
||||
json={
|
||||
"name": "New Device",
|
||||
"mac_address": "FF:EE:DD:CC:BB:AA",
|
||||
"allow_existing": False,
|
||||
},
|
||||
headers={"Authorization": f"Bearer {access_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_409_CONFLICT
|
||||
data = response.json()["detail"]
|
||||
assert data["error"] == "device_exists"
|
||||
assert data["device_id"] == "existing-hostname-device"
|
||||
assert data["device_id"] == "reject-duplicate-device"
|
||||
|
||||
def test_allow_existing_returns_existing_device(
|
||||
self, client, access_token: str, admin_user: User
|
||||
|
||||
Reference in New Issue
Block a user