From 03871b4462013a92949e278a1250d8f56d35edbc Mon Sep 17 00:00:00 2001 From: Xavier Bustamante Talavera Date: Thu, 18 Oct 2018 10:09:10 +0200 Subject: [PATCH] Fix tags not added to device search --- ereuse_devicehub/resources/device/models.py | 4 +++ ereuse_devicehub/resources/device/search.py | 29 ++++++++++++--------- ereuse_devicehub/resources/device/sync.py | 2 +- tests/test_device.py | 22 ---------------- tests/test_device_find.py | 16 ++++++++++++ tests/test_event.py | 15 ++++++++--- tests/test_rate.py | 2 +- tests/test_rate_workbench_v1.py | 10 +++---- tests/test_tag.py | 14 ++++++++-- 9 files changed, 68 insertions(+), 46 deletions(-) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index cc57ed74..d59eab1c 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -226,6 +226,10 @@ class Computer(Device): id = Column(BigInteger, ForeignKey(Device.id), primary_key=True) chassis = Column(DBEnum(ComputerChassis), nullable=False) + def __init__(self, chassis, **kwargs) -> None: + chassis = ComputerChassis(chassis) + super().__init__(chassis=chassis, **kwargs) + @property def events(self) -> list: return sorted(chain(super().events, self.events_parent), key=attrgetter('created')) diff --git a/ereuse_devicehub/resources/device/search.py b/ereuse_devicehub/resources/device/search.py index 8d330bfc..defd7cb7 100644 --- a/ereuse_devicehub/resources/device/search.py +++ b/ereuse_devicehub/resources/device/search.py @@ -1,3 +1,5 @@ +from itertools import chain + import inflection from sqlalchemy.dialects import postgresql from sqlalchemy.dialects.postgresql import TSVECTOR @@ -37,21 +39,24 @@ class DeviceSearch(db.Model): @classmethod def update_modified_devices(cls, session: db.Session): - """Updates the documents of the devices that are part of a modified - event in the passed-in session. + """Updates the documents of the devices that are part of a + modified event, or tag in the passed-in session. - This method is registered as a SQLAlchemy - listener in the Devicehub class. + This method is registered as a SQLAlchemy listener in the + Devicehub class. """ devices_to_update = set() - for event in (e for e in session.new if isinstance(e, Event)): - if isinstance(event, EventWithMultipleDevices): - devices_to_update |= event.devices - elif isinstance(event, EventWithOneDevice): - devices_to_update.add(event.device) - if event.parent: - devices_to_update.add(event.parent) - devices_to_update |= event.components + for model in chain(session.new, session.dirty): + if isinstance(model, Event): + if isinstance(model, EventWithMultipleDevices): + devices_to_update |= model.devices + elif isinstance(model, EventWithOneDevice): + devices_to_update.add(model.device) + if model.parent: + devices_to_update.add(model.parent) + devices_to_update |= model.components + elif isinstance(model, Tag) and model.device: + devices_to_update.add(model.device) # this flush is controversial: # see https://groups.google.com/forum/#!topic/sqlalchemy/hBzfypgPfYo diff --git a/ereuse_devicehub/resources/device/sync.py b/ereuse_devicehub/resources/device/sync.py index 7f883ab1..156b8734 100644 --- a/ereuse_devicehub/resources/device/sync.py +++ b/ereuse_devicehub/resources/device/sync.py @@ -229,7 +229,7 @@ class Sync: if adding: # For the components we are adding, let's remove them from their old parents def g_parent(component: Component) -> Device: - return component.parent or Computer(id=0) # Computer with id 0 is our Identity + return component.parent or Device(id=0) # Computer with id 0 is our Identity for parent, _components in groupby(sorted(adding, key=g_parent), key=g_parent): if parent.id != 0: # Is not Computer Identity diff --git a/tests/test_device.py b/tests/test_device.py index a630f490..2ea2d9e1 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -18,7 +18,6 @@ from ereuse_devicehub.resources.device.exceptions import NeedsId from ereuse_devicehub.resources.device.models import Component, ComputerMonitor, DataStorage, \ Desktop, Device, GraphicCard, Laptop, Motherboard, NetworkAdapter from ereuse_devicehub.resources.device.schemas import Device as DeviceS -from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.device.sync import MismatchBetweenTags, MismatchBetweenTagsAndHid, \ Sync from ereuse_devicehub.resources.enums import ComputerChassis, DisplayTech @@ -474,20 +473,6 @@ def test_computer_with_display(): pass -def test_device_search_all_devices_token_if_empty(app: Devicehub, user: UserClient): - """Ensures DeviceSearch can regenerate itself when the table is empty.""" - user.post(file('basic.snapshot'), res=m.Snapshot) - with app.app_context(): - app.db.session.execute('TRUNCATE TABLE {}'.format(DeviceSearch.__table__.name)) - app.db.session.commit() - i, _ = user.get(res=Device, query=[('search', 'Desktop')]) - assert not len(i['items']) - with app.app_context(): - DeviceSearch.set_all_devices_tokens_if_empty(app.db.session) - i, _ = user.get(res=Device, query=[('search', 'Desktop')]) - assert not len(i['items']) - - def test_manufacturer(user: UserClient): m, r = user.get(res='Manufacturer', query=[('name', 'asus')]) assert m == {'items': [{'name': 'Asus', 'url': 'https://en.wikipedia.org/wiki/Asus'}]} @@ -528,10 +513,3 @@ def test_device_public(user: UserClient, client: Client): html, _ = client.get(res=Device, item=s['device']['id'], accept=ANY) assert 'intel atom cpu n270 @ 1.60ghz' in html assert 'S/N 00:24:8C:7F:CF:2D – 100 Mbps' in html - - -@pytest.mark.xfail(reason='Functionality not yet developed.') -def test_device_search_multiple_tags(user: UserClient): - """Ensures that users can search multiple tags at once - and get their multiple devices.""" - pass diff --git a/tests/test_device_find.py b/tests/test_device_find.py index 484957ae..e5fd3807 100644 --- a/tests/test_device_find.py +++ b/tests/test_device_find.py @@ -6,6 +6,7 @@ from ereuse_devicehub.db import db from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.resources.device.models import Desktop, Device, Laptop, Processor, \ SolidStateDrive +from ereuse_devicehub.resources.device.search import DeviceSearch from ereuse_devicehub.resources.device.views import Filters, Sorting from ereuse_devicehub.resources.enums import ComputerChassis from ereuse_devicehub.resources.event.models import Snapshot @@ -174,6 +175,21 @@ def test_device_lots_query(user: UserClient): pass +def test_device_search_all_devices_token_if_empty(app: Devicehub, user: UserClient): + """Ensures DeviceSearch can regenerate itself when the table is empty.""" + user.post(file('basic.snapshot'), res=Snapshot) + with app.app_context(): + app.db.session.execute('TRUNCATE TABLE {}'.format(DeviceSearch.__table__.name)) + app.db.session.commit() + i, _ = user.get(res=Device, query=[('search', 'Desktop')]) + assert not len(i['items']) + with app.app_context(): + DeviceSearch.set_all_devices_tokens_if_empty(app.db.session) + app.db.session.commit() + i, _ = user.get(res=Device, query=[('search', 'Desktop')]) + assert i['items'] + + def test_device_query_search(user: UserClient): # todo improve user.post(file('basic.snapshot'), res=Snapshot) diff --git a/tests/test_event.py b/tests/test_event.py index 79f52d53..687bb34f 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -112,7 +112,10 @@ def test_install(): @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_update_components_event_one(): - computer = Desktop(serial_number='sn1', model='ml1', manufacturer='mr1') + computer = Desktop(serial_number='sn1', + model='ml1', + manufacturer='mr1', + chassis=ComputerChassis.Tower) hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar') computer.components.add(hdd) @@ -137,7 +140,10 @@ def test_update_components_event_one(): @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_update_components_event_multiple(): - computer = Desktop(serial_number='sn1', model='ml1', manufacturer='mr1') + computer = Desktop(serial_number='sn1', + model='ml1', + manufacturer='mr1', + chassis=ComputerChassis.Tower) hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar') computer.components.add(hdd) @@ -163,7 +169,10 @@ def test_update_components_event_multiple(): @pytest.mark.usefixtures(conftest.auth_app_context.__name__) def test_update_parent(): - computer = Desktop(serial_number='sn1', model='ml1', manufacturer='mr1') + computer = Desktop(serial_number='sn1', + model='ml1', + manufacturer='mr1', + chassis=ComputerChassis.Tower) hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar') computer.components.add(hdd) diff --git a/tests/test_rate.py b/tests/test_rate.py index 99a9420b..7f66cff4 100644 --- a/tests/test_rate.py +++ b/tests/test_rate.py @@ -51,7 +51,7 @@ def test_rate(): appearance_range=AppearanceRange.A, functionality_range=FunctionalityRange.A ) - pc = Desktop() + pc = Desktop(chassis=ComputerChassis.Tower) hdd = HardDrive(size=476940) hdd.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8)) cpu = Processor(cores=2, speed=3.4) diff --git a/tests/test_rate_workbench_v1.py b/tests/test_rate_workbench_v1.py index a078e797..da4a0a09 100644 --- a/tests/test_rate_workbench_v1.py +++ b/tests/test_rate_workbench_v1.py @@ -15,7 +15,7 @@ Excluded cases in tests import pytest from ereuse_devicehub.resources.device.models import Desktop, HardDrive, Processor, RamModule -from ereuse_devicehub.resources.enums import AppearanceRange, FunctionalityRange +from ereuse_devicehub.resources.enums import AppearanceRange, ComputerChassis, FunctionalityRange from ereuse_devicehub.resources.event.models import BenchmarkDataStorage, BenchmarkProcessor, \ WorkbenchRate from ereuse_devicehub.resources.event.rate.workbench.v1_0 import DataStorageRate, ProcessorRate, \ @@ -307,7 +307,7 @@ def test_rate_computer_rate(): """ # Create a new Computer with components characteristics of pc with id = 1193 - pc_test = Desktop() + pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=476940) data_storage.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8)) cpu = Processor(cores=2, speed=3.4) @@ -333,7 +333,7 @@ def test_rate_computer_rate(): assert round(rate_pc.rating, 2) == 4.61 # Create a new Computer with components characteristics of pc with id = 1201 - pc_test = Desktop() + pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=476940) data_storage.events_one.add(BenchmarkDataStorage(read_speed=158, write_speed=34.7)) cpu = Processor(cores=2, speed=3.3) @@ -358,7 +358,7 @@ def test_rate_computer_rate(): assert round(rate_pc.rating, 2) == 3.48 # Create a new Computer with components characteristics of pc with id = 79 - pc_test = Desktop() + pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=76319) data_storage.events_one.add(BenchmarkDataStorage(read_speed=72.2, write_speed=24.3)) cpu = Processor(cores=1, speed=1.6) @@ -386,7 +386,7 @@ def test_rate_computer_rate(): assert round(rate_pc.rating, 2) == 1.58 # Create a new Computer with components characteristics of pc with id = 798 - pc_test = Desktop() + pc_test = Desktop(chassis=ComputerChassis.Tower) data_storage = HardDrive(size=152587) data_storage.events_one.add(BenchmarkDataStorage(read_speed=78.1, write_speed=24.4)) cpu = Processor(cores=2, speed=2.5) diff --git a/tests/test_tag.py b/tests/test_tag.py index e20c2a7c..476cdd18 100644 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -155,8 +155,11 @@ def test_tag_create_etags_cli(app: Devicehub, user: UserClient): assert tag.provider == URL('https://t.ereuse.org') -def test_tag_manual_link(app: Devicehub, user: UserClient): - """Tests linking manually a tag through PUT /tags//device/""" +def test_tag_manual_link_search(app: Devicehub, user: UserClient): + """Tests linking manually a tag through PUT /tags//device/ + + Checks search has the term. + """ with app.app_context(): db.session.add(Tag('foo-bar', secondary='foo-sec')) desktop = Desktop(serial_number='foo', chassis=ComputerChassis.AllInOne) @@ -179,6 +182,13 @@ def test_tag_manual_link(app: Devicehub, user: UserClient): # cannot link to another device when already linked user.put({}, res=Tag, item='foo-bar/device/99', status=LinkedToAnotherDevice) + i, _ = user.get(res=Device, query=[('search', 'foo-bar')]) + assert i['items'] + i, _ = user.get(res=Device, query=[('search', 'foo-sec')]) + assert i['items'] + i, _ = user.get(res=Device, query=[('search', 'foo')]) + assert i['items'] + @pytest.mark.usefixtures(conftest.app_context.__name__) def test_tag_secondary_workbench_link_find(user: UserClient):