Merge pull request #179 from eReuse/bugfix/#177-trade

Bugfix/#177 trade
This commit is contained in:
cayop 2021-11-12 18:47:45 +01:00 committed by GitHub
commit 0daa9cf284
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 315 additions and 339 deletions

View File

@ -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()}')

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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():

View File

@ -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)

View File

@ -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):
""" """

View File

@ -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"""

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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']]