Merge remote-tracking branch 'origin/master' into reports
This commit is contained in:
commit
cad0b64125
|
@ -17,6 +17,12 @@
|
||||||
"elapsed": 19,
|
"elapsed": 19,
|
||||||
"rate": 19.3106,
|
"rate": 19.3106,
|
||||||
"type": "BenchmarkRamSysbench"
|
"type": "BenchmarkRamSysbench"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearanceRange": "A",
|
||||||
|
"biosRange": "A",
|
||||||
|
"functionalityRange": "A",
|
||||||
|
"type": "WorkbenchRate"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"manufacturer": "ASUSTeK Computer INC."
|
"manufacturer": "ASUSTeK Computer INC."
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
"error": false,
|
"error": false,
|
||||||
"type": "StressTest",
|
"type": "StressTest",
|
||||||
"elapsed": 60
|
"elapsed": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearanceRange": "A",
|
||||||
|
"biosRange": "A",
|
||||||
|
"functionalityRange": "A",
|
||||||
|
"type": "WorkbenchRate"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "Desktop",
|
"type": "Desktop",
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
type: Snapshot
|
||||||
|
version: '1.0'
|
||||||
|
software: Web
|
||||||
|
device:
|
||||||
|
type: Keyboard
|
||||||
|
model: FOO
|
||||||
|
serialNumber: BAR
|
||||||
|
manufacturer: BAZ
|
||||||
|
layout: ES
|
||||||
|
events:
|
||||||
|
- type: ManualRate
|
||||||
|
appearanceRange: A
|
||||||
|
functionalityRange: A
|
||||||
|
labelling: False
|
|
@ -14,6 +14,12 @@
|
||||||
"rate": 0.9323,
|
"rate": 0.9323,
|
||||||
"elapsed": 1,
|
"elapsed": 1,
|
||||||
"type": "BenchmarkRamSysbench"
|
"type": "BenchmarkRamSysbench"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearanceRange": "B",
|
||||||
|
"biosRange": "A",
|
||||||
|
"functionalityRange": "C",
|
||||||
|
"type": "WorkbenchRate"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"type": "Desktop",
|
"type": "Desktop",
|
||||||
|
|
|
@ -145,6 +145,12 @@
|
||||||
"type": "StressTest",
|
"type": "StressTest",
|
||||||
"error": false,
|
"error": false,
|
||||||
"elapsed": 60
|
"elapsed": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearanceRange": "B",
|
||||||
|
"biosRange": "C",
|
||||||
|
"functionalityRange": "A",
|
||||||
|
"type": "WorkbenchRate"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -148,6 +148,12 @@
|
||||||
"rate": 0.9759,
|
"rate": 0.9759,
|
||||||
"type": "BenchmarkRamSysbench",
|
"type": "BenchmarkRamSysbench",
|
||||||
"elapsed": 1
|
"elapsed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearanceRange": "B",
|
||||||
|
"biosRange": "A",
|
||||||
|
"functionalityRange": "D",
|
||||||
|
"type": "WorkbenchRate"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"serialNumber": "CZC0408YJG",
|
"serialNumber": "CZC0408YJG",
|
||||||
|
|
|
@ -161,6 +161,121 @@ class DisplayDef(ComponentDef):
|
||||||
SCHEMA = schemas.Display
|
SCHEMA = schemas.Display
|
||||||
|
|
||||||
|
|
||||||
|
class ComputerAccessoryDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.ComputerAccessory
|
||||||
|
|
||||||
|
def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None,
|
||||||
|
template_folder=None, url_prefix=None, subdomain=None, url_defaults=None,
|
||||||
|
root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
|
||||||
|
class MouseDef(ComputerAccessoryDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Mouse
|
||||||
|
|
||||||
|
|
||||||
|
class KeyboardDef(ComputerAccessoryDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Keyboard
|
||||||
|
|
||||||
|
|
||||||
|
class SAIDef(ComputerAccessoryDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.SAI
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryCardReaderDef(ComputerAccessoryDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.MemoryCardReader
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkingDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Networking
|
||||||
|
|
||||||
|
def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None,
|
||||||
|
template_folder=None, url_prefix=None, subdomain=None, url_defaults=None,
|
||||||
|
root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
|
||||||
|
class RouterDef(NetworkingDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Router
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchDef(NetworkingDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Switch
|
||||||
|
|
||||||
|
|
||||||
|
class HubDef(NetworkingDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Hub
|
||||||
|
|
||||||
|
|
||||||
|
class WirelessAccessPointDef(NetworkingDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.WirelessAccessPoint
|
||||||
|
|
||||||
|
|
||||||
|
class PrinterDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Printer
|
||||||
|
|
||||||
|
def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None,
|
||||||
|
template_folder=None, url_prefix=None, subdomain=None, url_defaults=None,
|
||||||
|
root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
|
||||||
|
class LabelPrinterDef(PrinterDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.LabelPrinter
|
||||||
|
|
||||||
|
|
||||||
|
class SoundDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Sound
|
||||||
|
|
||||||
|
def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None,
|
||||||
|
template_folder=None, url_prefix=None, subdomain=None, url_defaults=None,
|
||||||
|
root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
|
||||||
|
class MicrophoneDef(SoundDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Microphone
|
||||||
|
|
||||||
|
|
||||||
|
class VideoDef(DeviceDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Video
|
||||||
|
|
||||||
|
def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None,
|
||||||
|
template_folder=None, url_prefix=None, subdomain=None, url_defaults=None,
|
||||||
|
root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()):
|
||||||
|
super().__init__(app, import_name, static_folder, static_url_path, template_folder,
|
||||||
|
url_prefix, subdomain, url_defaults, root_path, cli_commands)
|
||||||
|
|
||||||
|
|
||||||
|
class VideoScalerDef(VideoDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.VideoScaler
|
||||||
|
|
||||||
|
|
||||||
|
class VideoconferenceDef(VideoDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.Videoconference
|
||||||
|
|
||||||
|
|
||||||
class ManufacturerDef(Resource):
|
class ManufacturerDef(Resource):
|
||||||
VIEW = ManufacturerView
|
VIEW = ManufacturerView
|
||||||
SCHEMA = schemas.Manufacturer
|
SCHEMA = schemas.Manufacturer
|
||||||
|
|
|
@ -17,12 +17,13 @@ from sqlalchemy_utils import ColorType
|
||||||
from stdnum import imei, meid
|
from stdnum import imei, meid
|
||||||
from teal.db import CASCADE, POLYMORPHIC_ID, POLYMORPHIC_ON, ResourceNotFound, URL, check_lower, \
|
from teal.db import CASCADE, POLYMORPHIC_ID, POLYMORPHIC_ON, ResourceNotFound, URL, check_lower, \
|
||||||
check_range
|
check_range
|
||||||
|
from teal.enums import Layouts
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
from teal.resource import url_for_resource
|
from teal.resource import url_for_resource
|
||||||
|
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
||||||
DataStoragePrivacyCompliance, DisplayTech, RamFormat, RamInterface
|
DataStoragePrivacyCompliance, DisplayTech, PrinterTechnology, RamFormat, RamInterface
|
||||||
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
|
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +63,19 @@ class Device(Thing):
|
||||||
"""
|
"""
|
||||||
color = Column(ColorType)
|
color = Column(ColorType)
|
||||||
color.comment = """The predominant color of the device."""
|
color.comment = """The predominant color of the device."""
|
||||||
|
production_date = Column(db.TIMESTAMP(timezone=True))
|
||||||
|
production_date.comment = """The date of production of the item."""
|
||||||
|
|
||||||
|
_NON_PHYSICAL_PROPS = {
|
||||||
|
'id',
|
||||||
|
'type',
|
||||||
|
'created',
|
||||||
|
'updated',
|
||||||
|
'parent_id',
|
||||||
|
'hid',
|
||||||
|
'production_date',
|
||||||
|
'color'
|
||||||
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def events(self) -> list:
|
def events(self) -> list:
|
||||||
|
@ -94,7 +108,7 @@ class Device(Thing):
|
||||||
for c in inspect(self.__class__).attrs
|
for c in inspect(self.__class__).attrs
|
||||||
if isinstance(c, ColumnProperty)
|
if isinstance(c, ColumnProperty)
|
||||||
and not getattr(c, 'foreign_keys', None)
|
and not getattr(c, 'foreign_keys', None)
|
||||||
and c.key not in {'id', 'type', 'created', 'updated', 'parent_id', 'hid'}}
|
and c.key not in self._NON_PHYSICAL_PROPS}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self) -> urlutils.URL:
|
def url(self) -> urlutils.URL:
|
||||||
|
@ -194,6 +208,11 @@ class Device(Thing):
|
||||||
|
|
||||||
|
|
||||||
class DisplayMixin:
|
class DisplayMixin:
|
||||||
|
"""
|
||||||
|
Aspect ratio can be computed as in
|
||||||
|
https://github.com/mirukan/whratio/blob/master/whratio/ratio.py and
|
||||||
|
could be a future property.
|
||||||
|
"""
|
||||||
size = Column(Float(decimal_return_scale=2), check_range('size', 2, 150))
|
size = Column(Float(decimal_return_scale=2), check_range('size', 2, 150))
|
||||||
size.comment = """
|
size.comment = """
|
||||||
The size of the monitor in inches.
|
The size of the monitor in inches.
|
||||||
|
@ -212,6 +231,10 @@ class DisplayMixin:
|
||||||
The maximum vertical resolution the monitor can natively support
|
The maximum vertical resolution the monitor can natively support
|
||||||
in pixels.
|
in pixels.
|
||||||
"""
|
"""
|
||||||
|
refresh_rate = Column(SmallInteger, check_range('refresh_rate', 10, 1000))
|
||||||
|
contrast_ratio = Column(SmallInteger, check_range('contrast_ratio', 100, 100000))
|
||||||
|
touchable = Column(Boolean, nullable=False, default=False)
|
||||||
|
touchable.comment = """Whether it is a touchscreen."""
|
||||||
|
|
||||||
def __format__(self, format_spec: str) -> str:
|
def __format__(self, format_spec: str) -> str:
|
||||||
v = ''
|
v = ''
|
||||||
|
@ -226,6 +249,10 @@ class Computer(Device):
|
||||||
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
chassis = Column(DBEnum(ComputerChassis), nullable=False)
|
chassis = Column(DBEnum(ComputerChassis), nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, chassis, **kwargs) -> None:
|
||||||
|
chassis = ComputerChassis(chassis)
|
||||||
|
super().__init__(chassis=chassis, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def events(self) -> list:
|
def events(self) -> list:
|
||||||
return sorted(chain(super().events, self.events_parent), key=attrgetter('created'))
|
return sorted(chain(super().events, self.events_parent), key=attrgetter('created'))
|
||||||
|
@ -285,7 +312,9 @@ class Desktop(Computer):
|
||||||
|
|
||||||
|
|
||||||
class Laptop(Computer):
|
class Laptop(Computer):
|
||||||
pass
|
layout = Column(DBEnum(Layouts))
|
||||||
|
layout.comment = """Layout of a built-in keyboard of the computer,
|
||||||
|
if any."""
|
||||||
|
|
||||||
|
|
||||||
class Server(Computer):
|
class Server(Computer):
|
||||||
|
@ -304,6 +333,10 @@ class TelevisionSet(Monitor):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Projector(Monitor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Mobile(Device):
|
class Mobile(Device):
|
||||||
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
imei = Column(BigInteger)
|
imei = Column(BigInteger)
|
||||||
|
@ -479,6 +512,83 @@ class Display(JoinedComponentTableMixin, DisplayMixin, Component):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ComputerAccessory(Device):
|
||||||
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SAI(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Keyboard(ComputerAccessory):
|
||||||
|
layout = Column(DBEnum(Layouts)) # If we want to do it not null
|
||||||
|
|
||||||
|
|
||||||
|
class Mouse(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryCardReader(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Networking(NetworkMixin, Device):
|
||||||
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Router(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Switch(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Hub(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class WirelessAccessPoint(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Printer(Device):
|
||||||
|
id = Column(BigInteger, ForeignKey(Device.id), primary_key=True)
|
||||||
|
wireless = Column(Boolean, nullable=False, default=False)
|
||||||
|
wireless.comment = """Whether it is a wireless printer."""
|
||||||
|
scanning = Column(Boolean, nullable=False, default=False)
|
||||||
|
scanning.comment = """Whether the printer has scanning capabilities."""
|
||||||
|
technology = Column(DBEnum(PrinterTechnology))
|
||||||
|
technology.comment = """Technology used to print."""
|
||||||
|
monochrome = Column(Boolean, nullable=False, default=True)
|
||||||
|
monochrome.comment = """Whether the printer is only monochrome."""
|
||||||
|
|
||||||
|
|
||||||
|
class LabelPrinter(Printer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Sound(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Microphone(Sound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Video(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VideoScaler(Video):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Videoconference(Video):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Manufacturer(db.Model):
|
class Manufacturer(db.Model):
|
||||||
__table_args__ = {'schema': 'common'}
|
__table_args__ = {'schema': 'common'}
|
||||||
CSV_DELIMITER = csv.get_dialect('excel').delimiter
|
CSV_DELIMITER = csv.get_dialect('excel').delimiter
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from datetime import datetime
|
||||||
from typing import Dict, List, Set, Type, Union
|
from typing import Dict, List, Set, Type, Union
|
||||||
|
|
||||||
from boltons import urlutils
|
from boltons import urlutils
|
||||||
|
@ -6,11 +7,12 @@ from colour import Color
|
||||||
from sqlalchemy import Column, Integer
|
from sqlalchemy import Column, Integer
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from teal.db import Model
|
from teal.db import Model
|
||||||
|
from teal.enums import Layouts
|
||||||
|
|
||||||
from ereuse_devicehub.resources.agent.models import Agent
|
from ereuse_devicehub.resources.agent.models import Agent
|
||||||
from ereuse_devicehub.resources.device import states
|
from ereuse_devicehub.resources.device import states
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
||||||
DataStoragePrivacyCompliance, DisplayTech, RamFormat, RamInterface
|
DataStoragePrivacyCompliance, DisplayTech, PrinterTechnology, RamFormat, RamInterface
|
||||||
from ereuse_devicehub.resources.event import models as e
|
from ereuse_devicehub.resources.event import models as e
|
||||||
from ereuse_devicehub.resources.image.models import ImageList
|
from ereuse_devicehub.resources.image.models import ImageList
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
|
@ -31,6 +33,7 @@ class Device(Thing):
|
||||||
depth = ... # type: Column
|
depth = ... # type: Column
|
||||||
color = ... # type: Column
|
color = ... # type: Column
|
||||||
lots = ... # type: relationship
|
lots = ... # type: relationship
|
||||||
|
production_date = ... # type: Column
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs) -> None:
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
@ -52,6 +55,7 @@ class Device(Thing):
|
||||||
self.images = ... # type: ImageList
|
self.images = ... # type: ImageList
|
||||||
self.tags = ... # type: Set[Tag]
|
self.tags = ... # type: Set[Tag]
|
||||||
self.lots = ... # type: Set[Lot]
|
self.lots = ... # type: Set[Lot]
|
||||||
|
self.production_date = ... # type: datetime
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self) -> urlutils.URL:
|
def url(self) -> urlutils.URL:
|
||||||
|
@ -86,6 +90,9 @@ class DisplayMixin:
|
||||||
size = ... # type: Column
|
size = ... # type: Column
|
||||||
resolution_width = ... # type: Column
|
resolution_width = ... # type: Column
|
||||||
resolution_height = ... # type: Column
|
resolution_height = ... # type: Column
|
||||||
|
refresh_rate = ... # type: Column
|
||||||
|
contrast_ratio = ... # type: Column
|
||||||
|
touchable = ... # type: Column
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -93,6 +100,9 @@ class DisplayMixin:
|
||||||
self.size = ... # type: Integer
|
self.size = ... # type: Integer
|
||||||
self.resolution_width = ... # type: int
|
self.resolution_width = ... # type: int
|
||||||
self.resolution_height = ... # type: int
|
self.resolution_height = ... # type: int
|
||||||
|
self.refresh_rate = ... # type: int
|
||||||
|
self.contrast_ratio = ... # type: int
|
||||||
|
self.touchable = ... # type: bool
|
||||||
|
|
||||||
|
|
||||||
class Computer(DisplayMixin, Device):
|
class Computer(DisplayMixin, Device):
|
||||||
|
@ -135,7 +145,11 @@ class Desktop(Computer):
|
||||||
|
|
||||||
|
|
||||||
class Laptop(Computer):
|
class Laptop(Computer):
|
||||||
pass
|
layout = ... # type: Column
|
||||||
|
|
||||||
|
def __init__(self, **kwargs) -> None:
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.layout = ... # type: Layouts
|
||||||
|
|
||||||
|
|
||||||
class Server(Computer):
|
class Server(Computer):
|
||||||
|
@ -233,12 +247,18 @@ class Motherboard(Component):
|
||||||
self.pcmcia = ... # type: int
|
self.pcmcia = ... # type: int
|
||||||
|
|
||||||
|
|
||||||
class NetworkAdapter(Component):
|
class NetworkMixin:
|
||||||
speed = ... # type: Column
|
speed = ... # type: Column
|
||||||
|
wireless = ... # type: Column
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs) -> None:
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.speed = ... # type: int
|
self.speed = ... # type: int
|
||||||
|
self.wireless = ... # type: bool
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAdapter(NetworkMixin, Component):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Processor(Component):
|
class Processor(Component):
|
||||||
|
@ -271,6 +291,88 @@ class Display(DisplayMixin, Component):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ComputerAccessory(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SAI(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Keyboard(ComputerAccessory):
|
||||||
|
layout = ... # type: Column
|
||||||
|
|
||||||
|
def __init__(self, layout: Layouts, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.layout = ... # type: Layouts
|
||||||
|
|
||||||
|
|
||||||
|
class Mouse(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryCardReader(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Networking(NetworkMixin, Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Router(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Switch(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Hub(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class WirelessAccessPoint(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Printer(Device):
|
||||||
|
wireless = ... # type: Column
|
||||||
|
scanning = ... # type: Column
|
||||||
|
technology = ... # type: Column
|
||||||
|
monochrome = ... # type: Column
|
||||||
|
|
||||||
|
def __init__(self, **kwargs) -> None:
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.wireless = ... # type: bool
|
||||||
|
self.scanning = ... # type: bool
|
||||||
|
self.technology = ... # type: PrinterTechnology
|
||||||
|
self.monochrome = ... # type: bool
|
||||||
|
|
||||||
|
|
||||||
|
class LabelPrinter(Printer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Sound(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Microphone(Sound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Video(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VideoScaler(Video):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Videoconference(Video):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Manufacturer(Model):
|
class Manufacturer(Model):
|
||||||
CUSTOM_MANUFACTURERS = ... # type: set
|
CUSTOM_MANUFACTURERS = ... # type: set
|
||||||
name = ... # type: Column
|
name = ... # type: Column
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
from marshmallow import post_load, pre_load
|
from marshmallow import post_load, pre_load
|
||||||
from marshmallow.fields import Boolean, Float, Integer, List, Str, String
|
from marshmallow.fields import Boolean, DateTime, Float, Integer, List, Str, String
|
||||||
from marshmallow.validate import Length, OneOf, Range
|
from marshmallow.validate import Length, OneOf, Range
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
from stdnum import imei, meid
|
from stdnum import imei, meid
|
||||||
|
from teal.enums import Layouts
|
||||||
from teal.marshmallow import EnumField, SanitizedStr, URL, ValidationError
|
from teal.marshmallow import EnumField, SanitizedStr, URL, ValidationError
|
||||||
from teal.resource import Schema
|
from teal.resource import Schema
|
||||||
|
|
||||||
from ereuse_devicehub.marshmallow import NestedOn
|
from ereuse_devicehub.marshmallow import NestedOn
|
||||||
from ereuse_devicehub.resources.device import models as m, states
|
from ereuse_devicehub.resources.device import models as m, states
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
from ereuse_devicehub.resources.enums import ComputerChassis, DataStorageInterface, \
|
||||||
DataStoragePrivacyCompliance, DisplayTech, RamFormat, RamInterface
|
DataStoragePrivacyCompliance, DisplayTech, PrinterTechnology, RamFormat, RamInterface
|
||||||
from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE
|
from ereuse_devicehub.resources.models import STR_BIG_SIZE, STR_SIZE
|
||||||
from ereuse_devicehub.resources.schemas import Thing, UnitCodes
|
from ereuse_devicehub.resources.schemas import Thing, UnitCodes
|
||||||
|
|
||||||
|
@ -40,6 +41,9 @@ class Device(Thing):
|
||||||
trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__)
|
trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__)
|
||||||
physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__)
|
physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__)
|
||||||
physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor')
|
physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor')
|
||||||
|
production_date = DateTime('iso',
|
||||||
|
description=m.Device.updated.comment,
|
||||||
|
data_key='productionDate')
|
||||||
|
|
||||||
@pre_load
|
@pre_load
|
||||||
def from_events_to_events_one(self, data: dict):
|
def from_events_to_events_one(self, data: dict):
|
||||||
|
@ -98,6 +102,9 @@ class DisplayMixin:
|
||||||
resolution_height = Integer(data_key='resolutionHeight',
|
resolution_height = Integer(data_key='resolutionHeight',
|
||||||
validate=Range(10, 20000),
|
validate=Range(10, 20000),
|
||||||
description=m.DisplayMixin.resolution_height.comment)
|
description=m.DisplayMixin.resolution_height.comment)
|
||||||
|
refresh_rate = Integer(data_key='refreshRate', validate=Range(10, 1000))
|
||||||
|
contrast_ratio = Integer(data_key='contrastRatio', validate=Range(100, 100000))
|
||||||
|
touchable = Boolean(missing=False, description=m.DisplayMixin.touchable.comment)
|
||||||
|
|
||||||
|
|
||||||
class NetworkMixin:
|
class NetworkMixin:
|
||||||
|
@ -212,3 +219,74 @@ class Manufacturer(Schema):
|
||||||
name = String(dump_only=True)
|
name = String(dump_only=True)
|
||||||
url = URL(dump_only=True)
|
url = URL(dump_only=True)
|
||||||
logo = URL(dump_only=True)
|
logo = URL(dump_only=True)
|
||||||
|
|
||||||
|
|
||||||
|
class ComputerAccessory(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Mouse(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryCardReader(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SAI(ComputerAccessory):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Keyboard(ComputerAccessory):
|
||||||
|
layout = EnumField(Layouts)
|
||||||
|
|
||||||
|
|
||||||
|
class Networking(NetworkMixin, Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Router(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Switch(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Hub(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class WirelessAccessPoint(Networking):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Printer(Device):
|
||||||
|
wireless = Boolean(required=True, missing=False)
|
||||||
|
scanning = Boolean(required=True, missing=False)
|
||||||
|
technology = EnumField(PrinterTechnology, required=True)
|
||||||
|
monochrome = Boolean(required=True, missing=True)
|
||||||
|
|
||||||
|
|
||||||
|
class LabelPrinter(Printer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Sound(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Microphone(Sound):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Video(Device):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VideoScaler(Video):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Videoconference(Video):
|
||||||
|
pass
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
import inflection
|
import inflection
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
from sqlalchemy.dialects.postgresql import TSVECTOR
|
from sqlalchemy.dialects.postgresql import TSVECTOR
|
||||||
|
@ -37,21 +39,24 @@ class DeviceSearch(db.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_modified_devices(cls, session: db.Session):
|
def update_modified_devices(cls, session: db.Session):
|
||||||
"""Updates the documents of the devices that are part of a modified
|
"""Updates the documents of the devices that are part of a
|
||||||
event in the passed-in session.
|
modified event, or tag in the passed-in session.
|
||||||
|
|
||||||
This method is registered as a SQLAlchemy
|
This method is registered as a SQLAlchemy listener in the
|
||||||
listener in the Devicehub class.
|
Devicehub class.
|
||||||
"""
|
"""
|
||||||
devices_to_update = set()
|
devices_to_update = set()
|
||||||
for event in (e for e in session.new if isinstance(e, Event)):
|
for model in chain(session.new, session.dirty):
|
||||||
if isinstance(event, EventWithMultipleDevices):
|
if isinstance(model, Event):
|
||||||
devices_to_update |= event.devices
|
if isinstance(model, EventWithMultipleDevices):
|
||||||
elif isinstance(event, EventWithOneDevice):
|
devices_to_update |= model.devices
|
||||||
devices_to_update.add(event.device)
|
elif isinstance(model, EventWithOneDevice):
|
||||||
if event.parent:
|
devices_to_update.add(model.device)
|
||||||
devices_to_update.add(event.parent)
|
if model.parent:
|
||||||
devices_to_update |= event.components
|
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:
|
# this flush is controversial:
|
||||||
# see https://groups.google.com/forum/#!topic/sqlalchemy/hBzfypgPfYo
|
# see https://groups.google.com/forum/#!topic/sqlalchemy/hBzfypgPfYo
|
||||||
|
|
|
@ -229,7 +229,7 @@ class Sync:
|
||||||
if adding:
|
if adding:
|
||||||
# For the components we are adding, let's remove them from their old parents
|
# For the components we are adding, let's remove them from their old parents
|
||||||
def g_parent(component: Component) -> Device:
|
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):
|
for parent, _components in groupby(sorted(adding, key=g_parent), key=g_parent):
|
||||||
if parent.id != 0: # Is not Computer Identity
|
if parent.id != 0: # Is not Computer Identity
|
||||||
|
|
|
@ -234,15 +234,15 @@ class DeviceRow(OrderedDict):
|
||||||
|
|
||||||
class ManufacturerView(View):
|
class ManufacturerView(View):
|
||||||
class FindArgs(marshmallow.Schema):
|
class FindArgs(marshmallow.Schema):
|
||||||
name = marshmallow.fields.Str(required=True,
|
search = marshmallow.fields.Str(required=True,
|
||||||
# Disallow like operators
|
# Disallow like operators
|
||||||
validate=lambda x: '%' not in x and '_' not in x)
|
validate=lambda x: '%' not in x and '_' not in x)
|
||||||
|
|
||||||
@cache(datetime.timedelta(days=1))
|
@cache(datetime.timedelta(days=1))
|
||||||
def find(self, args: dict):
|
def find(self, args: dict):
|
||||||
name = args['name']
|
search = args['search']
|
||||||
manufacturers = Manufacturer.query \
|
manufacturers = Manufacturer.query \
|
||||||
.filter(Manufacturer.name.ilike(name + '%')) \
|
.filter(Manufacturer.name.ilike(search + '%')) \
|
||||||
.paginate(page=1, per_page=6) # type: Pagination
|
.paginate(page=1, per_page=6) # type: Pagination
|
||||||
return jsonify(
|
return jsonify(
|
||||||
items=app.resources[Manufacturer.t].schema.dump(
|
items=app.resources[Manufacturer.t].schema.dump(
|
||||||
|
|
|
@ -276,3 +276,12 @@ class DataStoragePrivacyCompliance(Enum):
|
||||||
return cls.EraseSectors if not erasure.error else cls.EraseSectorsError
|
return cls.EraseSectors if not erasure.error else cls.EraseSectorsError
|
||||||
else:
|
else:
|
||||||
return cls.EraseBasic if not erasure.error else cls.EraseBasicError
|
return cls.EraseBasic if not erasure.error else cls.EraseBasicError
|
||||||
|
|
||||||
|
|
||||||
|
class PrinterTechnology(Enum):
|
||||||
|
"""Technology of the printer."""
|
||||||
|
Toner = 'Toner / Laser'
|
||||||
|
Inkjet = 'Liquid inkjet'
|
||||||
|
SolidInk = 'Solid ink'
|
||||||
|
Dye = 'Dye-sublimation'
|
||||||
|
Thermal = 'Thermal'
|
||||||
|
|
|
@ -4,7 +4,7 @@ from enum import Enum
|
||||||
from typing import List, Set
|
from typing import List, Set
|
||||||
|
|
||||||
import marshmallow as ma
|
import marshmallow as ma
|
||||||
from flask import jsonify, request
|
from flask import Response, jsonify, request
|
||||||
from marshmallow import Schema as MarshmallowSchema, fields as f
|
from marshmallow import Schema as MarshmallowSchema, fields as f
|
||||||
from teal.marshmallow import EnumField
|
from teal.marshmallow import EnumField
|
||||||
from teal.resource import View
|
from teal.resource import View
|
||||||
|
@ -36,6 +36,14 @@ class LotView(View):
|
||||||
ret.status_code = 201
|
ret.status_code = 201
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def patch(self, id):
|
||||||
|
l = request.get_json()
|
||||||
|
lot = Lot.query.filter_by(id=id).one()
|
||||||
|
for key, value in l.items():
|
||||||
|
setattr(lot, key, value)
|
||||||
|
db.session.commit()
|
||||||
|
return Response(status=204)
|
||||||
|
|
||||||
def one(self, id: uuid.UUID):
|
def one(self, id: uuid.UUID):
|
||||||
"""Gets one event."""
|
"""Gets one event."""
|
||||||
lot = Lot.query.filter_by(id=id).one() # type: Lot
|
lot = Lot.query.filter_by(id=id).one() # type: Lot
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from sqlalchemy import Column
|
from datetime import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import Column
|
||||||
from teal.db import Model
|
from teal.db import Model
|
||||||
|
|
||||||
STR_SIZE = 64
|
STR_SIZE = 64
|
||||||
|
@ -13,3 +14,8 @@ class Thing(Model):
|
||||||
type = ... # type: str
|
type = ... # type: str
|
||||||
updated = ... # type: Column
|
updated = ... # type: Column
|
||||||
created = ... # type: Column
|
created = ... # type: Column
|
||||||
|
|
||||||
|
def __init__(self, **kwargs) -> None:
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.updated = ... # type: datetime
|
||||||
|
self.created = ... # type: datetime
|
||||||
|
|
|
@ -22,8 +22,8 @@ class UnitCodes(Enum):
|
||||||
class Thing(Schema):
|
class Thing(Schema):
|
||||||
type = String(description='Only required when it is nested.')
|
type = String(description='Only required when it is nested.')
|
||||||
same_as = List(URL(dump_only=True), dump_only=True, data_key='sameAs')
|
same_as = List(URL(dump_only=True), dump_only=True, data_key='sameAs')
|
||||||
updated = DateTime('iso', dump_only=True, description=m.Thing.updated.comment.strip())
|
updated = DateTime('iso', dump_only=True, description=m.Thing.updated.comment)
|
||||||
created = DateTime('iso', dump_only=True, description=m.Thing.created.comment.strip())
|
created = DateTime('iso', dump_only=True, description=m.Thing.created.comment)
|
||||||
|
|
||||||
@post_load
|
@post_load
|
||||||
def remove_type(self, data: dict):
|
def remove_type(self, data: dict):
|
||||||
|
|
|
@ -25,7 +25,7 @@ requests==2.19.1
|
||||||
requests-mock==1.5.2
|
requests-mock==1.5.2
|
||||||
SQLAlchemy==1.2.11
|
SQLAlchemy==1.2.11
|
||||||
SQLAlchemy-Utils==0.33.3
|
SQLAlchemy-Utils==0.33.3
|
||||||
teal==0.2.0a25
|
teal==0.2.0a26
|
||||||
webargs==4.0.0
|
webargs==4.0.0
|
||||||
Werkzeug==0.14.1
|
Werkzeug==0.14.1
|
||||||
sqlalchemy-citext==1.3.post0
|
sqlalchemy-citext==1.3.post0
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -34,7 +34,7 @@ setup(
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'teal>=0.2.0a25', # teal always first
|
'teal>=0.2.0a26', # teal always first
|
||||||
'click',
|
'click',
|
||||||
'click-spinner',
|
'click-spinner',
|
||||||
'ereuse-utils[Naming]>=0.4b9',
|
'ereuse-utils[Naming]>=0.4b9',
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../ereuse_devicehub/dummy/files/keyboard.snapshot.yaml
|
|
@ -40,4 +40,4 @@ def test_api_docs(client: Client):
|
||||||
'scheme': 'basic',
|
'scheme': 'basic',
|
||||||
'name': 'Authorization'
|
'name': 'Authorization'
|
||||||
}
|
}
|
||||||
assert 75 == len(docs['definitions'])
|
assert 92 == len(docs['definitions'])
|
||||||
|
|
|
@ -9,16 +9,15 @@ from ereuse_utils.test import ANY
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
from teal.db import ResourceNotFound
|
from teal.db import ResourceNotFound
|
||||||
|
from teal.enums import Layouts
|
||||||
|
|
||||||
from ereuse_devicehub.client import Client, UserClient
|
from ereuse_devicehub.client import Client, UserClient
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.devicehub import Devicehub
|
from ereuse_devicehub.devicehub import Devicehub
|
||||||
from ereuse_devicehub.resources.agent.models import Person
|
from ereuse_devicehub.resources.agent.models import Person
|
||||||
|
from ereuse_devicehub.resources.device import models as d
|
||||||
from ereuse_devicehub.resources.device.exceptions import NeedsId
|
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.schemas import Device as DeviceS
|
||||||
from ereuse_devicehub.resources.device.search import DeviceSearch
|
|
||||||
from ereuse_devicehub.resources.device.sync import MismatchBetweenTags, MismatchBetweenTagsAndHid, \
|
from ereuse_devicehub.resources.device.sync import MismatchBetweenTags, MismatchBetweenTagsAndHid, \
|
||||||
Sync
|
Sync
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis, DisplayTech
|
from ereuse_devicehub.resources.enums import ComputerChassis, DisplayTech
|
||||||
|
@ -35,43 +34,43 @@ def test_device_model():
|
||||||
"""
|
"""
|
||||||
Tests that the correctness of the device model and its relationships.
|
Tests that the correctness of the device model and its relationships.
|
||||||
"""
|
"""
|
||||||
pc = Desktop(model='p1mo',
|
pc = d.Desktop(model='p1mo',
|
||||||
manufacturer='p1ma',
|
manufacturer='p1ma',
|
||||||
serial_number='p1s',
|
serial_number='p1s',
|
||||||
chassis=ComputerChassis.Tower)
|
chassis=ComputerChassis.Tower)
|
||||||
net = NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s')
|
net = d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s')
|
||||||
graphic = GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
graphic = d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
||||||
pc.components.add(net)
|
pc.components.add(net)
|
||||||
pc.components.add(graphic)
|
pc.components.add(graphic)
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
pc = Desktop.query.one()
|
pc = d.Desktop.query.one()
|
||||||
assert pc.serial_number == 'p1s'
|
assert pc.serial_number == 'p1s'
|
||||||
assert pc.components == OrderedSet([net, graphic])
|
assert pc.components == OrderedSet([net, graphic])
|
||||||
network_adapter = NetworkAdapter.query.one()
|
network_adapter = d.NetworkAdapter.query.one()
|
||||||
assert network_adapter.parent == pc
|
assert network_adapter.parent == pc
|
||||||
|
|
||||||
# Removing a component from pc doesn't delete the component
|
# Removing a component from pc doesn't delete the component
|
||||||
pc.components.remove(net)
|
pc.components.remove(net)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
pc = Device.query.first() # this is the same as querying for Desktop directly
|
pc = d.Device.query.first() # this is the same as querying for d.Desktop directly
|
||||||
assert pc.components == {graphic}
|
assert pc.components == {graphic}
|
||||||
network_adapter = NetworkAdapter.query.one()
|
network_adapter = d.NetworkAdapter.query.one()
|
||||||
assert network_adapter not in pc.components
|
assert network_adapter not in pc.components
|
||||||
assert network_adapter.parent is None
|
assert network_adapter.parent is None
|
||||||
|
|
||||||
# Deleting the pc deletes everything
|
# Deleting the pc deletes everything
|
||||||
gcard = GraphicCard.query.one()
|
gcard = d.GraphicCard.query.one()
|
||||||
db.session.delete(pc)
|
db.session.delete(pc)
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
assert pc.id == 1
|
assert pc.id == 1
|
||||||
assert Desktop.query.first() is None
|
assert d.Desktop.query.first() is None
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
assert Desktop.query.first() is None
|
assert d.Desktop.query.first() is None
|
||||||
assert network_adapter.id == 2
|
assert network_adapter.id == 2
|
||||||
assert NetworkAdapter.query.first() is not None, 'We removed the network adaptor'
|
assert d.NetworkAdapter.query.first() is not None, 'We removed the network adaptor'
|
||||||
assert gcard.id == 3, 'We should still hold a reference to a zombie graphic card'
|
assert gcard.id == 3, 'We should still hold a reference to a zombie graphic card'
|
||||||
assert GraphicCard.query.first() is None, 'We should have deleted it –it was inside the pc'
|
assert d.GraphicCard.query.first() is None, 'We should have deleted it –it was inside the pc'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
@ -79,19 +78,19 @@ def test_device_schema():
|
||||||
"""Ensures the user does not upload non-writable or extra fields."""
|
"""Ensures the user does not upload non-writable or extra fields."""
|
||||||
device_s = DeviceS()
|
device_s = DeviceS()
|
||||||
device_s.load({'serialNumber': 'foo1', 'model': 'foo', 'manufacturer': 'bar2'})
|
device_s.load({'serialNumber': 'foo1', 'model': 'foo', 'manufacturer': 'bar2'})
|
||||||
device_s.dump(Device(id=1))
|
device_s.dump(d.Device(id=1))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_physical_properties():
|
def test_physical_properties():
|
||||||
c = Motherboard(slots=2,
|
c = d.Motherboard(slots=2,
|
||||||
usb=3,
|
usb=3,
|
||||||
serial_number='sn',
|
serial_number='sn',
|
||||||
model='ml',
|
model='ml',
|
||||||
manufacturer='mr',
|
manufacturer='mr',
|
||||||
width=2.0,
|
width=2.0,
|
||||||
color=Color())
|
color=Color())
|
||||||
pc = Desktop(chassis=ComputerChassis.Tower,
|
pc = d.Desktop(chassis=ComputerChassis.Tower,
|
||||||
model='foo',
|
model='foo',
|
||||||
manufacturer='bar',
|
manufacturer='bar',
|
||||||
serial_number='foo-bar',
|
serial_number='foo-bar',
|
||||||
|
@ -114,7 +113,6 @@ def test_physical_properties():
|
||||||
'weight': None,
|
'weight': None,
|
||||||
'height': None,
|
'height': None,
|
||||||
'width': 2.0,
|
'width': 2.0,
|
||||||
'color': Color(),
|
|
||||||
'depth': None
|
'depth': None
|
||||||
}
|
}
|
||||||
assert pc.physical_properties == {
|
assert pc.physical_properties == {
|
||||||
|
@ -125,7 +123,6 @@ def test_physical_properties():
|
||||||
'width': 1.4,
|
'width': 1.4,
|
||||||
'height': 2.1,
|
'height': 2.1,
|
||||||
'depth': None,
|
'depth': None,
|
||||||
'color': Color('LightSeaGreen'),
|
|
||||||
'chassis': ComputerChassis.Tower
|
'chassis': ComputerChassis.Tower
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,18 +130,18 @@ def test_physical_properties():
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_component_similar_one():
|
def test_component_similar_one():
|
||||||
snapshot = conftest.file('pc-components.db')
|
snapshot = conftest.file('pc-components.db')
|
||||||
d = snapshot['device']
|
pc = snapshot['device']
|
||||||
snapshot['components'][0]['serial_number'] = snapshot['components'][1]['serial_number'] = None
|
snapshot['components'][0]['serial_number'] = snapshot['components'][1]['serial_number'] = None
|
||||||
pc = Desktop(**d, components=OrderedSet(Component(**c) for c in snapshot['components']))
|
pc = d.Desktop(**pc, components=OrderedSet(d.Component(**c) for c in snapshot['components']))
|
||||||
component1, component2 = pc.components # type: Component
|
component1, component2 = pc.components # type: d.Component
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
# Let's create a new component named 'A' similar to 1
|
# Let's create a new component named 'A' similar to 1
|
||||||
componentA = Component(model=component1.model, manufacturer=component1.manufacturer)
|
componentA = d.Component(model=component1.model, manufacturer=component1.manufacturer)
|
||||||
similar_to_a = componentA.similar_one(pc, set())
|
similar_to_a = componentA.similar_one(pc, set())
|
||||||
assert similar_to_a == component1
|
assert similar_to_a == component1
|
||||||
# Component B does not have the same model
|
# d.Component B does not have the same model
|
||||||
componentB = Component(model='nope', manufacturer=component1.manufacturer)
|
componentB = d.Component(model='nope', manufacturer=component1.manufacturer)
|
||||||
with pytest.raises(ResourceNotFound):
|
with pytest.raises(ResourceNotFound):
|
||||||
assert componentB.similar_one(pc, set())
|
assert componentB.similar_one(pc, set())
|
||||||
# If we blacklist component A we won't get anything
|
# If we blacklist component A we won't get anything
|
||||||
|
@ -160,14 +157,14 @@ def test_add_remove():
|
||||||
# c4 is not with any pc
|
# c4 is not with any pc
|
||||||
values = conftest.file('pc-components.db')
|
values = conftest.file('pc-components.db')
|
||||||
pc = values['device']
|
pc = values['device']
|
||||||
c1, c2 = (Component(**c) for c in values['components'])
|
c1, c2 = (d.Component(**c) for c in values['components'])
|
||||||
pc = Desktop(**pc, components=OrderedSet([c1, c2]))
|
pc = d.Desktop(**pc, components=OrderedSet([c1, c2]))
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
c3 = Component(serial_number='nc1')
|
c3 = d.Component(serial_number='nc1')
|
||||||
pc2 = Desktop(serial_number='s2',
|
pc2 = d.Desktop(serial_number='s2',
|
||||||
components=OrderedSet([c3]),
|
components=OrderedSet([c3]),
|
||||||
chassis=ComputerChassis.Microtower)
|
chassis=ComputerChassis.Microtower)
|
||||||
c4 = Component(serial_number='c4s')
|
c4 = d.Component(serial_number='c4s')
|
||||||
db.session.add(pc2)
|
db.session.add(pc2)
|
||||||
db.session.add(c4)
|
db.session.add(c4)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -190,12 +187,12 @@ def test_sync_run_components_empty():
|
||||||
remove all the components from the device.
|
remove all the components from the device.
|
||||||
"""
|
"""
|
||||||
s = conftest.file('pc-components.db')
|
s = conftest.file('pc-components.db')
|
||||||
pc = Desktop(**s['device'], components=OrderedSet(Component(**c) for c in s['components']))
|
pc = d.Desktop(**s['device'], components=OrderedSet(d.Component(**c) for c in s['components']))
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# Create a new transient non-db synced object
|
# Create a new transient non-db synced object
|
||||||
pc = Desktop(**s['device'])
|
pc = d.Desktop(**s['device'])
|
||||||
db_pc, _ = Sync().run(pc, components=OrderedSet())
|
db_pc, _ = Sync().run(pc, components=OrderedSet())
|
||||||
assert not db_pc.components
|
assert not db_pc.components
|
||||||
assert not pc.components
|
assert not pc.components
|
||||||
|
@ -208,25 +205,25 @@ def test_sync_run_components_none():
|
||||||
keep all the components from the device.
|
keep all the components from the device.
|
||||||
"""
|
"""
|
||||||
s = conftest.file('pc-components.db')
|
s = conftest.file('pc-components.db')
|
||||||
pc = Desktop(**s['device'], components=OrderedSet(Component(**c) for c in s['components']))
|
pc = d.Desktop(**s['device'], components=OrderedSet(d.Component(**c) for c in s['components']))
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# Create a new transient non-db synced object
|
# Create a new transient non-db synced object
|
||||||
transient_pc = Desktop(**s['device'])
|
transient_pc = d.Desktop(**s['device'])
|
||||||
db_pc, _ = Sync().run(transient_pc, components=None)
|
db_pc, _ = Sync().run(transient_pc, components=None)
|
||||||
assert db_pc.components
|
assert db_pc.components
|
||||||
assert db_pc.components == pc.components
|
assert db_pc.components == pc.components
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_sync_execute_register_desktop_new_Desktop_no_tag():
|
def test_sync_execute_register_desktop_new_desktop_no_tag():
|
||||||
"""
|
"""
|
||||||
Syncs a new Desktop with HID and without a tag, creating it.
|
Syncs a new d.Desktop with HID and without a tag, creating it.
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# Case 1: device does not exist on DB
|
# Case 1: device does not exist on DB
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'])
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
db_pc = Sync().execute_register(pc)
|
db_pc = Sync().execute_register(pc)
|
||||||
assert pc.physical_properties == db_pc.physical_properties
|
assert pc.physical_properties == db_pc.physical_properties
|
||||||
|
|
||||||
|
@ -234,13 +231,13 @@ def test_sync_execute_register_desktop_new_Desktop_no_tag():
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_sync_execute_register_desktop_existing_no_tag():
|
def test_sync_execute_register_desktop_existing_no_tag():
|
||||||
"""
|
"""
|
||||||
Syncs an existing Desktop with HID and without a tag.
|
Syncs an existing d.Desktop with HID and without a tag.
|
||||||
"""
|
"""
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'])
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
pc = Desktop(
|
pc = d.Desktop(
|
||||||
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
||||||
# 1: device exists on DB
|
# 1: device exists on DB
|
||||||
db_pc = Sync().execute_register(pc)
|
db_pc = Sync().execute_register(pc)
|
||||||
|
@ -250,11 +247,11 @@ def test_sync_execute_register_desktop_existing_no_tag():
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_sync_execute_register_desktop_no_hid_no_tag():
|
def test_sync_execute_register_desktop_no_hid_no_tag():
|
||||||
"""
|
"""
|
||||||
Syncs a Desktop without HID and no tag.
|
Syncs a d.Desktop without HID and no tag.
|
||||||
|
|
||||||
This should fail as we don't have a way to identify it.
|
This should fail as we don't have a way to identify it.
|
||||||
"""
|
"""
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'])
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
# 1: device has no HID
|
# 1: device has no HID
|
||||||
pc.hid = pc.model = None
|
pc.hid = pc.model = None
|
||||||
with pytest.raises(NeedsId):
|
with pytest.raises(NeedsId):
|
||||||
|
@ -264,7 +261,7 @@ def test_sync_execute_register_desktop_no_hid_no_tag():
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_sync_execute_register_desktop_tag_not_linked():
|
def test_sync_execute_register_desktop_tag_not_linked():
|
||||||
"""
|
"""
|
||||||
Syncs a new Desktop with HID and a non-linked tag.
|
Syncs a new d.Desktop with HID and a non-linked tag.
|
||||||
|
|
||||||
It is OK if the tag was not linked, it will be linked in this process.
|
It is OK if the tag was not linked, it will be linked in this process.
|
||||||
"""
|
"""
|
||||||
|
@ -273,24 +270,24 @@ def test_sync_execute_register_desktop_tag_not_linked():
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# Create a new transient non-db object
|
# Create a new transient non-db object
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([Tag(id='foo')]))
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([Tag(id='foo')]))
|
||||||
returned_pc = Sync().execute_register(pc)
|
returned_pc = Sync().execute_register(pc)
|
||||||
assert returned_pc == pc
|
assert returned_pc == pc
|
||||||
assert tag.device == pc, 'Tag has to be linked'
|
assert tag.device == pc, 'Tag has to be linked'
|
||||||
assert Desktop.query.one() == pc, 'Desktop had to be set to db'
|
assert d.Desktop.query.one() == pc, 'd.Desktop had to be set to db'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_sync_execute_register_no_hid_tag_not_linked(tag_id: str):
|
def test_sync_execute_register_no_hid_tag_not_linked(tag_id: str):
|
||||||
"""
|
"""
|
||||||
Validates registering a Desktop without HID and a non-linked tag.
|
Validates registering a d.Desktop without HID and a non-linked tag.
|
||||||
|
|
||||||
In this case it is ok still, as the non-linked tag proves that
|
In this case it is ok still, as the non-linked tag proves that
|
||||||
the Desktop was not existing before (otherwise the tag would
|
the d.Desktop was not existing before (otherwise the tag would
|
||||||
be linked), and thus it creates a new Desktop.
|
be linked), and thus it creates a new d.Desktop.
|
||||||
"""
|
"""
|
||||||
tag = Tag(id=tag_id)
|
tag = Tag(id=tag_id)
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([tag]))
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([tag]))
|
||||||
returned_pc = Sync().execute_register(pc)
|
returned_pc = Sync().execute_register(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
assert returned_pc == pc
|
assert returned_pc == pc
|
||||||
|
@ -300,7 +297,7 @@ def test_sync_execute_register_no_hid_tag_not_linked(tag_id: str):
|
||||||
# they have the same pk though
|
# they have the same pk though
|
||||||
assert tag != db_tag, 'They are not the same tags though'
|
assert tag != db_tag, 'They are not the same tags though'
|
||||||
assert db_tag.id == tag.id
|
assert db_tag.id == tag.id
|
||||||
assert Desktop.query.one() == pc, 'Desktop had to be set to db'
|
assert d.Desktop.query.one() == pc, 'd.Desktop had to be set to db'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
@ -311,7 +308,7 @@ def test_sync_execute_register_tag_does_not_exist():
|
||||||
|
|
||||||
Tags have to be created before trying to link them through a Snapshot.
|
Tags have to be created before trying to link them through a Snapshot.
|
||||||
"""
|
"""
|
||||||
pc = Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([Tag('foo')]))
|
pc = d.Desktop(**conftest.file('pc-components.db')['device'], tags=OrderedSet([Tag('foo')]))
|
||||||
with raises(ResourceNotFound):
|
with raises(ResourceNotFound):
|
||||||
Sync().execute_register(pc)
|
Sync().execute_register(pc)
|
||||||
|
|
||||||
|
@ -324,11 +321,11 @@ def test_sync_execute_register_tag_linked_same_device():
|
||||||
(If it has HID it validates both HID and tag point at the same
|
(If it has HID it validates both HID and tag point at the same
|
||||||
device, this his checked in ).
|
device, this his checked in ).
|
||||||
"""
|
"""
|
||||||
orig_pc = Desktop(**conftest.file('pc-components.db')['device'])
|
orig_pc = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
db.session.add(Tag(id='foo', device=orig_pc))
|
db.session.add(Tag(id='foo', device=orig_pc))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
pc = Desktop(
|
pc = d.Desktop(
|
||||||
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
||||||
pc.tags.add(Tag(id='foo'))
|
pc.tags.add(Tag(id='foo'))
|
||||||
db_pc = Sync().execute_register(pc)
|
db_pc = Sync().execute_register(pc)
|
||||||
|
@ -343,15 +340,15 @@ def test_sync_execute_register_tag_linked_other_device_mismatch_between_tags():
|
||||||
Checks that sync raises an error if finds that at least two passed-in
|
Checks that sync raises an error if finds that at least two passed-in
|
||||||
tags are not linked to the same device.
|
tags are not linked to the same device.
|
||||||
"""
|
"""
|
||||||
pc1 = Desktop(**conftest.file('pc-components.db')['device'])
|
pc1 = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
db.session.add(Tag(id='foo-1', device=pc1))
|
db.session.add(Tag(id='foo-1', device=pc1))
|
||||||
pc2 = Desktop(**conftest.file('pc-components.db')['device'])
|
pc2 = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
pc2.serial_number = 'pc2-serial'
|
pc2.serial_number = 'pc2-serial'
|
||||||
pc2.hid = Naming.hid(pc2.manufacturer, pc2.serial_number, pc2.model)
|
pc2.hid = Naming.hid(pc2.manufacturer, pc2.serial_number, pc2.model)
|
||||||
db.session.add(Tag(id='foo-2', device=pc2))
|
db.session.add(Tag(id='foo-2', device=pc2))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
pc1 = Desktop(
|
pc1 = d.Desktop(
|
||||||
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
||||||
pc1.tags.add(Tag(id='foo-1'))
|
pc1.tags.add(Tag(id='foo-1'))
|
||||||
pc1.tags.add(Tag(id='foo-2'))
|
pc1.tags.add(Tag(id='foo-2'))
|
||||||
|
@ -367,15 +364,15 @@ def test_sync_execute_register_mismatch_between_tags_and_hid():
|
||||||
|
|
||||||
In this case we set HID -> pc1 but tag -> pc2
|
In this case we set HID -> pc1 but tag -> pc2
|
||||||
"""
|
"""
|
||||||
pc1 = Desktop(**conftest.file('pc-components.db')['device'])
|
pc1 = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
db.session.add(Tag(id='foo-1', device=pc1))
|
db.session.add(Tag(id='foo-1', device=pc1))
|
||||||
pc2 = Desktop(**conftest.file('pc-components.db')['device'])
|
pc2 = d.Desktop(**conftest.file('pc-components.db')['device'])
|
||||||
pc2.serial_number = 'pc2-serial'
|
pc2.serial_number = 'pc2-serial'
|
||||||
pc2.hid = Naming.hid(pc2.manufacturer, pc2.serial_number, pc2.model)
|
pc2.hid = Naming.hid(pc2.manufacturer, pc2.serial_number, pc2.model)
|
||||||
db.session.add(Tag(id='foo-2', device=pc2))
|
db.session.add(Tag(id='foo-2', device=pc2))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
pc1 = Desktop(
|
pc1 = d.Desktop(
|
||||||
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
**conftest.file('pc-components.db')['device']) # Create a new transient non-db object
|
||||||
pc1.tags.add(Tag(id='foo-2'))
|
pc1.tags.add(Tag(id='foo-2'))
|
||||||
with raises(MismatchBetweenTagsAndHid):
|
with raises(MismatchBetweenTagsAndHid):
|
||||||
|
@ -383,15 +380,15 @@ def test_sync_execute_register_mismatch_between_tags_and_hid():
|
||||||
|
|
||||||
|
|
||||||
def test_get_device(app: Devicehub, user: UserClient):
|
def test_get_device(app: Devicehub, user: UserClient):
|
||||||
"""Checks GETting a Desktop with its components."""
|
"""Checks GETting a d.Desktop with its components."""
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
pc = Desktop(model='p1mo',
|
pc = d.Desktop(model='p1mo',
|
||||||
manufacturer='p1ma',
|
manufacturer='p1ma',
|
||||||
serial_number='p1s',
|
serial_number='p1s',
|
||||||
chassis=ComputerChassis.Tower)
|
chassis=ComputerChassis.Tower)
|
||||||
pc.components = OrderedSet([
|
pc.components = OrderedSet([
|
||||||
NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
|
d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
|
||||||
GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
||||||
])
|
])
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.add(Test(device=pc,
|
db.session.add(Test(device=pc,
|
||||||
|
@ -400,7 +397,7 @@ def test_get_device(app: Devicehub, user: UserClient):
|
||||||
agent=Person(name='Timmy'),
|
agent=Person(name='Timmy'),
|
||||||
author=User(email='bar@bar.com')))
|
author=User(email='bar@bar.com')))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
pc, _ = user.get(res=Device, item=1)
|
pc, _ = user.get(res=d.Device, item=1)
|
||||||
assert len(pc['events']) == 1
|
assert len(pc['events']) == 1
|
||||||
assert pc['events'][0]['type'] == 'Test'
|
assert pc['events'][0]['type'] == 'Test'
|
||||||
assert pc['events'][0]['device'] == 1
|
assert pc['events'][0]['device'] == 1
|
||||||
|
@ -415,40 +412,40 @@ def test_get_device(app: Devicehub, user: UserClient):
|
||||||
assert pc['model'] == 'p1mo'
|
assert pc['model'] == 'p1mo'
|
||||||
assert pc['manufacturer'] == 'p1ma'
|
assert pc['manufacturer'] == 'p1ma'
|
||||||
assert pc['serialNumber'] == 'p1s'
|
assert pc['serialNumber'] == 'p1s'
|
||||||
assert pc['type'] == 'Desktop'
|
assert pc['type'] == d.Desktop.t
|
||||||
|
|
||||||
|
|
||||||
def test_get_devices(app: Devicehub, user: UserClient):
|
def test_get_devices(app: Devicehub, user: UserClient):
|
||||||
"""Checks GETting multiple devices."""
|
"""Checks GETting multiple devices."""
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
pc = Desktop(model='p1mo',
|
pc = d.Desktop(model='p1mo',
|
||||||
manufacturer='p1ma',
|
manufacturer='p1ma',
|
||||||
serial_number='p1s',
|
serial_number='p1s',
|
||||||
chassis=ComputerChassis.Tower)
|
chassis=ComputerChassis.Tower)
|
||||||
pc.components = OrderedSet([
|
pc.components = OrderedSet([
|
||||||
NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
|
d.NetworkAdapter(model='c1mo', manufacturer='c1ma', serial_number='c1s'),
|
||||||
GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
d.GraphicCard(model='c2mo', manufacturer='c2ma', memory=1500)
|
||||||
])
|
])
|
||||||
pc1 = Desktop(model='p2mo',
|
pc1 = d.Desktop(model='p2mo',
|
||||||
manufacturer='p2ma',
|
manufacturer='p2ma',
|
||||||
serial_number='p2s',
|
serial_number='p2s',
|
||||||
chassis=ComputerChassis.Tower)
|
chassis=ComputerChassis.Tower)
|
||||||
pc2 = Laptop(model='p3mo',
|
pc2 = d.Laptop(model='p3mo',
|
||||||
manufacturer='p3ma',
|
manufacturer='p3ma',
|
||||||
serial_number='p3s',
|
serial_number='p3s',
|
||||||
chassis=ComputerChassis.Netbook)
|
chassis=ComputerChassis.Netbook)
|
||||||
db.session.add_all((pc, pc1, pc2))
|
db.session.add_all((pc, pc1, pc2))
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
devices, _ = user.get(res=Device)
|
devices, _ = user.get(res=d.Device)
|
||||||
assert tuple(d['id'] for d in devices['items']) == (1, 2, 3, 4, 5)
|
assert tuple(dev['id'] for dev in devices['items']) == (1, 2, 3, 4, 5)
|
||||||
assert tuple(d['type'] for d in devices['items']) == (
|
assert tuple(dev['type'] for dev in devices['items']) == (
|
||||||
'Desktop', 'Desktop', 'Laptop', 'NetworkAdapter', 'GraphicCard'
|
d.Desktop.t, d.Desktop.t, d.Laptop.t, d.NetworkAdapter.t, d.GraphicCard.t
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_computer_monitor():
|
def test_computer_monitor():
|
||||||
m = ComputerMonitor(technology=DisplayTech.LCD,
|
m = d.ComputerMonitor(technology=DisplayTech.LCD,
|
||||||
manufacturer='foo',
|
manufacturer='foo',
|
||||||
model='bar',
|
model='bar',
|
||||||
serial_number='foo-bar',
|
serial_number='foo-bar',
|
||||||
|
@ -474,22 +471,8 @@ def test_computer_with_display():
|
||||||
pass
|
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):
|
def test_manufacturer(user: UserClient):
|
||||||
m, r = user.get(res='Manufacturer', query=[('name', 'asus')])
|
m, r = user.get(res='Manufacturer', query=[('search', 'asus')])
|
||||||
assert m == {'items': [{'name': 'Asus', 'url': 'https://en.wikipedia.org/wiki/Asus'}]}
|
assert m == {'items': [{'name': 'Asus', 'url': 'https://en.wikipedia.org/wiki/Asus'}]}
|
||||||
assert r.cache_control.public
|
assert r.cache_control.public
|
||||||
assert r.expires > datetime.datetime.now()
|
assert r.expires > datetime.datetime.now()
|
||||||
|
@ -504,7 +487,7 @@ def test_manufacturer_enforced():
|
||||||
def test_device_properties_format(app: Devicehub, user: UserClient):
|
def test_device_properties_format(app: Devicehub, user: UserClient):
|
||||||
user.post(file('asus-eee-1000h.snapshot.11'), res=m.Snapshot)
|
user.post(file('asus-eee-1000h.snapshot.11'), res=m.Snapshot)
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
pc = Laptop.query.one() # type: Laptop
|
pc = d.Laptop.query.one() # type: d.Laptop
|
||||||
assert format(pc) == 'Laptop 1: model 1000h, S/N 94oaaq021116'
|
assert format(pc) == 'Laptop 1: model 1000h, S/N 94oaaq021116'
|
||||||
assert format(pc, 't') == 'Netbook 1000h'
|
assert format(pc, 't') == 'Netbook 1000h'
|
||||||
assert format(pc, 's') == '(asustek computer inc.) S/N 94OAAQ021116'
|
assert format(pc, 's') == '(asustek computer inc.) S/N 94OAAQ021116'
|
||||||
|
@ -512,12 +495,12 @@ def test_device_properties_format(app: Devicehub, user: UserClient):
|
||||||
assert pc.data_storage_size == 152627
|
assert pc.data_storage_size == 152627
|
||||||
assert pc.graphic_card_model == 'mobile 945gse express integrated graphics controller'
|
assert pc.graphic_card_model == 'mobile 945gse express integrated graphics controller'
|
||||||
assert pc.processor_model == 'intel atom cpu n270 @ 1.60ghz'
|
assert pc.processor_model == 'intel atom cpu n270 @ 1.60ghz'
|
||||||
net = next(c for c in pc.components if isinstance(c, NetworkAdapter))
|
net = next(c for c in pc.components if isinstance(c, d.NetworkAdapter))
|
||||||
assert format(net) == 'NetworkAdapter 2: model ar8121/ar8113/ar8114 ' \
|
assert format(net) == 'NetworkAdapter 2: model ar8121/ar8113/ar8114 ' \
|
||||||
'gigabit or fast ethernet, S/N 00:24:8c:7f:cf:2d'
|
'gigabit or fast ethernet, S/N 00:24:8c:7f:cf:2d'
|
||||||
assert format(net, 't') == 'NetworkAdapter ar8121/ar8113/ar8114 gigabit or fast ethernet'
|
assert format(net, 't') == 'NetworkAdapter ar8121/ar8113/ar8114 gigabit or fast ethernet'
|
||||||
assert format(net, 's') == '(qualcomm atheros) S/N 00:24:8C:7F:CF:2D – 100 Mbps'
|
assert format(net, 's') == '(qualcomm atheros) S/N 00:24:8C:7F:CF:2D – 100 Mbps'
|
||||||
hdd = next(c for c in pc.components if isinstance(c, DataStorage))
|
hdd = next(c for c in pc.components if isinstance(c, d.DataStorage))
|
||||||
assert format(hdd) == 'HardDrive 7: model st9160310as, S/N 5sv4tqa6'
|
assert format(hdd) == 'HardDrive 7: model st9160310as, S/N 5sv4tqa6'
|
||||||
assert format(hdd, 't') == 'HardDrive st9160310as'
|
assert format(hdd, 't') == 'HardDrive st9160310as'
|
||||||
assert format(hdd, 's') == '(seagate) S/N 5SV4TQA6 – 152 GB'
|
assert format(hdd, 's') == '(seagate) S/N 5SV4TQA6 – 152 GB'
|
||||||
|
@ -525,13 +508,26 @@ def test_device_properties_format(app: Devicehub, user: UserClient):
|
||||||
|
|
||||||
def test_device_public(user: UserClient, client: Client):
|
def test_device_public(user: UserClient, client: Client):
|
||||||
s, _ = user.post(file('asus-eee-1000h.snapshot.11'), res=m.Snapshot)
|
s, _ = user.post(file('asus-eee-1000h.snapshot.11'), res=m.Snapshot)
|
||||||
html, _ = client.get(res=Device, item=s['device']['id'], accept=ANY)
|
html, _ = client.get(res=d.Device, item=s['device']['id'], accept=ANY)
|
||||||
assert 'intel atom cpu n270 @ 1.60ghz' in html
|
assert 'intel atom cpu n270 @ 1.60ghz' in html
|
||||||
assert 'S/N 00:24:8C:7F:CF:2D – 100 Mbps' in html
|
assert 'S/N 00:24:8C:7F:CF:2D – 100 Mbps' in html
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(reason='Functionality not yet developed.')
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_device_search_multiple_tags(user: UserClient):
|
def test_computer_accessory_model():
|
||||||
"""Ensures that users can search multiple tags at once
|
sai = d.SAI()
|
||||||
and get their multiple devices."""
|
db.session.add(sai)
|
||||||
pass
|
keyboard = d.Keyboard(layout=Layouts.ES)
|
||||||
|
db.session.add(keyboard)
|
||||||
|
mouse = d.Mouse()
|
||||||
|
db.session.add(mouse)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_networking_model():
|
||||||
|
router = d.Router(speed=1000, wireless=True)
|
||||||
|
db.session.add(router)
|
||||||
|
switch = d.Switch(speed=1000, wireless=False)
|
||||||
|
db.session.add(switch)
|
||||||
|
db.session.commit()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.devicehub import Devicehub
|
from ereuse_devicehub.devicehub import Devicehub
|
||||||
from ereuse_devicehub.resources.device.models import Desktop, Device, Laptop, Processor, \
|
from ereuse_devicehub.resources.device.models import Desktop, Device, Laptop, Processor, \
|
||||||
SolidStateDrive
|
SolidStateDrive
|
||||||
|
from ereuse_devicehub.resources.device.search import DeviceSearch
|
||||||
from ereuse_devicehub.resources.device.views import Filters, Sorting
|
from ereuse_devicehub.resources.device.views import Filters, Sorting
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis
|
from ereuse_devicehub.resources.enums import ComputerChassis
|
||||||
from ereuse_devicehub.resources.event.models import Snapshot
|
from ereuse_devicehub.resources.event.models import Snapshot
|
||||||
|
@ -174,6 +175,21 @@ def test_device_lots_query(user: UserClient):
|
||||||
pass
|
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):
|
def test_device_query_search(user: UserClient):
|
||||||
# todo improve
|
# todo improve
|
||||||
user.post(file('basic.snapshot'), res=Snapshot)
|
user.post(file('basic.snapshot'), res=Snapshot)
|
||||||
|
|
|
@ -112,7 +112,10 @@ def test_install():
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
||||||
def test_update_components_event_one():
|
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')
|
hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar')
|
||||||
computer.components.add(hdd)
|
computer.components.add(hdd)
|
||||||
|
|
||||||
|
@ -137,7 +140,10 @@ def test_update_components_event_one():
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
||||||
def test_update_components_event_multiple():
|
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')
|
hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar')
|
||||||
computer.components.add(hdd)
|
computer.components.add(hdd)
|
||||||
|
|
||||||
|
@ -163,7 +169,10 @@ def test_update_components_event_multiple():
|
||||||
|
|
||||||
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
||||||
def test_update_parent():
|
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')
|
hdd = HardDrive(serial_number='foo', manufacturer='bar', model='foo-bar')
|
||||||
computer.components.add(hdd)
|
computer.components.add(hdd)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,15 @@ In case of error, debug with:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_lot_modify_patch_endpoint(user: UserClient):
|
||||||
|
"""Creates and modifies lot properties through the endpoint"""
|
||||||
|
l, _ = user.post({'name': 'foo'}, res=Lot)
|
||||||
|
assert l['name'] == 'foo'
|
||||||
|
user.patch({'name': 'bar'}, res=Lot, item=l['id'], status=204)
|
||||||
|
l_after, _ = user.get(res=Lot, item=l['id'])
|
||||||
|
assert l_after['name'] == 'bar'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(reason='Components are not added to lots!')
|
@pytest.mark.xfail(reason='Components are not added to lots!')
|
||||||
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
@pytest.mark.usefixtures(conftest.auth_app_context.__name__)
|
||||||
def test_lot_device_relationship():
|
def test_lot_device_relationship():
|
||||||
|
|
|
@ -51,7 +51,7 @@ def test_rate():
|
||||||
appearance_range=AppearanceRange.A,
|
appearance_range=AppearanceRange.A,
|
||||||
functionality_range=FunctionalityRange.A
|
functionality_range=FunctionalityRange.A
|
||||||
)
|
)
|
||||||
pc = Desktop()
|
pc = Desktop(chassis=ComputerChassis.Tower)
|
||||||
hdd = HardDrive(size=476940)
|
hdd = HardDrive(size=476940)
|
||||||
hdd.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8))
|
hdd.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8))
|
||||||
cpu = Processor(cores=2, speed=3.4)
|
cpu = Processor(cores=2, speed=3.4)
|
||||||
|
|
|
@ -15,7 +15,7 @@ Excluded cases in tests
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ereuse_devicehub.resources.device.models import Desktop, HardDrive, Processor, RamModule
|
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, \
|
from ereuse_devicehub.resources.event.models import BenchmarkDataStorage, BenchmarkProcessor, \
|
||||||
WorkbenchRate
|
WorkbenchRate
|
||||||
from ereuse_devicehub.resources.event.rate.workbench.v1_0 import DataStorageRate, ProcessorRate, \
|
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
|
# 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 = HardDrive(size=476940)
|
||||||
data_storage.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8))
|
data_storage.events_one.add(BenchmarkDataStorage(read_speed=126, write_speed=29.8))
|
||||||
cpu = Processor(cores=2, speed=3.4)
|
cpu = Processor(cores=2, speed=3.4)
|
||||||
|
@ -333,7 +333,7 @@ def test_rate_computer_rate():
|
||||||
assert round(rate_pc.rating, 2) == 4.61
|
assert round(rate_pc.rating, 2) == 4.61
|
||||||
|
|
||||||
# Create a new Computer with components characteristics of pc with id = 1201
|
# 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 = HardDrive(size=476940)
|
||||||
data_storage.events_one.add(BenchmarkDataStorage(read_speed=158, write_speed=34.7))
|
data_storage.events_one.add(BenchmarkDataStorage(read_speed=158, write_speed=34.7))
|
||||||
cpu = Processor(cores=2, speed=3.3)
|
cpu = Processor(cores=2, speed=3.3)
|
||||||
|
@ -358,7 +358,7 @@ def test_rate_computer_rate():
|
||||||
assert round(rate_pc.rating, 2) == 3.48
|
assert round(rate_pc.rating, 2) == 3.48
|
||||||
|
|
||||||
# Create a new Computer with components characteristics of pc with id = 79
|
# 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 = HardDrive(size=76319)
|
||||||
data_storage.events_one.add(BenchmarkDataStorage(read_speed=72.2, write_speed=24.3))
|
data_storage.events_one.add(BenchmarkDataStorage(read_speed=72.2, write_speed=24.3))
|
||||||
cpu = Processor(cores=1, speed=1.6)
|
cpu = Processor(cores=1, speed=1.6)
|
||||||
|
@ -386,7 +386,7 @@ def test_rate_computer_rate():
|
||||||
assert round(rate_pc.rating, 2) == 1.58
|
assert round(rate_pc.rating, 2) == 1.58
|
||||||
|
|
||||||
# Create a new Computer with components characteristics of pc with id = 798
|
# 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 = HardDrive(size=152587)
|
||||||
data_storage.events_one.add(BenchmarkDataStorage(read_speed=78.1, write_speed=24.4))
|
data_storage.events_one.add(BenchmarkDataStorage(read_speed=78.1, write_speed=24.4))
|
||||||
cpu = Processor(cores=2, speed=2.5)
|
cpu = Processor(cores=2, speed=2.5)
|
||||||
|
|
|
@ -411,3 +411,10 @@ def snapshot_and_check(user: UserClient,
|
||||||
return snapshot_and_check(user, input_snapshot, event_types, perform_second_snapshot=False)
|
return snapshot_and_check(user, input_snapshot, event_types, perform_second_snapshot=False)
|
||||||
else:
|
else:
|
||||||
return snapshot
|
return snapshot
|
||||||
|
|
||||||
|
|
||||||
|
def test_snapshot_keyboard(user: UserClient):
|
||||||
|
s = file('keyboard.snapshot')
|
||||||
|
snapshot = snapshot_and_check(user, s, event_types=('ManualRate',))
|
||||||
|
keyboard = snapshot['device']
|
||||||
|
assert keyboard['layout'] == 'ES'
|
||||||
|
|
|
@ -155,8 +155,11 @@ def test_tag_create_etags_cli(app: Devicehub, user: UserClient):
|
||||||
assert tag.provider == URL('https://t.ereuse.org')
|
assert tag.provider == URL('https://t.ereuse.org')
|
||||||
|
|
||||||
|
|
||||||
def test_tag_manual_link(app: Devicehub, user: UserClient):
|
def test_tag_manual_link_search(app: Devicehub, user: UserClient):
|
||||||
"""Tests linking manually a tag through PUT /tags/<id>/device/<id>"""
|
"""Tests linking manually a tag through PUT /tags/<id>/device/<id>
|
||||||
|
|
||||||
|
Checks search has the term.
|
||||||
|
"""
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.session.add(Tag('foo-bar', secondary='foo-sec'))
|
db.session.add(Tag('foo-bar', secondary='foo-sec'))
|
||||||
desktop = Desktop(serial_number='foo', chassis=ComputerChassis.AllInOne)
|
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
|
# cannot link to another device when already linked
|
||||||
user.put({}, res=Tag, item='foo-bar/device/99', status=LinkedToAnotherDevice)
|
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__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_tag_secondary_workbench_link_find(user: UserClient):
|
def test_tag_secondary_workbench_link_find(user: UserClient):
|
||||||
|
|
|
@ -142,6 +142,9 @@ def test_real_hp_11(user: UserClient):
|
||||||
assert pc['hid'] == 'hewlett-packard-czc0408yjg-hp_compaq_8100_elite_sff'
|
assert pc['hid'] == 'hewlett-packard-czc0408yjg-hp_compaq_8100_elite_sff'
|
||||||
assert pc['chassis'] == 'Tower'
|
assert pc['chassis'] == 'Tower'
|
||||||
assert set(e['type'] for e in snapshot['events']) == {
|
assert set(e['type'] for e in snapshot['events']) == {
|
||||||
|
'EreusePrice',
|
||||||
|
'AggregateRate',
|
||||||
|
'WorkbenchRate',
|
||||||
'BenchmarkDataStorage',
|
'BenchmarkDataStorage',
|
||||||
'BenchmarkProcessor',
|
'BenchmarkProcessor',
|
||||||
'BenchmarkProcessorSysbench',
|
'BenchmarkProcessorSysbench',
|
||||||
|
@ -149,11 +152,12 @@ def test_real_hp_11(user: UserClient):
|
||||||
'BenchmarkRamSysbench',
|
'BenchmarkRamSysbench',
|
||||||
'StressTest'
|
'StressTest'
|
||||||
}
|
}
|
||||||
assert len(list(e['type'] for e in snapshot['events'])) == 6
|
assert len(list(e['type'] for e in snapshot['events'])) == 9
|
||||||
assert pc['networkSpeeds'] == [1000, None], 'Device has no WiFi'
|
assert pc['networkSpeeds'] == [1000, None], 'Device has no WiFi'
|
||||||
assert pc['processorModel'] == 'intel core i3 cpu 530 @ 2.93ghz'
|
assert pc['processorModel'] == 'intel core i3 cpu 530 @ 2.93ghz'
|
||||||
assert pc['ramSize'] == 8192
|
assert pc['ramSize'] == 8192
|
||||||
assert pc['dataStorageSize'] == 305245
|
assert pc['dataStorageSize'] == 305245
|
||||||
|
# todo check rating
|
||||||
|
|
||||||
|
|
||||||
def test_real_toshiba_11(user: UserClient):
|
def test_real_toshiba_11(user: UserClient):
|
||||||
|
@ -177,6 +181,20 @@ def test_snapshot_real_eee_1001pxd(user: UserClient):
|
||||||
assert pc['hid'] == 'asustek_computer_inc-b8oaas048286-1001pxd'
|
assert pc['hid'] == 'asustek_computer_inc-b8oaas048286-1001pxd'
|
||||||
assert pc['tags'] == []
|
assert pc['tags'] == []
|
||||||
assert pc['networkSpeeds'] == [100, 0], 'Although it has WiFi we do not know the speed'
|
assert pc['networkSpeeds'] == [100, 0], 'Although it has WiFi we do not know the speed'
|
||||||
|
assert pc['rate']
|
||||||
|
rate = pc['rate']
|
||||||
|
assert rate['appearanceRange'] == 'B'
|
||||||
|
assert rate['functionalityRange'] == 'A'
|
||||||
|
assert rate['processorRange'] == 'VERY_LOW'
|
||||||
|
assert rate['ramRange'] == 'VERY_LOW'
|
||||||
|
assert rate['ratingRange'] == 'VERY_LOW'
|
||||||
|
assert rate['ram'] == 1.53
|
||||||
|
assert rate['data_storage'] == 3.76
|
||||||
|
assert rate['type'] == 'AggregateRate'
|
||||||
|
assert rate['biosRange'] == 'C'
|
||||||
|
assert rate['appearance'] > 0
|
||||||
|
assert rate['functionality'] > 0
|
||||||
|
assert rate['rating'] > 0 and rate['rating'] != 1
|
||||||
components = snapshot['components']
|
components = snapshot['components']
|
||||||
wifi = components[0]
|
wifi = components[0]
|
||||||
assert wifi['hid'] == 'qualcomm_atheros-74_2f_68_8b_fd_c8-ar9285_wireless_network_adapter'
|
assert wifi['hid'] == 'qualcomm_atheros-74_2f_68_8b_fd_c8-ar9285_wireless_network_adapter'
|
||||||
|
@ -208,7 +226,7 @@ def test_snapshot_real_eee_1001pxd(user: UserClient):
|
||||||
assert em.BenchmarkRamSysbench.t in event_types
|
assert em.BenchmarkRamSysbench.t in event_types
|
||||||
assert em.StressTest.t in event_types
|
assert em.StressTest.t in event_types
|
||||||
assert em.Snapshot.t in event_types
|
assert em.Snapshot.t in event_types
|
||||||
assert len(events) == 5
|
assert len(events) == 7
|
||||||
gpu = components[3]
|
gpu = components[3]
|
||||||
assert gpu['model'] == 'atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller'
|
assert gpu['model'] == 'atom processor d4xx/d5xx/n4xx/n5xx integrated graphics controller'
|
||||||
assert gpu['manufacturer'] == 'intel corporation'
|
assert gpu['manufacturer'] == 'intel corporation'
|
||||||
|
|
Reference in New Issue