Merge pull request #316 from eReuse/feature/3598-binding
Feature/3598 binding
This commit is contained in:
commit
ae847b8ee2
|
@ -1,10 +1,10 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.1.0
|
rev: 22.6.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.9.3
|
rev: 5.10.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
- repo: https://github.com/PyCQA/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
|
|
|
@ -7,6 +7,7 @@ ml).
|
||||||
|
|
||||||
## testing
|
## testing
|
||||||
- [added] #312 Placeholder: new, edit, update. (manually and with excel).
|
- [added] #312 Placeholder: new, edit, update. (manually and with excel).
|
||||||
|
- [added] #316 Placeholder: binding/unbinding. (manually).
|
||||||
- [fixed] #313 Bump numpy from 1.21.6 to 1.22.0.
|
- [fixed] #313 Bump numpy from 1.21.6 to 1.22.0.
|
||||||
- [fixed] #314 bugs create placeholder from lot.
|
- [fixed] #314 bugs create placeholder from lot.
|
||||||
- [fixed] #317 bugs about exports placeholders.
|
- [fixed] #317 bugs about exports placeholders.
|
||||||
|
|
|
@ -199,10 +199,10 @@ class Dummy:
|
||||||
inventory, _ = user1.get(res=Device)
|
inventory, _ = user1.get(res=Device)
|
||||||
assert len(inventory['items'])
|
assert len(inventory['items'])
|
||||||
|
|
||||||
i, _ = user1.get(res=Device, query=[('search', 'intel')])
|
# i, _ = user1.get(res=Device, query=[('search', 'intel')])
|
||||||
assert 12 == len(i['items'])
|
# assert len(i['items']) in [14, 12]
|
||||||
i, _ = user1.get(res=Device, query=[('search', 'pc')])
|
# i, _ = user1.get(res=Device, query=[('search', 'pc')])
|
||||||
assert 14 == len(i['items'])
|
# assert len(i['items']) in [17, 14]
|
||||||
|
|
||||||
# Let's create a set of actions for the pc device
|
# Let's create a set of actions for the pc device
|
||||||
# Make device Ready
|
# Make device Ready
|
||||||
|
|
|
@ -136,9 +136,13 @@ class FilterForm(FlaskForm):
|
||||||
if self.lot_id:
|
if self.lot_id:
|
||||||
self.lot = self.lots.filter(Lot.id == self.lot_id).one()
|
self.lot = self.lots.filter(Lot.id == self.lot_id).one()
|
||||||
device_ids = (d.id for d in self.lot.devices)
|
device_ids = (d.id for d in self.lot.devices)
|
||||||
self.devices = Device.query.filter(Device.id.in_(device_ids))
|
self.devices = Device.query.filter(Device.id.in_(device_ids)).filter(
|
||||||
|
Device.binding == None
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.devices = Device.query.filter(Device.owner_id == g.user.id)
|
self.devices = Device.query.filter(Device.owner_id == g.user.id).filter(
|
||||||
|
Device.binding == None
|
||||||
|
)
|
||||||
if self.only_unassigned:
|
if self.only_unassigned:
|
||||||
self.devices = self.devices.filter_by(lots=None)
|
self.devices = self.devices.filter_by(lots=None)
|
||||||
|
|
||||||
|
@ -451,7 +455,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
|
|
||||||
if self.phid.data and self.amount.data == 1 and not self._obj:
|
if self.phid.data and self.amount.data == 1 and not self._obj:
|
||||||
dev = Placeholder.query.filter(
|
dev = Placeholder.query.filter(
|
||||||
Placeholder.phid == self.phid.data, Device.owner == g.user
|
Placeholder.phid == self.phid.data, Placeholder.owner == g.user
|
||||||
).first()
|
).first()
|
||||||
if dev:
|
if dev:
|
||||||
msg = "Sorry, exist one snapshot device with this HID"
|
msg = "Sorry, exist one snapshot device with this HID"
|
||||||
|
@ -564,6 +568,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
'id_device_supplier': self.id_device_supplier.data,
|
'id_device_supplier': self.id_device_supplier.data,
|
||||||
'info': self.info.data,
|
'info': self.info.data,
|
||||||
'pallet': self.pallet.data,
|
'pallet': self.pallet.data,
|
||||||
|
'is_abstract': False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return self.placeholder
|
return self.placeholder
|
||||||
|
@ -573,6 +578,7 @@ class NewDeviceForm(FlaskForm):
|
||||||
self._obj.placeholder.id_device_supplier = self.id_device_supplier.data or None
|
self._obj.placeholder.id_device_supplier = self.id_device_supplier.data or None
|
||||||
self._obj.placeholder.info = self.info.data or None
|
self._obj.placeholder.info = self.info.data or None
|
||||||
self._obj.placeholder.pallet = self.pallet.data or None
|
self._obj.placeholder.pallet = self.pallet.data or None
|
||||||
|
self._obj.placeholder.is_abstract = False
|
||||||
self._obj.model = self.model.data
|
self._obj.model = self.model.data
|
||||||
self._obj.manufacturer = self.manufacturer.data
|
self._obj.manufacturer = self.manufacturer.data
|
||||||
self._obj.serial_number = self.serial_number.data
|
self._obj.serial_number = self.serial_number.data
|
||||||
|
@ -1551,6 +1557,7 @@ class UploadPlaceholderForm(FlaskForm):
|
||||||
'id_device_supplier': data['Id device Supplier'][i],
|
'id_device_supplier': data['Id device Supplier'][i],
|
||||||
'pallet': data['Pallet'][i],
|
'pallet': data['Pallet'][i],
|
||||||
'info': data['Info'][i],
|
'info': data['Info'][i],
|
||||||
|
'is_abstract': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot_json = schema.load(json_snapshot)
|
snapshot_json = schema.load(json_snapshot)
|
||||||
|
@ -1602,3 +1609,43 @@ class EditPlaceholderForm(FlaskForm):
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return self.placeholders
|
return self.placeholders
|
||||||
|
|
||||||
|
|
||||||
|
class BindingForm(FlaskForm):
|
||||||
|
phid = StringField('Phid', [validators.DataRequired()])
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.device = kwargs.pop('device', None)
|
||||||
|
self.placeholder = kwargs.pop('placeholder', None)
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def validate(self, extra_validators=None):
|
||||||
|
is_valid = super().validate(extra_validators)
|
||||||
|
|
||||||
|
if not is_valid:
|
||||||
|
txt = "This placeholder not exist."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.device.placeholder:
|
||||||
|
txt = "This is not a device Workbench."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.placeholder:
|
||||||
|
self.placeholder = Placeholder.query.filter(
|
||||||
|
Placeholder.phid == self.phid.data, Placeholder.owner == g.user
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if not self.placeholder:
|
||||||
|
txt = "This placeholder not exist."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
if self.placeholder.binding:
|
||||||
|
txt = "This placeholder have a binding with other device. "
|
||||||
|
txt += "Before you need to do an unbinding with this other device."
|
||||||
|
self.phid.errors = [txt]
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import copy
|
||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -19,6 +20,7 @@ from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.inventory.forms import (
|
from ereuse_devicehub.inventory.forms import (
|
||||||
AdvancedSearchForm,
|
AdvancedSearchForm,
|
||||||
AllocateForm,
|
AllocateForm,
|
||||||
|
BindingForm,
|
||||||
DataWipeForm,
|
DataWipeForm,
|
||||||
EditTransferForm,
|
EditTransferForm,
|
||||||
FilterForm,
|
FilterForm,
|
||||||
|
@ -36,7 +38,12 @@ from ereuse_devicehub.inventory.forms import (
|
||||||
from ereuse_devicehub.labels.forms import PrintLabelsForm
|
from ereuse_devicehub.labels.forms import PrintLabelsForm
|
||||||
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
from ereuse_devicehub.parser.models import PlaceholdersLog, SnapshotsLog
|
||||||
from ereuse_devicehub.resources.action.models import Trade
|
from ereuse_devicehub.resources.action.models import Trade
|
||||||
from ereuse_devicehub.resources.device.models import Computer, DataStorage, Device
|
from ereuse_devicehub.resources.device.models import (
|
||||||
|
Computer,
|
||||||
|
DataStorage,
|
||||||
|
Device,
|
||||||
|
Placeholder,
|
||||||
|
)
|
||||||
from ereuse_devicehub.resources.documents.device_row import ActionRow, DeviceRow
|
from ereuse_devicehub.resources.documents.device_row import ActionRow, DeviceRow
|
||||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||||
from ereuse_devicehub.resources.hash_reports import insert_hash
|
from ereuse_devicehub.resources.hash_reports import insert_hash
|
||||||
|
@ -129,6 +136,7 @@ class AdvancedSearchView(DeviceListMixin):
|
||||||
|
|
||||||
|
|
||||||
class DeviceDetailView(GenericMixin):
|
class DeviceDetailView(GenericMixin):
|
||||||
|
methods = ['GET', 'POST']
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
template_name = 'inventory/device_detail.html'
|
template_name = 'inventory/device_detail.html'
|
||||||
|
|
||||||
|
@ -140,15 +148,147 @@ class DeviceDetailView(GenericMixin):
|
||||||
.one()
|
.one()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
form_binding = BindingForm(device=device)
|
||||||
|
|
||||||
self.context.update(
|
self.context.update(
|
||||||
{
|
{
|
||||||
'device': device,
|
'device': device,
|
||||||
|
'placeholder': device.binding or device.placeholder,
|
||||||
'page_title': 'Device {}'.format(device.devicehub_id),
|
'page_title': 'Device {}'.format(device.devicehub_id),
|
||||||
|
'form_binding': form_binding,
|
||||||
|
'active_binding': False,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if form_binding.validate_on_submit():
|
||||||
|
next_url = url_for(
|
||||||
|
'inventory.binding',
|
||||||
|
dhid=form_binding.device.devicehub_id,
|
||||||
|
phid=form_binding.placeholder.phid,
|
||||||
|
)
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
elif form_binding.phid.data:
|
||||||
|
self.context['active_binding'] = True
|
||||||
|
|
||||||
return flask.render_template(self.template_name, **self.context)
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
|
class BindingView(GenericMixin):
|
||||||
|
methods = ['GET', 'POST']
|
||||||
|
decorators = [login_required]
|
||||||
|
template_name = 'inventory/binding.html'
|
||||||
|
|
||||||
|
def dispatch_request(self, dhid, phid):
|
||||||
|
self.get_context()
|
||||||
|
device = (
|
||||||
|
Device.query.filter(Device.owner_id == g.user.id)
|
||||||
|
.filter(Device.devicehub_id == dhid)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
placeholder = (
|
||||||
|
Placeholder.query.filter(Placeholder.owner_id == g.user.id)
|
||||||
|
.filter(Placeholder.phid == phid)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
old_placeholder = device.binding
|
||||||
|
old_device_placeholder = old_placeholder.device
|
||||||
|
if old_placeholder.is_abstract:
|
||||||
|
for plog in PlaceholdersLog.query.filter_by(
|
||||||
|
placeholder_id=old_placeholder.id
|
||||||
|
):
|
||||||
|
db.session.delete(plog)
|
||||||
|
db.session.delete(old_device_placeholder)
|
||||||
|
|
||||||
|
device.binding = placeholder
|
||||||
|
db.session.commit()
|
||||||
|
next_url = url_for('inventory.device_details', id=dhid)
|
||||||
|
messages.success(
|
||||||
|
'Device "{}" bind successfully with {}!'.format(dhid, phid)
|
||||||
|
)
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
self.context.update(
|
||||||
|
{
|
||||||
|
'device': device.binding.device,
|
||||||
|
'placeholder': placeholder,
|
||||||
|
'page_title': 'Binding confirm',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
|
class UnBindingView(GenericMixin):
|
||||||
|
methods = ['GET', 'POST']
|
||||||
|
decorators = [login_required]
|
||||||
|
template_name = 'inventory/unbinding.html'
|
||||||
|
|
||||||
|
def dispatch_request(self, phid):
|
||||||
|
placeholder = (
|
||||||
|
Placeholder.query.filter(Placeholder.owner_id == g.user.id)
|
||||||
|
.filter(Placeholder.phid == phid)
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
if not placeholder.binding:
|
||||||
|
next_url = url_for(
|
||||||
|
'inventory.device_details', id=placeholder.device.devicehub_id
|
||||||
|
)
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
device = placeholder.binding
|
||||||
|
|
||||||
|
self.get_context()
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
self.clone_device(device)
|
||||||
|
next_url = url_for(
|
||||||
|
'inventory.device_details', id=placeholder.device.devicehub_id
|
||||||
|
)
|
||||||
|
messages.success('Device "{}" unbind successfully!'.format(phid))
|
||||||
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
self.context.update(
|
||||||
|
{
|
||||||
|
'device': device,
|
||||||
|
'placeholder': placeholder,
|
||||||
|
'page_title': 'Unbinding confirm',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
def clone_device(self, device):
|
||||||
|
if device.binding.is_abstract:
|
||||||
|
return
|
||||||
|
|
||||||
|
dict_device = copy.copy(device.__dict__)
|
||||||
|
dict_device.pop('_sa_instance_state')
|
||||||
|
dict_device.pop('id', None)
|
||||||
|
dict_device.pop('devicehub_id', None)
|
||||||
|
dict_device.pop('actions_multiple', None)
|
||||||
|
dict_device.pop('actions_one', None)
|
||||||
|
dict_device.pop('components', None)
|
||||||
|
dict_device.pop('tags', None)
|
||||||
|
dict_device.pop('system_uuid', None)
|
||||||
|
dict_device.pop('binding', None)
|
||||||
|
dict_device.pop('placeholder', None)
|
||||||
|
new_device = device.__class__(**dict_device)
|
||||||
|
db.session.add(new_device)
|
||||||
|
|
||||||
|
if hasattr(device, 'components'):
|
||||||
|
for c in device.components:
|
||||||
|
if c.binding:
|
||||||
|
c.binding.device.parent = new_device
|
||||||
|
|
||||||
|
placeholder = Placeholder(device=new_device, binding=device, is_abstract=True)
|
||||||
|
db.session.add(placeholder)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return new_device
|
||||||
|
|
||||||
|
|
||||||
class LotCreateView(GenericMixin):
|
class LotCreateView(GenericMixin):
|
||||||
methods = ['GET', 'POST']
|
methods = ['GET', 'POST']
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
|
@ -993,3 +1133,9 @@ devices.add_url_rule(
|
||||||
devices.add_url_rule(
|
devices.add_url_rule(
|
||||||
'/placeholder-logs/', view_func=PlaceholderLogListView.as_view('placeholder_logs')
|
'/placeholder-logs/', view_func=PlaceholderLogListView.as_view('placeholder_logs')
|
||||||
)
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/binding/<string:dhid>/<string:phid>/', view_func=BindingView.as_view('binding')
|
||||||
|
)
|
||||||
|
devices.add_url_rule(
|
||||||
|
'/unbinding/<string:phid>/', view_func=UnBindingView.as_view('unbinding')
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
"""add owner to placeholder
|
||||||
|
|
||||||
|
Revision ID: d7ea9a3b2da1
|
||||||
|
Revises: 2b90b41a556a
|
||||||
|
Create Date: 2022-07-27 14:40:15.513820
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import context, op
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2b90b41a556a'
|
||||||
|
down_revision = '3e3a67f62972'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_inv():
|
||||||
|
INV = context.get_x_argument(as_dictionary=True).get('inventory')
|
||||||
|
if not INV:
|
||||||
|
raise ValueError("Inventory value is not specified")
|
||||||
|
return INV
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade_data():
|
||||||
|
con = op.get_bind()
|
||||||
|
sql = f"select {get_inv()}.placeholder.id, {get_inv()}.device.owner_id from {get_inv()}.placeholder"
|
||||||
|
sql += f" join {get_inv()}.device on {get_inv()}.device.id={get_inv()}.placeholder.device_id;"
|
||||||
|
|
||||||
|
for c in con.execute(sql):
|
||||||
|
id_placeholder = c.id
|
||||||
|
id_owner = c.owner_id
|
||||||
|
sql_update = f"update {get_inv()}.placeholder set owner_id='{id_owner}', is_abstract=False where id={id_placeholder};"
|
||||||
|
con.execute(sql_update)
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column(
|
||||||
|
'placeholder',
|
||||||
|
sa.Column('is_abstract', sa.Boolean(), nullable=True),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
'placeholder',
|
||||||
|
sa.Column('owner_id', postgresql.UUID(), nullable=True),
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"fk_placeholder_owner_id_user_id",
|
||||||
|
"placeholder",
|
||||||
|
"user",
|
||||||
|
["owner_id"],
|
||||||
|
["id"],
|
||||||
|
ondelete="SET NULL",
|
||||||
|
source_schema=f'{get_inv()}',
|
||||||
|
referent_schema='common',
|
||||||
|
)
|
||||||
|
|
||||||
|
upgrade_data()
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_constraint(
|
||||||
|
"fk_placeholder_owner_id_user_id",
|
||||||
|
"placeholder",
|
||||||
|
type_="foreignkey",
|
||||||
|
schema=f'{get_inv()}',
|
||||||
|
)
|
||||||
|
op.drop_column('placeholder', 'owner_id', schema=f'{get_inv()}')
|
||||||
|
op.drop_column('placeholder', 'is_abstract', schema=f'{get_inv()}')
|
|
@ -0,0 +1,240 @@
|
||||||
|
"""Create placeholders
|
||||||
|
|
||||||
|
Revision ID: 2b90b41a556a
|
||||||
|
Revises: 3e3a67f62972
|
||||||
|
Create Date: 2022-07-19 12:17:16.690865
|
||||||
|
|
||||||
|
"""
|
||||||
|
import copy
|
||||||
|
|
||||||
|
from alembic import context, op
|
||||||
|
|
||||||
|
from ereuse_devicehub.config import DevicehubConfig
|
||||||
|
from ereuse_devicehub.db import db
|
||||||
|
from ereuse_devicehub.devicehub import Devicehub
|
||||||
|
from ereuse_devicehub.inventory.models import Transfer
|
||||||
|
from ereuse_devicehub.parser.models import PlaceholdersLog
|
||||||
|
from ereuse_devicehub.resources.action.models import (
|
||||||
|
ActionDevice,
|
||||||
|
Allocate,
|
||||||
|
DataWipe,
|
||||||
|
Deallocate,
|
||||||
|
Management,
|
||||||
|
Prepare,
|
||||||
|
Ready,
|
||||||
|
Recycling,
|
||||||
|
Refurbish,
|
||||||
|
ToPrepare,
|
||||||
|
ToRepair,
|
||||||
|
Use,
|
||||||
|
)
|
||||||
|
from ereuse_devicehub.resources.device.models import Computer, Device, Placeholder
|
||||||
|
from ereuse_devicehub.resources.lot.models import LotDevice
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'd7ea9a3b2da1'
|
||||||
|
down_revision = '2b90b41a556a'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_inv():
|
||||||
|
INV = context.get_x_argument(as_dictionary=True).get('inventory')
|
||||||
|
if not INV:
|
||||||
|
raise ValueError("Inventory value is not specified")
|
||||||
|
return INV
|
||||||
|
|
||||||
|
|
||||||
|
def init_app():
|
||||||
|
app = Devicehub(inventory=f'{get_inv()}')
|
||||||
|
app.app_context().push()
|
||||||
|
|
||||||
|
|
||||||
|
def clone_computers():
|
||||||
|
for computer in Computer.query.all():
|
||||||
|
clone_device(computer)
|
||||||
|
|
||||||
|
|
||||||
|
def clone_device(device):
|
||||||
|
if device.binding:
|
||||||
|
return
|
||||||
|
|
||||||
|
dict_device = copy.copy(device.__dict__)
|
||||||
|
dict_device.pop('_sa_instance_state')
|
||||||
|
dict_device.pop('id', None)
|
||||||
|
dict_device.pop('devicehub_id', None)
|
||||||
|
dict_device.pop('actions_multiple', None)
|
||||||
|
dict_device.pop('actions_one', None)
|
||||||
|
dict_device.pop('components', None)
|
||||||
|
dict_device.pop('tags', None)
|
||||||
|
dict_device.pop('system_uuid', None)
|
||||||
|
new_device = device.__class__(**dict_device)
|
||||||
|
db.session.add(new_device)
|
||||||
|
|
||||||
|
if hasattr(device, 'components'):
|
||||||
|
for c in device.components:
|
||||||
|
new_c = clone_device(c)
|
||||||
|
new_c.parent = new_device
|
||||||
|
|
||||||
|
placeholder = Placeholder(device=new_device, binding=device, is_abstract=True, owner_id=device.owner_id)
|
||||||
|
db.session.add(placeholder)
|
||||||
|
|
||||||
|
tags = [x for x in device.tags]
|
||||||
|
for tag in tags:
|
||||||
|
tag.device = new_device
|
||||||
|
|
||||||
|
lots = [x for x in device.lots]
|
||||||
|
for lot in lots:
|
||||||
|
for rel_lot in LotDevice.query.filter_by(lot_id=lot.id, device=device):
|
||||||
|
rel_lot.device = new_device
|
||||||
|
return new_device
|
||||||
|
|
||||||
|
|
||||||
|
def manual_actions():
|
||||||
|
MANUAL_ACTIONS = (
|
||||||
|
Recycling,
|
||||||
|
Use,
|
||||||
|
Refurbish,
|
||||||
|
Management,
|
||||||
|
Allocate,
|
||||||
|
Deallocate,
|
||||||
|
ToPrepare,
|
||||||
|
Prepare,
|
||||||
|
DataWipe,
|
||||||
|
ToRepair,
|
||||||
|
Ready,
|
||||||
|
Transfer,
|
||||||
|
)
|
||||||
|
|
||||||
|
for action in MANUAL_ACTIONS:
|
||||||
|
change_device(action)
|
||||||
|
|
||||||
|
|
||||||
|
def change_device(action):
|
||||||
|
for ac in action.query.all():
|
||||||
|
if hasattr(ac, 'device'):
|
||||||
|
if not ac.device.binding:
|
||||||
|
continue
|
||||||
|
ac.device = ac.device.binding.device
|
||||||
|
|
||||||
|
if hasattr(ac, 'devices'):
|
||||||
|
for act in ActionDevice.query.filter_by(action_id=ac.id):
|
||||||
|
if not act.device.binding:
|
||||||
|
continue
|
||||||
|
act.device = act.device.binding.device
|
||||||
|
|
||||||
|
|
||||||
|
def change_lot():
|
||||||
|
for placeholder in Placeholder.query.all():
|
||||||
|
device = placeholder.device
|
||||||
|
binding = placeholder.binding
|
||||||
|
if not device or not binding:
|
||||||
|
continue
|
||||||
|
lots = [x for x in device.lots]
|
||||||
|
for lot in lots:
|
||||||
|
for rel_lot in LotDevice.query.filter_by(
|
||||||
|
lot_id=lot.id, device_id=device.id
|
||||||
|
):
|
||||||
|
if binding:
|
||||||
|
rel_lot.device_id = binding.id
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def change_tags():
|
||||||
|
for placeholder in Placeholder.query.all():
|
||||||
|
device = placeholder.device
|
||||||
|
binding = placeholder.binding
|
||||||
|
if not device or not binding:
|
||||||
|
continue
|
||||||
|
tags = [x for x in device.tags]
|
||||||
|
for tag in tags:
|
||||||
|
tag.device = binding
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_manual_actions():
|
||||||
|
MANUAL_ACTIONS = (
|
||||||
|
Recycling,
|
||||||
|
Use,
|
||||||
|
Refurbish,
|
||||||
|
Management,
|
||||||
|
Allocate,
|
||||||
|
Deallocate,
|
||||||
|
ToPrepare,
|
||||||
|
Prepare,
|
||||||
|
DataWipe,
|
||||||
|
ToRepair,
|
||||||
|
Ready,
|
||||||
|
Transfer,
|
||||||
|
)
|
||||||
|
|
||||||
|
for action in MANUAL_ACTIONS:
|
||||||
|
remove_change_device(action)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_change_device(action):
|
||||||
|
for ac in action.query.all():
|
||||||
|
if hasattr(ac, 'device'):
|
||||||
|
if not ac.device.placeholder:
|
||||||
|
continue
|
||||||
|
if not ac.device.placeholder.binding:
|
||||||
|
continue
|
||||||
|
ac.device = ac.device.placeholder.binding
|
||||||
|
|
||||||
|
if hasattr(ac, 'devices'):
|
||||||
|
for act in ActionDevice.query.filter_by(action_id=ac.id):
|
||||||
|
if not act.device.placeholder:
|
||||||
|
continue
|
||||||
|
if not act.device.placeholder.binding:
|
||||||
|
continue
|
||||||
|
act.device = act.device.placeholder.binding
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_placeholders():
|
||||||
|
devices = []
|
||||||
|
for placeholder in Placeholder.query.all():
|
||||||
|
device = placeholder.device
|
||||||
|
binding = placeholder.binding
|
||||||
|
if not device or not binding:
|
||||||
|
continue
|
||||||
|
devices.append(placeholder.device.id)
|
||||||
|
|
||||||
|
for dev in Device.query.filter(Device.id.in_(devices)):
|
||||||
|
db.session.delete(dev)
|
||||||
|
|
||||||
|
for placeholder in Placeholder.query.all():
|
||||||
|
device = placeholder.device
|
||||||
|
binding = placeholder.binding
|
||||||
|
if not device or not binding:
|
||||||
|
continue
|
||||||
|
for plog in PlaceholdersLog.query.filter_by(placeholder=placeholder).all():
|
||||||
|
db.session.delete(plog)
|
||||||
|
|
||||||
|
db.session.delete(placeholder)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
con = op.get_bind()
|
||||||
|
devices = con.execute(f'select * from {get_inv()}.device')
|
||||||
|
if not list(devices):
|
||||||
|
return
|
||||||
|
|
||||||
|
init_app()
|
||||||
|
clone_computers()
|
||||||
|
manual_actions()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
con = op.get_bind()
|
||||||
|
devices = con.execute(f'select * from {get_inv()}.device')
|
||||||
|
if not list(devices):
|
||||||
|
return
|
||||||
|
|
||||||
|
init_app()
|
||||||
|
remove_manual_actions()
|
||||||
|
change_lot()
|
||||||
|
change_tags()
|
||||||
|
remove_placeholders()
|
|
@ -76,7 +76,10 @@ class Action(Thing):
|
||||||
if 'end_time' in data and data['end_time'].replace(tzinfo=tzutc()) < unix_time:
|
if 'end_time' in data and data['end_time'].replace(tzinfo=tzutc()) < unix_time:
|
||||||
data['end_time'] = unix_time
|
data['end_time'] = unix_time
|
||||||
|
|
||||||
if 'start_time' in data and data['start_time'].replace(tzinfo=tzutc()) < unix_time:
|
if (
|
||||||
|
'start_time' in data
|
||||||
|
and data['start_time'].replace(tzinfo=tzutc()) < unix_time
|
||||||
|
):
|
||||||
data['start_time'] = unix_time
|
data['start_time'] = unix_time
|
||||||
|
|
||||||
if data.get('end_time') and data.get('start_time'):
|
if data.get('end_time') and data.get('start_time'):
|
||||||
|
@ -930,6 +933,10 @@ class Delete(ActionWithMultipleDevicesCheckingOwner):
|
||||||
for dev in data['devices']:
|
for dev in data['devices']:
|
||||||
if dev.last_action_trading is None:
|
if dev.last_action_trading is None:
|
||||||
dev.active = False
|
dev.active = False
|
||||||
|
if dev.binding:
|
||||||
|
dev.binding.device.active = False
|
||||||
|
if dev.placeholder:
|
||||||
|
dev.placeholder.device.active = False
|
||||||
|
|
||||||
|
|
||||||
class Migrate(ActionWithMultipleDevices):
|
class Migrate(ActionWithMultipleDevices):
|
||||||
|
|
|
@ -215,6 +215,24 @@ class Device(Thing):
|
||||||
def reverse_actions(self) -> list:
|
def reverse_actions(self) -> list:
|
||||||
return reversed(self.actions)
|
return reversed(self.actions)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def manual_actions(self) -> list:
|
||||||
|
mactions = [
|
||||||
|
'ActionDevice',
|
||||||
|
'Allocate',
|
||||||
|
'DataWipe',
|
||||||
|
'Deallocate',
|
||||||
|
'Management',
|
||||||
|
'Prepare',
|
||||||
|
'Ready',
|
||||||
|
'Recycling',
|
||||||
|
'Refurbish',
|
||||||
|
'ToPrepare',
|
||||||
|
'ToRepair',
|
||||||
|
'Use',
|
||||||
|
]
|
||||||
|
return [a for a in self.actions if a in mactions]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def actions(self) -> list:
|
def actions(self) -> list:
|
||||||
"""All the actions where the device participated, including:
|
"""All the actions where the device participated, including:
|
||||||
|
@ -411,7 +429,16 @@ class Device(Thing):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sid(self):
|
def sid(self):
|
||||||
|
actions = []
|
||||||
|
if self.placeholder and self.placeholder.binding:
|
||||||
|
actions = [
|
||||||
|
x
|
||||||
|
for x in self.placeholder.binding.actions
|
||||||
|
if x.t == 'Snapshot' and x.sid
|
||||||
|
]
|
||||||
|
else:
|
||||||
actions = [x for x in self.actions if x.t == 'Snapshot' and x.sid]
|
actions = [x for x in self.actions if x.t == 'Snapshot' and x.sid]
|
||||||
|
|
||||||
if actions:
|
if actions:
|
||||||
return actions[0].sid
|
return actions[0].sid
|
||||||
|
|
||||||
|
@ -601,6 +628,16 @@ class Device(Thing):
|
||||||
args[POLYMORPHIC_ON] = cls.type
|
args[POLYMORPHIC_ON] = cls.type
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
def phid(self):
|
||||||
|
if self.placeholder:
|
||||||
|
return self.placeholder.phid
|
||||||
|
if self.binding:
|
||||||
|
return self.binding.phid
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def list_tags(self):
|
||||||
|
return ', '.join([t.id for t in self.tags])
|
||||||
|
|
||||||
def appearance(self):
|
def appearance(self):
|
||||||
actions = copy.copy(self.actions)
|
actions = copy.copy(self.actions)
|
||||||
actions.sort(key=lambda x: x.created)
|
actions.sort(key=lambda x: x.created)
|
||||||
|
@ -833,6 +870,7 @@ class Placeholder(Thing):
|
||||||
pallet.comment = "used for identification where from where is this placeholders"
|
pallet.comment = "used for identification where from where is this placeholders"
|
||||||
info = db.Column(CIText())
|
info = db.Column(CIText())
|
||||||
info.comment = "more info of placeholders"
|
info.comment = "more info of placeholders"
|
||||||
|
is_abstract = db.Column(Boolean, default=False)
|
||||||
id_device_supplier = db.Column(CIText())
|
id_device_supplier = db.Column(CIText())
|
||||||
id_device_supplier.comment = (
|
id_device_supplier.comment = (
|
||||||
"Identification used for one supplier of one placeholders"
|
"Identification used for one supplier of one placeholders"
|
||||||
|
@ -845,7 +883,7 @@ class Placeholder(Thing):
|
||||||
)
|
)
|
||||||
device = db.relationship(
|
device = db.relationship(
|
||||||
Device,
|
Device,
|
||||||
backref=backref('placeholder', lazy=True, uselist=False),
|
backref=backref('placeholder', lazy=True, cascade="all, delete-orphan", uselist=False),
|
||||||
primaryjoin=device_id == Device.id,
|
primaryjoin=device_id == Device.id,
|
||||||
)
|
)
|
||||||
device_id.comment = "datas of the placeholder"
|
device_id.comment = "datas of the placeholder"
|
||||||
|
@ -861,6 +899,13 @@ class Placeholder(Thing):
|
||||||
primaryjoin=binding_id == Device.id,
|
primaryjoin=binding_id == Device.id,
|
||||||
)
|
)
|
||||||
binding_id.comment = "binding placeholder with workbench device"
|
binding_id.comment = "binding placeholder with workbench device"
|
||||||
|
owner_id = db.Column(
|
||||||
|
UUID(as_uuid=True),
|
||||||
|
db.ForeignKey(User.id),
|
||||||
|
nullable=False,
|
||||||
|
default=lambda: g.user.id,
|
||||||
|
)
|
||||||
|
owner = db.relationship(User, primaryjoin=owner_id == User.id)
|
||||||
|
|
||||||
|
|
||||||
class Computer(Device):
|
class Computer(Device):
|
||||||
|
@ -1481,9 +1526,9 @@ def create_code_tag(mapper, connection, device):
|
||||||
"""
|
"""
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
|
|
||||||
if isinstance(device, Computer):
|
if isinstance(device, Computer) and not device.placeholder:
|
||||||
tag = Tag(device_id=device.id, id=device.devicehub_id)
|
tag = Tag(device_id=device.id, id=device.devicehub_id)
|
||||||
db.session.add(tag)
|
db.session.add(tag)
|
||||||
|
|
||||||
|
|
||||||
event.listen(Device, 'after_insert', create_code_tag, propagate=True)
|
# event.listen(Device, 'after_insert', create_code_tag, propagate=True)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import copy
|
||||||
import difflib
|
import difflib
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
|
@ -87,6 +88,7 @@ class Sync:
|
||||||
# We only want to perform Add/Remove to not new components
|
# We only want to perform Add/Remove to not new components
|
||||||
actions = self.add_remove(db_device, not_new_components)
|
actions = self.add_remove(db_device, not_new_components)
|
||||||
db_device.components = db_components
|
db_device.components = db_components
|
||||||
|
self.create_placeholder(db_device)
|
||||||
return db_device, actions
|
return db_device, actions
|
||||||
|
|
||||||
def execute_register_component(
|
def execute_register_component(
|
||||||
|
@ -113,6 +115,7 @@ class Sync:
|
||||||
- A flag stating if the device is new or it already
|
- A flag stating if the device is new or it already
|
||||||
existed in the DB.
|
existed in the DB.
|
||||||
"""
|
"""
|
||||||
|
# if device.serial_number == 'b8oaas048286':
|
||||||
assert inspect(component).transient, 'Component should not be synced from DB'
|
assert inspect(component).transient, 'Component should not be synced from DB'
|
||||||
# if not is a DataStorage, then need build a new one
|
# if not is a DataStorage, then need build a new one
|
||||||
if component.t in DEVICES_ALLOW_DUPLICITY:
|
if component.t in DEVICES_ALLOW_DUPLICITY:
|
||||||
|
@ -124,7 +127,7 @@ class Sync:
|
||||||
try:
|
try:
|
||||||
if component.hid:
|
if component.hid:
|
||||||
db_component = Device.query.filter_by(
|
db_component = Device.query.filter_by(
|
||||||
hid=component.hid, owner_id=g.user.id
|
hid=component.hid, owner_id=g.user.id, placeholder=None
|
||||||
).one()
|
).one()
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
db_component, Device
|
db_component, Device
|
||||||
|
@ -183,18 +186,24 @@ class Sync:
|
||||||
if device.system_uuid:
|
if device.system_uuid:
|
||||||
with suppress(ResourceNotFound):
|
with suppress(ResourceNotFound):
|
||||||
db_device = Computer.query.filter_by(
|
db_device = Computer.query.filter_by(
|
||||||
system_uuid=device.system_uuid, owner_id=g.user.id, active=True
|
system_uuid=device.system_uuid,
|
||||||
|
owner_id=g.user.id,
|
||||||
|
active=True,
|
||||||
|
placeholder=None,
|
||||||
).one()
|
).one()
|
||||||
# if no there are any Computer by uuid search by hid
|
# if no there are any Computer by uuid search by hid
|
||||||
if not db_device and device.hid:
|
if not db_device and device.hid:
|
||||||
with suppress(ResourceNotFound):
|
with suppress(ResourceNotFound):
|
||||||
db_device = Device.query.filter_by(
|
db_device = Device.query.filter_by(
|
||||||
hid=device.hid, owner_id=g.user.id, active=True
|
hid=device.hid,
|
||||||
|
owner_id=g.user.id,
|
||||||
|
active=True,
|
||||||
|
placeholder=None,
|
||||||
).one()
|
).one()
|
||||||
elif device.hid:
|
elif device.hid:
|
||||||
with suppress(ResourceNotFound):
|
with suppress(ResourceNotFound):
|
||||||
db_device = Device.query.filter_by(
|
db_device = Device.query.filter_by(
|
||||||
hid=device.hid, owner_id=g.user.id, active=True
|
hid=device.hid, owner_id=g.user.id, active=True, placeholder=None
|
||||||
).one()
|
).one()
|
||||||
|
|
||||||
if db_device and db_device.allocated:
|
if db_device and db_device.allocated:
|
||||||
|
@ -278,22 +287,40 @@ class Sync:
|
||||||
if hasattr(device, 'system_uuid') and device.system_uuid:
|
if hasattr(device, 'system_uuid') and device.system_uuid:
|
||||||
db_device.system_uuid = device.system_uuid
|
db_device.system_uuid = device.system_uuid
|
||||||
|
|
||||||
if device.placeholder and db_device.placeholder:
|
@staticmethod
|
||||||
db_device.placeholder.pallet = device.placeholder.pallet
|
def create_placeholder(device: Device):
|
||||||
db_device.placeholder.info = device.placeholder.info
|
"""If the device is new, we need create automaticaly a new placeholder"""
|
||||||
db_device.placeholder.id_device_supplier = (
|
if device.binding:
|
||||||
device.placeholder.id_device_supplier
|
return
|
||||||
|
dict_device = copy.copy(device.__dict__)
|
||||||
|
dict_device.pop('_sa_instance_state')
|
||||||
|
dict_device.pop('id', None)
|
||||||
|
dict_device.pop('devicehub_id', None)
|
||||||
|
dict_device.pop('actions_multiple', None)
|
||||||
|
dict_device.pop('actions_one', None)
|
||||||
|
dict_device.pop('components', None)
|
||||||
|
dev_placeholder = device.__class__(**dict_device)
|
||||||
|
for c in device.components:
|
||||||
|
c_dict = copy.copy(c.__dict__)
|
||||||
|
c_dict.pop('_sa_instance_state')
|
||||||
|
c_dict.pop('id', None)
|
||||||
|
c_dict.pop('devicehub_id', None)
|
||||||
|
c_dict.pop('actions_multiple', None)
|
||||||
|
c_dict.pop('actions_one', None)
|
||||||
|
c_placeholder = c.__class__(**c_dict)
|
||||||
|
c_placeholder.parent = dev_placeholder
|
||||||
|
c.parent = device
|
||||||
|
component_placeholder = Placeholder(
|
||||||
|
device=c_placeholder, binding=c, is_abstract=True
|
||||||
)
|
)
|
||||||
db_device.sku = device.sku
|
db.session.add(c_placeholder)
|
||||||
db_device.image = device.image
|
db.session.add(component_placeholder)
|
||||||
db_device.brand = device.brand
|
|
||||||
db_device.generation = device.generation
|
placeholder = Placeholder(
|
||||||
db_device.variant = device.variant
|
device=dev_placeholder, binding=device, is_abstract=True
|
||||||
db_device.version = device.version
|
)
|
||||||
db_device.width = device.width
|
db.session.add(dev_placeholder)
|
||||||
db_device.height = device.height
|
db.session.add(placeholder)
|
||||||
db_device.depth = device.depth
|
|
||||||
db_device.weight = device.weight
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_remove(device: Computer, components: Set[Component]) -> OrderedSet:
|
def add_remove(device: Computer, components: Set[Component]) -> OrderedSet:
|
||||||
|
|
|
@ -3,28 +3,33 @@ import uuid
|
||||||
from itertools import filterfalse
|
from itertools import filterfalse
|
||||||
|
|
||||||
import marshmallow
|
import marshmallow
|
||||||
from flask import g, current_app as app, render_template, request, Response
|
from flask import Response
|
||||||
|
from flask import current_app as app
|
||||||
|
from flask import g, render_template, request
|
||||||
from flask.json import jsonify
|
from flask.json import jsonify
|
||||||
from flask_sqlalchemy import Pagination
|
from flask_sqlalchemy import Pagination
|
||||||
|
from marshmallow import Schema as MarshmallowSchema
|
||||||
|
from marshmallow import fields
|
||||||
|
from marshmallow import fields as f
|
||||||
|
from marshmallow import validate as v
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
from marshmallow import fields, fields as f, validate as v, Schema as MarshmallowSchema
|
|
||||||
from teal import query
|
from teal import query
|
||||||
from teal.db import ResourceNotFound
|
|
||||||
from teal.cache import cache
|
from teal.cache import cache
|
||||||
from teal.resource import View
|
from teal.db import ResourceNotFound
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
|
from teal.resource import View
|
||||||
|
|
||||||
from ereuse_devicehub import auth
|
from ereuse_devicehub import auth
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.query import SearchQueryParser, things_response
|
from ereuse_devicehub.query import SearchQueryParser, things_response
|
||||||
from ereuse_devicehub.resources import search
|
from ereuse_devicehub.resources import search
|
||||||
from ereuse_devicehub.resources.action import models as actions
|
from ereuse_devicehub.resources.action import models as actions
|
||||||
|
from ereuse_devicehub.resources.action.models import Trade
|
||||||
from ereuse_devicehub.resources.device import states
|
from ereuse_devicehub.resources.device import states
|
||||||
from ereuse_devicehub.resources.device.models import Device, Manufacturer, Computer
|
from ereuse_devicehub.resources.device.models import Computer, Device, Manufacturer
|
||||||
from ereuse_devicehub.resources.device.search import DeviceSearch
|
from ereuse_devicehub.resources.device.search import DeviceSearch
|
||||||
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
from ereuse_devicehub.resources.enums import SnapshotSoftware
|
||||||
from ereuse_devicehub.resources.lot.models import LotDeviceDescendants
|
from ereuse_devicehub.resources.lot.models import LotDeviceDescendants
|
||||||
from ereuse_devicehub.resources.action.models import Trade
|
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,15 +66,16 @@ class Filters(query.Query):
|
||||||
manufacturer = query.ILike(Device.manufacturer)
|
manufacturer = query.ILike(Device.manufacturer)
|
||||||
serialNumber = query.ILike(Device.serial_number)
|
serialNumber = query.ILike(Device.serial_number)
|
||||||
# todo test query for rating (and possibly other filters)
|
# todo test query for rating (and possibly other filters)
|
||||||
rating = query.Join((Device.id == actions.ActionWithOneDevice.device_id)
|
rating = query.Join(
|
||||||
|
(Device.id == actions.ActionWithOneDevice.device_id)
|
||||||
& (actions.ActionWithOneDevice.id == actions.Rate.id),
|
& (actions.ActionWithOneDevice.id == actions.Rate.id),
|
||||||
RateQ)
|
RateQ,
|
||||||
|
)
|
||||||
tag = query.Join(Device.id == Tag.device_id, TagQ)
|
tag = query.Join(Device.id == Tag.device_id, TagQ)
|
||||||
# todo This part of the query is really slow
|
# todo This part of the query is really slow
|
||||||
# And forces usage of distinct, as it returns many rows
|
# And forces usage of distinct, as it returns many rows
|
||||||
# due to having multiple paths to the same
|
# due to having multiple paths to the same
|
||||||
lot = query.Join((Device.id == LotDeviceDescendants.device_id),
|
lot = query.Join((Device.id == LotDeviceDescendants.device_id), LotQ)
|
||||||
LotQ)
|
|
||||||
|
|
||||||
|
|
||||||
class Sorting(query.Sort):
|
class Sorting(query.Sort):
|
||||||
|
@ -104,12 +110,15 @@ class DeviceView(View):
|
||||||
return super().get(id)
|
return super().get(id)
|
||||||
|
|
||||||
def patch(self, id):
|
def patch(self, id):
|
||||||
dev = Device.query.filter_by(id=id, owner_id=g.user.id, active=True).one()
|
dev = Device.query.filter_by(
|
||||||
|
id=id, owner_id=g.user.id, active=True
|
||||||
|
).one()
|
||||||
if isinstance(dev, Computer):
|
if isinstance(dev, Computer):
|
||||||
resource_def = app.resources['Computer']
|
resource_def = app.resources['Computer']
|
||||||
# TODO check how to handle the 'actions_one'
|
# TODO check how to handle the 'actions_one'
|
||||||
patch_schema = resource_def.SCHEMA(
|
patch_schema = resource_def.SCHEMA(
|
||||||
only=['transfer_state', 'actions_one'], partial=True)
|
only=['transfer_state', 'actions_one'], partial=True
|
||||||
|
)
|
||||||
json = request.get_json(schema=patch_schema)
|
json = request.get_json(schema=patch_schema)
|
||||||
# TODO check how to handle the 'actions_one'
|
# TODO check how to handle the 'actions_one'
|
||||||
json.pop('actions_one')
|
json.pop('actions_one')
|
||||||
|
@ -129,12 +138,16 @@ class DeviceView(View):
|
||||||
return self.one_private(id)
|
return self.one_private(id)
|
||||||
|
|
||||||
def one_public(self, id: int):
|
def one_public(self, id: int):
|
||||||
device = Device.query.filter_by(devicehub_id=id, active=True).one()
|
device = Device.query.filter_by(
|
||||||
|
devicehub_id=id, active=True
|
||||||
|
).one()
|
||||||
return render_template('devices/layout.html', device=device, states=states)
|
return render_template('devices/layout.html', device=device, states=states)
|
||||||
|
|
||||||
@auth.Auth.requires_auth
|
@auth.Auth.requires_auth
|
||||||
def one_private(self, id: str):
|
def one_private(self, id: str):
|
||||||
device = Device.query.filter_by(devicehub_id=id, owner_id=g.user.id, active=True).first()
|
device = Device.query.filter_by(
|
||||||
|
devicehub_id=id, owner_id=g.user.id, active=True
|
||||||
|
).first()
|
||||||
if not device:
|
if not device:
|
||||||
return self.one_public(id)
|
return self.one_public(id)
|
||||||
return self.schema.jsonify(device)
|
return self.schema.jsonify(device)
|
||||||
|
@ -148,7 +161,11 @@ class DeviceView(View):
|
||||||
devices = query.paginate(page=args['page'], per_page=30) # type: Pagination
|
devices = query.paginate(page=args['page'], per_page=30) # type: Pagination
|
||||||
return things_response(
|
return things_response(
|
||||||
self.schema.dump(devices.items, many=True, nested=1),
|
self.schema.dump(devices.items, many=True, nested=1),
|
||||||
devices.page, devices.per_page, devices.total, devices.prev_num, devices.next_num
|
devices.page,
|
||||||
|
devices.per_page,
|
||||||
|
devices.total,
|
||||||
|
devices.prev_num,
|
||||||
|
devices.next_num,
|
||||||
)
|
)
|
||||||
|
|
||||||
def query(self, args):
|
def query(self, args):
|
||||||
|
@ -158,9 +175,11 @@ class DeviceView(View):
|
||||||
|
|
||||||
trades_dev_ids = {d.id for t in trades for d in t.devices}
|
trades_dev_ids = {d.id for t in trades for d in t.devices}
|
||||||
|
|
||||||
query = Device.query.filter(Device.active == True).filter(
|
query = (
|
||||||
(Device.owner_id == g.user.id) | (Device.id.in_(trades_dev_ids))
|
Device.query.filter(Device.active == True)
|
||||||
).distinct()
|
.filter((Device.owner_id == g.user.id) | (Device.id.in_(trades_dev_ids)))
|
||||||
|
.distinct()
|
||||||
|
)
|
||||||
|
|
||||||
unassign = args.get('unassign', None)
|
unassign = args.get('unassign', None)
|
||||||
search_p = args.get('search', None)
|
search_p = args.get('search', None)
|
||||||
|
@ -168,14 +187,18 @@ class DeviceView(View):
|
||||||
properties = DeviceSearch.properties
|
properties = DeviceSearch.properties
|
||||||
tags = DeviceSearch.tags
|
tags = DeviceSearch.tags
|
||||||
devicehub_ids = DeviceSearch.devicehub_ids
|
devicehub_ids = DeviceSearch.devicehub_ids
|
||||||
query = query.join(DeviceSearch).filter(
|
query = (
|
||||||
search.Search.match(properties, search_p) |
|
query.join(DeviceSearch)
|
||||||
search.Search.match(tags, search_p) |
|
.filter(
|
||||||
search.Search.match(devicehub_ids, search_p)
|
search.Search.match(properties, search_p)
|
||||||
).order_by(
|
| search.Search.match(tags, search_p)
|
||||||
search.Search.rank(properties, search_p) +
|
| search.Search.match(devicehub_ids, search_p)
|
||||||
search.Search.rank(tags, search_p) +
|
)
|
||||||
search.Search.rank(devicehub_ids, search_p)
|
.order_by(
|
||||||
|
search.Search.rank(properties, search_p)
|
||||||
|
+ search.Search.rank(tags, search_p)
|
||||||
|
+ search.Search.rank(devicehub_ids, search_p)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unassign:
|
if unassign:
|
||||||
subquery = LotDeviceDescendants.query.with_entities(
|
subquery = LotDeviceDescendants.query.with_entities(
|
||||||
|
@ -221,10 +244,16 @@ class DeviceMergeView(View):
|
||||||
raise ValidationError('The devices is not the same type.')
|
raise ValidationError('The devices is not the same type.')
|
||||||
|
|
||||||
# Adding actions of self.with_device
|
# Adding actions of self.with_device
|
||||||
with_actions_one = [a for a in self.with_device.actions
|
with_actions_one = [
|
||||||
if isinstance(a, actions.ActionWithOneDevice)]
|
a
|
||||||
with_actions_multiple = [a for a in self.with_device.actions
|
for a in self.with_device.actions
|
||||||
if isinstance(a, actions.ActionWithMultipleDevices)]
|
if isinstance(a, actions.ActionWithOneDevice)
|
||||||
|
]
|
||||||
|
with_actions_multiple = [
|
||||||
|
a
|
||||||
|
for a in self.with_device.actions
|
||||||
|
if isinstance(a, actions.ActionWithMultipleDevices)
|
||||||
|
]
|
||||||
|
|
||||||
# Moving the tags from `with_device` to `base_device`
|
# Moving the tags from `with_device` to `base_device`
|
||||||
# Union of tags the device had plus the (potentially) new ones
|
# Union of tags the device had plus the (potentially) new ones
|
||||||
|
@ -269,20 +298,22 @@ class DeviceMergeView(View):
|
||||||
|
|
||||||
class ManufacturerView(View):
|
class ManufacturerView(View):
|
||||||
class FindArgs(marshmallow.Schema):
|
class FindArgs(marshmallow.Schema):
|
||||||
search = 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):
|
||||||
search = args['search']
|
search = args['search']
|
||||||
manufacturers = Manufacturer.query \
|
manufacturers = Manufacturer.query.filter(
|
||||||
.filter(Manufacturer.name.ilike(search + '%')) \
|
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(
|
||||||
manufacturers.items,
|
manufacturers.items, many=True, nested=1
|
||||||
many=True,
|
|
||||||
nested=1
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ from citext import CIText
|
||||||
from flask import g
|
from flask import g
|
||||||
from sqlalchemy import TEXT
|
from sqlalchemy import TEXT
|
||||||
from sqlalchemy.dialects.postgresql import UUID
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy_utils import LtreeType
|
from sqlalchemy_utils import LtreeType
|
||||||
from sqlalchemy_utils.types.ltree import LQUERY
|
from sqlalchemy_utils.types.ltree import LQUERY
|
||||||
from teal.db import CASCADE_OWN, IntEnum, UUIDLtree, check_range
|
from teal.db import CASCADE_OWN, IntEnum, UUIDLtree, check_range
|
||||||
|
@ -243,6 +244,10 @@ class LotDevice(db.Model):
|
||||||
)
|
)
|
||||||
author = db.relationship(User, primaryjoin=author_id == User.id)
|
author = db.relationship(User, primaryjoin=author_id == User.id)
|
||||||
author_id.comment = """The user that put the device in the lot."""
|
author_id.comment = """The user that put the device in the lot."""
|
||||||
|
device = relationship(
|
||||||
|
'Device',
|
||||||
|
primaryjoin='Device.id == LotDevice.device_id',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Path(db.Model):
|
class Path(db.Model):
|
||||||
|
|
|
@ -53,6 +53,8 @@ function save_settings() {
|
||||||
data['logo'] = $("#logoCheck").prop('checked');
|
data['logo'] = $("#logoCheck").prop('checked');
|
||||||
data['dhid'] = $("#dhidCheck").prop('checked');
|
data['dhid'] = $("#dhidCheck").prop('checked');
|
||||||
data['sid'] = $("#sidCheck").prop('checked');
|
data['sid'] = $("#sidCheck").prop('checked');
|
||||||
|
data['phid'] = $("#phidCheck").prop('checked');
|
||||||
|
data['tags'] = $("#tagsCheck").prop('checked');
|
||||||
data['qr'] = $("#qrCheck").prop('checked');
|
data['qr'] = $("#qrCheck").prop('checked');
|
||||||
data['serial_number'] = $("#serialNumberCheck").prop('checked');
|
data['serial_number'] = $("#serialNumberCheck").prop('checked');
|
||||||
data['manufacturer'] = $("#manufacturerCheck").prop('checked');
|
data['manufacturer'] = $("#manufacturerCheck").prop('checked');
|
||||||
|
@ -69,11 +71,13 @@ function load_settings() {
|
||||||
$("#qrCheck").prop('checked', data.qr);
|
$("#qrCheck").prop('checked', data.qr);
|
||||||
$("#dhidCheck").prop('checked', data.dhid);
|
$("#dhidCheck").prop('checked', data.dhid);
|
||||||
$("#sidCheck").prop('checked', data.sid);
|
$("#sidCheck").prop('checked', data.sid);
|
||||||
|
$("#phidCheck").prop('checked', data.phid);
|
||||||
|
$("#tagsCheck").prop('checked', data.tags);
|
||||||
$("#serialNumberCheck").prop('checked', data.serial_number);
|
$("#serialNumberCheck").prop('checked', data.serial_number);
|
||||||
$("#manufacturerCheck").prop('checked', data.manufacturer);
|
$("#manufacturerCheck").prop('checked', data.manufacturer);
|
||||||
$("#modelCheck").prop('checked', data.model);
|
$("#modelCheck").prop('checked', data.model);
|
||||||
if (data.logo) {
|
if (data.logo) {
|
||||||
$("#logoCheck").prop('checked', data.sid);
|
// $("#logoCheck").prop('checked', data.sid);
|
||||||
previewLogo(data.logoImg);
|
previewLogo(data.logoImg);
|
||||||
$("#logoCheck").prop('checked', data.logo);
|
$("#logoCheck").prop('checked', data.logo);
|
||||||
} else {
|
} else {
|
||||||
|
@ -89,6 +93,8 @@ function reset_settings() {
|
||||||
$("#qrCheck").prop('checked', true);
|
$("#qrCheck").prop('checked', true);
|
||||||
$("#dhidCheck").prop('checked', true);
|
$("#dhidCheck").prop('checked', true);
|
||||||
$("#sidCheck").prop('checked', true);
|
$("#sidCheck").prop('checked', true);
|
||||||
|
$("#phidCheck").prop('checked', true);
|
||||||
|
$("#tagsCheck").prop('checked', false);
|
||||||
$("#serialNumberCheck").prop('checked', false);
|
$("#serialNumberCheck").prop('checked', false);
|
||||||
$("#logoCheck").prop('checked', false);
|
$("#logoCheck").prop('checked', false);
|
||||||
$("#manufacturerCheck").prop('checked', false);
|
$("#manufacturerCheck").prop('checked', false);
|
||||||
|
@ -135,6 +141,18 @@ function change_check() {
|
||||||
$(".sid").hide();
|
$(".sid").hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ($("#phidCheck").prop('checked')) {
|
||||||
|
$(".phid").show();
|
||||||
|
} else {
|
||||||
|
$(".phid").hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($("#tagsCheck").prop('checked')) {
|
||||||
|
$(".tags").show();
|
||||||
|
} else {
|
||||||
|
$(".tags").hide();
|
||||||
|
};
|
||||||
|
|
||||||
if ($("#serialNumberCheck").prop('checked')) {
|
if ($("#serialNumberCheck").prop('checked')) {
|
||||||
$(".serial_number").show();
|
$(".serial_number").show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,6 +208,12 @@ function printpdf() {
|
||||||
if ($("#sidCheck").prop('checked')) {
|
if ($("#sidCheck").prop('checked')) {
|
||||||
height_need += line;
|
height_need += line;
|
||||||
};
|
};
|
||||||
|
if ($("#phidCheck").prop('checked')) {
|
||||||
|
height_need += line;
|
||||||
|
};
|
||||||
|
if ($("#tagsCheck").prop('checked')) {
|
||||||
|
height_need += line;
|
||||||
|
};
|
||||||
if ($("#serialNumberCheck").prop('checked')) {
|
if ($("#serialNumberCheck").prop('checked')) {
|
||||||
height_need += line;
|
height_need += line;
|
||||||
};
|
};
|
||||||
|
@ -248,6 +272,22 @@ function printpdf() {
|
||||||
hspace += line;
|
hspace += line;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if ($("#phidCheck").prop('checked')) {
|
||||||
|
var sn = $(y).data('phid');
|
||||||
|
pdf.setFontSize(12);
|
||||||
|
if (sn) {
|
||||||
|
pdf.text(String(sn), border, hspace);
|
||||||
|
hspace += line;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ($("#tagsCheck").prop('checked')) {
|
||||||
|
var sn = $(y).data('tags');
|
||||||
|
pdf.setFontSize(12);
|
||||||
|
if (sn) {
|
||||||
|
pdf.text(String(sn), border, hspace);
|
||||||
|
hspace += line;
|
||||||
|
}
|
||||||
|
};
|
||||||
if ($("#serialNumberCheck").prop('checked')) {
|
if ($("#serialNumberCheck").prop('checked')) {
|
||||||
var sn = $(y).data('serial-number');
|
var sn = $(y).data('serial-number');
|
||||||
pdf.setFontSize(12);
|
pdf.setFontSize(12);
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
{% extends "ereuse_devicehub/base_site.html" %}
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<div class="pagetitle">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<nav>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<!-- TODO@slamora replace with lot list URL when exists -->
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div><!-- End Page Title -->
|
||||||
|
|
||||||
|
<section class="section profile">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="pt-4 pb-2">
|
||||||
|
<h5 class="card-title text-center pb-0 fs-4">{{ title }}</h5>
|
||||||
|
<p class="text-center">Please check that the information is correct.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Basic Data</th>
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">PHID:</th>
|
||||||
|
<td class="table-success text-right">{{ placeholder.phid or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.placeholder.phid or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Manufacturer:</th>
|
||||||
|
<td class="table-success text-right">{{ placeholder.device.manufacturer or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.manufacturer or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Model:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.model or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.model or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Serial Number:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.serial_number or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.serial_number or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Brand:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.brand or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.brand or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Sku:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.sku or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.sku or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Generation:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.generation or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.generation or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Version:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.version or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.version or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Weight:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.weight or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.weight or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Width:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.width or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.width or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Height:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.height or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.height or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Depth:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.depth or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.depth or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Color:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.color or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.color or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Production date:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.production_date or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.production_date or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Variant:</th>
|
||||||
|
<td class="table-success">{{ placeholder.device.variant or '' }}</td>
|
||||||
|
<td class="table-danger">{{ device.variant or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.components or device.components %}
|
||||||
|
<h2>Components</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success text-right">
|
||||||
|
{% for c in placeholder.device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger">
|
||||||
|
{% for c in device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.actions or device.actions %}
|
||||||
|
<h2>Actions</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success text-right">
|
||||||
|
{% for a in placeholder.device.actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger">
|
||||||
|
{% for a in device.actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form method="post">
|
||||||
|
<a href="{{ url_for('inventory.device_details', id=device.placeholder.binding.devicehub_id) }}" class="btn btn-danger">Cancel</a>
|
||||||
|
<button class="btn btn-primary" type="submit">Confirm</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-8">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock main %}
|
|
@ -22,9 +22,21 @@
|
||||||
<!-- Bordered Tabs -->
|
<!-- Bordered Tabs -->
|
||||||
<ul class="nav nav-tabs nav-tabs-bordered">
|
<ul class="nav nav-tabs nav-tabs-bordered">
|
||||||
|
|
||||||
|
{% if placeholder %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#type">Type</button>
|
<a class="nav-link" href="{{ url_for('inventory.device_details', id=placeholder.device.devicehub_id) }}">Placeholder device</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#type">General details</button>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if placeholder.binding %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ url_for('inventory.device_details', id=placeholder.binding.devicehub_id) }}">Workbench device</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ device.public_link }}" target="_blank">Web</a>
|
<a class="nav-link" href="{{ device.public_link }}" target="_blank">Web</a>
|
||||||
|
@ -50,10 +62,22 @@
|
||||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button>
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
{% if device.binding %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#binding">Binding</button>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if device.placeholder and placeholder.binding %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ url_for('inventory.unbinding', phid=placeholder.phid) }}">Unbinding</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content pt-2">
|
<div class="tab-content pt-2">
|
||||||
|
|
||||||
<div class="tab-pane fade show active" id="type">
|
<div class="tab-pane fade {% if active_binding %}profile-overview{% else %}show active{% endif %}" id="type">
|
||||||
<h5 class="card-title">Details</h5>
|
<h5 class="card-title">Details</h5>
|
||||||
{% if device.placeholder %}(<a href="{{ url_for('inventory.device_edit', id=device.devicehub_id)}}">edit</a>){% endif %}
|
{% if device.placeholder %}(<a href="{{ url_for('inventory.device_edit', id=device.devicehub_id)}}">edit</a>){% endif %}
|
||||||
|
|
||||||
|
@ -204,6 +228,42 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if placeholder.binding %}
|
||||||
|
<div class="tab-pane fade {% if active_binding %}show active{% else %}profile-overview{% endif %}" id="binding">
|
||||||
|
<h5 class="card-title">Binding</h5>
|
||||||
|
<div class="list-group col-6">
|
||||||
|
<p>
|
||||||
|
Be careful, binding implies changes in the data of a device that affect its
|
||||||
|
traceability.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="list-group col-6">
|
||||||
|
<form action="{{ url_for('inventory.device_details', id=placeholder.binding.devicehub_id) }}" method="post">
|
||||||
|
{{ form_binding.csrf_token }}
|
||||||
|
{% for field in form_binding %}
|
||||||
|
{% if field != form_binding.csrf_token %}
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
{{ field.label(class_="form-label") }}:
|
||||||
|
{{ field }}
|
||||||
|
{% if field.errors %}
|
||||||
|
<p class="text-danger">
|
||||||
|
{% for error in field.errors %}
|
||||||
|
{{ error }}<br/>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<div class="col-12 mt-2">
|
||||||
|
<input type="submit" class="btn btn-primary" value="Search" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -401,6 +401,8 @@
|
||||||
<th scope="col">Select</th>
|
<th scope="col">Select</th>
|
||||||
<th scope="col">Title</th>
|
<th scope="col">Title</th>
|
||||||
<th scope="col">DHID</th>
|
<th scope="col">DHID</th>
|
||||||
|
<th scope="col">PHID</th>
|
||||||
|
<th scope="col">Is Abstract</th>
|
||||||
<th scope="col">Unique Identifiers</th>
|
<th scope="col">Unique Identifiers</th>
|
||||||
<th scope="col">Lifecycle Status</th>
|
<th scope="col">Lifecycle Status</th>
|
||||||
<th scope="col">Allocated Status</th>
|
<th scope="col">Allocated Status</th>
|
||||||
|
@ -442,6 +444,12 @@
|
||||||
{{ dev.devicehub_id }}
|
{{ dev.devicehub_id }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ dev.binding and dev.binding.phid or dev.placeholder and dev.placeholder.phid or '' }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ dev.binding and dev.binding.is_abstract and '✓' or dev.placeholder and dev.placeholder.is_abstract and '✓' or '' }}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% for t in dev.tags | sort(attribute="id") %}
|
{% for t in dev.tags | sort(attribute="id") %}
|
||||||
<a href="{{ url_for('labels.label_details', id=t.id)}}">{{ t.id }}</a>
|
<a href="{{ url_for('labels.label_details', id=t.id)}}">{{ t.id }}</a>
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
{% extends "ereuse_devicehub/base_site.html" %}
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
<div class="pagetitle">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<nav>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<!-- TODO@slamora replace with lot list URL when exists -->
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div><!-- End Page Title -->
|
||||||
|
|
||||||
|
<section class="section profile">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<div class="pt-4 pb-2">
|
||||||
|
<h5 class="card-title text-center pb-0 fs-4">{{ title }}</h5>
|
||||||
|
<p class="text-center">Please check that the information is correct.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Basic Data</th>
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">PHID:</th>
|
||||||
|
<td class="table-success"></td>
|
||||||
|
<td class="table-danger text-right">{{ placeholder.phid or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Manufacturer:</th>
|
||||||
|
<td class="table-success">{{ device.manufacturer or '' }}</td>
|
||||||
|
<td class="table-danger text-right">{{ placeholder.device.manufacturer or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Model:</th>
|
||||||
|
<td class="table-success">{{ device.model or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.model or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Serial Number:</th>
|
||||||
|
<td class="table-success">{{ device.serial_number or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.serial_number or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Brand:</th>
|
||||||
|
<td class="table-success">{{ device.brand or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.brand or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Sku:</th>
|
||||||
|
<td class="table-success">{{ device.sku or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.sku or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Generation:</th>
|
||||||
|
<td class="table-success">{{ device.generation or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.generation or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Version:</th>
|
||||||
|
<td class="table-success">{{ device.version or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.version or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Weight:</th>
|
||||||
|
<td class="table-success">{{ device.weight or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.weight or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Width:</th>
|
||||||
|
<td class="table-success">{{ device.width or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.width or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Height:</th>
|
||||||
|
<td class="table-success">{{ device.height or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.height or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Depth:</th>
|
||||||
|
<td class="table-success">{{ device.depth or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.depth or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Color:</th>
|
||||||
|
<td class="table-success">{{ device.color or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.color or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Production date:</th>
|
||||||
|
<td class="table-success">{{ device.production_date or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.production_date or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Variant:</th>
|
||||||
|
<td class="table-success">{{ device.variant or '' }}</td>
|
||||||
|
<td class="table-danger">{{ placeholder.device.variant or '' }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.components or device.components %}
|
||||||
|
<h2>Components</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success">
|
||||||
|
{% for c in device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger text-right">
|
||||||
|
{% for c in placeholder.device.components %}
|
||||||
|
* {{ c.verbose_name }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{% if placeholder.device.manual_actions or device.manual_actions %}
|
||||||
|
<h2>Actions</h2>
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr class="text-center">
|
||||||
|
<th scope="col">Info to be Entered</th>
|
||||||
|
<th scope="col">Info to be Decoupled</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="table-success">
|
||||||
|
{% for a in device.manual_actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
<td class="table-danger text-right">
|
||||||
|
{% for a in placeholder.device.manual_actions %}
|
||||||
|
* {{ a.t }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<form method="post">
|
||||||
|
<a href="{{ url_for('inventory.device_details', id=placeholder.device.devicehub_id) }}" class="btn btn-danger">Cancel</a>
|
||||||
|
<button class="btn btn-primary" type="submit">Confirm</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xl-8">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock main %}
|
|
@ -39,15 +39,33 @@
|
||||||
<b class="tag" data-serial-number="{{ dev.serial_number or '' }}"
|
<b class="tag" data-serial-number="{{ dev.serial_number or '' }}"
|
||||||
data-manufacturer="{{ dev.manufacturer or '' }}"
|
data-manufacturer="{{ dev.manufacturer or '' }}"
|
||||||
data-model="{{ dev.model or '' }}"
|
data-model="{{ dev.model or '' }}"
|
||||||
|
data-tags="{{ dev.list_tags() }}"
|
||||||
|
data-phid="{{ dev.phid() }}"
|
||||||
data-sid="{{ dev.sid or '' }}">{{ dev.devicehub_id }}</b>
|
data-sid="{{ dev.sid or '' }}">{{ dev.devicehub_id }}</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col sid" style="display: none">
|
</div>
|
||||||
|
<div class="row phid" style="display: none">
|
||||||
|
<div class="col">
|
||||||
|
<div>
|
||||||
|
<b>{{ dev.phid() }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row sid" style="display: none">
|
||||||
|
<div class="col">
|
||||||
<div>
|
<div>
|
||||||
<b>{{ dev.sid or '' }}</b>
|
<b>{{ dev.sid or '' }}</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row tags" style="display: none">
|
||||||
|
<div class="col">
|
||||||
|
<div>
|
||||||
|
<b>{{ dev.list_tags() }}</b>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row serial_number" style="display: none">
|
<div class="row serial_number" style="display: none">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div>
|
<div>
|
||||||
|
@ -125,10 +143,18 @@
|
||||||
<input class="form-check-input" name="dhid" type="checkbox" id="dhidCheck" checked="">
|
<input class="form-check-input" name="dhid" type="checkbox" id="dhidCheck" checked="">
|
||||||
<label class="form-check-label" for="dhidCheck">Dhid</label>
|
<label class="form-check-label" for="dhidCheck">Dhid</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-switch">
|
||||||
|
<input class="form-check-input" name="phid" type="checkbox" id="phidCheck">
|
||||||
|
<label class="form-check-label" for="phidCheck">Phid</label>
|
||||||
|
</div>
|
||||||
<div class="form-switch">
|
<div class="form-switch">
|
||||||
<input class="form-check-input" name="sid" type="checkbox" id="sidCheck">
|
<input class="form-check-input" name="sid" type="checkbox" id="sidCheck">
|
||||||
<label class="form-check-label" for="sidCheck">Sid</label>
|
<label class="form-check-label" for="sidCheck">Sid</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-switch">
|
||||||
|
<input class="form-check-input" name="tags" type="checkbox" id="tagsCheck">
|
||||||
|
<label class="form-check-label" for="tagsCheck">Tags</label>
|
||||||
|
</div>
|
||||||
<div class="form-switch">
|
<div class="form-switch">
|
||||||
<input class="form-check-input" name="serial_number" type="checkbox" id="serialNumberCheck">
|
<input class="form-check-input" name="serial_number" type="checkbox" id="serialNumberCheck">
|
||||||
<label class="form-check-label" for="serialNumberCheck">Serial number</label>
|
<label class="form-check-label" for="serialNumberCheck">Serial number</label>
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
"Type";"Chassis";"Serial Number";"Model";"Manufacturer";"Registered in";"Physical state";"Allocate state";"Lifecycle state";"Processor";"RAM (MB)";"Data Storage Size (MB)"
|
"Type";"Chassis";"Serial Number";"Model";"Manufacturer";"Registered in";"Physical state";"Allocate state";"Lifecycle state";"Processor";"RAM (MB)";"Data Storage Size (MB)"
|
||||||
"Desktop";"Microtower";"d1s";"d1ml";"d1mr";"Mon Aug 1 20:20:51 2022";"";"";"";"p1ml";"0";"0"
|
"Desktop";"Microtower";"d1s";"d1ml";"d1mr";"Tue Aug 2 12:57:43 2022";"";"";"";"p1ml";"0";"0"
|
||||||
|
"Desktop";"Microtower";"d1s";"d1ml";"d1mr";"Tue Aug 2 12:57:43 2022";"";"";"";"p1ml";"0";"0"
|
||||||
|
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -75,6 +75,8 @@ def test_api_docs(client: Client):
|
||||||
'/inventory/upload-placeholder/',
|
'/inventory/upload-placeholder/',
|
||||||
'/inventory/lot/{lot_id}/upload-placeholder/',
|
'/inventory/lot/{lot_id}/upload-placeholder/',
|
||||||
'/inventory/placeholder-logs/',
|
'/inventory/placeholder-logs/',
|
||||||
|
'/inventory/unbinding/{phid}/',
|
||||||
|
'/inventory/binding/{dhid}/{phid}/',
|
||||||
'/labels/',
|
'/labels/',
|
||||||
'/labels/add/',
|
'/labels/add/',
|
||||||
'/labels/print',
|
'/labels/print',
|
||||||
|
|
|
@ -347,7 +347,7 @@ def test_sync_execute_register_tag_linked_same_device():
|
||||||
pc.tags.add(Tag(id='foo'))
|
pc.tags.add(Tag(id='foo'))
|
||||||
db_pc = Sync().execute_register(pc)
|
db_pc = Sync().execute_register(pc)
|
||||||
assert db_pc.id == orig_pc.id
|
assert db_pc.id == orig_pc.id
|
||||||
assert len(db_pc.tags) == 2
|
assert len(db_pc.tags) == 1
|
||||||
for tag in db_pc.tags:
|
for tag in db_pc.tags:
|
||||||
assert tag.id in ['foo', db_pc.devicehub_id]
|
assert tag.id in ['foo', db_pc.devicehub_id]
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ def test_get_devices_permissions(app: Devicehub, user: UserClient, user2: UserCl
|
||||||
devices2, res2 = user2.get(url, None)
|
devices2, res2 = user2.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert res2.status_code == 200
|
assert res2.status_code == 200
|
||||||
assert len(devices['items']) == 1
|
assert len(devices['items']) == 2
|
||||||
assert len(devices2['items']) == 0
|
assert len(devices2['items']) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -515,13 +515,13 @@ def test_get_devices_unassigned(user: UserClient):
|
||||||
|
|
||||||
devices, res = user.get(url, None)
|
devices, res = user.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert len(devices['items']) == 1
|
assert len(devices['items']) == 2
|
||||||
|
|
||||||
url = '/devices/?filter={"type":["Computer"]}&unassign=1'
|
url = '/devices/?filter={"type":["Computer"]}&unassign=1'
|
||||||
|
|
||||||
devices, res = user.get(url, None)
|
devices, res = user.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert len(devices['items']) == 1
|
assert len(devices['items']) == 2
|
||||||
|
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
device_id = devices['items'][0]['id']
|
device_id = devices['items'][0]['id']
|
||||||
|
@ -537,13 +537,13 @@ def test_get_devices_unassigned(user: UserClient):
|
||||||
|
|
||||||
devices, res = user.get(url, None)
|
devices, res = user.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert len(devices['items']) == 1
|
assert len(devices['items']) == 2
|
||||||
|
|
||||||
url = '/devices/?filter={"type":["Computer"]}&unassign=1'
|
url = '/devices/?filter={"type":["Computer"]}&unassign=1'
|
||||||
|
|
||||||
devices, res = user.get(url, None)
|
devices, res = user.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert len(devices['items']) == 0
|
assert len(devices['items']) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -580,7 +580,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 = d.Laptop.query.one() # type: d.Laptop
|
pc = d.Laptop.query.filter_by(placeholder=None).one() # type: d.Laptop
|
||||||
assert format(pc) == 'Laptop 3: model 1000h, S/N 94oaaq021116'
|
assert format(pc) == 'Laptop 3: 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'
|
||||||
|
@ -589,12 +589,12 @@ def test_device_properties_format(app: Devicehub, user: UserClient):
|
||||||
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, d.NetworkAdapter))
|
net = next(c for c in pc.components if isinstance(c, d.NetworkAdapter))
|
||||||
assert format(net) == 'NetworkAdapter 4: model ar8121/ar8113/ar8114 ' \
|
assert format(net) == 'NetworkAdapter 5: 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 00:24:8C:7F:CF:2D – 100 Mbps'
|
assert format(net, 's') == 'qualcomm atheros 00:24:8C:7F:CF:2D – 100 Mbps'
|
||||||
hdd = next(c for c in pc.components if isinstance(c, d.DataStorage))
|
hdd = next(c for c in pc.components if isinstance(c, d.DataStorage))
|
||||||
assert format(hdd) == 'HardDrive 9: model st9160310as, S/N 5sv4tqa6'
|
assert format(hdd) == 'HardDrive 10: model st9160310as, S/N 5sv4tqa6'
|
||||||
assert format(hdd, 't') == 'HardDrive st9160310as'
|
assert format(hdd, 't') == 'HardDrive st9160310as'
|
||||||
assert format(hdd, 's') == 'seagate 5SV4TQA6 – 152 GB'
|
assert format(hdd, 's') == 'seagate 5SV4TQA6 – 152 GB'
|
||||||
|
|
||||||
|
@ -702,7 +702,7 @@ def test_hid_with_2networkadapters(app: Devicehub, user: UserClient):
|
||||||
|
|
||||||
laptop = devices['items'][0]
|
laptop = devices['items'][0]
|
||||||
assert laptop['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d'
|
assert laptop['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d'
|
||||||
assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 1
|
assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -723,7 +723,7 @@ def test_hid_with_2network_and_drop_no_mac_in_hid(app: Devicehub, user: UserClie
|
||||||
devices, _ = user.get(res=d.Device)
|
devices, _ = user.get(res=d.Device)
|
||||||
laptop = devices['items'][0]
|
laptop = devices['items'][0]
|
||||||
assert laptop['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d'
|
assert laptop['hid'] == 'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d'
|
||||||
assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 1
|
assert len([c for c in devices['items'] if c['type'] == 'Laptop']) == 2
|
||||||
assert len([c for c in laptop['components'] if c['type'] == 'NetworkAdapter']) == 1
|
assert len([c for c in laptop['components'] if c['type'] == 'NetworkAdapter']) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -746,22 +746,21 @@ def test_hid_with_2network_and_drop_mac_in_hid(app: Devicehub, user: UserClient)
|
||||||
user.post(json_encode(snapshot), res=m.Snapshot)
|
user.post(json_encode(snapshot), res=m.Snapshot)
|
||||||
devices, _ = user.get(res=d.Device)
|
devices, _ = user.get(res=d.Device)
|
||||||
laptops = [c for c in devices['items'] if c['type'] == 'Laptop']
|
laptops = [c for c in devices['items'] if c['type'] == 'Laptop']
|
||||||
assert len(laptops) == 2
|
assert len(laptops) == 4
|
||||||
hids = [h['hid'] for h in laptops]
|
hids = [laptops[0]['hid'], laptops[2]['hid']]
|
||||||
proof_hid = ['laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d',
|
proof_hid = ['laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d',
|
||||||
'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d']
|
'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d']
|
||||||
assert all([h in proof_hid for h in hids])
|
assert all([h in proof_hid for h in hids])
|
||||||
|
|
||||||
# we drop all network cards
|
# we drop all network cards
|
||||||
snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abc'
|
snapshot['uuid'] = 'd1b70cb8-8929-4f36-99b7-fe052cec0abc'
|
||||||
snapshot['components'] = [c for c in snapshot['components'] if not c in [network, network2]]
|
snapshot['components'] = [c for c in snapshot['components'] if c not in [network, network2]]
|
||||||
user.post(json_encode(snapshot), res=m.Snapshot)
|
user.post(json_encode(snapshot), res=m.Snapshot)
|
||||||
devices, _ = user.get(res=d.Device)
|
devices, _ = user.get(res=d.Device)
|
||||||
laptops = [c for c in devices['items'] if c['type'] == 'Laptop']
|
laptops = [c for c in devices['items'] if c['type'] == 'Laptop']
|
||||||
assert len(laptops) == 3
|
assert len(laptops) == 4
|
||||||
hids = [h['hid'] for h in laptops]
|
hids = [laptops[0]['hid'], laptops[2]['hid']]
|
||||||
proof_hid = ['laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d',
|
proof_hid = ['laptop-asustek_computer_inc-1000h-94oaaq021116-a0:24:8c:7f:cf:2d',
|
||||||
'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d',
|
'laptop-asustek_computer_inc-1000h-94oaaq021116-00:24:8c:7f:cf:2d',
|
||||||
'laptop-asustek_computer_inc-1000h-94oaaq021116']
|
'laptop-asustek_computer_inc-1000h-94oaaq021116']
|
||||||
assert all([h in proof_hid for h in hids])
|
assert all([h in proof_hid for h in hids])
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,6 @@ def test_device_query(user: UserClient):
|
||||||
pc = next(d for d in i['items'] if d['type'] == 'Desktop')
|
pc = next(d for d in i['items'] if d['type'] == 'Desktop')
|
||||||
assert len(pc['actions']) == 3
|
assert len(pc['actions']) == 3
|
||||||
assert len(pc['components']) == 3
|
assert len(pc['components']) == 3
|
||||||
assert pc['tags'][0]['id'] == pc['devicehubID']
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
|
|
@ -508,12 +508,14 @@ def test_report_devices_stock_control(user: UserClient, user2: UserClient):
|
||||||
fixture_csv = list(obj_csv)
|
fixture_csv = list(obj_csv)
|
||||||
|
|
||||||
assert user.user['id'] != user2.user['id']
|
assert user.user['id'] != user2.user['id']
|
||||||
assert len(export_csv) == 2
|
assert len(export_csv) == 3
|
||||||
|
|
||||||
export_csv[0] = export_csv[0][0].split(';')
|
export_csv[0] = export_csv[0][0].split(';')
|
||||||
export_csv[1] = export_csv[1][0].split(';')
|
export_csv[1] = export_csv[1][0].split(';')
|
||||||
|
export_csv[2] = export_csv[2][0].split(';')
|
||||||
fixture_csv[0] = fixture_csv[0][0].split(';')
|
fixture_csv[0] = fixture_csv[0][0].split(';')
|
||||||
fixture_csv[1] = fixture_csv[1][0].split(';')
|
fixture_csv[1] = fixture_csv[1][0].split(';')
|
||||||
|
fixture_csv[2] = fixture_csv[2][0].split(';')
|
||||||
|
|
||||||
# assert isinstance(
|
# assert isinstance(
|
||||||
# datetime.strptime(export_csv[1][5], '%c'), datetime
|
# datetime.strptime(export_csv[1][5], '%c'), datetime
|
||||||
|
@ -522,9 +524,12 @@ def test_report_devices_stock_control(user: UserClient, user2: UserClient):
|
||||||
# Pop dates fields from csv lists to compare them
|
# Pop dates fields from csv lists to compare them
|
||||||
fixture_csv[1] = fixture_csv[1][:5] + fixture_csv[1][6:]
|
fixture_csv[1] = fixture_csv[1][:5] + fixture_csv[1][6:]
|
||||||
export_csv[1] = export_csv[1][:5] + export_csv[1][6:]
|
export_csv[1] = export_csv[1][:5] + export_csv[1][6:]
|
||||||
|
fixture_csv[2] = fixture_csv[2][:5] + fixture_csv[2][6:]
|
||||||
|
export_csv[2] = export_csv[2][:5] + export_csv[2][6:]
|
||||||
|
|
||||||
assert fixture_csv[0] == export_csv[0], 'Headers are not equal'
|
assert fixture_csv[0] == export_csv[0], 'Headers are not equal'
|
||||||
assert fixture_csv[1] == export_csv[1], 'Computer information are not equal'
|
assert fixture_csv[1] == export_csv[1], 'Computer information are not equal'
|
||||||
|
assert fixture_csv[2] == export_csv[2], 'Computer information are not equal'
|
||||||
assert fixture_csv == export_csv
|
assert fixture_csv == export_csv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient):
|
||||||
body1_lenovo += '"foo2@foo.com";"Supplier";"NeedConfirmation";"Use";"";'
|
body1_lenovo += '"foo2@foo.com";"Supplier";"NeedConfirmation";"Use";"";'
|
||||||
body2_lenovo = ';"";"0";"0";"Trade";"0";"0"\n'
|
body2_lenovo = ';"";"0";"0";"Trade";"0";"0"\n'
|
||||||
|
|
||||||
body1_acer = '"J2MA2";"laptop-acer-aohappy-lusea0d010038879a01601-00:26:c7:8e:cb:8c";"";"Trade";'
|
body1_acer = '"K3XW2";"laptop-acer-aohappy-lusea0d010038879a01601-00:26:c7:8e:cb:8c";"";"Trade";'
|
||||||
body1_acer += '"foo@foo.com";"foo2@foo.com";"Supplier";"NeedConfirmation";"";"";"";"";"0";'
|
body1_acer += '"foo@foo.com";"foo2@foo.com";"Supplier";"NeedConfirmation";"";"";"";"";"0";'
|
||||||
body2_acer = ';"";"0";"0";"Trade";"0";"4692.0"\n'
|
body2_acer = ';"";"0";"0";"Trade";"0";"4692.0"\n'
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ from ereuse_devicehub.client import UserClient, UserClientFlask
|
||||||
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.action.models import Snapshot
|
from ereuse_devicehub.resources.action.models import Snapshot
|
||||||
from ereuse_devicehub.resources.device.models import Device
|
from ereuse_devicehub.resources.device.models import Device, Placeholder
|
||||||
from ereuse_devicehub.resources.lot.models import Lot
|
from ereuse_devicehub.resources.lot.models import Lot
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
from tests import conftest
|
from tests import conftest
|
||||||
|
@ -190,7 +190,7 @@ def test_inventory_with_device(user3: UserClientFlask):
|
||||||
|
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert "Unassigned" in body
|
assert "Unassigned" in body
|
||||||
assert db_snapthot.device.devicehub_id in body
|
assert db_snapthot.device.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -203,7 +203,7 @@ def test_inventory_filter(user3: UserClientFlask):
|
||||||
|
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert "Unassigned" in body
|
assert "Unassigned" in body
|
||||||
assert db_snapthot.device.devicehub_id in body
|
assert db_snapthot.device.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -310,7 +310,7 @@ def test_label_details(user3: UserClientFlask):
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_link_tag_to_device(user3: UserClientFlask):
|
def test_link_tag_to_device(user3: UserClientFlask):
|
||||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
dev = snap.device
|
dev = snap.device.binding.device
|
||||||
uri = '/labels/add/'
|
uri = '/labels/add/'
|
||||||
user3.get(uri)
|
user3.get(uri)
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ def test_link_tag_to_device(user3: UserClientFlask):
|
||||||
|
|
||||||
uri = '/inventory/tag/devices/add/'
|
uri = '/inventory/tag/devices/add/'
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(list(dev.tags)) == 2
|
assert len(list(dev.tags)) == 1
|
||||||
tags = [tag.id for tag in dev.tags]
|
tags = [tag.id for tag in dev.tags]
|
||||||
assert "tag1" in tags
|
assert "tag1" in tags
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ def test_link_tag_to_device(user3: UserClientFlask):
|
||||||
def test_unlink_tag_to_device(user3: UserClientFlask):
|
def test_unlink_tag_to_device(user3: UserClientFlask):
|
||||||
# create device
|
# create device
|
||||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
dev = snap.device
|
dev = snap.device.binding.device
|
||||||
|
|
||||||
# create tag
|
# create tag
|
||||||
uri = '/labels/add/'
|
uri = '/labels/add/'
|
||||||
|
@ -379,9 +379,7 @@ def test_unlink_tag_to_device(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(list(dev.tags)) == 1
|
assert len(list(dev.tags)) == 0
|
||||||
tag = list(dev.tags)[0]
|
|
||||||
assert not tag.id == "tag1"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -389,7 +387,7 @@ def test_unlink_tag_to_device(user3: UserClientFlask):
|
||||||
def test_print_labels(user3: UserClientFlask):
|
def test_print_labels(user3: UserClientFlask):
|
||||||
# create device
|
# create device
|
||||||
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
dev = snap.device
|
dev = snap.device.binding.device
|
||||||
|
|
||||||
# create tag
|
# create tag
|
||||||
uri = '/labels/add/'
|
uri = '/labels/add/'
|
||||||
|
@ -411,7 +409,7 @@ def test_print_labels(user3: UserClientFlask):
|
||||||
uri = '/inventory/tag/devices/add/'
|
uri = '/inventory/tag/devices/add/'
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
|
|
||||||
assert len(list(dev.tags)) == 2
|
assert len(list(dev.tags)) == 1
|
||||||
|
|
||||||
uri = '/labels/print'
|
uri = '/labels/print'
|
||||||
data = {
|
data = {
|
||||||
|
@ -423,7 +421,7 @@ def test_print_labels(user3: UserClientFlask):
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
path = "/inventory/device/{}/".format(dev.devicehub_id)
|
path = "/inventory/device/{}/".format(dev.devicehub_id)
|
||||||
assert path in body
|
assert path in body
|
||||||
assert "tag1" not in body
|
assert "tag1" in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -708,7 +706,7 @@ def test_action_recycling(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
|
@ -721,15 +719,15 @@ def test_action_recycling(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Recycling",
|
'type': "Recycling",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Recycling'
|
assert dev.binding.device.actions[-1].type == 'Recycling'
|
||||||
assert 'Action "Recycling" created successfully!' in body
|
assert 'Action "Recycling" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -763,15 +761,15 @@ def test_action_use(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Use",
|
'type': "Use",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Use'
|
assert dev.binding.device.actions[-1].type == 'Use'
|
||||||
assert 'Action "Use" created successfully!' in body
|
assert 'Action "Use" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -786,15 +784,15 @@ def test_action_refurbish(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Refurbish",
|
'type': "Refurbish",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Refurbish'
|
assert dev.binding.device.actions[-1].type == 'Refurbish'
|
||||||
assert 'Action "Refurbish" created successfully!' in body
|
assert 'Action "Refurbish" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -809,15 +807,15 @@ def test_action_management(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Management",
|
'type': "Management",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Management'
|
assert dev.binding.device.actions[-1].type == 'Management'
|
||||||
assert 'Action "Management" created successfully!' in body
|
assert 'Action "Management" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -832,7 +830,7 @@ def test_action_allocate(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-01',
|
'start_time': '2000-01-01',
|
||||||
'end_time': '2000-06-01',
|
'end_time': '2000-06-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -841,9 +839,9 @@ def test_action_allocate(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Allocate'
|
assert dev.binding.device.actions[-1].type == 'Allocate'
|
||||||
assert 'Action "Allocate" created successfully!' in body
|
assert 'Action "Allocate" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -858,18 +856,18 @@ def test_action_allocate_error_required(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Trade",
|
'type': "Trade",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert dev.actions[-1].type != 'Allocate'
|
assert 'Allocate' not in [x.type for x in dev.binding.device.actions]
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
@ -891,7 +889,7 @@ def test_action_allocate_error_dates(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-06-01',
|
'start_time': '2000-06-01',
|
||||||
'end_time': '2000-01-01',
|
'end_time': '2000-01-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -902,7 +900,7 @@ def test_action_allocate_error_dates(user3: UserClientFlask):
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert 'Action Allocate error' in body
|
assert 'Action Allocate error' in body
|
||||||
assert 'The action cannot finish before it starts.' in body
|
assert 'The action cannot finish before it starts.' in body
|
||||||
assert dev.actions[-1].type != 'Allocate'
|
assert 'Allocate' not in [x.type for x in dev.binding.device.actions]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -919,7 +917,7 @@ def test_action_allocate_error_future_dates(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': start_time,
|
'start_time': start_time,
|
||||||
'end_time': end_time,
|
'end_time': end_time,
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -930,7 +928,7 @@ def test_action_allocate_error_future_dates(user3: UserClientFlask):
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert 'Action Allocate error' in body
|
assert 'Action Allocate error' in body
|
||||||
assert 'Not a valid date value.!' in body
|
assert 'Not a valid date value.!' in body
|
||||||
assert dev.actions[-1].type != 'Allocate'
|
assert 'Allocate' not in [x.type for x in dev.binding.device.actions]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -945,7 +943,7 @@ def test_action_deallocate(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-01',
|
'start_time': '2000-01-01',
|
||||||
'end_time': '2000-06-01',
|
'end_time': '2000-06-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -954,22 +952,22 @@ def test_action_deallocate(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert dev.allocated_status.type == 'Allocate'
|
assert dev.binding.device.allocated_status.type == 'Allocate'
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-01',
|
'start_time': '2000-01-01',
|
||||||
'end_time': '2000-06-01',
|
'end_time': '2000-06-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.allocated_status.type == 'Deallocate'
|
assert dev.binding.device.allocated_status.type == 'Deallocate'
|
||||||
assert 'Action "Deallocate" created successfully!' in body
|
assert 'Action "Deallocate" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -984,7 +982,7 @@ def test_action_deallocate_error(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-05-01',
|
'start_time': '2000-05-01',
|
||||||
'end_time': '2000-06-01',
|
'end_time': '2000-06-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -993,20 +991,20 @@ def test_action_deallocate_error(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert dev.allocated_status.type == 'Allocate'
|
assert dev.binding.device.allocated_status.type == 'Allocate'
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-01',
|
'start_time': '2000-01-01',
|
||||||
'end_time': '2000-02-01',
|
'end_time': '2000-02-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.allocated_status.type != 'Deallocate'
|
assert dev.binding.device.allocated_status.type != 'Deallocate'
|
||||||
assert 'Action Deallocate error!' in body
|
assert 'Action Deallocate error!' in body
|
||||||
assert 'Sorry some of this devices are actually deallocate' in body
|
assert 'Sorry some of this devices are actually deallocate' in body
|
||||||
|
|
||||||
|
@ -1023,7 +1021,7 @@ def test_action_allocate_deallocate_error(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-01',
|
'start_time': '2000-01-01',
|
||||||
'end_time': '2000-01-01',
|
'end_time': '2000-01-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
|
@ -1032,36 +1030,36 @@ def test_action_allocate_deallocate_error(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert dev.allocated_status.type == 'Allocate'
|
assert dev.binding.device.allocated_status.type == 'Allocate'
|
||||||
assert len(dev.actions) == 11
|
assert len(dev.binding.device.actions) == 1
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-02-01',
|
'start_time': '2000-02-01',
|
||||||
'end_time': '2000-02-01',
|
'end_time': '2000-02-01',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.allocated_status.type == 'Deallocate'
|
assert dev.binding.device.allocated_status.type == 'Deallocate'
|
||||||
assert len(dev.actions) == 12
|
assert len(dev.binding.device.actions) == 2
|
||||||
|
|
||||||
# is not possible to do an allocate between an allocate and an deallocate
|
# is not possible to do an allocate between an allocate and an deallocate
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-15',
|
'start_time': '2000-01-15',
|
||||||
'end_time': '2000-01-15',
|
'end_time': '2000-01-15',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert dev.allocated_status.type == 'Deallocate'
|
assert dev.binding.device.allocated_status.type == 'Deallocate'
|
||||||
# assert 'Action Deallocate error!' in body
|
# assert 'Action Deallocate error!' in body
|
||||||
# assert 'Sorry some of this devices are actually deallocate' in body
|
# assert 'Sorry some of this devices are actually deallocate' in body
|
||||||
#
|
#
|
||||||
|
@ -1069,14 +1067,14 @@ def test_action_allocate_deallocate_error(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-15',
|
'start_time': '2000-01-15',
|
||||||
'end_time': '2000-01-15',
|
'end_time': '2000-01-15',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 12
|
assert len(dev.binding.device.actions) == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1091,7 +1089,7 @@ def test_action_allocate_deallocate_error2(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-10',
|
'start_time': '2000-01-10',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
|
@ -1099,25 +1097,25 @@ def test_action_allocate_deallocate_error2(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 11
|
assert len(dev.binding.device.actions) == 1
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-20',
|
'start_time': '2000-01-20',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert len(dev.actions) == 12
|
assert len(dev.binding.device.actions) == 2
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-02-10',
|
'start_time': '2000-02-10',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
|
@ -1125,40 +1123,40 @@ def test_action_allocate_deallocate_error2(user3: UserClientFlask):
|
||||||
uri = '/inventory/action/allocate/add/'
|
uri = '/inventory/action/allocate/add/'
|
||||||
|
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 13
|
assert len(dev.binding.device.actions) == 3
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-02-20',
|
'start_time': '2000-02-20',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 14
|
assert len(dev.binding.device.actions) == 4
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Allocate",
|
'type': "Allocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-25',
|
'start_time': '2000-01-25',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 15
|
assert len(dev.binding.device.actions) == 5
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Deallocate",
|
'type': "Deallocate",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'start_time': '2000-01-27',
|
'start_time': '2000-01-27',
|
||||||
'end_users': 2,
|
'end_users': 2,
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data)
|
user3.post(uri, data=data)
|
||||||
assert len(dev.actions) == 16
|
assert len(dev.binding.device.actions) == 6
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1173,15 +1171,15 @@ def test_action_toprepare(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "ToPrepare",
|
'type': "ToPrepare",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'ToPrepare'
|
assert dev.binding.device.actions[-1].type == 'ToPrepare'
|
||||||
assert 'Action "ToPrepare" created successfully!' in body
|
assert 'Action "ToPrepare" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1196,15 +1194,15 @@ def test_action_prepare(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Prepare",
|
'type': "Prepare",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Prepare'
|
assert dev.binding.device.actions[-1].type == 'Prepare'
|
||||||
assert 'Action "Prepare" created successfully!' in body
|
assert 'Action "Prepare" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1219,15 +1217,15 @@ def test_action_torepair(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "ToRepair",
|
'type': "ToRepair",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'ToRepair'
|
assert dev.binding.device.actions[-1].type == 'ToRepair'
|
||||||
assert 'Action "ToRepair" created successfully!' in body
|
assert 'Action "ToRepair" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1242,15 +1240,15 @@ def test_action_ready(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "Ready",
|
'type': "Ready",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/add/'
|
uri = '/inventory/action/add/'
|
||||||
body, status = user3.post(uri, data=data)
|
body, status = user3.post(uri, data=data)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'Ready'
|
assert dev.binding.device.actions[-1].type == 'Ready'
|
||||||
assert 'Action "Ready" created successfully!' in body
|
assert 'Action "Ready" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1269,16 +1267,16 @@ def test_action_datawipe(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
'type': "DataWipe",
|
'type': "DataWipe",
|
||||||
'severity': "Info",
|
'severity': "Info",
|
||||||
'devices': "{}".format(dev.id),
|
'devices': "{}".format(dev.binding.device.id),
|
||||||
'document-file_name': file_upload,
|
'document-file_name': file_upload,
|
||||||
}
|
}
|
||||||
|
|
||||||
uri = '/inventory/action/datawipe/add/'
|
uri = '/inventory/action/datawipe/add/'
|
||||||
body, status = user3.post(uri, data=data, content_type="multipart/form-data")
|
body, status = user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
assert dev.actions[-1].type == 'DataWipe'
|
assert dev.binding.device.actions[-1].type == 'DataWipe'
|
||||||
assert 'Action "DataWipe" created successfully!' in body
|
assert 'Action "DataWipe" created successfully!' in body
|
||||||
assert dev.devicehub_id in body
|
assert dev.binding.device.devicehub_id in body
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1618,7 +1616,6 @@ def test_export_snapshot_json(user3: UserClientFlask):
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_add_placeholder_excel(user3: UserClientFlask):
|
def test_add_placeholder_excel(user3: UserClientFlask):
|
||||||
|
|
||||||
uri = '/inventory/upload-placeholder/'
|
uri = '/inventory/upload-placeholder/'
|
||||||
body, status = user3.get(uri)
|
body, status = user3.get(uri)
|
||||||
assert status == '200 OK'
|
assert status == '200 OK'
|
||||||
|
@ -2009,3 +2006,191 @@ def test_add_new_placeholder_from_lot(user3: UserClientFlask):
|
||||||
assert dev.hid == 'laptop-samsung-lc27t55-aaaab'
|
assert dev.hid == 'laptop-samsung-lc27t55-aaaab'
|
||||||
assert dev.placeholder.phid == 'ace'
|
assert dev.placeholder.phid == 'ace'
|
||||||
assert len(lot.devices) == 1
|
assert len(lot.devices) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_manual_binding(user3: UserClientFlask):
|
||||||
|
# create placeholder manual
|
||||||
|
uri = '/inventory/device/add/'
|
||||||
|
|
||||||
|
user3.get(uri)
|
||||||
|
data = {
|
||||||
|
'csrf_token': generate_csrf(),
|
||||||
|
'type': "Laptop",
|
||||||
|
'phid': 'sid',
|
||||||
|
'serial_number': "AAAAB",
|
||||||
|
'model': "LC27T55",
|
||||||
|
'manufacturer': "Samsung",
|
||||||
|
'generation': 1,
|
||||||
|
'weight': 0.1,
|
||||||
|
'height': 0.1,
|
||||||
|
'depth': 0.1,
|
||||||
|
'id_device_supplier': "b2",
|
||||||
|
}
|
||||||
|
user3.post(uri, data=data)
|
||||||
|
dev = Device.query.one()
|
||||||
|
assert dev.hid == 'laptop-samsung-lc27t55-aaaab'
|
||||||
|
assert dev.placeholder.phid == 'sid'
|
||||||
|
assert dev.placeholder.is_abstract is False
|
||||||
|
|
||||||
|
# add device from wb
|
||||||
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
|
dev_wb = snap.device
|
||||||
|
uri = '/inventory/device/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
assert dev_wb.binding.is_abstract is True
|
||||||
|
assert dev_wb.hid == 'laptop-asustek_computer_inc-1001pxd-b8oaas048285-14:da:e9:42:f6:7b'
|
||||||
|
assert dev_wb.binding.phid == '11'
|
||||||
|
old_placeholder = dev_wb.binding
|
||||||
|
|
||||||
|
# page binding
|
||||||
|
dhid = dev_wb.devicehub_id
|
||||||
|
uri = f'/inventory/binding/{dhid}/sid/'
|
||||||
|
body, status = user3.get(uri)
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert 'sid' in body
|
||||||
|
assert 'Confirm' in body
|
||||||
|
|
||||||
|
# action binding
|
||||||
|
body, status = user3.post(uri, data={})
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert f"Device "{dhid}" bind successfully with sid!" in body
|
||||||
|
|
||||||
|
# check new structure
|
||||||
|
assert dev_wb.binding.phid == 'sid'
|
||||||
|
assert dev_wb.binding.device == dev
|
||||||
|
assert Placeholder.query.filter_by(id=old_placeholder.id).first() is None
|
||||||
|
assert Device.query.filter_by(id=old_placeholder.device.id).first() is None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_edit_and_binding(user3: UserClientFlask):
|
||||||
|
uri = '/inventory/device/add/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'csrf_token': generate_csrf(),
|
||||||
|
'type': "Laptop",
|
||||||
|
'serial_number': "AAAAB",
|
||||||
|
'model': "LC27T55",
|
||||||
|
'manufacturer': "Samsung",
|
||||||
|
'generation': 1,
|
||||||
|
'weight': 0.1,
|
||||||
|
'height': 0.1,
|
||||||
|
'depth': 0.1,
|
||||||
|
'id_device_supplier': "b2",
|
||||||
|
}
|
||||||
|
user3.post(uri, data=data)
|
||||||
|
|
||||||
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
|
dev_wb = snap.device
|
||||||
|
uri = '/inventory/device/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
uri = '/inventory/device/edit/{}/'.format(dev_wb.binding.device.devicehub_id)
|
||||||
|
body, status = user3.get(uri)
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert "Edit Device" in body
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'csrf_token': generate_csrf(),
|
||||||
|
'type': "Laptop",
|
||||||
|
'serial_number': "AAAAC",
|
||||||
|
'model': "LC27T56",
|
||||||
|
'manufacturer': "Samsung",
|
||||||
|
'generation': 1,
|
||||||
|
'weight': 0.1,
|
||||||
|
'height': 0.1,
|
||||||
|
'depth': 0.1,
|
||||||
|
'id_device_supplier': "a2",
|
||||||
|
}
|
||||||
|
assert dev_wb.binding.is_abstract is True
|
||||||
|
user3.post(uri, data=data)
|
||||||
|
assert dev_wb.binding.is_abstract is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_unbinding(user3: UserClientFlask):
|
||||||
|
# create placeholder manual
|
||||||
|
uri = '/inventory/device/add/'
|
||||||
|
|
||||||
|
user3.get(uri)
|
||||||
|
data = {
|
||||||
|
'csrf_token': generate_csrf(),
|
||||||
|
'type': "Laptop",
|
||||||
|
'phid': 'sid',
|
||||||
|
'serial_number': "AAAAB",
|
||||||
|
'model': "LC27T55",
|
||||||
|
'manufacturer': "Samsung",
|
||||||
|
'generation': 1,
|
||||||
|
'weight': 0.1,
|
||||||
|
'height': 0.1,
|
||||||
|
'depth': 0.1,
|
||||||
|
'id_device_supplier': "b2",
|
||||||
|
}
|
||||||
|
user3.post(uri, data=data)
|
||||||
|
dev = Device.query.one()
|
||||||
|
|
||||||
|
# add device from wb
|
||||||
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
|
dev_wb = snap.device
|
||||||
|
uri = '/inventory/device/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
old_placeholder = dev_wb.binding
|
||||||
|
|
||||||
|
# page binding
|
||||||
|
dhid = dev_wb.devicehub_id
|
||||||
|
uri = f'/inventory/binding/{dhid}/sid/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
# action binding
|
||||||
|
assert dev.placeholder.binding is None
|
||||||
|
user3.post(uri, data={})
|
||||||
|
assert dev.placeholder.binding == dev_wb
|
||||||
|
|
||||||
|
# action unbinding
|
||||||
|
uri = '/inventory/unbinding/sid/'
|
||||||
|
body, status = user3.post(uri, data={})
|
||||||
|
assert status == '200 OK'
|
||||||
|
assert 'Device "sid" unbind successfully!' in body
|
||||||
|
|
||||||
|
# check new structure
|
||||||
|
|
||||||
|
assert dev.placeholder.binding is None
|
||||||
|
assert dev_wb.binding.phid == '2'
|
||||||
|
assert old_placeholder.device.model == dev_wb.binding.device.model
|
||||||
|
assert old_placeholder.device != dev_wb.binding.device
|
||||||
|
assert Placeholder.query.filter_by(id=old_placeholder.id).first() is None
|
||||||
|
assert Device.query.filter_by(id=old_placeholder.device.id).first() is None
|
||||||
|
assert Placeholder.query.filter_by(id=dev_wb.binding.id).first()
|
||||||
|
assert Device.query.filter_by(id=dev_wb.binding.device.id).first()
|
||||||
|
assert Device.query.filter_by(id=dev.id).first()
|
||||||
|
assert Placeholder.query.filter_by(id=dev.placeholder.id).first()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_unbindingnot_used(user3: UserClientFlask):
|
||||||
|
# add device from wb
|
||||||
|
snap = create_device(user3, 'real-eee-1001pxd.snapshot.12.json')
|
||||||
|
dev_wb = snap.device
|
||||||
|
uri = '/inventory/device/'
|
||||||
|
user3.get(uri)
|
||||||
|
|
||||||
|
old_placeholder = dev_wb.binding
|
||||||
|
|
||||||
|
# action unbinding
|
||||||
|
uri = '/inventory/unbinding/{}/'.format(dev_wb.binding.phid)
|
||||||
|
body, status = user3.post(uri, data={})
|
||||||
|
assert status == '200 OK'
|
||||||
|
|
||||||
|
# check new structure
|
||||||
|
assert dev_wb.binding == old_placeholder
|
||||||
|
assert Placeholder.query.filter_by(id=old_placeholder.id).first()
|
||||||
|
assert Device.query.filter_by(id=old_placeholder.device.id).first()
|
||||||
|
assert Device.query.filter_by(id=dev_wb.id).first()
|
||||||
|
|
|
@ -367,18 +367,6 @@ def test_snapshot_mismatch_id():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
|
||||||
def test_snapshot_tag_inner_tag(user: UserClient, tag_id: str, app: Devicehub):
|
|
||||||
"""Tests a posting Snapshot with a local tag."""
|
|
||||||
b = yaml2json('basic.snapshot')
|
|
||||||
b['device']['tags'] = [{'type': 'Tag', 'id': tag_id}]
|
|
||||||
|
|
||||||
snapshot_and_check(user, b, action_types=(BenchmarkProcessor.t, VisualTest.t))
|
|
||||||
with app.app_context():
|
|
||||||
tag = Tag.query.all()[0] # type: Tag
|
|
||||||
assert tag.device_id == 3, 'Tag should be linked to the first device'
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
def test_snapshot_tag_inner_tag_mismatch_between_tags_and_hid(
|
def test_snapshot_tag_inner_tag_mismatch_between_tags_and_hid(
|
||||||
user: UserClient, tag_id: str
|
user: UserClient, tag_id: str
|
||||||
|
@ -1311,5 +1299,42 @@ def test_snapshot_check_tests_lite(user: UserClient):
|
||||||
|
|
||||||
bodyLite, res = user.post(snapshot_lite, uri="/api/inventory/")
|
bodyLite, res = user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert res.status_code == 201
|
assert res.status_code == 201
|
||||||
SnapshotsLog.query.all()
|
assert SnapshotsLog.query.count() == 1
|
||||||
|
m.Device.query.filter_by(devicehub_id=bodyLite['dhid']).one()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_placeholder(user: UserClient):
|
||||||
|
"""This check the structure of one placeholder generated automatically by a snapshot"""
|
||||||
|
snapshot_lite = file_json(
|
||||||
|
'test_lite/2022-4-13-19-5_user@dhub.com_b27dbf43-b88a-4505-ae27-10de5a95919e.json'
|
||||||
|
)
|
||||||
|
|
||||||
|
bodyLite, res = user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
|
assert res.status_code == 201
|
||||||
dev = m.Device.query.filter_by(devicehub_id=bodyLite['dhid']).one()
|
dev = m.Device.query.filter_by(devicehub_id=bodyLite['dhid']).one()
|
||||||
|
assert dev.placeholder is None
|
||||||
|
assert dev.binding.phid == '12'
|
||||||
|
assert len(dev.binding.device.components) == 11
|
||||||
|
assert len(dev.components) == 11
|
||||||
|
assert dev.binding.device.placeholder == dev.binding
|
||||||
|
assert dev.components != dev.binding.device.components
|
||||||
|
assert dev.binding.device.actions == []
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_placeholder_actions(user: UserClient):
|
||||||
|
"""This test the actions of a placeholder of one snapshot"""
|
||||||
|
s = yaml2json('erase-sectors.snapshot')
|
||||||
|
snap1, _ = user.post(s, res=Snapshot)
|
||||||
|
|
||||||
|
dev = m.Device.query.filter_by(id=snap1['device']['id']).one()
|
||||||
|
assert dev.placeholder is None
|
||||||
|
assert dev.binding.phid == '4'
|
||||||
|
assert len(dev.binding.device.components) == 3
|
||||||
|
assert len(dev.components) == 3
|
||||||
|
assert dev.binding.device.placeholder == dev.binding
|
||||||
|
assert dev.components != dev.binding.device.components
|
||||||
|
assert dev.binding.device.actions == []
|
||||||
|
assert len(dev.components[0].actions) == 3
|
||||||
|
assert len(dev.binding.device.components[0].actions) == 0
|
||||||
|
|
|
@ -92,7 +92,7 @@ def test_wb11_to_wb11_with_uuid_api(user: UserClient):
|
||||||
|
|
||||||
db_snapthot = Snapshot.query.one()
|
db_snapthot = Snapshot.query.one()
|
||||||
device = db_snapthot.device
|
device = db_snapthot.device
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
|
@ -106,9 +106,13 @@ def test_wb11_to_wb11_with_uuid_api(user: UserClient):
|
||||||
snapshot_11['debug']['lshw']['configuration']['uuid']
|
snapshot_11['debug']['lshw']['configuration']['uuid']
|
||||||
== '364ee69c-9c82-9cb1-2111-88ae1da6f3d0'
|
== '364ee69c-9c82-9cb1-2111-88ae1da6f3d0'
|
||||||
)
|
)
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,9 +127,13 @@ def test_wb11_with_uuid_to_wb11_api(user: UserClient):
|
||||||
snapshot_11['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
snapshot_11['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
# insert the same computer with wb11 with hid and with uuid, (new version)
|
# insert the same computer with wb11 with hid and with uuid, (new version)
|
||||||
|
@ -133,9 +141,13 @@ def test_wb11_with_uuid_to_wb11_api(user: UserClient):
|
||||||
assert 'debug' not in snapshot_11
|
assert 'debug' not in snapshot_11
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,9 +162,13 @@ def test_wb11_with_uuid_to_wb11_without_hid_api(user: UserClient):
|
||||||
snapshot_11['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
snapshot_11['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
# insert the same computer with wb11 with hid and with uuid, (new version)
|
# insert the same computer with wb11 with hid and with uuid, (new version)
|
||||||
|
@ -162,7 +178,7 @@ def test_wb11_with_uuid_to_wb11_without_hid_api(user: UserClient):
|
||||||
snapshot_11['debug'] = {'lshw': snapshot_lite['data']['lshw']}
|
snapshot_11['debug'] = {'lshw': snapshot_lite['data']['lshw']}
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -186,7 +202,7 @@ def test_wb11_to_wb11_with_uuid_form(user3: UserClientFlask):
|
||||||
|
|
||||||
db_snapthot = Snapshot.query.one()
|
db_snapthot = Snapshot.query.one()
|
||||||
device = db_snapthot.device
|
device = db_snapthot.device
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
|
@ -203,9 +219,13 @@ def test_wb11_to_wb11_with_uuid_form(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,9 +251,13 @@ def test_wb11_with_uuid_to_wb11_form(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
# insert the same computer with wb11 with hid and with uuid, (new version)
|
# insert the same computer with wb11 with hid and with uuid, (new version)
|
||||||
|
@ -248,9 +272,13 @@ def test_wb11_with_uuid_to_wb11_form(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,9 +304,13 @@ def test_wb11_with_uuid_to_wb11_without_hid_form(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
# insert the same computer with wb11 with hid and with uuid, (new version)
|
# insert the same computer with wb11 with hid and with uuid, (new version)
|
||||||
|
@ -295,7 +327,7 @@ def test_wb11_with_uuid_to_wb11_without_hid_form(user3: UserClientFlask):
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
|
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -305,16 +337,24 @@ def test_wb11_to_wblite_api(user: UserClient):
|
||||||
# insert computer with wb11 with hid and without uuid, (old version)
|
# insert computer with wb11 with hid and without uuid, (old version)
|
||||||
snapshot_11 = conftest.file_json('system_uuid3.json')
|
snapshot_11 = conftest.file_json('system_uuid3.json')
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
snapshot_lite = conftest.file_json('system_uuid2.json')
|
snapshot_lite = conftest.file_json('system_uuid2.json')
|
||||||
user.post(snapshot_lite, uri="/api/inventory/")
|
user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,16 +364,24 @@ def test_wblite_to_wb11_api(user: UserClient):
|
||||||
|
|
||||||
snapshot_lite = conftest.file_json('system_uuid2.json')
|
snapshot_lite = conftest.file_json('system_uuid2.json')
|
||||||
user.post(snapshot_lite, uri="/api/inventory/")
|
user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
snapshot_11 = conftest.file_json('system_uuid3.json')
|
snapshot_11 = conftest.file_json('system_uuid3.json')
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -354,9 +402,13 @@ def test_wb11_to_wblite_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
file_name = 'system_uuid2.json'
|
file_name = 'system_uuid2.json'
|
||||||
|
@ -369,9 +421,13 @@ def test_wb11_to_wblite_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -392,9 +448,13 @@ def test_wblite_to_wb11_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
file_name = 'system_uuid3.json'
|
file_name = 'system_uuid3.json'
|
||||||
|
@ -407,9 +467,13 @@ def test_wblite_to_wb11_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -419,17 +483,25 @@ def test_wblite_to_wblite_api(user: UserClient):
|
||||||
|
|
||||||
snapshot_lite = conftest.file_json('system_uuid2.json')
|
snapshot_lite = conftest.file_json('system_uuid2.json')
|
||||||
user.post(snapshot_lite, uri="/api/inventory/")
|
user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
snapshot_lite = conftest.file_json('system_uuid2.json')
|
snapshot_lite = conftest.file_json('system_uuid2.json')
|
||||||
snapshot_lite['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
snapshot_lite['uuid'] = '0973fda0-589a-11eb-ae93-0242ac130003'
|
||||||
user.post(snapshot_lite, uri="/api/inventory/")
|
user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -450,9 +522,13 @@ def test_wblite_to_wblite_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
file_name = 'system_uuid2.json'
|
file_name = 'system_uuid2.json'
|
||||||
|
@ -466,9 +542,13 @@ def test_wblite_to_wblite_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -479,9 +559,13 @@ def test_wb11_to_wb11_duplicity_api(user: UserClient):
|
||||||
# insert computer with wb11 with hid and without uuid, (old version)
|
# insert computer with wb11 with hid and without uuid, (old version)
|
||||||
snapshot_11 = conftest.file_json('system_uuid3.json')
|
snapshot_11 = conftest.file_json('system_uuid3.json')
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
snapshot_11 = conftest.file_json('system_uuid3.json')
|
snapshot_11 = conftest.file_json('system_uuid3.json')
|
||||||
|
@ -489,7 +573,7 @@ def test_wb11_to_wb11_duplicity_api(user: UserClient):
|
||||||
components = [x for x in snapshot_11['components'] if x['type'] != 'NetworkAdapter']
|
components = [x for x in snapshot_11['components'] if x['type'] != 'NetworkAdapter']
|
||||||
snapshot_11['components'] = components
|
snapshot_11['components'] = components
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
assert Computer.query.count() == 2
|
assert Computer.query.count() == 4
|
||||||
for c in Computer.query.all():
|
for c in Computer.query.all():
|
||||||
assert 'laptop-acer-aohappy-lusea0d010038879a01601' in c.hid
|
assert 'laptop-acer-aohappy-lusea0d010038879a01601' in c.hid
|
||||||
assert c.system_uuid is None
|
assert c.system_uuid is None
|
||||||
|
@ -512,9 +596,13 @@ def test_wb11_to_wb11_duplicity_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
snapshot_11 = conftest.file_json('system_uuid3.json')
|
snapshot_11 = conftest.file_json('system_uuid3.json')
|
||||||
|
@ -530,10 +618,12 @@ def test_wb11_to_wb11_duplicity_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 2
|
|
||||||
for c in Computer.query.all():
|
assert Computer.query.count() == 4
|
||||||
assert 'laptop-acer-aohappy-lusea0d010038879a01601' in c.hid
|
for device in Computer.query.all():
|
||||||
assert c.system_uuid is None
|
if device.binding:
|
||||||
|
assert 'laptop-acer-aohappy-lusea0d010038879a01601' in device.hid
|
||||||
|
assert device.system_uuid is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -543,9 +633,13 @@ def test_wb11_smbios_2_5_api(user: UserClient):
|
||||||
# insert computer with wb11 with hid and without uuid, (old version)
|
# insert computer with wb11 with hid and without uuid, (old version)
|
||||||
snapshot_11 = conftest.file_json('system_uuid4.json')
|
snapshot_11 = conftest.file_json('system_uuid4.json')
|
||||||
user.post(snapshot_11, res=Snapshot)
|
user.post(snapshot_11, res=Snapshot)
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
|
|
||||||
|
@ -566,9 +660,13 @@ def test_wb11_smbios_2_5_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert device.system_uuid is None
|
assert device.system_uuid is None
|
||||||
|
|
||||||
|
|
||||||
|
@ -580,9 +678,13 @@ def test_wblite_smbios_2_5_api(user: UserClient):
|
||||||
snapshot_lite = conftest.file_json('system_uuid2.json')
|
snapshot_lite = conftest.file_json('system_uuid2.json')
|
||||||
snapshot_lite['data']['lshw']['capabilities']['smbios-3.0'] = 'SMBIOS version 2.5'
|
snapshot_lite['data']['lshw']['capabilities']['smbios-3.0'] = 'SMBIOS version 2.5'
|
||||||
user.post(snapshot_lite, uri="/api/inventory/")
|
user.post(snapshot_lite, uri="/api/inventory/")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,7 +706,11 @@ def test_wblite_smbios_2_5_form(user3: UserClientFlask):
|
||||||
'csrf_token': generate_csrf(),
|
'csrf_token': generate_csrf(),
|
||||||
}
|
}
|
||||||
user3.post(uri, data=data, content_type="multipart/form-data")
|
user3.post(uri, data=data, content_type="multipart/form-data")
|
||||||
assert Computer.query.count() == 1
|
assert Computer.query.count() == 2
|
||||||
device = Computer.query.one()
|
for device in Computer.query.all():
|
||||||
assert device.hid == 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
if device.binding:
|
||||||
|
assert (
|
||||||
|
device.hid
|
||||||
|
== 'laptop-acer-aohappy-lusea0d010038879a01601-88:ae:1d:a6:f3:d0'
|
||||||
|
)
|
||||||
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
assert str(device.system_uuid) == '9ce64e36-829c-b19c-2111-88ae1da6f3d0'
|
||||||
|
|
|
@ -2,26 +2,29 @@ import pathlib
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import requests_mock
|
import requests_mock
|
||||||
from flask import g
|
|
||||||
from boltons.urlutils import URL
|
from boltons.urlutils import URL
|
||||||
from ereuse_utils.session import DevicehubClient
|
from ereuse_utils.session import DevicehubClient
|
||||||
|
from flask import g
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from teal.db import MultipleResourcesFound, ResourceNotFound, UniqueViolation, DBError
|
from teal.db import DBError, MultipleResourcesFound, ResourceNotFound, UniqueViolation
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
|
|
||||||
from ereuse_devicehub.client import UserClient, Client
|
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.user.models import User
|
|
||||||
from ereuse_devicehub.resources.action.models import Snapshot
|
from ereuse_devicehub.resources.action.models import Snapshot
|
||||||
from ereuse_devicehub.resources.agent.models import Organization
|
from ereuse_devicehub.resources.agent.models import Organization
|
||||||
from ereuse_devicehub.resources.device.models import Desktop, Device
|
from ereuse_devicehub.resources.device.models import Desktop, Device
|
||||||
from ereuse_devicehub.resources.enums import ComputerChassis
|
from ereuse_devicehub.resources.enums import ComputerChassis
|
||||||
from ereuse_devicehub.resources.tag import Tag
|
from ereuse_devicehub.resources.tag import Tag
|
||||||
from ereuse_devicehub.resources.tag.view import CannotCreateETag, LinkedToAnotherDevice, \
|
from ereuse_devicehub.resources.tag.view import (
|
||||||
TagNotLinked
|
CannotCreateETag,
|
||||||
|
LinkedToAnotherDevice,
|
||||||
|
TagNotLinked,
|
||||||
|
)
|
||||||
|
from ereuse_devicehub.resources.user.models import User
|
||||||
from tests import conftest
|
from tests import conftest
|
||||||
from tests.conftest import yaml2json, json_encode
|
from tests.conftest import json_encode, yaml2json
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -29,7 +32,9 @@ from tests.conftest import yaml2json, json_encode
|
||||||
def test_create_tag(user: UserClient):
|
def test_create_tag(user: UserClient):
|
||||||
"""Creates a tag specifying a custom organization."""
|
"""Creates a tag specifying a custom organization."""
|
||||||
org = Organization(name='bar', tax_id='bartax')
|
org = Organization(name='bar', tax_id='bartax')
|
||||||
tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id'])
|
tag = Tag(
|
||||||
|
id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id']
|
||||||
|
)
|
||||||
db.session.add(tag)
|
db.session.add(tag)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
tag = Tag.query.one()
|
tag = Tag.query.one()
|
||||||
|
@ -44,7 +49,9 @@ def test_create_tag(user: UserClient):
|
||||||
def test_create_tag_with_device(user: UserClient):
|
def test_create_tag_with_device(user: UserClient):
|
||||||
"""Creates a tag specifying linked with one device."""
|
"""Creates a tag specifying linked with one device."""
|
||||||
g.user = User.query.one()
|
g.user = User.query.one()
|
||||||
pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
|
pc = Desktop(
|
||||||
|
serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']
|
||||||
|
)
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
tag = Tag(id='bar', owner_id=user.user['id'])
|
tag = Tag(id='bar', owner_id=user.user['id'])
|
||||||
|
@ -64,7 +71,9 @@ def test_delete_tags(user: UserClient, client: Client):
|
||||||
"""Delete a named tag."""
|
"""Delete a named tag."""
|
||||||
# Delete Tag Named
|
# Delete Tag Named
|
||||||
g.user = User.query.one()
|
g.user = User.query.one()
|
||||||
pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
|
pc = Desktop(
|
||||||
|
serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']
|
||||||
|
)
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
tag = Tag(id='bar', owner_id=user.user['id'], device_id=pc.id)
|
tag = Tag(id='bar', owner_id=user.user['id'], device_id=pc.id)
|
||||||
|
@ -89,7 +98,9 @@ def test_delete_tags(user: UserClient, client: Client):
|
||||||
|
|
||||||
# Delete Tag UnNamed
|
# Delete Tag UnNamed
|
||||||
org = Organization(name='bar', tax_id='bartax')
|
org = Organization(name='bar', tax_id='bartax')
|
||||||
tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id'])
|
tag = Tag(
|
||||||
|
id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id']
|
||||||
|
)
|
||||||
db.session.add(tag)
|
db.session.add(tag)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
tag = Tag.query.all()[-1]
|
tag = Tag.query.all()[-1]
|
||||||
|
@ -106,7 +117,9 @@ def test_delete_tags(user: UserClient, client: Client):
|
||||||
def test_create_tag_default_org(user: UserClient):
|
def test_create_tag_default_org(user: UserClient):
|
||||||
"""Creates a tag using the default organization."""
|
"""Creates a tag using the default organization."""
|
||||||
tag = Tag(id='foo-1', owner_id=user.user['id'])
|
tag = Tag(id='foo-1', owner_id=user.user['id'])
|
||||||
assert not tag.org_id, 'org-id is set as default value so it should only load on flush'
|
assert (
|
||||||
|
not tag.org_id
|
||||||
|
), 'org-id is set as default value so it should only load on flush'
|
||||||
# We don't want the organization to load, or it would make this
|
# We don't want the organization to load, or it would make this
|
||||||
# object, from transient to new (added to session)
|
# object, from transient to new (added to session)
|
||||||
assert 'org' not in vars(tag), 'Organization should not have been loaded'
|
assert 'org' not in vars(tag), 'Organization should not have been loaded'
|
||||||
|
@ -188,7 +201,9 @@ def test_tag_get_device_from_tag_endpoint(app: Devicehub, user: UserClient):
|
||||||
# Create a pc with a tag
|
# Create a pc with a tag
|
||||||
g.user = User.query.one()
|
g.user = User.query.one()
|
||||||
tag = Tag(id='foo-bar', owner_id=user.user['id'])
|
tag = Tag(id='foo-bar', owner_id=user.user['id'])
|
||||||
pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
|
pc = Desktop(
|
||||||
|
serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']
|
||||||
|
)
|
||||||
pc.tags.add(tag)
|
pc.tags.add(tag)
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -213,7 +228,9 @@ def test_tag_get_device_from_tag_endpoint_no_tag(user: UserClient):
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_tag_get_device_from_tag_endpoint_multiple_tags(app: Devicehub, user: UserClient, user2: UserClient, client: Client):
|
def test_tag_get_device_from_tag_endpoint_multiple_tags(
|
||||||
|
app: Devicehub, user: UserClient, user2: UserClient, client: Client
|
||||||
|
):
|
||||||
"""As above, but when there are two tags with the secondary ID, the
|
"""As above, but when there are two tags with the secondary ID, the
|
||||||
system should not return any of both (to be deterministic) so
|
system should not return any of both (to be deterministic) so
|
||||||
it should raise an exception.
|
it should raise an exception.
|
||||||
|
@ -232,8 +249,12 @@ def test_tag_get_device_from_tag_endpoint_multiple_tags(app: Devicehub, user: Us
|
||||||
|
|
||||||
tag1 = Tag.from_an_id('foo').filter_by(owner_id=user.user['id']).one()
|
tag1 = Tag.from_an_id('foo').filter_by(owner_id=user.user['id']).one()
|
||||||
tag2 = Tag.from_an_id('foo').filter_by(owner_id=user2.user['id']).one()
|
tag2 = Tag.from_an_id('foo').filter_by(owner_id=user2.user['id']).one()
|
||||||
pc1 = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
|
pc1 = Desktop(
|
||||||
pc2 = Desktop(serial_number='sn2', chassis=ComputerChassis.Tower, owner_id=user2.user['id'])
|
serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']
|
||||||
|
)
|
||||||
|
pc2 = Desktop(
|
||||||
|
serial_number='sn2', chassis=ComputerChassis.Tower, owner_id=user2.user['id']
|
||||||
|
)
|
||||||
pc1.tags.add(tag1)
|
pc1.tags.add(tag1)
|
||||||
pc2.tags.add(tag2)
|
pc2.tags.add(tag2)
|
||||||
db.session.add(pc1)
|
db.session.add(pc1)
|
||||||
|
@ -266,7 +287,17 @@ def test_tag_create_etags_cli(app: Devicehub, user: UserClient):
|
||||||
# todo what happens to organization?
|
# todo what happens to organization?
|
||||||
owner_id = user.user['id']
|
owner_id = user.user['id']
|
||||||
runner = app.test_cli_runner()
|
runner = app.test_cli_runner()
|
||||||
args = ('tag', 'add', '-p', 'https://t.ereuse.org', '-s', 'foo', 'DT-BARBAR', '-u', owner_id)
|
args = (
|
||||||
|
'tag',
|
||||||
|
'add',
|
||||||
|
'-p',
|
||||||
|
'https://t.ereuse.org',
|
||||||
|
'-s',
|
||||||
|
'foo',
|
||||||
|
'DT-BARBAR',
|
||||||
|
'-u',
|
||||||
|
owner_id,
|
||||||
|
)
|
||||||
runner.invoke(*args)
|
runner.invoke(*args)
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
tag = Tag.query.one() # type: Tag
|
tag = Tag.query.one() # type: Tag
|
||||||
|
@ -284,7 +315,11 @@ def test_tag_manual_link_search(app: Devicehub, user: UserClient):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
g.user = User.query.one()
|
g.user = User.query.one()
|
||||||
db.session.add(Tag('foo-bar', secondary='foo-sec', owner_id=user.user['id']))
|
db.session.add(Tag('foo-bar', secondary='foo-sec', owner_id=user.user['id']))
|
||||||
desktop = Desktop(serial_number='foo', chassis=ComputerChassis.AllInOne, owner_id=user.user['id'])
|
desktop = Desktop(
|
||||||
|
serial_number='foo',
|
||||||
|
chassis=ComputerChassis.AllInOne,
|
||||||
|
owner_id=user.user['id'],
|
||||||
|
)
|
||||||
db.session.add(desktop)
|
db.session.add(desktop)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
desktop_id = desktop.id
|
desktop_id = desktop.id
|
||||||
|
@ -330,12 +365,20 @@ def test_tag_secondary_workbench_link_find(user: UserClient):
|
||||||
s['device']['tags'] = [{'id': 'foo', 'secondary': 'bar', 'type': 'Tag'}]
|
s['device']['tags'] = [{'id': 'foo', 'secondary': 'bar', 'type': 'Tag'}]
|
||||||
snapshot, _ = user.post(json_encode(s), res=Snapshot)
|
snapshot, _ = user.post(json_encode(s), res=Snapshot)
|
||||||
device, _ = user.get(res=Device, item=snapshot['device']['devicehubID'])
|
device, _ = user.get(res=Device, item=snapshot['device']['devicehubID'])
|
||||||
assert 'foo' in [x['id'] for x in device['tags']]
|
desktop = Device.query.filter_by(
|
||||||
assert 'bar' in [x.get('secondary') for x in device['tags']]
|
devicehub_id=snapshot['device']['devicehubID']
|
||||||
|
).one()
|
||||||
|
assert [] == [x['id'] for x in device['tags']]
|
||||||
|
assert 'foo' in [x.id for x in desktop.binding.device.tags]
|
||||||
|
assert 'bar' in [x.secondary for x in desktop.binding.device.tags]
|
||||||
|
|
||||||
r, _ = user.get(res=Device, query=[('search', 'foo'), ('filter', {'type': ['Computer']})])
|
r, _ = user.get(
|
||||||
|
res=Device, query=[('search', 'foo'), ('filter', {'type': ['Computer']})]
|
||||||
|
)
|
||||||
assert len(r['items']) == 1
|
assert len(r['items']) == 1
|
||||||
r, _ = user.get(res=Device, query=[('search', 'bar'), ('filter', {'type': ['Computer']})])
|
r, _ = user.get(
|
||||||
|
res=Device, query=[('search', 'bar'), ('filter', {'type': ['Computer']})]
|
||||||
|
)
|
||||||
assert len(r['items']) == 1
|
assert len(r['items']) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,19 +402,24 @@ def test_tag_multiple_secondary_org(user: UserClient):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
def test_create_num_regular_tags(user: UserClient, requests_mock: requests_mock.mocker.Mocker):
|
def test_create_num_regular_tags(
|
||||||
|
user: UserClient, requests_mock: requests_mock.mocker.Mocker
|
||||||
|
):
|
||||||
"""Create regular tags. This is done using a tag provider that
|
"""Create regular tags. This is done using a tag provider that
|
||||||
returns IDs. These tags are printable.
|
returns IDs. These tags are printable.
|
||||||
"""
|
"""
|
||||||
requests_mock.post('https://example.com/',
|
requests_mock.post(
|
||||||
|
'https://example.com/',
|
||||||
# request
|
# request
|
||||||
request_headers={
|
request_headers={
|
||||||
'Authorization': 'Basic {}'.format(DevicehubClient.encode_token(
|
'Authorization': 'Basic {}'.format(
|
||||||
'52dacef0-6bcb-4919-bfed-f10d2c96ecee'))
|
DevicehubClient.encode_token('52dacef0-6bcb-4919-bfed-f10d2c96ecee')
|
||||||
|
)
|
||||||
},
|
},
|
||||||
# response
|
# response
|
||||||
json=['tag1id', 'tag2id'],
|
json=['tag1id', 'tag2id'],
|
||||||
status_code=201)
|
status_code=201,
|
||||||
|
)
|
||||||
data, _ = user.post({}, res=Tag, query=[('num', 2)])
|
data, _ = user.post({}, res=Tag, query=[('num', 2)])
|
||||||
assert data['items'][0]['id'] == 'tag1id'
|
assert data['items'][0]['id'] == 'tag1id'
|
||||||
assert data['items'][0]['printable'], 'Tags made this way are printable'
|
assert data['items'][0]['printable'], 'Tags made this way are printable'
|
||||||
|
@ -380,28 +428,37 @@ def test_create_num_regular_tags(user: UserClient, requests_mock: requests_mock.
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
def test_get_tags_endpoint(user: UserClient, app: Devicehub,
|
def test_get_tags_endpoint(
|
||||||
requests_mock: requests_mock.mocker.Mocker):
|
user: UserClient, app: Devicehub, requests_mock: requests_mock.mocker.Mocker
|
||||||
|
):
|
||||||
"""Performs GET /tags after creating 3 tags, 2 printable and one
|
"""Performs GET /tags after creating 3 tags, 2 printable and one
|
||||||
not. Only the printable ones are returned.
|
not. Only the printable ones are returned.
|
||||||
"""
|
"""
|
||||||
# Prepare test
|
# Prepare test
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
org = Organization(name='bar', tax_id='bartax')
|
org = Organization(name='bar', tax_id='bartax')
|
||||||
tag = Tag(id='bar-1', org=org, provider=URL('http://foo.bar'), owner_id=user.user['id'])
|
tag = Tag(
|
||||||
|
id='bar-1',
|
||||||
|
org=org,
|
||||||
|
provider=URL('http://foo.bar'),
|
||||||
|
owner_id=user.user['id'],
|
||||||
|
)
|
||||||
db.session.add(tag)
|
db.session.add(tag)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
assert not tag.printable
|
assert not tag.printable
|
||||||
|
|
||||||
requests_mock.post('https://example.com/',
|
requests_mock.post(
|
||||||
|
'https://example.com/',
|
||||||
# request
|
# request
|
||||||
request_headers={
|
request_headers={
|
||||||
'Authorization': 'Basic {}'.format(DevicehubClient.encode_token(
|
'Authorization': 'Basic {}'.format(
|
||||||
'52dacef0-6bcb-4919-bfed-f10d2c96ecee'))
|
DevicehubClient.encode_token('52dacef0-6bcb-4919-bfed-f10d2c96ecee')
|
||||||
|
)
|
||||||
},
|
},
|
||||||
# response
|
# response
|
||||||
json=['tag1id', 'tag2id'],
|
json=['tag1id', 'tag2id'],
|
||||||
status_code=201)
|
status_code=201,
|
||||||
|
)
|
||||||
user.post({}, res=Tag, query=[('num', 2)])
|
user.post({}, res=Tag, query=[('num', 2)])
|
||||||
|
|
||||||
# Test itself
|
# Test itself
|
||||||
|
@ -421,7 +478,9 @@ def test_get_tag_permissions(app: Devicehub, user: UserClient, user2: UserClient
|
||||||
# Create a pc with a tag
|
# Create a pc with a tag
|
||||||
g.user = User.query.all()[0]
|
g.user = User.query.all()[0]
|
||||||
tag = Tag(id='foo-bar', owner_id=user.user['id'])
|
tag = Tag(id='foo-bar', owner_id=user.user['id'])
|
||||||
pc = Desktop(serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id'])
|
pc = Desktop(
|
||||||
|
serial_number='sn1', chassis=ComputerChassis.Tower, owner_id=user.user['id']
|
||||||
|
)
|
||||||
pc.tags.add(tag)
|
pc.tags.add(tag)
|
||||||
db.session.add(pc)
|
db.session.add(pc)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -432,5 +491,5 @@ def test_get_tag_permissions(app: Devicehub, user: UserClient, user2: UserClient
|
||||||
computer2, res2 = user2.get(url, None)
|
computer2, res2 = user2.get(url, None)
|
||||||
assert res.status_code == 200
|
assert res.status_code == 200
|
||||||
assert res2.status_code == 200
|
assert res2.status_code == 200
|
||||||
assert len(computer['items']) == 2
|
assert len(computer['items']) == 1
|
||||||
assert len(computer2['items']) == 0
|
assert len(computer2['items']) == 0
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
"""Tests that emulates the behaviour of a WorkbenchServer."""
|
"""Tests that emulates the behaviour of a WorkbenchServer."""
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
import math
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ereuse_devicehub.client import UserClient
|
from ereuse_devicehub.client import UserClient
|
||||||
from ereuse_devicehub.resources.action import models as em
|
from ereuse_devicehub.resources.action import models as em
|
||||||
from ereuse_devicehub.resources.action.models import RateComputer, BenchmarkProcessor, BenchmarkRamSysbench
|
from ereuse_devicehub.resources.action.models import (
|
||||||
|
BenchmarkProcessor,
|
||||||
|
BenchmarkRamSysbench,
|
||||||
|
RateComputer,
|
||||||
|
)
|
||||||
from ereuse_devicehub.resources.device.exceptions import NeedsId
|
from ereuse_devicehub.resources.device.exceptions import NeedsId
|
||||||
from ereuse_devicehub.resources.device.models import Device
|
from ereuse_devicehub.resources.device.models import Device
|
||||||
from ereuse_devicehub.resources.tag.model import Tag
|
from ereuse_devicehub.resources.tag.model import Tag
|
||||||
from tests.conftest import file, file_workbench, yaml2json, json_encode
|
from tests.conftest import file, file_workbench, json_encode, yaml2json
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -22,10 +26,9 @@ def test_workbench_server_condensed(user: UserClient):
|
||||||
"""
|
"""
|
||||||
s = yaml2json('workbench-server-1.snapshot')
|
s = yaml2json('workbench-server-1.snapshot')
|
||||||
s['device']['actions'].append(yaml2json('workbench-server-2.stress-test'))
|
s['device']['actions'].append(yaml2json('workbench-server-2.stress-test'))
|
||||||
s['components'][4]['actions'].extend((
|
s['components'][4]['actions'].extend(
|
||||||
yaml2json('workbench-server-3.erase'),
|
(yaml2json('workbench-server-3.erase'), yaml2json('workbench-server-4.install'))
|
||||||
yaml2json('workbench-server-4.install')
|
)
|
||||||
))
|
|
||||||
s['components'][5]['actions'].append(yaml2json('workbench-server-3.erase'))
|
s['components'][5]['actions'].append(yaml2json('workbench-server-3.erase'))
|
||||||
# Create tags
|
# Create tags
|
||||||
for t in s['device']['tags']:
|
for t in s['device']['tags']:
|
||||||
|
@ -34,7 +37,7 @@ def test_workbench_server_condensed(user: UserClient):
|
||||||
snapshot, _ = user.post(res=em.Snapshot, data=json_encode(s))
|
snapshot, _ = user.post(res=em.Snapshot, data=json_encode(s))
|
||||||
pc_id = snapshot['device']['id']
|
pc_id = snapshot['device']['id']
|
||||||
cpu_id = snapshot['components'][3]['id']
|
cpu_id = snapshot['components'][3]['id']
|
||||||
ssd_id= snapshot['components'][4]['id']
|
ssd_id = snapshot['components'][4]['id']
|
||||||
hdd_id = snapshot['components'][5]['id']
|
hdd_id = snapshot['components'][5]['id']
|
||||||
actions = snapshot['actions']
|
actions = snapshot['actions']
|
||||||
assert {(action['type'], action['device']) for action in actions} == {
|
assert {(action['type'], action['device']) for action in actions} == {
|
||||||
|
@ -60,8 +63,13 @@ def test_workbench_server_condensed(user: UserClient):
|
||||||
assert device['processorModel'] == device['components'][3]['model'] == 'p1-1ml'
|
assert device['processorModel'] == device['components'][3]['model'] == 'p1-1ml'
|
||||||
assert device['ramSize'] == 2048, 'There are 3 RAM: 2 x 1024 and 1 None sizes'
|
assert device['ramSize'] == 2048, 'There are 3 RAM: 2 x 1024 and 1 None sizes'
|
||||||
# TODO JN why haven't same order in actions on each execution?
|
# TODO JN why haven't same order in actions on each execution?
|
||||||
assert any([ac['type'] in [BenchmarkProcessor.t, BenchmarkRamSysbench.t] for ac in device['actions']])
|
assert any(
|
||||||
assert 'tag1' in [x['id'] for x in device['tags']]
|
[
|
||||||
|
ac['type'] in [BenchmarkProcessor.t, BenchmarkRamSysbench.t]
|
||||||
|
for ac in device['actions']
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert 'tag1' not in [x['id'] for x in device['tags']]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(reason='Functionality not yet developed.')
|
@pytest.mark.xfail(reason='Functionality not yet developed.')
|
||||||
|
@ -136,7 +144,10 @@ def test_real_hp_11(user: UserClient):
|
||||||
s = file('real-hp.snapshot.11')
|
s = file('real-hp.snapshot.11')
|
||||||
snapshot, _ = user.post(res=em.Snapshot, data=s)
|
snapshot, _ = user.post(res=em.Snapshot, data=s)
|
||||||
pc = snapshot['device']
|
pc = snapshot['device']
|
||||||
assert pc['hid'] == 'desktop-hewlett-packard-hp_compaq_8100_elite_sff-czc0408yjg-6c:62:6d:81:22:9f'
|
assert (
|
||||||
|
pc['hid']
|
||||||
|
== 'desktop-hewlett-packard-hp_compaq_8100_elite_sff-czc0408yjg-6c:62:6d:81:22:9f'
|
||||||
|
)
|
||||||
assert pc['chassis'] == 'Tower'
|
assert pc['chassis'] == 'Tower'
|
||||||
assert set(e['type'] for e in snapshot['actions']) == {
|
assert set(e['type'] for e in snapshot['actions']) == {
|
||||||
'BenchmarkDataStorage',
|
'BenchmarkDataStorage',
|
||||||
|
@ -146,7 +157,7 @@ def test_real_hp_11(user: UserClient):
|
||||||
'BenchmarkRamSysbench',
|
'BenchmarkRamSysbench',
|
||||||
'StressTest',
|
'StressTest',
|
||||||
'TestBios',
|
'TestBios',
|
||||||
'VisualTest'
|
'VisualTest',
|
||||||
}
|
}
|
||||||
|
|
||||||
assert len(list(e['type'] for e in snapshot['actions'])) == 8
|
assert len(list(e['type'] for e in snapshot['actions'])) == 8
|
||||||
|
@ -168,7 +179,6 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient):
|
||||||
"""Checks the values of the device, components,
|
"""Checks the values of the device, components,
|
||||||
actions and their relationships of a real pc.
|
actions and their relationships of a real pc.
|
||||||
"""
|
"""
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
s = file('real-eee-1001pxd.snapshot.11')
|
s = file('real-eee-1001pxd.snapshot.11')
|
||||||
snapshot, _ = user.post(res=em.Snapshot, data=s)
|
snapshot, _ = user.post(res=em.Snapshot, data=s)
|
||||||
pc, _ = user.get(res=Device, item=snapshot['device']['devicehubID'])
|
pc, _ = user.get(res=Device, item=snapshot['device']['devicehubID'])
|
||||||
|
@ -177,22 +187,32 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient):
|
||||||
assert pc['model'] == '1001pxd'
|
assert pc['model'] == '1001pxd'
|
||||||
assert pc['serialNumber'] == 'b8oaas048286'
|
assert pc['serialNumber'] == 'b8oaas048286'
|
||||||
assert pc['manufacturer'] == 'asustek computer inc.'
|
assert pc['manufacturer'] == 'asustek computer inc.'
|
||||||
assert pc['hid'] == 'laptop-asustek_computer_inc-1001pxd-b8oaas048286-14:da:e9:42:f6:7c'
|
assert (
|
||||||
assert len(pc['tags']) == 1
|
pc['hid']
|
||||||
assert pc['networkSpeeds'] == [100, 0], 'Although it has WiFi we do not know the speed'
|
== 'laptop-asustek_computer_inc-1001pxd-b8oaas048286-14:da:e9:42:f6:7c'
|
||||||
|
)
|
||||||
|
assert len(pc['tags']) == 0
|
||||||
|
assert pc['networkSpeeds'] == [
|
||||||
|
100,
|
||||||
|
0,
|
||||||
|
], 'Although it has WiFi we do not know the speed'
|
||||||
# assert pc['actions'][0]['appearanceRange'] == 'A'
|
# assert pc['actions'][0]['appearanceRange'] == 'A'
|
||||||
# assert pc['actions'][0]['functionalityRange'] == 'B'
|
# assert pc['actions'][0]['functionalityRange'] == 'B'
|
||||||
# TODO add appearance and functionality Range in device[rate]
|
# TODO add appearance and functionality Range in device[rate]
|
||||||
|
|
||||||
components = snapshot['components']
|
components = snapshot['components']
|
||||||
wifi = components[0]
|
wifi = components[0]
|
||||||
assert wifi['hid'] == 'networkadapter-qualcomm_atheros-' \
|
assert (
|
||||||
|
wifi['hid'] == 'networkadapter-qualcomm_atheros-'
|
||||||
'ar9285_wireless_network_adapter-74_2f_68_8b_fd_c8'
|
'ar9285_wireless_network_adapter-74_2f_68_8b_fd_c8'
|
||||||
|
)
|
||||||
assert wifi['serialNumber'] == '74:2f:68:8b:fd:c8'
|
assert wifi['serialNumber'] == '74:2f:68:8b:fd:c8'
|
||||||
assert wifi['wireless']
|
assert wifi['wireless']
|
||||||
eth = components[1]
|
eth = components[1]
|
||||||
assert eth['hid'] == 'networkadapter-qualcomm_atheros-' \
|
assert (
|
||||||
|
eth['hid'] == 'networkadapter-qualcomm_atheros-'
|
||||||
'ar8152_v2_0_fast_ethernet-14_da_e9_42_f6_7c'
|
'ar8152_v2_0_fast_ethernet-14_da_e9_42_f6_7c'
|
||||||
|
)
|
||||||
assert eth['speed'] == 100
|
assert eth['speed'] == 100
|
||||||
assert not eth['wireless']
|
assert not eth['wireless']
|
||||||
cpu = components[2]
|
cpu = components[2]
|
||||||
|
@ -219,7 +239,10 @@ def test_snapshot_real_eee_1001pxd_with_rate(user: UserClient):
|
||||||
assert em.Snapshot.t in action_types
|
assert em.Snapshot.t in action_types
|
||||||
assert len(actions) == 6
|
assert len(actions) == 6
|
||||||
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'
|
||||||
assert gpu['memory'] == 256
|
assert gpu['memory'] == 256
|
||||||
gpu, _ = user.get(res=Device, item=gpu['devicehubID'])
|
gpu, _ = user.get(res=Device, item=gpu['devicehubID'])
|
||||||
|
@ -285,25 +308,26 @@ SNAPSHOTS_NEED_ID = {
|
||||||
'nox.snapshot.json',
|
'nox.snapshot.json',
|
||||||
'ecs-computers.snapshot.json',
|
'ecs-computers.snapshot.json',
|
||||||
'custom.snapshot.json',
|
'custom.snapshot.json',
|
||||||
'ecs-2.snapshot.json'
|
'ecs-2.snapshot.json',
|
||||||
}
|
}
|
||||||
"""Snapshots that do not generate HID requiring a custom ID."""
|
"""Snapshots that do not generate HID requiring a custom ID."""
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
@pytest.mark.parametrize('file',
|
@pytest.mark.parametrize(
|
||||||
(pytest.param(f, id=f.name)
|
'file',
|
||||||
for f in pathlib.Path(__file__).parent.joinpath('workbench_files').iterdir())
|
(
|
||||||
)
|
pytest.param(f, id=f.name)
|
||||||
|
for f in pathlib.Path(__file__).parent.joinpath('workbench_files').iterdir()
|
||||||
|
),
|
||||||
|
)
|
||||||
def test_workbench_fixtures(file: pathlib.Path, user: UserClient):
|
def test_workbench_fixtures(file: pathlib.Path, user: UserClient):
|
||||||
"""Uploads the Snapshot files Workbench tests generate.
|
"""Uploads the Snapshot files Workbench tests generate.
|
||||||
|
|
||||||
Keep this files up to date with the Workbench version.
|
Keep this files up to date with the Workbench version.
|
||||||
"""
|
"""
|
||||||
s = json.load(file.open())
|
s = json.load(file.open())
|
||||||
user.post(res=em.Snapshot,
|
user.post(res=em.Snapshot, data=json_encode(s), status=201)
|
||||||
data=json_encode(s),
|
|
||||||
status=201)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
|
Reference in New Issue