diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 5cf37afe..39ab0cf2 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -76,7 +76,11 @@ class Device(Thing): 'parent_id', 'hid', 'production_date', - 'color' + 'color', # these are only user-input thus volatile + 'width', + 'height', + 'depth', + 'weight' } def __init__(self, **kw) -> None: diff --git a/ereuse_devicehub/resources/device/sync.py b/ereuse_devicehub/resources/device/sync.py index 156b8734..07c238e2 100644 --- a/ereuse_devicehub/resources/device/sync.py +++ b/ereuse_devicehub/resources/device/sync.py @@ -1,7 +1,9 @@ +import difflib from contextlib import suppress from itertools import groupby from typing import Iterable, Set +import yaml from sqlalchemy import inspect from sqlalchemy.exc import IntegrityError from sqlalchemy.util import OrderedSet @@ -166,11 +168,16 @@ class Sync: sample_tag = next(iter(linked_tags)) for tag in linked_tags: if tag.device_id != sample_tag.device_id: - raise MismatchBetweenTags(tag, sample_tag) # Linked to different devices + raise MismatchBetweenTags(tag, sample_tag) # Tags linked to different devices if db_device: # Device from hid if sample_tag.device_id != db_device.id: # Device from hid != device from tags raise MismatchBetweenTagsAndHid(db_device.id, db_device.hid) else: # There was no device from hid + if sample_tag.device.physical_properties != device.physical_properties: + # Incoming physical props of device != props from tag's device + # which means that the devices are not the same + raise MismatchBetweenProperties(sample_tag.device.physical_properties, + device.physical_properties) db_device = sample_tag.device if db_device: # Device from hid or tags self.merge(device, db_device) @@ -254,3 +261,12 @@ class MismatchBetweenTagsAndHid(ValidationError): message = 'Tags are linked to device {} but hid refers to device {}.'.format(device_id, hid) super().__init__(message, field_names) + + +class MismatchBetweenProperties(ValidationError): + def __init__(self, props1, props2, field_names={'device'}): + message = 'The device from the tag and the passed-in differ the following way:' + message += '\n'.join( + difflib.ndiff(yaml.dump(props1).splitlines(), yaml.dump(props2).splitlines()) + ) + super().__init__(message, field_names) diff --git a/tests/test_device.py b/tests/test_device.py index 3eeb7adb..d8a5d87f 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -116,19 +116,11 @@ def test_physical_properties(): 'serial': None, 'firewire': None, 'manufacturer': 'mr', - 'weight': None, - 'height': None, - 'width': 2.0, - 'depth': None } assert pc.physical_properties == { 'model': 'foo', 'manufacturer': 'bar', 'serial_number': 'foo-bar', - 'weight': 2.8, - 'width': 1.4, - 'height': 2.1, - 'depth': None, 'chassis': ComputerChassis.Tower } diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py index 2e8ad343..8dde37ba 100644 --- a/tests/test_snapshot.py +++ b/tests/test_snapshot.py @@ -12,7 +12,8 @@ from ereuse_devicehub.db import db from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.device import models as m from ereuse_devicehub.resources.device.exceptions import NeedsId -from ereuse_devicehub.resources.device.sync import MismatchBetweenTagsAndHid +from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \ + MismatchBetweenTagsAndHid from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware from ereuse_devicehub.resources.event.models import AggregateRate, BenchmarkProcessor, \ EraseSectors, Event, Snapshot, SnapshotRequest, WorkbenchRate @@ -246,10 +247,8 @@ def test_snapshot_tag_inner_tag_mismatch_between_tags_and_hid(user: UserClient, user.post(pc2, res=Snapshot, status=MismatchBetweenTagsAndHid) -@pytest.mark.xfail(reason='There is no attribute checking for tag-matching devices') def test_snapshot_different_properties_same_tags(user: UserClient, tag_id: str): - """ - Tests a snapshot performed to device 1 with tag A and then to + """Tests a snapshot performed to device 1 with tag A and then to device 2 with tag B. Both don't have HID but are different type. Devicehub must fail the Snapshot. """ @@ -262,9 +261,9 @@ def test_snapshot_different_properties_same_tags(user: UserClient, tag_id: str): pc2 = file('basic.snapshot') pc2['uuid'] = uuid4() pc2['device']['tags'] = pc1['device']['tags'] - del pc2['device'][ - 'model'] # pc2 model is unknown but pc1 model is set = different characteristic - user.post(pc2, res=Snapshot, status=422) + # pc2 model is unknown but pc1 model is set = different property + del pc2['device']['model'] + user.post(pc2, res=Snapshot, status=MismatchBetweenProperties) def test_snapshot_upload_twice_uuid_error(user: UserClient):