Merge pull request #179 from eReuse/bugfix/#177-trade
Bugfix/#177 trade
This commit is contained in:
commit
0daa9cf284
|
@ -0,0 +1,43 @@
|
||||||
|
"""adding author action_device
|
||||||
|
|
||||||
|
Revision ID: d22d230d2850
|
||||||
|
Revises: 1bb2b5e0fae7
|
||||||
|
Create Date: 2021-11-10 17:37:12.304853
|
||||||
|
|
||||||
|
"""
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import context
|
||||||
|
from alembic import op
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'd22d230d2850'
|
||||||
|
down_revision = '1bb2b5e0fae7'
|
||||||
|
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():
|
||||||
|
op.add_column('action_device',
|
||||||
|
sa.Column('author_id',
|
||||||
|
postgresql.UUID(),
|
||||||
|
nullable=True),
|
||||||
|
schema=f'{get_inv()}')
|
||||||
|
op.create_foreign_key("fk_action_device_author",
|
||||||
|
"action_device", "user",
|
||||||
|
["author_id"], ["id"],
|
||||||
|
ondelete="SET NULL",
|
||||||
|
source_schema=f'{get_inv()}',
|
||||||
|
referent_schema='common')
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_constraint("fk_action_device_author", "device", type_="foreignkey", schema=f'{get_inv()}')
|
||||||
|
op.drop_column('action_device', 'author_id', schema=f'{get_inv()}')
|
|
@ -280,16 +280,16 @@ class ConfirmDef(ActionDef):
|
||||||
SCHEMA = schemas.Confirm
|
SCHEMA = schemas.Confirm
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevokeDef(ActionDef):
|
|
||||||
VIEW = None
|
|
||||||
SCHEMA = schemas.ConfirmRevoke
|
|
||||||
|
|
||||||
|
|
||||||
class RevokeDef(ActionDef):
|
class RevokeDef(ActionDef):
|
||||||
VIEW = None
|
VIEW = None
|
||||||
SCHEMA = schemas.Revoke
|
SCHEMA = schemas.Revoke
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmRevokeDef(ActionDef):
|
||||||
|
VIEW = None
|
||||||
|
SCHEMA = schemas.ConfirmRevoke
|
||||||
|
|
||||||
|
|
||||||
class TradeDef(ActionDef):
|
class TradeDef(ActionDef):
|
||||||
VIEW = None
|
VIEW = None
|
||||||
SCHEMA = schemas.Trade
|
SCHEMA = schemas.Trade
|
||||||
|
|
|
@ -317,6 +317,14 @@ class ActionDevice(db.Model):
|
||||||
index=True,
|
index=True,
|
||||||
server_default=db.text('CURRENT_TIMESTAMP'))
|
server_default=db.text('CURRENT_TIMESTAMP'))
|
||||||
created.comment = """When Devicehub created this."""
|
created.comment = """When Devicehub created this."""
|
||||||
|
author_id = Column(UUID(as_uuid=True),
|
||||||
|
ForeignKey(User.id),
|
||||||
|
nullable=False,
|
||||||
|
default=lambda: g.user.id)
|
||||||
|
# todo compute the org
|
||||||
|
author = relationship(User,
|
||||||
|
backref=backref('authored_actions_device', lazy=True, collection_class=set),
|
||||||
|
primaryjoin=author_id == User.id)
|
||||||
|
|
||||||
def __init__(self, **kwargs) -> None:
|
def __init__(self, **kwargs) -> None:
|
||||||
self.created = kwargs.get('created', datetime.now(timezone.utc))
|
self.created = kwargs.get('created', datetime.now(timezone.utc))
|
||||||
|
@ -1610,11 +1618,11 @@ class Revoke(Confirm):
|
||||||
"""Users can revoke one confirmation of one action trade"""
|
"""Users can revoke one confirmation of one action trade"""
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevoke(Confirm):
|
# class ConfirmRevoke(Confirm):
|
||||||
"""Users can confirm and accept one action revoke"""
|
# """Users can confirm and accept one action revoke"""
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
# def __repr__(self) -> str:
|
||||||
return '<{0.t} {0.id} accepted by {0.user}>'.format(self)
|
# return '<{0.t} {0.id} accepted by {0.user}>'.format(self)
|
||||||
|
|
||||||
|
|
||||||
class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||||
|
|
|
@ -445,16 +445,13 @@ class ActionStatus(Action):
|
||||||
@post_load
|
@post_load
|
||||||
def put_rol_user(self, data: dict):
|
def put_rol_user(self, data: dict):
|
||||||
for dev in data['devices']:
|
for dev in data['devices']:
|
||||||
if dev.trading in [None, 'Revoke', 'ConfirmRevoke']:
|
|
||||||
return data
|
|
||||||
|
|
||||||
trades = [ac for ac in dev.actions if ac.t == 'Trade']
|
trades = [ac for ac in dev.actions if ac.t == 'Trade']
|
||||||
if not trades:
|
if not trades:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
trade = trades[-1]
|
trade = trades[-1]
|
||||||
|
|
||||||
if trade.user_to != g.user:
|
if trade.user_from == g.user:
|
||||||
data['rol_user'] = trade.user_to
|
data['rol_user'] = trade.user_to
|
||||||
data['trade'] = trade
|
data['trade'] = trade
|
||||||
|
|
||||||
|
@ -588,6 +585,10 @@ class Revoke(ActionWithMultipleDevices):
|
||||||
raise ValidationError(txt)
|
raise ValidationError(txt)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfirmRevoke(Revoke):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ConfirmDocument(ActionWithMultipleDocuments):
|
class ConfirmDocument(ActionWithMultipleDocuments):
|
||||||
__doc__ = m.Confirm.__doc__
|
__doc__ = m.Confirm.__doc__
|
||||||
action = NestedOn('Action', only_query='id')
|
action = NestedOn('Action', only_query='id')
|
||||||
|
@ -642,7 +643,7 @@ class RevokeDocument(ActionWithMultipleDocuments):
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
||||||
__doc__ = m.ConfirmRevoke.__doc__
|
__doc__ = m.ConfirmRevokeDocument.__doc__
|
||||||
action = NestedOn('Action', only_query='id')
|
action = NestedOn('Action', only_query='id')
|
||||||
|
|
||||||
@validates_schema
|
@validates_schema
|
||||||
|
@ -669,66 +670,6 @@ class ConfirmRevokeDocument(ActionWithMultipleDocuments):
|
||||||
data['action'] = doc.actions[-1]
|
data['action'] = doc.actions[-1]
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevoke(ActionWithMultipleDevices):
|
|
||||||
__doc__ = m.ConfirmRevoke.__doc__
|
|
||||||
action = NestedOn('Action', only_query='id')
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_revoke(self, data: dict):
|
|
||||||
for dev in data['devices']:
|
|
||||||
# if device not exist in the Trade, then this query is wrong
|
|
||||||
if not dev in data['action'].devices:
|
|
||||||
txt = "Device {} not exist in the trade".format(dev.devicehub_id)
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
for doc in data.get('documents', []):
|
|
||||||
# if document not exist in the Trade, then this query is wrong
|
|
||||||
if not doc in data['action'].documents:
|
|
||||||
txt = "Document {} not exist in the trade".format(doc.file_name)
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
@validates_schema
|
|
||||||
def validate_docs(self, data):
|
|
||||||
"""Check if there are or no one before confirmation,
|
|
||||||
This is not checked in the view becouse the list of documents is inmutable
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not data['devices'] == OrderedSet():
|
|
||||||
return
|
|
||||||
|
|
||||||
documents = []
|
|
||||||
for doc in data['documents']:
|
|
||||||
actions = copy.copy(doc.actions)
|
|
||||||
actions.reverse()
|
|
||||||
for ac in actions:
|
|
||||||
if ac == data['action']:
|
|
||||||
# If document have the last action the action for confirm
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == 'Revoke' and not ac.user == g.user:
|
|
||||||
# If document is revoke before you can Confirm now
|
|
||||||
# and revoke is an action of one other user
|
|
||||||
documents.append(doc)
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == ConfirmRevoke.t and ac.user == g.user:
|
|
||||||
# If document is confirmed we don't need confirmed again
|
|
||||||
break
|
|
||||||
|
|
||||||
if ac.t == Confirm.t:
|
|
||||||
# if onwer of trade confirm again before than this user Confirm the
|
|
||||||
# revoke, then is not possible confirm the revoke
|
|
||||||
#
|
|
||||||
# If g.user confirm the trade before do a ConfirmRevoke
|
|
||||||
# then g.user can not to do the ConfirmRevoke more
|
|
||||||
break
|
|
||||||
|
|
||||||
if not documents:
|
|
||||||
txt = 'No there are documents with revoke for confirm'
|
|
||||||
raise ValidationError(txt)
|
|
||||||
|
|
||||||
|
|
||||||
class Trade(ActionWithMultipleDevices):
|
class Trade(ActionWithMultipleDevices):
|
||||||
__doc__ = m.Trade.__doc__
|
__doc__ = m.Trade.__doc__
|
||||||
date = DateTime(data_key='date', required=False)
|
date = DateTime(data_key='date', required=False)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from sqlalchemy.util import OrderedSet
|
||||||
from teal.marshmallow import ValidationError
|
from teal.marshmallow import ValidationError
|
||||||
|
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.resources.action.models import (Trade, Confirm, ConfirmRevoke,
|
from ereuse_devicehub.resources.action.models import (Trade, Confirm,
|
||||||
Revoke, RevokeDocument, ConfirmDocument,
|
Revoke, RevokeDocument, ConfirmDocument,
|
||||||
ConfirmRevokeDocument)
|
ConfirmRevokeDocument)
|
||||||
from ereuse_devicehub.resources.user.models import User
|
from ereuse_devicehub.resources.user.models import User
|
||||||
|
@ -181,17 +181,17 @@ class ConfirmView(ConfirmMixin):
|
||||||
then remove the list this device of the list of devices of this action
|
then remove the list this device of the list of devices of this action
|
||||||
"""
|
"""
|
||||||
real_devices = []
|
real_devices = []
|
||||||
|
trade = data['action']
|
||||||
|
lot = trade.lot
|
||||||
for dev in data['devices']:
|
for dev in data['devices']:
|
||||||
ac = dev.last_action_trading
|
if dev.trading(lot, simple=True) not in ['NeedConfirmation', 'NeedConfirmRevoke']:
|
||||||
if ac.type == Confirm.t and not ac.user == g.user:
|
raise ValidationError('Some devices not possible confirm.')
|
||||||
real_devices.append(dev)
|
|
||||||
|
|
||||||
data['devices'] = OrderedSet(real_devices)
|
|
||||||
|
|
||||||
# Change the owner for every devices
|
# Change the owner for every devices
|
||||||
for dev in data['devices']:
|
for dev in data['devices']:
|
||||||
user_to = data['action'].user_to
|
if dev.trading(lot) == 'NeedConfirmation':
|
||||||
dev.change_owner(user_to)
|
user_to = data['action'].user_to
|
||||||
|
dev.change_owner(user_to)
|
||||||
|
|
||||||
|
|
||||||
class RevokeView(ConfirmMixin):
|
class RevokeView(ConfirmMixin):
|
||||||
|
@ -215,57 +215,12 @@ class RevokeView(ConfirmMixin):
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
"""All devices need to have the status of DoubleConfirmation."""
|
"""All devices need to have the status of DoubleConfirmation."""
|
||||||
|
|
||||||
### check ###
|
devices = data['devices']
|
||||||
if not data['devices']:
|
if not devices:
|
||||||
raise ValidationError('Devices not exist.')
|
raise ValidationError('Devices not exist.')
|
||||||
|
|
||||||
for dev in data['devices']:
|
|
||||||
if not dev.trading == 'TradeConfirmed':
|
|
||||||
txt = 'Some of devices do not have enough to confirm for to do a revoke'
|
|
||||||
ValidationError(txt)
|
|
||||||
### End check ###
|
|
||||||
|
|
||||||
ids = {d.id for d in data['devices']}
|
|
||||||
lot = data['action'].lot
|
lot = data['action'].lot
|
||||||
self.model = delete_from_trade(lot, ids)
|
self.model = delete_from_trade(lot, devices)
|
||||||
|
|
||||||
|
|
||||||
class ConfirmRevokeView(ConfirmMixin):
|
|
||||||
"""Handler for manager the Confirmation register from post
|
|
||||||
|
|
||||||
request_confirm_revoke = {
|
|
||||||
'type': 'ConfirmRevoke',
|
|
||||||
'action': action_revoke.id,
|
|
||||||
'devices': [device_id]
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
Model = ConfirmRevoke
|
|
||||||
|
|
||||||
def validate(self, data):
|
|
||||||
"""All devices need to have the status of revoke."""
|
|
||||||
|
|
||||||
if not data['action'].type == 'Revoke':
|
|
||||||
txt = 'Error: this action is not a revoke action'
|
|
||||||
ValidationError(txt)
|
|
||||||
|
|
||||||
for dev in data['devices']:
|
|
||||||
if not dev.trading == 'Revoke':
|
|
||||||
txt = 'Some of devices do not have revoke to confirm'
|
|
||||||
ValidationError(txt)
|
|
||||||
|
|
||||||
devices = OrderedSet(data['devices'])
|
|
||||||
data['devices'] = devices
|
|
||||||
|
|
||||||
# Change the owner for every devices
|
|
||||||
# data['action'] == 'Revoke'
|
|
||||||
|
|
||||||
trade = data['action'].action
|
|
||||||
for dev in devices:
|
|
||||||
dev.reset_owner()
|
|
||||||
|
|
||||||
trade.lot.devices.difference_update(devices)
|
|
||||||
|
|
||||||
|
|
||||||
class ConfirmDocumentMixin():
|
class ConfirmDocumentMixin():
|
||||||
|
|
|
@ -15,7 +15,7 @@ from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.query import things_response
|
from ereuse_devicehub.query import things_response
|
||||||
from ereuse_devicehub.resources.action.models import (Action, Snapshot, VisualTest,
|
from ereuse_devicehub.resources.action.models import (Action, Snapshot, VisualTest,
|
||||||
InitTransfer, Live, Allocate, Deallocate,
|
InitTransfer, Live, Allocate, Deallocate,
|
||||||
Trade, Confirm, ConfirmRevoke, Revoke)
|
Trade, Confirm, Revoke)
|
||||||
from ereuse_devicehub.resources.action.views import trade as trade_view
|
from ereuse_devicehub.resources.action.views import trade as trade_view
|
||||||
from ereuse_devicehub.resources.action.views.snapshot import SnapshotView, save_json, move_json
|
from ereuse_devicehub.resources.action.views.snapshot import SnapshotView, save_json, move_json
|
||||||
from ereuse_devicehub.resources.action.views.documents import ErasedView
|
from ereuse_devicehub.resources.action.views.documents import ErasedView
|
||||||
|
@ -235,9 +235,9 @@ class ActionView(View):
|
||||||
revoke = trade_view.RevokeView(json, resource_def, self.schema)
|
revoke = trade_view.RevokeView(json, resource_def, self.schema)
|
||||||
return revoke.post()
|
return revoke.post()
|
||||||
|
|
||||||
if json['type'] == ConfirmRevoke.t:
|
if json['type'] == 'ConfirmRevoke':
|
||||||
confirm_revoke = trade_view.ConfirmRevokeView(json, resource_def, self.schema)
|
revoke = trade_view.RevokeView(json, resource_def, self.schema)
|
||||||
return confirm_revoke.post()
|
return revoke.post()
|
||||||
|
|
||||||
if json['type'] == 'RevokeDocument':
|
if json['type'] == 'RevokeDocument':
|
||||||
revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema)
|
revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema)
|
||||||
|
|
|
@ -89,7 +89,6 @@ class Metrics(MetricsMix):
|
||||||
trade['status_receiver_created'] = self.act.created
|
trade['status_receiver_created'] = self.act.created
|
||||||
return
|
return
|
||||||
|
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
# necesitamos poder poner un cambio de estado de un trade mas antiguo que last_trade
|
# necesitamos poder poner un cambio de estado de un trade mas antiguo que last_trade
|
||||||
# lo mismo con confirm
|
# lo mismo con confirm
|
||||||
|
|
||||||
|
@ -148,9 +147,7 @@ class Metrics(MetricsMix):
|
||||||
if the action is one trade action, is possible than have a list of confirmations.
|
if the action is one trade action, is possible than have a list of confirmations.
|
||||||
Get the doble confirm for to know if this trade is confirmed or not.
|
Get the doble confirm for to know if this trade is confirmed or not.
|
||||||
"""
|
"""
|
||||||
if self.device.trading == 'TradeConfirmed':
|
return self.device.trading(self.act.lot, simple=True)
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_trade(self):
|
def get_trade(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import pathlib
|
import pathlib
|
||||||
import copy
|
import copy
|
||||||
|
import time
|
||||||
from flask import g
|
from flask import g
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from fractions import Fraction
|
from fractions import Fraction
|
||||||
|
@ -311,75 +312,90 @@ class Device(Thing):
|
||||||
return history
|
return history
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def trading(self):
|
def tradings(self):
|
||||||
|
return {str(x.id): self.trading(x.lot) for x in self.actions if x.t == 'Trade'}
|
||||||
|
|
||||||
|
def trading(self, lot, simple=None):
|
||||||
"""The trading state, or None if no Trade action has
|
"""The trading state, or None if no Trade action has
|
||||||
ever been performed to this device. This extract the posibilities for to do"""
|
ever been performed to this device. This extract the posibilities for to do.
|
||||||
|
This method is performed for show in the web.
|
||||||
# trade = 'Trade'
|
If you need to do one simple and generic response you can put simple=True for that."""
|
||||||
confirm = 'Confirm'
|
if not hasattr(lot, 'trade'):
|
||||||
need_confirm = 'NeedConfirmation'
|
|
||||||
double_confirm = 'TradeConfirmed'
|
|
||||||
revoke = 'Revoke'
|
|
||||||
revoke_pending = 'RevokePending'
|
|
||||||
confirm_revoke = 'ConfirmRevoke'
|
|
||||||
# revoke_confirmed = 'RevokeConfirmed'
|
|
||||||
|
|
||||||
# return the correct status of trade depending of the user
|
|
||||||
|
|
||||||
# #### CASES #####
|
|
||||||
# User1 == owner of trade (This user have automatic Confirmation)
|
|
||||||
# =======================
|
|
||||||
# if the last action is => only allow to do
|
|
||||||
# ==========================================
|
|
||||||
# Confirmation not User1 => Revoke
|
|
||||||
# Confirmation User1 => Revoke
|
|
||||||
# Revoke not User1 => ConfirmRevoke
|
|
||||||
# Revoke User1 => RevokePending
|
|
||||||
# RevokeConfirmation => RevokeConfirmed
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# User2 == Not owner of trade
|
|
||||||
# =======================
|
|
||||||
# if the last action is => only allow to do
|
|
||||||
# ==========================================
|
|
||||||
# Confirmation not User2 => Confirm
|
|
||||||
# Confirmation User2 => Revoke
|
|
||||||
# Revoke not User2 => ConfirmRevoke
|
|
||||||
# Revoke User2 => RevokePending
|
|
||||||
# RevokeConfirmation => RevokeConfirmed
|
|
||||||
|
|
||||||
ac = self.last_action_trading
|
|
||||||
if not ac:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
first_owner = self.which_user_put_this_device_in_trace()
|
Status = {0: 'Trade',
|
||||||
|
1: 'Confirm',
|
||||||
|
2: 'NeedConfirmation',
|
||||||
|
3: 'TradeConfirmed',
|
||||||
|
4: 'Revoke',
|
||||||
|
5: 'NeedConfirmRevoke',
|
||||||
|
6: 'RevokeConfirmed'}
|
||||||
|
|
||||||
if ac.type == confirm_revoke:
|
trade = lot.trade
|
||||||
# can to do revoke_confirmed
|
user_from = trade.user_from
|
||||||
return confirm_revoke
|
user_to = trade.user_to
|
||||||
|
status = 0
|
||||||
|
last_user = None
|
||||||
|
|
||||||
if ac.type == revoke:
|
if not hasattr(trade, 'acceptances'):
|
||||||
if ac.user == g.user:
|
return Status[status]
|
||||||
# can todo revoke_pending
|
|
||||||
return revoke_pending
|
|
||||||
else:
|
|
||||||
# can to do confirm_revoke
|
|
||||||
return revoke
|
|
||||||
|
|
||||||
if ac.type == confirm:
|
for ac in self.actions:
|
||||||
if not first_owner:
|
if ac.t not in ['Confirm', 'Revoke']:
|
||||||
return
|
continue
|
||||||
|
|
||||||
if ac.user == first_owner:
|
if ac.user not in [user_from, user_to]:
|
||||||
if first_owner == g.user:
|
continue
|
||||||
# can to do revoke
|
|
||||||
return confirm
|
if ac.t == 'Confirm' and ac.action == trade:
|
||||||
else:
|
if status in [0, 6]:
|
||||||
# can to do confirm
|
if simple:
|
||||||
return need_confirm
|
status = 2
|
||||||
else:
|
continue
|
||||||
# can to do revoke
|
status = 1
|
||||||
return double_confirm
|
last_user = ac.user
|
||||||
|
if ac.user == user_from and user_to == g.user:
|
||||||
|
status = 2
|
||||||
|
if ac.user == user_to and user_from == g.user:
|
||||||
|
status = 2
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status in [1, 2]:
|
||||||
|
if last_user != ac.user:
|
||||||
|
status = 3
|
||||||
|
last_user = ac.user
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status in [4, 5]:
|
||||||
|
status = 3
|
||||||
|
last_user = ac.user
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ac.t == 'Revoke' and ac.action == trade:
|
||||||
|
if status == 3:
|
||||||
|
if simple:
|
||||||
|
status = 5
|
||||||
|
continue
|
||||||
|
status = 4
|
||||||
|
last_user = ac.user
|
||||||
|
if ac.user == user_from and user_to == g.user:
|
||||||
|
status = 5
|
||||||
|
if ac.user == user_to and user_from == g.user:
|
||||||
|
status = 5
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status in [4, 5]:
|
||||||
|
if last_user != ac.user:
|
||||||
|
status = 6
|
||||||
|
last_user = ac.user
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status in [1, 2]:
|
||||||
|
status = 6
|
||||||
|
last_user = ac.user
|
||||||
|
continue
|
||||||
|
|
||||||
|
return Status[status]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def revoke(self):
|
def revoke(self):
|
||||||
|
@ -485,15 +501,15 @@ class Device(Thing):
|
||||||
def which_user_put_this_device_in_trace(self):
|
def which_user_put_this_device_in_trace(self):
|
||||||
"""which is the user than put this device in this trade"""
|
"""which is the user than put this device in this trade"""
|
||||||
actions = copy.copy(self.actions)
|
actions = copy.copy(self.actions)
|
||||||
actions.sort(key=lambda x: x.created)
|
|
||||||
actions.reverse()
|
actions.reverse()
|
||||||
last_ac = None
|
|
||||||
# search the automatic Confirm
|
# search the automatic Confirm
|
||||||
for ac in actions:
|
for ac in actions:
|
||||||
if ac.type == 'Trade':
|
if ac.type == 'Trade':
|
||||||
return last_ac.user
|
action_device = [x for x in ac.actions_device if x.device == self][0]
|
||||||
if ac.type == 'Confirm':
|
if action_device.author:
|
||||||
last_ac = ac
|
return action_device.author
|
||||||
|
|
||||||
|
return ac.author
|
||||||
|
|
||||||
def change_owner(self, new_user):
|
def change_owner(self, new_user):
|
||||||
"""util for change the owner one device"""
|
"""util for change the owner one device"""
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from marshmallow import post_load, pre_load, fields as f
|
from marshmallow import post_load, pre_load, fields as f
|
||||||
from marshmallow.fields import Boolean, Date, DateTime, Float, Integer, List, Str, String, UUID
|
from marshmallow.fields import Boolean, Date, DateTime, Float, Integer, List, Str, String, UUID, Dict
|
||||||
from marshmallow.validate import Length, OneOf, Range
|
from marshmallow.validate import Length, OneOf, Range
|
||||||
from sqlalchemy.util import OrderedSet
|
from sqlalchemy.util import OrderedSet
|
||||||
from stdnum import imei, meid
|
from stdnum import imei, meid
|
||||||
|
@ -50,12 +50,11 @@ class Device(Thing):
|
||||||
description='The lots where this device is directly under.')
|
description='The lots where this device is directly under.')
|
||||||
rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__)
|
rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__)
|
||||||
price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__)
|
price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__)
|
||||||
# trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__)
|
tradings = Dict(dump_only=True, description='')
|
||||||
trading = SanitizedStr(dump_only=True, description='')
|
|
||||||
physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__)
|
physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__)
|
||||||
traking= EnumField(states.Traking, dump_only=True, description=m.Device.physical.__doc__)
|
traking = EnumField(states.Traking, dump_only=True, description=m.Device.physical.__doc__)
|
||||||
usage = EnumField(states.Usage, dump_only=True, description=m.Device.physical.__doc__)
|
usage = EnumField(states.Usage, dump_only=True, description=m.Device.physical.__doc__)
|
||||||
revoke = UUID(dump_only=True)
|
revoke = UUID(dump_only=True)
|
||||||
physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor')
|
physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor')
|
||||||
production_date = DateTime('iso',
|
production_date = DateTime('iso',
|
||||||
description=m.Device.updated.comment,
|
description=m.Device.updated.comment,
|
||||||
|
|
|
@ -37,7 +37,6 @@ class Trading(State):
|
||||||
Trade = e.Trade
|
Trade = e.Trade
|
||||||
Confirm = e.Confirm
|
Confirm = e.Confirm
|
||||||
Revoke = e.Revoke
|
Revoke = e.Revoke
|
||||||
ConfirmRevoke = e.ConfirmRevoke
|
|
||||||
Cancelled = e.CancelTrade
|
Cancelled = e.CancelTrade
|
||||||
Sold = e.Sell
|
Sold = e.Sell
|
||||||
Donated = e.Donate
|
Donated = e.Donate
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import uuid
|
import uuid
|
||||||
|
from sqlalchemy.util import OrderedSet
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict, List, Set, Union
|
from typing import Dict, List, Set, Union
|
||||||
|
@ -13,7 +14,7 @@ from teal.resource import View
|
||||||
from ereuse_devicehub.db import db
|
from ereuse_devicehub.db import db
|
||||||
from ereuse_devicehub.query import things_response
|
from ereuse_devicehub.query import things_response
|
||||||
from ereuse_devicehub.resources.device.models import Device, Computer
|
from ereuse_devicehub.resources.device.models import Device, Computer
|
||||||
from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke, ConfirmRevoke
|
from ereuse_devicehub.resources.action.models import Trade, Confirm, Revoke
|
||||||
from ereuse_devicehub.resources.lot.models import Lot, Path
|
from ereuse_devicehub.resources.lot.models import Lot, Path
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,7 +231,7 @@ class LotDeviceView(LotBaseChildrenView):
|
||||||
return
|
return
|
||||||
|
|
||||||
devices = set(Device.query.filter(Device.id.in_(ids)).filter(
|
devices = set(Device.query.filter(Device.id.in_(ids)).filter(
|
||||||
Device.owner==g.user))
|
Device.owner == g.user))
|
||||||
|
|
||||||
lot.devices.update(devices)
|
lot.devices.update(devices)
|
||||||
|
|
||||||
|
@ -246,7 +247,8 @@ class LotDeviceView(LotBaseChildrenView):
|
||||||
return
|
return
|
||||||
|
|
||||||
if lot.trade:
|
if lot.trade:
|
||||||
return delete_from_trade(lot, ids)
|
devices = Device.query.filter(Device.id.in_(ids)).all()
|
||||||
|
return delete_from_trade(lot, devices)
|
||||||
|
|
||||||
if not g.user == lot.owner:
|
if not g.user == lot.owner:
|
||||||
txt = 'This is not your lot'
|
txt = 'This is not your lot'
|
||||||
|
@ -258,49 +260,45 @@ class LotDeviceView(LotBaseChildrenView):
|
||||||
lot.devices.difference_update(devices)
|
lot.devices.difference_update(devices)
|
||||||
|
|
||||||
|
|
||||||
def delete_from_trade(lot: Lot, ids: Set[int]):
|
def delete_from_trade(lot: Lot, devices: List):
|
||||||
users = [lot.trade.user_from.id, lot.trade.user_to.id]
|
users = [lot.trade.user_from, lot.trade.user_to]
|
||||||
if not g.user.id in users:
|
if g.user not in users:
|
||||||
# theoretically this case is impossible
|
# theoretically this case is impossible
|
||||||
txt = 'This is not your trade'
|
txt = 'This is not your trade'
|
||||||
raise ma.ValidationError(txt)
|
raise ma.ValidationError(txt)
|
||||||
|
|
||||||
devices = set(Device.query.filter(Device.id.in_(ids)).filter(
|
# we need lock the action revoke for devices than travel for futures trades
|
||||||
Device.owner_id.in_(users)))
|
for dev in devices:
|
||||||
|
if dev.owner not in users:
|
||||||
|
txt = 'This is not your device'
|
||||||
|
raise ma.ValidationError(txt)
|
||||||
|
|
||||||
# Now we need to know which devices we need extract of the lot
|
drop_of_lot = []
|
||||||
without_confirms = set() # set of devs without confirms of user2
|
without_confirms = []
|
||||||
|
for dev in devices:
|
||||||
|
if dev.trading(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']:
|
||||||
|
drop_of_lot.append(dev)
|
||||||
|
dev.reset_owner()
|
||||||
|
|
||||||
# if the trade need confirmation, then extract all devs than
|
if not lot.trade.confirm:
|
||||||
# have only one confirmation and is from the same user than try to do
|
drop_of_lot.append(dev)
|
||||||
# now the revoke action
|
without_confirms.append(dev)
|
||||||
if lot.trade.confirm:
|
dev.reset_owner()
|
||||||
for dev in devices:
|
|
||||||
# if have only one confirmation
|
|
||||||
# then can be revoked and deleted of the lot
|
|
||||||
# Confirm of dev.trading mean that there are only one confirmation
|
|
||||||
# and the first user than put this device in trade is the actual g.user
|
|
||||||
if dev.trading == 'Confirm':
|
|
||||||
without_confirms.add(dev)
|
|
||||||
dev.reset_owner()
|
|
||||||
|
|
||||||
# we need to mark one revoke for every devs
|
revoke = Revoke(action=lot.trade, user=g.user, devices=set(devices))
|
||||||
revoke = Revoke(action=lot.trade, user=g.user, devices=devices)
|
|
||||||
db.session.add(revoke)
|
db.session.add(revoke)
|
||||||
|
|
||||||
if not lot.trade.confirm:
|
|
||||||
# if the trade is with phantom account
|
|
||||||
without_confirms = devices
|
|
||||||
|
|
||||||
if without_confirms:
|
if without_confirms:
|
||||||
confirm_revoke = ConfirmRevoke(
|
phantom = lot.trade.user_to
|
||||||
action=revoke,
|
if lot.trade.user_to == g.user:
|
||||||
user=g.user,
|
phantom = lot.trade.user_from
|
||||||
devices=without_confirms
|
|
||||||
|
phantom_revoke = Revoke(
|
||||||
|
action=lot.trade,
|
||||||
|
user=phantom,
|
||||||
|
devices=set(without_confirms)
|
||||||
)
|
)
|
||||||
db.session.add(confirm_revoke)
|
db.session.add(phantom_revoke)
|
||||||
|
|
||||||
lot.devices.difference_update(without_confirms)
|
|
||||||
lot.trade.devices = lot.devices
|
|
||||||
|
|
||||||
|
lot.devices.difference_update(OrderedSet(drop_of_lot))
|
||||||
return revoke
|
return revoke
|
||||||
|
|
|
@ -328,7 +328,7 @@ def test_outgoinlot_status_actions(action_model: models.Action, user: UserClient
|
||||||
|
|
||||||
assert device['actions'][-1]['id'] == action['id']
|
assert device['actions'][-1]['id'] == action['id']
|
||||||
assert action['author']['id'] == user.user['id']
|
assert action['author']['id'] == user.user['id']
|
||||||
assert action['rol_user']['id'] == user.user['id']
|
assert action['rol_user']['id'] == user2.user['id']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -386,14 +386,14 @@ def test_history_status_actions(user: UserClient, user2: UserClient):
|
||||||
assert action['id'] == str(device.status.id)
|
assert action['id'] == str(device.status.id)
|
||||||
assert device.status.t == models.Recycling.t
|
assert device.status.t == models.Recycling.t
|
||||||
assert [action['id']] == [str(ac.id) for ac in device.history_status]
|
assert [action['id']] == [str(ac.id) for ac in device.history_status]
|
||||||
|
|
||||||
# Case 2
|
# Case 2
|
||||||
action2 = {'type': models.Refurbish.t, 'devices': [device.id]}
|
action2 = {'type': models.Refurbish.t, 'devices': [device.id]}
|
||||||
action2, _ = user.post(action2, res=models.Action)
|
action2, _ = user.post(action2, res=models.Action)
|
||||||
assert action2['id'] == str(device.status.id)
|
assert action2['id'] == str(device.status.id)
|
||||||
assert device.status.t == models.Refurbish.t
|
assert device.status.t == models.Refurbish.t
|
||||||
assert [action2['id']] == [str(ac.id) for ac in device.history_status]
|
assert [action2['id']] == [str(ac.id) for ac in device.history_status]
|
||||||
|
|
||||||
# Case 3
|
# Case 3
|
||||||
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
|
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
|
||||||
user.post({},
|
user.post({},
|
||||||
|
@ -1396,6 +1396,7 @@ def test_confirm_revoke(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_post)
|
user.post(res=models.Action, data=request_post)
|
||||||
trade = models.Trade.query.one()
|
trade = models.Trade.query.one()
|
||||||
|
device = trade.devices[0]
|
||||||
|
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
|
@ -1416,9 +1417,10 @@ def test_confirm_revoke(user: UserClient, user2: UserClient):
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user2.post(res=models.Action, data=request_revoke)
|
user2.post(res=models.Action, data=request_revoke)
|
||||||
|
|
||||||
# You can not to do one confirmation next of one revoke
|
# You can to do one confirmation next of one revoke
|
||||||
user2.post(res=models.Action, data=request_confirm, status=422)
|
user2.post(res=models.Action, data=request_confirm)
|
||||||
assert len(trade.acceptances) == 3
|
assert len(trade.acceptances) == 4
|
||||||
|
assert device.trading(trade.lot) == "TradeConfirmed"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1455,7 +1457,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient):
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[:7])
|
query=devices[:7])
|
||||||
|
|
||||||
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
||||||
# for the SCRAP to confirm it
|
# for the SCRAP to confirm it
|
||||||
request_post = {
|
request_post = {
|
||||||
'type': 'Trade',
|
'type': 'Trade',
|
||||||
|
@ -1516,9 +1518,6 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient):
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
'action': trade.id,
|
'action': trade.id,
|
||||||
'devices': [
|
'devices': [
|
||||||
snap1['device']['id'],
|
|
||||||
snap2['device']['id'],
|
|
||||||
snap3['device']['id'],
|
|
||||||
snap4['device']['id'],
|
snap4['device']['id'],
|
||||||
snap5['device']['id'],
|
snap5['device']['id'],
|
||||||
snap6['device']['id'],
|
snap6['device']['id'],
|
||||||
|
@ -1535,7 +1534,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient):
|
||||||
assert trade.devices[-1].actions[-1].user == trade.user_from
|
assert trade.devices[-1].actions[-1].user == trade.user_from
|
||||||
assert len(trade.devices[0].actions) == n_actions
|
assert len(trade.devices[0].actions) == n_actions
|
||||||
|
|
||||||
# The manager remove one device of the lot and automaticaly
|
# The manager remove one device of the lot and automaticaly
|
||||||
# is create one revoke action
|
# is create one revoke action
|
||||||
device_10 = trade.devices[-1]
|
device_10 = trade.devices[-1]
|
||||||
lot, _ = user.delete({},
|
lot, _ = user.delete({},
|
||||||
|
@ -1554,31 +1553,28 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# the SCRAP confirms the revoke action
|
# the SCRAP confirms the revoke action
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device_10.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [
|
'devices': [
|
||||||
snap10['device']['id']
|
snap10['device']['id']
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
assert device_10.actions[-1].t == 'ConfirmRevoke'
|
assert device_10.actions[-1].t == 'Revoke'
|
||||||
assert device_10.actions[-2].t == 'Revoke'
|
assert device_10.actions[-2].t == 'Revoke'
|
||||||
# assert len(trade.lot.devices) == len(trade.devices) == 9
|
# assert len(trade.lot.devices) == len(trade.devices) == 9
|
||||||
# assert not device_10 in trade.devices
|
# assert not device_10 in trade.devices
|
||||||
|
|
||||||
# check validation error
|
# check validation error
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device_10.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [
|
'devices': [
|
||||||
snap9['device']['id']
|
snap9['device']['id']
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke, status=422)
|
|
||||||
|
|
||||||
|
|
||||||
# The manager add again device_10
|
# The manager add again device_10
|
||||||
# assert len(trade.devices) == 9
|
# assert len(trade.devices) == 9
|
||||||
lot, _ = user.post({},
|
lot, _ = user.post({},
|
||||||
|
@ -1604,7 +1600,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient):
|
||||||
assert device_10.actions[-1].user == trade.user_from
|
assert device_10.actions[-1].user == trade.user_from
|
||||||
assert device_10.actions[-2].t == 'Confirm'
|
assert device_10.actions[-2].t == 'Confirm'
|
||||||
assert device_10.actions[-2].user == trade.user_to
|
assert device_10.actions[-2].user == trade.user_to
|
||||||
assert device_10.actions[-3].t == 'ConfirmRevoke'
|
assert device_10.actions[-3].t == 'Revoke'
|
||||||
# assert len(device_10.actions) == 13
|
# assert len(device_10.actions) == 13
|
||||||
|
|
||||||
|
|
||||||
|
@ -1756,7 +1752,7 @@ def test_trade_case1(user: UserClient, user2: UserClient):
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[:-1])
|
query=devices[:-1])
|
||||||
|
|
||||||
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
||||||
# for the CRAP to confirm it
|
# for the CRAP to confirm it
|
||||||
request_post = {
|
request_post = {
|
||||||
'type': 'Trade',
|
'type': 'Trade',
|
||||||
|
@ -1772,31 +1768,23 @@ def test_trade_case1(user: UserClient, user2: UserClient):
|
||||||
user.post(res=models.Action, data=request_post)
|
user.post(res=models.Action, data=request_post)
|
||||||
trade = models.Trade.query.one()
|
trade = models.Trade.query.one()
|
||||||
|
|
||||||
lot, _ = user.post({},
|
lot = trade.lot
|
||||||
res=Lot,
|
device = trade.devices[0]
|
||||||
item='{}/devices'.format(lot['id']),
|
|
||||||
query=devices[-1:])
|
|
||||||
|
|
||||||
device1, device2 = trade.devices
|
assert device.actions[-2].t == 'Trade'
|
||||||
|
assert device.actions[-1].t == 'Confirm'
|
||||||
|
assert device.actions[-1].user == trade.user_to
|
||||||
|
|
||||||
assert device1.actions[-2].t == 'Trade'
|
user.delete({},
|
||||||
assert device1.actions[-1].t == 'Confirm'
|
res=Lot,
|
||||||
assert device1.actions[-1].user == trade.user_to
|
item='{}/devices'.format(lot.id),
|
||||||
assert device2.actions[-2].t == 'Trade'
|
query=devices[:-1], status=200)
|
||||||
assert device2.actions[-1].t == 'Confirm'
|
|
||||||
assert device2.actions[-1].user == trade.user_to
|
|
||||||
|
|
||||||
lot, _ = user.delete({},
|
assert device not in trade.lot.devices
|
||||||
res=Lot,
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
item='{}/devices'.format(lot['id']),
|
assert device.actions[-2].t == 'Confirm'
|
||||||
query=devices, status=200)
|
assert device.actions[-1].t == 'Revoke'
|
||||||
|
assert device.actions[-1].user == trade.user_to
|
||||||
assert device1.actions[-2].t == 'Revoke'
|
|
||||||
assert device1.actions[-1].t == 'ConfirmRevoke'
|
|
||||||
assert device1.actions[-1].user == trade.user_to
|
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
|
||||||
assert device2.actions[-1].user == trade.user_to
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1855,12 +1843,13 @@ def test_trade_case2(user: UserClient, user2: UserClient):
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user.post(res=models.Action, data=request_revoke)
|
user.post(res=models.Action, data=request_revoke)
|
||||||
|
|
||||||
assert device1.actions[-2].t == 'Revoke'
|
assert device1.actions[-2].t == 'Confirm'
|
||||||
assert device1.actions[-1].t == 'ConfirmRevoke'
|
assert device1.actions[-1].t == 'Revoke'
|
||||||
assert device1.actions[-1].user == trade.user_to
|
assert device1.actions[-1].user == trade.user_to
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
assert device2.actions[-2].t == 'Confirm'
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
assert device2.actions[-1].t == 'Revoke'
|
||||||
assert device2.actions[-1].user == trade.user_to
|
assert device2.actions[-1].user == trade.user_to
|
||||||
|
assert device1.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1868,7 +1857,6 @@ def test_trade_case2(user: UserClient, user2: UserClient):
|
||||||
def test_trade_case3(user: UserClient, user2: UserClient):
|
def test_trade_case3(user: UserClient, user2: UserClient):
|
||||||
# the pRp (manatest_usecase_confirmationger) creates a temporary lot
|
# the pRp (manatest_usecase_confirmationger) creates a temporary lot
|
||||||
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
|
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
|
||||||
# The manager add 7 device into the lot
|
|
||||||
snap1, _ = user.post(file('basic.snapshot'), res=models.Snapshot)
|
snap1, _ = user.post(file('basic.snapshot'), res=models.Snapshot)
|
||||||
snap2, _ = user2.post(file('acer.happy.battery.snapshot'), res=models.Snapshot)
|
snap2, _ = user2.post(file('acer.happy.battery.snapshot'), res=models.Snapshot)
|
||||||
|
|
||||||
|
@ -1880,7 +1868,7 @@ def test_trade_case3(user: UserClient, user2: UserClient):
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[:-1])
|
query=devices[:-1])
|
||||||
|
|
||||||
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
# the manager shares the temporary lot with the SCRAP as an incoming lot
|
||||||
# for the CRAP to confirm it
|
# for the CRAP to confirm it
|
||||||
request_post = {
|
request_post = {
|
||||||
'type': 'Trade',
|
'type': 'Trade',
|
||||||
|
@ -1915,9 +1903,10 @@ def test_trade_case3(user: UserClient, user2: UserClient):
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[-1:], status=200)
|
query=devices[-1:], status=200)
|
||||||
|
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
assert device2.actions[-2].t == 'Confirm'
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
assert device2.actions[-1].t == 'Revoke'
|
||||||
assert device2.actions[-1].user == trade.user_from
|
assert device2.actions[-1].user == trade.user_from
|
||||||
|
assert device2.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -1979,9 +1968,10 @@ def test_trade_case4(user: UserClient, user2: UserClient):
|
||||||
assert device1.actions[-2].t == 'Trade'
|
assert device1.actions[-2].t == 'Trade'
|
||||||
assert device1.actions[-1].t == 'Confirm'
|
assert device1.actions[-1].t == 'Confirm'
|
||||||
assert device1.actions[-1].user == trade.user_to
|
assert device1.actions[-1].user == trade.user_to
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
assert device2.actions[-2].t == 'Confirm'
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
assert device2.actions[-1].t == 'Revoke'
|
||||||
assert device2.actions[-1].user == trade.user_from
|
assert device2.actions[-1].user == trade.user_from
|
||||||
|
assert device2.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2036,8 +2026,8 @@ def test_trade_case5(user: UserClient, user2: UserClient):
|
||||||
assert device2.actions[-1].user == trade.user_from
|
assert device2.actions[-1].user == trade.user_from
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device2.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device2.id],
|
'devices': [device2.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2045,8 +2035,9 @@ def test_trade_case5(user: UserClient, user2: UserClient):
|
||||||
user.post(res=models.Action, data=request_confirm_revoke)
|
user.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
assert device2.actions[-2].t == 'Revoke'
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
assert device2.actions[-1].t == 'Revoke'
|
||||||
assert device2.actions[-1].user == trade.user_to
|
assert device2.actions[-1].user == trade.user_to
|
||||||
|
assert device2.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2106,8 +2097,8 @@ def test_trade_case6(user: UserClient, user2: UserClient):
|
||||||
assert device2.actions[-1].user == trade.user_to
|
assert device2.actions[-1].user == trade.user_to
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device2.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device2.id],
|
'devices': [device2.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2115,8 +2106,9 @@ def test_trade_case6(user: UserClient, user2: UserClient):
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
|
||||||
assert device2.actions[-2].t == 'Revoke'
|
assert device2.actions[-2].t == 'Revoke'
|
||||||
assert device2.actions[-1].t == 'ConfirmRevoke'
|
assert device2.actions[-1].t == 'Revoke'
|
||||||
assert device2.actions[-1].user == trade.user_from
|
assert device2.actions[-1].user == trade.user_from
|
||||||
|
assert device2.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2158,6 +2150,7 @@ def test_trade_case7(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user2.post(res=models.Action, data=request_confirm)
|
user2.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
lot, _ = user.delete({},
|
lot, _ = user.delete({},
|
||||||
res=Lot,
|
res=Lot,
|
||||||
|
@ -2165,14 +2158,14 @@ def test_trade_case7(user: UserClient, user2: UserClient):
|
||||||
query=devices, status=200)
|
query=devices, status=200)
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_from
|
assert device.actions[-1].user == trade.user_from
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_to
|
assert device.actions[-2].user == trade.user_to
|
||||||
|
@ -2182,6 +2175,7 @@ def test_trade_case7(user: UserClient, user2: UserClient):
|
||||||
assert device.actions[-4].user == trade.user_to
|
assert device.actions[-4].user == trade.user_to
|
||||||
assert device.actions[-5].t == 'Trade'
|
assert device.actions[-5].t == 'Trade'
|
||||||
assert device.actions[-5].author == trade.user_to
|
assert device.actions[-5].author == trade.user_to
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2223,6 +2217,7 @@ def test_trade_case8(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user2.post(res=models.Action, data=request_confirm)
|
user2.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
request_revoke = {
|
request_revoke = {
|
||||||
'type': 'Revoke',
|
'type': 'Revoke',
|
||||||
|
@ -2234,14 +2229,14 @@ def test_trade_case8(user: UserClient, user2: UserClient):
|
||||||
user.post(res=models.Action, data=request_revoke)
|
user.post(res=models.Action, data=request_revoke)
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_from
|
assert device.actions[-1].user == trade.user_from
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_to
|
assert device.actions[-2].user == trade.user_to
|
||||||
|
@ -2251,6 +2246,7 @@ def test_trade_case8(user: UserClient, user2: UserClient):
|
||||||
assert device.actions[-4].user == trade.user_to
|
assert device.actions[-4].user == trade.user_to
|
||||||
assert device.actions[-5].t == 'Trade'
|
assert device.actions[-5].t == 'Trade'
|
||||||
assert device.actions[-5].author == trade.user_to
|
assert device.actions[-5].author == trade.user_to
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2303,6 +2299,7 @@ def test_trade_case9(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user.post(res=models.Action, data=request_confirm)
|
user.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
assert device.owner == trade.user_to
|
assert device.owner == trade.user_to
|
||||||
|
|
||||||
|
@ -2312,8 +2309,8 @@ def test_trade_case9(user: UserClient, user2: UserClient):
|
||||||
query=devices[-1:], status=200)
|
query=devices[-1:], status=200)
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2321,7 +2318,7 @@ def test_trade_case9(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
assert device.owner == trade.user_from
|
assert device.owner == trade.user_from
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_to
|
assert device.actions[-1].user == trade.user_to
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_from
|
assert device.actions[-2].user == trade.user_from
|
||||||
|
@ -2331,6 +2328,7 @@ def test_trade_case9(user: UserClient, user2: UserClient):
|
||||||
assert device.actions[-4].user == trade.user_from
|
assert device.actions[-4].user == trade.user_from
|
||||||
assert device.actions[-5].t == 'Trade'
|
assert device.actions[-5].t == 'Trade'
|
||||||
assert device.actions[-5].author == trade.user_to
|
assert device.actions[-5].author == trade.user_to
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2374,6 +2372,7 @@ def test_trade_case10(user: UserClient, user2: UserClient):
|
||||||
device1, device = trade.devices
|
device1, device = trade.devices
|
||||||
|
|
||||||
assert device.owner == trade.user_from
|
assert device.owner == trade.user_from
|
||||||
|
# assert device.trading(trade.lot) == 'Confirm'
|
||||||
|
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
|
@ -2383,6 +2382,7 @@ def test_trade_case10(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal confirm
|
# Normal confirm
|
||||||
user.post(res=models.Action, data=request_confirm)
|
user.post(res=models.Action, data=request_confirm)
|
||||||
|
# assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
assert device.owner == trade.user_to
|
assert device.owner == trade.user_to
|
||||||
|
|
||||||
|
@ -2394,18 +2394,18 @@ def test_trade_case10(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user2.post(res=models.Action, data=request_revoke)
|
user2.post(res=models.Action, data=request_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'Revoke'
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_confirm_revoke)
|
user.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
|
||||||
assert device.owner == trade.user_from
|
assert device.owner == trade.user_from
|
||||||
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
|
||||||
assert device.actions[-1].user == trade.user_to
|
assert device.actions[-1].user == trade.user_to
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_from
|
assert device.actions[-2].user == trade.user_from
|
||||||
|
@ -2415,6 +2415,7 @@ def test_trade_case10(user: UserClient, user2: UserClient):
|
||||||
assert device.actions[-4].user == trade.user_from
|
assert device.actions[-4].user == trade.user_from
|
||||||
assert device.actions[-5].t == 'Trade'
|
assert device.actions[-5].t == 'Trade'
|
||||||
assert device.actions[-5].author == trade.user_to
|
assert device.actions[-5].author == trade.user_to
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
|
@ -2451,6 +2452,7 @@ def test_trade_case11(user: UserClient, user2: UserClient):
|
||||||
trade = models.Trade.query.one()
|
trade = models.Trade.query.one()
|
||||||
|
|
||||||
device1, device = trade.devices
|
device1, device = trade.devices
|
||||||
|
assert device.trading(trade.lot) == 'Confirm'
|
||||||
|
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
|
@ -2459,21 +2461,24 @@ def test_trade_case11(user: UserClient, user2: UserClient):
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm)
|
user2.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
lot, _ = user2.delete({},
|
lot, _ = user2.delete({},
|
||||||
res=Lot,
|
res=Lot,
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[-1:], status=200)
|
query=devices[-1:], status=200)
|
||||||
|
assert device.trading(trade.lot) == 'Revoke'
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_confirm_revoke)
|
user.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_to
|
assert device.actions[-1].user == trade.user_to
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_from
|
assert device.actions[-2].user == trade.user_from
|
||||||
|
@ -2519,6 +2524,7 @@ def test_trade_case12(user: UserClient, user2: UserClient):
|
||||||
trade = models.Trade.query.one()
|
trade = models.Trade.query.one()
|
||||||
|
|
||||||
device1, device = trade.devices
|
device1, device = trade.devices
|
||||||
|
assert device.trading(trade.lot) == 'Confirm'
|
||||||
|
|
||||||
# Normal confirm
|
# Normal confirm
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
|
@ -2528,6 +2534,7 @@ def test_trade_case12(user: UserClient, user2: UserClient):
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm)
|
user2.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
request_revoke = {
|
request_revoke = {
|
||||||
'type': 'Revoke',
|
'type': 'Revoke',
|
||||||
|
@ -2537,16 +2544,18 @@ def test_trade_case12(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user2.post(res=models.Action, data=request_revoke)
|
user2.post(res=models.Action, data=request_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'Revoke'
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_confirm_revoke)
|
user.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_to
|
assert device.actions[-1].user == trade.user_to
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_from
|
assert device.actions[-2].user == trade.user_from
|
||||||
|
@ -2597,6 +2606,8 @@ def test_trade_case13(user: UserClient, user2: UserClient):
|
||||||
query=devices[-1:])
|
query=devices[-1:])
|
||||||
|
|
||||||
device1, device = trade.devices
|
device1, device = trade.devices
|
||||||
|
assert device1.trading(trade.lot) == 'NeedConfirmation'
|
||||||
|
assert device.trading(trade.lot) == 'Confirm'
|
||||||
|
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
'type': 'Confirm',
|
'type': 'Confirm',
|
||||||
|
@ -2605,21 +2616,26 @@ def test_trade_case13(user: UserClient, user2: UserClient):
|
||||||
}
|
}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_confirm)
|
user.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device1.trading(trade.lot) == 'Confirm'
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
lot, _ = user.delete({},
|
lot, _ = user.delete({},
|
||||||
res=Lot,
|
res=Lot,
|
||||||
item='{}/devices'.format(lot['id']),
|
item='{}/devices'.format(lot['id']),
|
||||||
query=devices[-1:], status=200)
|
query=devices[-1:], status=200)
|
||||||
|
assert device1.trading(trade.lot) == 'Confirm'
|
||||||
|
assert device.trading(trade.lot) == 'Revoke'
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_from
|
assert device.actions[-1].user == trade.user_from
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_to
|
assert device.actions[-2].user == trade.user_to
|
||||||
|
@ -2670,6 +2686,8 @@ def test_trade_case14(user: UserClient, user2: UserClient):
|
||||||
query=devices[-1:])
|
query=devices[-1:])
|
||||||
|
|
||||||
device1, device = trade.devices
|
device1, device = trade.devices
|
||||||
|
assert device1.trading(trade.lot) == 'NeedConfirmation'
|
||||||
|
assert device.trading(trade.lot) == 'Confirm'
|
||||||
|
|
||||||
# Normal confirm
|
# Normal confirm
|
||||||
request_confirm = {
|
request_confirm = {
|
||||||
|
@ -2679,6 +2697,7 @@ def test_trade_case14(user: UserClient, user2: UserClient):
|
||||||
}
|
}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request_confirm)
|
user.post(res=models.Action, data=request_confirm)
|
||||||
|
assert device.trading(trade.lot) == 'TradeConfirmed'
|
||||||
|
|
||||||
request_revoke = {
|
request_revoke = {
|
||||||
'type': 'Revoke',
|
'type': 'Revoke',
|
||||||
|
@ -2688,16 +2707,18 @@ def test_trade_case14(user: UserClient, user2: UserClient):
|
||||||
|
|
||||||
# Normal revoke
|
# Normal revoke
|
||||||
user.post(res=models.Action, data=request_revoke)
|
user.post(res=models.Action, data=request_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'Revoke'
|
||||||
|
|
||||||
request_confirm_revoke = {
|
request_confirm_revoke = {
|
||||||
'type': 'ConfirmRevoke',
|
'type': 'Revoke',
|
||||||
'action': device.actions[-1].id,
|
'action': trade.id,
|
||||||
'devices': [device.id],
|
'devices': [device.id],
|
||||||
}
|
}
|
||||||
|
|
||||||
user2.post(res=models.Action, data=request_confirm_revoke)
|
user2.post(res=models.Action, data=request_confirm_revoke)
|
||||||
|
assert device.trading(trade.lot) == 'RevokeConfirmed'
|
||||||
|
|
||||||
assert device.actions[-1].t == 'ConfirmRevoke'
|
assert device.actions[-1].t == 'Revoke'
|
||||||
assert device.actions[-1].user == trade.user_from
|
assert device.actions[-1].user == trade.user_from
|
||||||
assert device.actions[-2].t == 'Revoke'
|
assert device.actions[-2].t == 'Revoke'
|
||||||
assert device.actions[-2].user == trade.user_to
|
assert device.actions[-2].user == trade.user_to
|
||||||
|
@ -2718,7 +2739,7 @@ def test_action_web_erase(user: UserClient, client: Client):
|
||||||
hash3 = hashlib.sha3_256(bfile.read()).hexdigest()
|
hash3 = hashlib.sha3_256(bfile.read()).hexdigest()
|
||||||
snap, _ = user.post(file('acer.happy.battery.snapshot'), res=models.Snapshot)
|
snap, _ = user.post(file('acer.happy.battery.snapshot'), res=models.Snapshot)
|
||||||
request = {'type': 'DataWipe', 'devices': [snap['device']['id']], 'name': 'borrado universal', 'severity': 'Info', 'description': 'nada que describir', 'url': 'http://www.google.com/', 'documentId': '33', 'endTime': '2021-07-07T22:00:00.000Z', 'filename': 'Certificado de borrado1.pdf', 'hash': hash3, 'success': 1, 'software': "Blanco"}
|
request = {'type': 'DataWipe', 'devices': [snap['device']['id']], 'name': 'borrado universal', 'severity': 'Info', 'description': 'nada que describir', 'url': 'http://www.google.com/', 'documentId': '33', 'endTime': '2021-07-07T22:00:00.000Z', 'filename': 'Certificado de borrado1.pdf', 'hash': hash3, 'success': 1, 'software': "Blanco"}
|
||||||
|
|
||||||
user.post(res=models.Action, data=request)
|
user.post(res=models.Action, data=request)
|
||||||
action = models.DataWipe.query.one()
|
action = models.DataWipe.query.one()
|
||||||
for dev in action.devices:
|
for dev in action.devices:
|
||||||
|
|
|
@ -181,14 +181,13 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient):
|
||||||
query=[('filter', {'type': ['Computer']})])
|
query=[('filter', {'type': ['Computer']})])
|
||||||
|
|
||||||
body1_lenovo = 'O48N2;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Trade;foo@foo.com;'
|
body1_lenovo = 'O48N2;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Trade;foo@foo.com;'
|
||||||
body1_lenovo += 'foo2@foo.com;Supplier;False;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 = 'J2MA2;laptop-acer-aohappy-lusea0d010038879a01601-00:26:c7:8e:cb:8c;;Trade;'
|
||||||
body1_acer += 'foo@foo.com;foo2@foo.com;Supplier;False;;;;;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'
|
||||||
|
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
assert body1_lenovo in csv_str
|
assert body1_lenovo in csv_str
|
||||||
assert body2_lenovo in csv_str
|
assert body2_lenovo in csv_str
|
||||||
assert body1_acer in csv_str
|
assert body1_acer in csv_str
|
||||||
|
@ -203,7 +202,7 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient):
|
||||||
query=[('filter', {'type': ['Computer']})])
|
query=[('filter', {'type': ['Computer']})])
|
||||||
|
|
||||||
body1_lenovo = 'O48N2;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Trade;foo@foo.com;'
|
body1_lenovo = 'O48N2;desktop-lenovo-9644w8n-0169622-00:1a:6b:5e:7f:10;;Trade;foo@foo.com;'
|
||||||
body1_lenovo += 'foo2@foo.com;Supplier;False;Use;Use;'
|
body1_lenovo += 'foo2@foo.com;Supplier;NeedConfirmation;Use;Use;'
|
||||||
body2_lenovo = ';;0;0;Trade;0;0\n'
|
body2_lenovo = ';;0;0;Trade;0;0\n'
|
||||||
body2_acer = ';;0;0;Trade;0;4692.0\n'
|
body2_acer = ';;0;0;Trade;0;4692.0\n'
|
||||||
|
|
||||||
|
@ -353,8 +352,8 @@ def test_bug_trade_confirmed(user: UserClient, user2: UserClient):
|
||||||
accept='text/csv',
|
accept='text/csv',
|
||||||
query=[('filter', {'type': ['Computer']})])
|
query=[('filter', {'type': ['Computer']})])
|
||||||
|
|
||||||
body_not_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;False;"
|
body_not_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;NeedConfirmation;"
|
||||||
body_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;True;"
|
body_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;TradeConfirmed;"
|
||||||
|
|
||||||
assert body_not_confirmed in csv_not_confirmed
|
assert body_not_confirmed in csv_not_confirmed
|
||||||
assert body_confirmed in csv_confirmed
|
assert body_confirmed in csv_confirmed
|
||||||
|
|
|
@ -66,7 +66,7 @@ def test_workbench_server_condensed(user: UserClient):
|
||||||
assert device['rate']['rating'] == 1
|
assert device['rate']['rating'] == 1
|
||||||
assert device['rate']['type'] == RateComputer.t
|
assert device['rate']['type'] == RateComputer.t
|
||||||
# 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 device['actions'][2]['type'] == BenchmarkProcessor.t or device['actions'][2]['type'] == BenchmarkRamSysbench.t
|
assert any([ac['type'] in [BenchmarkProcessor.t, BenchmarkRamSysbench.t] for ac in device['actions']])
|
||||||
assert 'tag1' in [x['id'] for x in device['tags']]
|
assert 'tag1' in [x['id'] for x in device['tags']]
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue