From 5861d2fd6ff79920ff2e6d727cf0f953baab720e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 26 Oct 2021 16:21:05 +0200 Subject: [PATCH 01/13] fixing session in listener --- ereuse_devicehub/resources/device/models.py | 31 +++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 473ca640..6cccc8b9 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1167,14 +1167,27 @@ class Manufacturer(db.Model): listener_reset_field_updated_in_actual_time(Device) +# def create_code_tag(mapper, connection, device): +# """ +# This function create a new tag every time than one device is create. +# this tag is the same of devicehub_id. +# """ +# from ereuse_devicehub.resources.tag.model import Tag +# tag = Tag(device_id=device.id, id=device.devicehub_id) +# import pdb; pdb.set_trace() +# db.session.add(tag) + + +# event.listen(Device, 'after_insert', create_code_tag, propagate=True) + + +@event.listens_for(Device, 'after_insert') def create_code_tag(mapper, connection, device): - """ - This function create a new tag every time than one device is create. - this tag is the same of devicehub_id. - """ - from ereuse_devicehub.resources.tag.model import Tag - tag = Tag(device_id=device.id, id=device.devicehub_id) - db.session.add(tag) + print(device.devicehub_id) - -event.listen(Device, 'after_insert', create_code_tag, propagate=True) + @event.listens_for(Session, 'after_flush', one=True) + def create_code_tag_after_fush(session, context): + from ereuse_devicehub.resources.tag.model import Tag + tag = Tag(device_id=device.id, id=device.devicehub_id) + # import pdb; pdb.set_trace() + session.add(tag) From 03238acb9fe8c71b7b0b460911ac522cbf9e2370 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 26 Oct 2021 16:35:41 +0200 Subject: [PATCH 02/13] fixing session in listener --- ereuse_devicehub/resources/device/models.py | 31 ++++++--------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 6cccc8b9..473ca640 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1167,27 +1167,14 @@ class Manufacturer(db.Model): listener_reset_field_updated_in_actual_time(Device) -# def create_code_tag(mapper, connection, device): -# """ -# This function create a new tag every time than one device is create. -# this tag is the same of devicehub_id. -# """ -# from ereuse_devicehub.resources.tag.model import Tag -# tag = Tag(device_id=device.id, id=device.devicehub_id) -# import pdb; pdb.set_trace() -# db.session.add(tag) - - -# event.listen(Device, 'after_insert', create_code_tag, propagate=True) - - -@event.listens_for(Device, 'after_insert') def create_code_tag(mapper, connection, device): - print(device.devicehub_id) + """ + This function create a new tag every time than one device is create. + this tag is the same of devicehub_id. + """ + from ereuse_devicehub.resources.tag.model import Tag + tag = Tag(device_id=device.id, id=device.devicehub_id) + db.session.add(tag) - @event.listens_for(Session, 'after_flush', one=True) - def create_code_tag_after_fush(session, context): - from ereuse_devicehub.resources.tag.model import Tag - tag = Tag(device_id=device.id, id=device.devicehub_id) - # import pdb; pdb.set_trace() - session.add(tag) + +event.listen(Device, 'after_insert', create_code_tag, propagate=True) From 283f869b4d24e04bbcc625e90173edea83df8cd8 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 28 Oct 2021 12:19:49 +0200 Subject: [PATCH 03/13] drop remove --- ereuse_devicehub/resources/action/models.py | 8 +-- .../resources/action/views/trade.py | 3 +- ereuse_devicehub/resources/device/models.py | 59 ++++++++++++++++++- ereuse_devicehub/resources/lot/views.py | 14 +++-- 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index fbc05234..5679decd 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -1583,11 +1583,11 @@ class Revoke(Confirm): """Users can revoke one confirmation of one action trade""" -class ConfirmRevoke(Confirm): - """Users can confirm and accept one action revoke""" +# class ConfirmRevoke(Confirm): +# """Users can confirm and accept one action revoke""" - def __repr__(self) -> str: - return '<{0.t} {0.id} accepted by {0.user}>'.format(self) +# def __repr__(self) -> str: +# return '<{0.t} {0.id} accepted by {0.user}>'.format(self) class Trade(JoinedTableMixin, ActionWithMultipleTradeDocuments): diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 16f2572b..9d330ace 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -219,8 +219,9 @@ class RevokeView(ConfirmMixin): if not data['devices']: raise ValidationError('Devices not exist.') + lot = data['action'].lot for dev in data['devices']: - if not dev.trading == 'TradeConfirmed': + if not dev.trading(lot) == 'TradeConfirmed': txt = 'Some of devices do not have enough to confirm for to do a revoke' ValidationError(txt) ### End check ### diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 473ca640..ce021b55 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -301,11 +301,66 @@ class Device(Thing): return history - @property - def trading(self): + def trading(self, lot): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do""" + if not hasattr(lot, 'trade'): + return + Status = {0: 'Trade', + 1: 'Confirm', + 2: 'TradeConfirmed', + 3: 'Revoke', + 4: 'RevokeConfirmed'} + + trade = lot.trade + user_from = trade.user_from + user_to = trade.user_to + user_from_confirm = False + user_to_confirm = False + user_from_revoke = False + user_to_revoke = False + status = 0 + confirms = {} + revokes = {} + # acceptances = copy.copy(trade.acceptances) + # acceptances = sorted(acceptances, key=lambda x: x.created) + + if not hasattr(ac, 'acceptances'): + return Status[status] + + for ac in trade.acceptances: + if ac.user not in [user_from, user_to]: + continue + + if ac.t == 'Confirm': + if ac.user == user_from: + user_from_confirm = True + elif ac.user == user_to: + user_to_confirm = True + + if ac.t == 'Revoke': + if ac.user == user_from: + user_from_revoke = True + elif ac.user == user_to: + user_to_revoke= True + + confirms = [user_from_confirm, user_to_confirm] + revokes = [user_from_revoke, user_to_revoke] + + if any(confirms): + status = 1 + if all(confirms): + status = 2 + + if any(revokes): + status = 3 + if all(revokes): + status = 4 + + def trading2(self): + """The trading state, or None if no Trade action has + ever been performed to this device. This extract the posibilities for to do""" # trade = 'Trade' confirm = 'Confirm' need_confirm = 'NeedConfirmation' diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index fcbca827..83b3b7c5 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -280,7 +280,7 @@ def delete_from_trade(lot: Lot, ids: Set[int]): # 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': + if dev.trading(lot) == 'Confirm': without_confirms.add(dev) dev.reset_owner() @@ -293,12 +293,16 @@ def delete_from_trade(lot: Lot, ids: Set[int]): without_confirms = devices if without_confirms: - confirm_revoke = ConfirmRevoke( - action=revoke, - user=g.user, + phantom = lot.trade.user_to + if lot.trade.user_to == g.user: + phantom = lot.trade.user_from + + phantom_revoke = Revoke( + action=lot.trade, + user=phantom, devices=without_confirms ) - db.session.add(confirm_revoke) + db.session.add(phantom_revoke) lot.devices.difference_update(without_confirms) lot.trade.devices = lot.devices From 34def7bd70423ef10841ae462b9371938fe8a3c8 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 2 Nov 2021 14:25:49 +0100 Subject: [PATCH 04/13] fixint trading fuction --- ereuse_devicehub/resources/action/__init__.py | 5 -- ereuse_devicehub/resources/action/schemas.py | 79 +++---------------- .../resources/action/views/trade.py | 55 ++++++------- .../resources/action/views/views.py | 6 +- ereuse_devicehub/resources/device/models.py | 11 ++- ereuse_devicehub/resources/device/states.py | 1 - ereuse_devicehub/resources/lot/views.py | 2 +- 7 files changed, 47 insertions(+), 112 deletions(-) diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index e70bd18b..331d4dec 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -280,11 +280,6 @@ class ConfirmDef(ActionDef): SCHEMA = schemas.Confirm -class ConfirmRevokeDef(ActionDef): - VIEW = None - SCHEMA = schemas.ConfirmRevoke - - class RevokeDef(ActionDef): VIEW = None SCHEMA = schemas.Revoke diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 7c594375..bd81590a 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -442,14 +442,15 @@ class ActionStatus(Action): if not 'devices' in data.keys(): data['devices'] = [] - @post_load - def put_rol_user(self, data: dict): - for dev in data['devices']: - if dev.trading in [None, 'Revoke', 'ConfirmRevoke']: - return data - trade = [ac for ac in dev.actions if ac.t == 'Trade'][-1] - if trade.user_to != g.user: - data['rol_user'] = trade.user_to + # @post_load + # def put_rol_user(self, data: dict): + # TODO we need rebuild this functin + # for dev in data['devices']: + # if dev.trading in [None, 'Revoke']: + # return data + # trade = [ac for ac in dev.actions if ac.t == 'Trade'][-1] + # if trade.user_to != g.user: + # data['rol_user'] = trade.user_to class Recycling(ActionStatus): @@ -635,7 +636,7 @@ class RevokeDocument(ActionWithMultipleDocuments): class ConfirmRevokeDocument(ActionWithMultipleDocuments): - __doc__ = m.ConfirmRevoke.__doc__ + __doc__ = m.ConfirmRevokeDocument.__doc__ action = NestedOn('Action', only_query='id') @validates_schema @@ -662,66 +663,6 @@ class ConfirmRevokeDocument(ActionWithMultipleDocuments): 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): __doc__ = m.Trade.__doc__ date = DateTime(data_key='date', required=False) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 9d330ace..601d2b17 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -3,7 +3,7 @@ from sqlalchemy.util import OrderedSet from teal.marshmallow import ValidationError 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, ConfirmRevokeDocument) from ereuse_devicehub.resources.user.models import User @@ -231,42 +231,43 @@ class RevokeView(ConfirmMixin): self.model = delete_from_trade(lot, ids) -class ConfirmRevokeView(ConfirmMixin): - """Handler for manager the Confirmation register from post +# class ConfirmRevokeView(ConfirmMixin): +# """Handler for manager the Confirmation register from post - request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': action_revoke.id, - 'devices': [device_id] - } +# request_confirm_revoke = { +# 'type': 'ConfirmRevoke', +# 'action': action_revoke.id, +# 'devices': [device_id] +# } - """ +# """ - Model = ConfirmRevoke +# Model = ConfirmRevoke - def validate(self, data): - """All devices need to have the status of revoke.""" +# 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) +# 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) +# lot = data['action'].lot +# for dev in data['devices']: +# if not dev.trading(lot) == 'Revoke': +# txt = 'Some of devices do not have revoke to confirm' +# ValidationError(txt) - devices = OrderedSet(data['devices']) - data['devices'] = devices +# devices = OrderedSet(data['devices']) +# data['devices'] = devices - # Change the owner for every devices - # data['action'] == 'Revoke' +# # Change the owner for every devices +# # data['action'] == 'Revoke' - trade = data['action'].action - for dev in devices: - dev.reset_owner() +# trade = data['action'].action +# for dev in devices: +# dev.reset_owner() - trade.lot.devices.difference_update(devices) +# trade.lot.devices.difference_update(devices) class ConfirmDocumentMixin(): diff --git a/ereuse_devicehub/resources/action/views/views.py b/ereuse_devicehub/resources/action/views/views.py index 415effb8..82e3f5e0 100644 --- a/ereuse_devicehub/resources/action/views/views.py +++ b/ereuse_devicehub/resources/action/views/views.py @@ -15,7 +15,7 @@ from ereuse_devicehub.db import db from ereuse_devicehub.query import things_response from ereuse_devicehub.resources.action.models import (Action, Snapshot, VisualTest, 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.snapshot import SnapshotView, save_json, move_json from ereuse_devicehub.resources.action.views.documents import ErasedView @@ -235,10 +235,6 @@ class ActionView(View): revoke = trade_view.RevokeView(json, resource_def, self.schema) return revoke.post() - if json['type'] == ConfirmRevoke.t: - confirm_revoke = trade_view.ConfirmRevokeView(json, resource_def, self.schema) - return confirm_revoke.post() - if json['type'] == 'RevokeDocument': revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema) return revoke.post() diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index ce021b55..95040dd0 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -323,13 +323,14 @@ class Device(Thing): status = 0 confirms = {} revokes = {} - # acceptances = copy.copy(trade.acceptances) - # acceptances = sorted(acceptances, key=lambda x: x.created) - if not hasattr(ac, 'acceptances'): + if not hasattr(trade, 'acceptances'): return Status[status] - for ac in trade.acceptances: + acceptances = copy.copy(trade.acceptances) + acceptances = sorted(acceptances, key=lambda x: x.created) + + for ac in acceptances: if ac.user not in [user_from, user_to]: continue @@ -358,6 +359,8 @@ class Device(Thing): if all(revokes): status = 4 + return Status[status] + def trading2(self): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do""" diff --git a/ereuse_devicehub/resources/device/states.py b/ereuse_devicehub/resources/device/states.py index 5177f701..3cfefe4b 100644 --- a/ereuse_devicehub/resources/device/states.py +++ b/ereuse_devicehub/resources/device/states.py @@ -37,7 +37,6 @@ class Trading(State): Trade = e.Trade Confirm = e.Confirm Revoke = e.Revoke - ConfirmRevoke = e.ConfirmRevoke Cancelled = e.CancelTrade Sold = e.Sell Donated = e.Donate diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 83b3b7c5..d41f2008 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -13,7 +13,7 @@ from teal.resource import View from ereuse_devicehub.db import db from ereuse_devicehub.query import things_response 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 9dc79a59dc421ac4baa12409c42747e6c6082de0 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 10 Nov 2021 18:59:44 +0100 Subject: [PATCH 05/13] fixing revokeView and reset_owner --- ...22d230d2850_adding_author_action_device.py | 43 +++++ ereuse_devicehub/resources/action/__init__.py | 5 + ereuse_devicehub/resources/action/models.py | 8 + ereuse_devicehub/resources/action/schemas.py | 9 +- .../resources/action/views/trade.py | 26 ++- .../resources/action/views/views.py | 4 + ereuse_devicehub/resources/device/metrics.py | 4 +- ereuse_devicehub/resources/device/models.py | 168 +++++++++--------- ereuse_devicehub/resources/device/schemas.py | 9 +- ereuse_devicehub/resources/lot/views.py | 1 + tests/test_action.py | 22 ++- 11 files changed, 188 insertions(+), 111 deletions(-) create mode 100644 ereuse_devicehub/migrations/versions/d22d230d2850_adding_author_action_device.py diff --git a/ereuse_devicehub/migrations/versions/d22d230d2850_adding_author_action_device.py b/ereuse_devicehub/migrations/versions/d22d230d2850_adding_author_action_device.py new file mode 100644 index 00000000..ed58f669 --- /dev/null +++ b/ereuse_devicehub/migrations/versions/d22d230d2850_adding_author_action_device.py @@ -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()}') diff --git a/ereuse_devicehub/resources/action/__init__.py b/ereuse_devicehub/resources/action/__init__.py index 331d4dec..0d89f557 100644 --- a/ereuse_devicehub/resources/action/__init__.py +++ b/ereuse_devicehub/resources/action/__init__.py @@ -285,6 +285,11 @@ class RevokeDef(ActionDef): SCHEMA = schemas.Revoke +class ConfirmRevokeDef(ActionDef): + VIEW = None + SCHEMA = schemas.ConfirmRevoke + + class TradeDef(ActionDef): VIEW = None SCHEMA = schemas.Trade diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index b2fb2c18..e4e8c3b6 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -317,6 +317,14 @@ class ActionDevice(db.Model): index=True, server_default=db.text('CURRENT_TIMESTAMP')) 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: self.created = kwargs.get('created', datetime.now(timezone.utc)) diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index 0202a3a3..1f7f3fef 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -445,16 +445,13 @@ class ActionStatus(Action): @post_load def put_rol_user(self, data: dict): for dev in data['devices']: - if dev.trading in [None, 'Revoke']: - return data - trades = [ac for ac in dev.actions if ac.t == 'Trade'] if not trades: return data trade = trades[-1] - if trade.user_to != g.user: + if trade.user_from == g.user: data['rol_user'] = trade.user_to data['trade'] = trade @@ -588,6 +585,10 @@ class Revoke(ActionWithMultipleDevices): raise ValidationError(txt) +class ConfirmRevoke(Revoke): + pass + + class ConfirmDocument(ActionWithMultipleDocuments): __doc__ = m.Confirm.__doc__ action = NestedOn('Action', only_query='id') diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 601d2b17..4aac48d4 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -220,15 +220,29 @@ class RevokeView(ConfirmMixin): raise ValidationError('Devices not exist.') lot = data['action'].lot + + revokeConfirmed = [] for dev in data['devices']: - if not dev.trading(lot) == 'TradeConfirmed': - txt = 'Some of devices do not have enough to confirm for to do a revoke' - ValidationError(txt) + if dev.trading(lot) == 'RevokeConfirmed': + # this device is revoked before + revokeConfirmed.append(dev) ### End check ### - ids = {d.id for d in data['devices']} - lot = data['action'].lot - self.model = delete_from_trade(lot, ids) + devices = {d for d in data['devices'] if d not in revokeConfirmed} + # self.model = delete_from_trade(lot, devices) + # TODO @cayop we dont need delete_from_trade + + drop_of_lot = [] + # import pdb; pdb.set_trace() + for dev in devices: + # import pdb; pdb.set_trace() + if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: + drop_of_lot.append(dev) + dev.reset_owner() + + self.model = Revoke(action=lot.trade, user=g.user, devices=devices) + db.session.add(self.model) + lot.devices.difference_update(OrderedSet(drop_of_lot)) # class ConfirmRevokeView(ConfirmMixin): diff --git a/ereuse_devicehub/resources/action/views/views.py b/ereuse_devicehub/resources/action/views/views.py index 82e3f5e0..88c95438 100644 --- a/ereuse_devicehub/resources/action/views/views.py +++ b/ereuse_devicehub/resources/action/views/views.py @@ -235,6 +235,10 @@ class ActionView(View): revoke = trade_view.RevokeView(json, resource_def, self.schema) return revoke.post() + if json['type'] == 'ConfirmRevoke': + revoke = trade_view.RevokeView(json, resource_def, self.schema) + return revoke.post() + if json['type'] == 'RevokeDocument': revoke = trade_view.RevokeDocumentView(json, resource_def, self.schema) return revoke.post() diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index 3365e6cc..e60312a2 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -89,7 +89,6 @@ class Metrics(MetricsMix): trade['status_receiver_created'] = self.act.created return - # import pdb; pdb.set_trace() # necesitamos poder poner un cambio de estado de un trade mas antiguo que last_trade # lo mismo con confirm @@ -148,7 +147,8 @@ class Metrics(MetricsMix): 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. """ - if self.device.trading == 'TradeConfirmed': + # import pdb; pdb.set_trace() + if self.device.trading(self.act.lot) == 'TradeConfirmed': return True return False diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index b0d09848..842c009d 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -310,6 +310,80 @@ class Device(Thing): return history + @property + def tradings(self): + return {str(x.id): self.trading_for_web(x.lot) for x in self.actions if x.t == 'Trade'} + + def trading_for_web(self, lot): + """The trading state, or None if no Trade action has + ever been performed to this device. This extract the posibilities for to do. + This method is performed for show in the web.""" + if not hasattr(lot, 'trade'): + return + + Status = {0: 'Trade', + 1: 'Confirm', + 2: 'NeedConfirmation', + 3: 'TradeConfirmed', + 4: 'Revoke', + 5: 'NeedConfirmRevoke', + 6: 'RevokeConfirmed'} + + trade = lot.trade + user_from = trade.user_from + user_to = trade.user_to + user_from_confirm = False + user_to_confirm = False + user_from_revoke = False + user_to_revoke = False + status = 0 + + if not hasattr(trade, 'acceptances'): + return Status[status] + + for ac in self.actions: + if ac.t not in ['Confirm', 'Revoke']: + continue + + if ac.user not in [user_from, user_to]: + continue + + if ac.t == 'Confirm' and ac.action == trade: + if ac.user == user_from: + user_from_confirm = True + elif ac.user == user_to: + user_to_confirm = True + + if ac.t == 'Revoke' and ac.action == trade: + if ac.user == user_from: + user_from_revoke = True + elif ac.user == user_to: + user_to_revoke = True + + confirms = [user_from_confirm, user_to_confirm] + revokes = [user_from_revoke, user_to_revoke] + + if any(confirms): + status = 1 + if user_to_confirm and user_from == g.user: + status = 2 + if user_from_confirm and user_to == g.user: + status = 2 + + if all(confirms): + status = 3 + + if any(revokes): + status = 4 + if user_to_revoke and user_from == g.user: + status = 5 + if user_from_revoke and user_to == g.user: + status = 5 + if all(revokes): + status = 6 + + return Status[status] + def trading(self, lot): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do""" @@ -330,30 +404,28 @@ class Device(Thing): user_from_revoke = False user_to_revoke = False status = 0 - confirms = {} - revokes = {} if not hasattr(trade, 'acceptances'): return Status[status] - acceptances = copy.copy(trade.acceptances) - acceptances = sorted(acceptances, key=lambda x: x.created) + for ac in self.actions: + if ac.t not in ['Confirm', 'Revoke']: + continue - for ac in acceptances: if ac.user not in [user_from, user_to]: continue - if ac.t == 'Confirm': + if ac.t == 'Confirm' and ac.action == trade: if ac.user == user_from: user_from_confirm = True elif ac.user == user_to: user_to_confirm = True - if ac.t == 'Revoke': + if ac.t == 'Revoke' and ac.action == trade: if ac.user == user_from: user_from_revoke = True elif ac.user == user_to: - user_to_revoke= True + user_to_revoke = True confirms = [user_from_confirm, user_to_confirm] revokes = [user_from_revoke, user_to_revoke] @@ -370,75 +442,6 @@ class Device(Thing): return Status[status] - def trading2(self): - """The trading state, or None if no Trade action has - ever been performed to this device. This extract the posibilities for to do""" - # trade = 'Trade' - confirm = 'Confirm' - 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 - - first_owner = self.which_user_put_this_device_in_trace() - - if ac.type == confirm_revoke: - # can to do revoke_confirmed - return confirm_revoke - - if ac.type == revoke: - if ac.user == g.user: - # can todo revoke_pending - return revoke_pending - else: - # can to do confirm_revoke - return revoke - - if ac.type == confirm: - if not first_owner: - return - - if ac.user == first_owner: - if first_owner == g.user: - # can to do revoke - return confirm - else: - # can to do confirm - return need_confirm - else: - # can to do revoke - return double_confirm - @property def revoke(self): """If the actual trading state is an revoke action, this property show @@ -543,15 +546,16 @@ class Device(Thing): def which_user_put_this_device_in_trace(self): """which is the user than put this device in this trade""" actions = copy.copy(self.actions) - actions.sort(key=lambda x: x.created) actions.reverse() - last_ac = None # search the automatic Confirm for ac in actions: if ac.type == 'Trade': - return last_ac.user - if ac.type == 'Confirm': - last_ac = ac + # import pdb; pdb.set_trace() + action_device = [x.device for x in ac.actions_device if x.device == self][0] + if action_device.author: + return action_device.author + + return ac.author def change_owner(self, new_user): """util for change the owner one device""" diff --git a/ereuse_devicehub/resources/device/schemas.py b/ereuse_devicehub/resources/device/schemas.py index d9a658fe..bc18b995 100644 --- a/ereuse_devicehub/resources/device/schemas.py +++ b/ereuse_devicehub/resources/device/schemas.py @@ -1,7 +1,7 @@ import datetime 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 sqlalchemy.util import OrderedSet from stdnum import imei, meid @@ -50,12 +50,11 @@ class Device(Thing): description='The lots where this device is directly under.') rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__) price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__) - # trading = EnumField(states.Trading, dump_only=True, description=m.Device.trading.__doc__) - trading = SanitizedStr(dump_only=True, description='') + tradings = Dict(dump_only=True, description='') 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__) - revoke = UUID(dump_only=True) + revoke = UUID(dump_only=True) physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor') production_date = DateTime('iso', description=m.Device.updated.comment, diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index d41f2008..12309888 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -305,6 +305,7 @@ def delete_from_trade(lot: Lot, ids: Set[int]): db.session.add(phantom_revoke) lot.devices.difference_update(without_confirms) + # TODO @cayop ?? we dont need this line lot.trade.devices = lot.devices return revoke diff --git a/tests/test_action.py b/tests/test_action.py index 888541f3..86e811e3 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -1516,8 +1516,8 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): 'type': 'Confirm', 'action': trade.id, 'devices': [ - snap1['device']['id'], - snap2['device']['id'], + snap1['device']['id'], + snap2['device']['id'], snap3['device']['id'], snap4['device']['id'], snap5['device']['id'], @@ -1535,7 +1535,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): assert trade.devices[-1].actions[-1].user == trade.user_from 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 device_10 = trade.devices[-1] lot, _ = user.delete({}, @@ -1554,31 +1554,28 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): # the SCRAP confirms the revoke action request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device_10.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [ snap10['device']['id'] ] } 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 len(trade.lot.devices) == len(trade.devices) == 9 # assert not device_10 in trade.devices # check validation error request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device_10.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [ snap9['device']['id'] ] } - user2.post(res=models.Action, data=request_confirm_revoke, status=422) - - # The manager add again device_10 # assert len(trade.devices) == 9 lot, _ = user.post({}, @@ -1604,7 +1601,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): assert device_10.actions[-1].user == trade.user_from assert device_10.actions[-2].t == 'Confirm' 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 @@ -1712,6 +1709,7 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): assert len(trade.devices) == 10 # the SCRAP confirms the revoke action + import pdb; pdb.set_trace() request_confirm_revoke = { 'type': 'ConfirmRevoke', 'action': device_10.actions[-2].id, From 54977d432d481668b59e25cdf1b7342627f07cfe Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 11 Nov 2021 17:06:26 +0100 Subject: [PATCH 06/13] refactory in delete_from_trade function --- .../resources/action/views/trade.py | 67 +------------------ ereuse_devicehub/resources/device/models.py | 19 ++++-- ereuse_devicehub/resources/lot/views.py | 47 ++++++++++++- 3 files changed, 62 insertions(+), 71 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 4aac48d4..842808ba 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -215,73 +215,12 @@ class RevokeView(ConfirmMixin): def validate(self, data): """All devices need to have the status of DoubleConfirmation.""" - ### check ### - if not data['devices']: + devices = data['devices'] + if not devices: raise ValidationError('Devices not exist.') lot = data['action'].lot - - revokeConfirmed = [] - for dev in data['devices']: - if dev.trading(lot) == 'RevokeConfirmed': - # this device is revoked before - revokeConfirmed.append(dev) - ### End check ### - - devices = {d for d in data['devices'] if d not in revokeConfirmed} - # self.model = delete_from_trade(lot, devices) - # TODO @cayop we dont need delete_from_trade - - drop_of_lot = [] - # import pdb; pdb.set_trace() - for dev in devices: - # import pdb; pdb.set_trace() - if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: - drop_of_lot.append(dev) - dev.reset_owner() - - self.model = Revoke(action=lot.trade, user=g.user, devices=devices) - db.session.add(self.model) - lot.devices.difference_update(OrderedSet(drop_of_lot)) - - -# 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) - -# lot = data['action'].lot -# for dev in data['devices']: -# if not dev.trading(lot) == '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) + self.model = delete_from_trade(lot, devices) class ConfirmDocumentMixin(): diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 842c009d..e74cad0a 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -1,5 +1,6 @@ import pathlib import copy +import time from flask import g from contextlib import suppress from fractions import Fraction @@ -337,6 +338,7 @@ class Device(Thing): user_from_revoke = False user_to_revoke = False status = 0 + last_action = {'confirm': 0, 'revoke': 0} if not hasattr(trade, 'acceptances'): return Status[status] @@ -351,19 +353,29 @@ class Device(Thing): if ac.t == 'Confirm' and ac.action == trade: if ac.user == user_from: user_from_confirm = True + # import pdb; pdb.set_trace() + last_action['confirm'] = time.mktime(ac.created.timetuple()) + user_from_revoke, user_to_revoke = False, False elif ac.user == user_to: user_to_confirm = True + last_action['confirm'] = time.mktime(ac.created.timetuple()) + user_from_revoke, user_to_revoke = False, False if ac.t == 'Revoke' and ac.action == trade: if ac.user == user_from: user_from_revoke = True + last_action['revoke'] = time.mktime(ac.created.timetuple()) + user_from_confirm, user_to_confirm = False, False elif ac.user == user_to: user_to_revoke = True + last_action['revoke'] = time.mktime(ac.created.timetuple()) + user_from_confirm, user_to_confirm = False, False confirms = [user_from_confirm, user_to_confirm] revokes = [user_from_revoke, user_to_revoke] - if any(confirms): + confirm_vs_revoke = 'confirm' if last_action['confirm'] > last_action['revoke'] else 'revoke' + if any(confirms) and confirm_vs_revoke == 'confirm': status = 1 if user_to_confirm and user_from == g.user: status = 2 @@ -373,7 +385,7 @@ class Device(Thing): if all(confirms): status = 3 - if any(revokes): + if any(revokes) and confirm_vs_revoke == 'revoke': status = 4 if user_to_revoke and user_from == g.user: status = 5 @@ -550,8 +562,7 @@ class Device(Thing): # search the automatic Confirm for ac in actions: if ac.type == 'Trade': - # import pdb; pdb.set_trace() - action_device = [x.device for x in ac.actions_device if x.device == self][0] + action_device = [x for x in ac.actions_device if x.device == self][0] if action_device.author: return action_device.author diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 12309888..6ee86cdf 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -1,4 +1,5 @@ import uuid +from sqlalchemy.util import OrderedSet from collections import deque from enum import Enum from typing import Dict, List, Set, Union @@ -246,7 +247,8 @@ class LotDeviceView(LotBaseChildrenView): return 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: txt = 'This is not your lot' @@ -258,7 +260,46 @@ class LotDeviceView(LotBaseChildrenView): 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] + if g.user.id not in users: + # theoretically this case is impossible + txt = 'This is not your trade' + raise ma.ValidationError(txt) + + drop_of_lot = [] + without_confirms = [] + for dev in devices: + if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: + drop_of_lot.append(dev) + dev.reset_owner() + + if lot.trade.confirm: + drop_of_lot.append(dev) + without_confirms.append(dev) + dev.reset_owner() + + + revoke = Revoke(action=lot.trade, user=g.user, devices=set(devices)) + db.session.add(revoke) + + if without_confirms: + phantom = lot.trade.user_to + if lot.trade.user_to == g.user: + phantom = lot.trade.user_from + + phantom_revoke = Revoke( + action=lot.trade, + user=phantom, + devices=set(without_confirms) + ) + db.session.add(phantom_revoke) + + lot.devices.difference_update(OrderedSet(drop_of_lot)) + return revoke + + +def delete_from_trade2(lot: Lot, ids: Set[int]): users = [lot.trade.user_from.id, lot.trade.user_to.id] if not g.user.id in users: # theoretically this case is impossible @@ -280,7 +321,7 @@ def delete_from_trade(lot: Lot, ids: Set[int]): # 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(lot) == 'Confirm': + if dev.trading(lot) == 'Confirm': without_confirms.add(dev) dev.reset_owner() From cef22f01cee0014829bf5fb336049ad6e68b4f19 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 11 Nov 2021 17:23:45 +0100 Subject: [PATCH 07/13] fixing deletr_from_trade --- ereuse_devicehub/resources/lot/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 6ee86cdf..521696f0 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -269,12 +269,13 @@ def delete_from_trade(lot: Lot, devices: List): drop_of_lot = [] without_confirms = [] + # import pdb; pdb.set_trace() for dev in devices: if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: drop_of_lot.append(dev) dev.reset_owner() - if lot.trade.confirm: + if not lot.trade.confirm: drop_of_lot.append(dev) without_confirms.append(dev) dev.reset_owner() From 872a0be866345a92148416d8c4e79dd22400bf0f Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 11 Nov 2021 22:08:28 +0100 Subject: [PATCH 08/13] rebuild trading function --- ereuse_devicehub/resources/device/metrics.py | 5 +- ereuse_devicehub/resources/device/models.py | 139 ++++++++++++---- ereuse_devicehub/resources/lot/views.py | 1 - tests/test_action.py | 163 +++++++++++-------- tests/test_metrics.py | 11 +- 5 files changed, 210 insertions(+), 109 deletions(-) diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index e60312a2..c9576fdf 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -147,10 +147,7 @@ class Metrics(MetricsMix): 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. """ - # import pdb; pdb.set_trace() - if self.device.trading(self.act.lot) == 'TradeConfirmed': - return True - return False + return self.device.trading(self.act.lot) def get_trade(self): """ diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index e74cad0a..0c3d03c7 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -330,6 +330,81 @@ class Device(Thing): 5: 'NeedConfirmRevoke', 6: 'RevokeConfirmed'} + trade = lot.trade + user_from = trade.user_from + user_to = trade.user_to + status = 0 + last_user = None + + if not hasattr(trade, 'acceptances'): + return Status[status] + + for ac in self.actions: + if ac.t not in ['Confirm', 'Revoke']: + continue + + if ac.user not in [user_from, user_to]: + continue + + if ac.t == 'Confirm' and ac.action == trade: + if status in [0, 6]: + status = 1 + 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: + 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] + + def trading_for_web2(self, lot): + """The trading state, or None if no Trade action has + ever been performed to this device. This extract the posibilities for to do. + This method is performed for show in the web.""" + if not hasattr(lot, 'trade'): + return + + Status = {0: 'Trade', + 1: 'Confirm', + 2: 'NeedConfirmation', + 3: 'TradeConfirmed', + 4: 'Revoke', + 5: 'NeedConfirmRevoke', + 6: 'RevokeConfirmed'} + trade = lot.trade user_from = trade.user_from user_to = trade.user_to @@ -353,7 +428,6 @@ class Device(Thing): if ac.t == 'Confirm' and ac.action == trade: if ac.user == user_from: user_from_confirm = True - # import pdb; pdb.set_trace() last_action['confirm'] = time.mktime(ac.created.timetuple()) user_from_revoke, user_to_revoke = False, False elif ac.user == user_to: @@ -398,24 +472,22 @@ class Device(Thing): def trading(self, lot): """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.""" if not hasattr(lot, 'trade'): return Status = {0: 'Trade', - 1: 'Confirm', - 2: 'TradeConfirmed', - 3: 'Revoke', - 4: 'RevokeConfirmed'} + 2: 'NeedConfirmation', + 3: 'TradeConfirmed', + 5: 'NeedConfirmRevoke', + 6: 'RevokeConfirmed'} trade = lot.trade user_from = trade.user_from user_to = trade.user_to - user_from_confirm = False - user_to_confirm = False - user_from_revoke = False - user_to_revoke = False status = 0 + last_user = None if not hasattr(trade, 'acceptances'): return Status[status] @@ -428,29 +500,38 @@ class Device(Thing): continue if ac.t == 'Confirm' and ac.action == trade: - if ac.user == user_from: - user_from_confirm = True - elif ac.user == user_to: - user_to_confirm = True + if status in [0, 6]: + status = 2 + last_user = ac.user + continue + + if status == 2: + if last_user != ac.user: + status = 3 + last_user = ac.user + continue + + if status == 5: + status = 3 + last_user = ac.user + continue if ac.t == 'Revoke' and ac.action == trade: - if ac.user == user_from: - user_from_revoke = True - elif ac.user == user_to: - user_to_revoke = True + if status == 3: + status = 5 + last_user = ac.user + continue - confirms = [user_from_confirm, user_to_confirm] - revokes = [user_from_revoke, user_to_revoke] + if status == 5: + if last_user != ac.user: + status = 6 + last_user = ac.user + continue - if any(confirms): - status = 1 - if all(confirms): - status = 2 - - if any(revokes): - status = 3 - if all(revokes): - status = 4 + if status == 2: + status = 6 + last_user = ac.user + continue return Status[status] diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 521696f0..6a7b7f79 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -269,7 +269,6 @@ def delete_from_trade(lot: Lot, devices: List): drop_of_lot = [] without_confirms = [] - # import pdb; pdb.set_trace() for dev in devices: if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: drop_of_lot.append(dev) diff --git a/tests/test_action.py b/tests/test_action.py index 86e811e3..4d38131a 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -328,7 +328,7 @@ def test_outgoinlot_status_actions(action_model: models.Action, user: UserClient assert device['actions'][-1]['id'] == action['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 @@ -386,14 +386,14 @@ def test_history_status_actions(user: UserClient, user2: UserClient): assert action['id'] == str(device.status.id) assert device.status.t == models.Recycling.t assert [action['id']] == [str(ac.id) for ac in device.history_status] - + # Case 2 action2 = {'type': models.Refurbish.t, 'devices': [device.id]} action2, _ = user.post(action2, res=models.Action) assert action2['id'] == str(device.status.id) assert device.status.t == models.Refurbish.t assert [action2['id']] == [str(ac.id) for ac in device.history_status] - + # Case 3 lot, _ = user.post({'name': 'MyLot'}, res=Lot) user.post({}, @@ -1709,7 +1709,6 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): assert len(trade.devices) == 10 # the SCRAP confirms the revoke action - import pdb; pdb.set_trace() request_confirm_revoke = { 'type': 'ConfirmRevoke', 'action': device_10.actions[-2].id, @@ -1754,7 +1753,7 @@ def test_trade_case1(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), 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 request_post = { 'type': 'Trade', @@ -1770,31 +1769,23 @@ def test_trade_case1(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_post) trade = models.Trade.query.one() - lot, _ = user.post({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices[-1:]) + lot = trade.lot + device = trade.devices[0] - 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' - assert device1.actions[-1].t == 'Confirm' - assert device1.actions[-1].user == trade.user_to - assert device2.actions[-2].t == 'Trade' - assert device2.actions[-1].t == 'Confirm' - assert device2.actions[-1].user == trade.user_to + user.delete({}, + res=Lot, + item='{}/devices'.format(lot.id), + query=devices[:-1], status=200) - lot, _ = user.delete({}, - res=Lot, - item='{}/devices'.format(lot['id']), - query=devices, status=200) - - 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 + assert device not in trade.lot.devices + assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.actions[-2].t == 'Confirm' + assert device.actions[-1].t == 'Revoke' + assert device.actions[-1].user == trade.user_to @pytest.mark.mvp @@ -1837,6 +1828,7 @@ def test_trade_case2(user: UserClient, user2: UserClient): device1, device2 = trade.devices + # import pdb; pdb.set_trace() assert device1.actions[-2].t == 'Trade' assert device1.actions[-1].t == 'Confirm' assert device1.actions[-1].user == trade.user_to @@ -1853,12 +1845,13 @@ def test_trade_case2(user: UserClient, user2: UserClient): # Normal revoke user.post(res=models.Action, data=request_revoke) - assert device1.actions[-2].t == 'Revoke' - assert device1.actions[-1].t == 'ConfirmRevoke' + assert device1.actions[-2].t == 'Confirm' + assert device1.actions[-1].t == 'Revoke' assert device1.actions[-1].user == trade.user_to - assert device2.actions[-2].t == 'Revoke' - assert device2.actions[-1].t == 'ConfirmRevoke' + assert device2.actions[-2].t == 'Confirm' + assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_to + assert device1.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -1866,7 +1859,6 @@ def test_trade_case2(user: UserClient, user2: UserClient): def test_trade_case3(user: UserClient, user2: UserClient): # the pRp (manatest_usecase_confirmationger) creates a temporary 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) snap2, _ = user2.post(file('acer.happy.battery.snapshot'), res=models.Snapshot) @@ -1878,7 +1870,7 @@ def test_trade_case3(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), 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 request_post = { 'type': 'Trade', @@ -1913,9 +1905,10 @@ def test_trade_case3(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[-1:], status=200) - assert device2.actions[-2].t == 'Revoke' - assert device2.actions[-1].t == 'ConfirmRevoke' + assert device2.actions[-2].t == 'Confirm' + assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_from + assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -1977,9 +1970,10 @@ def test_trade_case4(user: UserClient, user2: UserClient): assert device1.actions[-2].t == 'Trade' assert device1.actions[-1].t == 'Confirm' assert device1.actions[-1].user == trade.user_to - assert device2.actions[-2].t == 'Revoke' - assert device2.actions[-1].t == 'ConfirmRevoke' + assert device2.actions[-2].t == 'Confirm' + assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_from + assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2034,8 +2028,8 @@ def test_trade_case5(user: UserClient, user2: UserClient): assert device2.actions[-1].user == trade.user_from request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device2.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device2.id], } @@ -2043,8 +2037,9 @@ def test_trade_case5(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_confirm_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.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2104,8 +2099,8 @@ def test_trade_case6(user: UserClient, user2: UserClient): assert device2.actions[-1].user == trade.user_to request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device2.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device2.id], } @@ -2113,8 +2108,9 @@ def test_trade_case6(user: UserClient, user2: UserClient): user2.post(res=models.Action, data=request_confirm_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.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2156,6 +2152,7 @@ def test_trade_case7(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' lot, _ = user.delete({}, res=Lot, @@ -2163,14 +2160,14 @@ def test_trade_case7(user: UserClient, user2: UserClient): query=devices, status=200) request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } 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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_to @@ -2180,6 +2177,7 @@ def test_trade_case7(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_to assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to + assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2221,6 +2219,7 @@ def test_trade_case8(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2232,14 +2231,14 @@ def test_trade_case8(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_revoke) request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } 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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_to @@ -2249,6 +2248,7 @@ def test_trade_case8(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_to assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to + assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2301,6 +2301,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): # Normal revoke user.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' assert device.owner == trade.user_to @@ -2310,8 +2311,8 @@ def test_trade_case9(user: UserClient, user2: UserClient): query=devices[-1:], status=200) request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } @@ -2319,7 +2320,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): 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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_from @@ -2329,6 +2330,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_from assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to + assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2372,6 +2374,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): device1, device = trade.devices assert device.owner == trade.user_from + # assert device.trading_for_web(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2381,6 +2384,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): # Normal confirm user.post(res=models.Action, data=request_confirm) + # assert device.trading_for_web(trade.lot) == 'TradeConfirmed' assert device.owner == trade.user_to @@ -2392,18 +2396,18 @@ def test_trade_case10(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_revoke) + assert device.trading_for_web(trade.lot) == 'Revoke' request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } user.post(res=models.Action, data=request_confirm_revoke) 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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_from @@ -2413,6 +2417,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_from assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to + assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2449,6 +2454,7 @@ def test_trade_case11(user: UserClient, user2: UserClient): trade = models.Trade.query.one() device1, device = trade.devices + assert device.trading_for_web(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2457,21 +2463,24 @@ def test_trade_case11(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' lot, _ = user2.delete({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices[-1:], status=200) + assert device.trading_for_web(trade.lot) == 'Revoke' request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } user.post(res=models.Action, data=request_confirm_revoke) + assert device.trading_for_web(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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_from @@ -2517,6 +2526,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): trade = models.Trade.query.one() device1, device = trade.devices + assert device.trading_for_web(trade.lot) == 'Confirm' # Normal confirm request_confirm = { @@ -2526,6 +2536,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2535,16 +2546,18 @@ def test_trade_case12(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_revoke) + assert device.trading_for_web(trade.lot) == 'Revoke' request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } user.post(res=models.Action, data=request_confirm_revoke) + assert device.trading_for_web(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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_from @@ -2595,6 +2608,8 @@ def test_trade_case13(user: UserClient, user2: UserClient): query=devices[-1:]) device1, device = trade.devices + assert device1.trading_for_web(trade.lot) == 'NeedConfirmation' + assert device.trading_for_web(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2603,21 +2618,26 @@ def test_trade_case13(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm) + assert device1.trading_for_web(trade.lot) == 'Confirm' + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' lot, _ = user.delete({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices[-1:], status=200) + assert device1.trading_for_web(trade.lot) == 'Confirm' + assert device.trading_for_web(trade.lot) == 'Revoke' request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } user2.post(res=models.Action, data=request_confirm_revoke) + assert device.trading_for_web(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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_to @@ -2668,6 +2688,8 @@ def test_trade_case14(user: UserClient, user2: UserClient): query=devices[-1:]) device1, device = trade.devices + assert device1.trading_for_web(trade.lot) == 'NeedConfirmation' + assert device.trading_for_web(trade.lot) == 'Confirm' # Normal confirm request_confirm = { @@ -2677,6 +2699,7 @@ def test_trade_case14(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm) + assert device.trading_for_web(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2686,16 +2709,18 @@ def test_trade_case14(user: UserClient, user2: UserClient): # Normal revoke user.post(res=models.Action, data=request_revoke) + assert device.trading_for_web(trade.lot) == 'Revoke' request_confirm_revoke = { - 'type': 'ConfirmRevoke', - 'action': device.actions[-1].id, + 'type': 'Revoke', + 'action': trade.id, 'devices': [device.id], } user2.post(res=models.Action, data=request_confirm_revoke) + assert device.trading_for_web(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[-2].t == 'Revoke' assert device.actions[-2].user == trade.user_to @@ -2716,7 +2741,7 @@ def test_action_web_erase(user: UserClient, client: Client): hash3 = hashlib.sha3_256(bfile.read()).hexdigest() 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"} - + user.post(res=models.Action, data=request) action = models.DataWipe.query.one() for dev in action.devices: diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 6ad7a516..cab985d1 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -181,14 +181,13 @@ def test_complet_metrics_with_trade(user: UserClient, user2: UserClient): query=[('filter', {'type': ['Computer']})]) 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' 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' - # import pdb; pdb.set_trace() assert body1_lenovo in csv_str assert body2_lenovo 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']})]) 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_acer = ';;0;0;Trade;0;4692.0\n' @@ -353,8 +352,8 @@ def test_bug_trade_confirmed(user: UserClient, user2: UserClient): accept='text/csv', query=[('filter', {'type': ['Computer']})]) - body_not_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;False;" - body_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;True;" + body_not_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;NeedConfirmation;" + body_confirmed = "Trade;foo2@foo.com;foo@foo.com;Receiver;TradeConfirmed;" assert body_not_confirmed in csv_not_confirmed assert body_confirmed in csv_confirmed From e326e8ccdf343e185b4131224d7f112caf323ac4 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 11 Nov 2021 22:21:58 +0100 Subject: [PATCH 09/13] fixing revoke when the device is in one future trade --- ereuse_devicehub/resources/lot/views.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 6a7b7f79..961ab812 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -267,6 +267,12 @@ def delete_from_trade(lot: Lot, devices: List): txt = 'This is not your trade' raise ma.ValidationError(txt) + # we need lock the action revoke for devices than travel for futures trades + for dev in devices: + if dev.owner not in users: + txt = 'This is not your device' + raise ma.ValidationError(txt) + drop_of_lot = [] without_confirms = [] for dev in devices: From 1279180700051758f4e245064df714f54c7c3c2c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 11 Nov 2021 22:50:07 +0100 Subject: [PATCH 10/13] fixing confirms --- .../resources/action/views/trade.py | 14 ++--- ereuse_devicehub/resources/lot/views.py | 57 +------------------ 2 files changed, 9 insertions(+), 62 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 842808ba..242b32ba 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -181,17 +181,17 @@ class ConfirmView(ConfirmMixin): then remove the list this device of the list of devices of this action """ real_devices = [] + trade = data['action'] + lot = trade.lot for dev in data['devices']: - ac = dev.last_action_trading - if ac.type == Confirm.t and not ac.user == g.user: - real_devices.append(dev) - - data['devices'] = OrderedSet(real_devices) + if dev.trading(lot) not in ['NeedConfirmation', 'NeedConfirmRevoke']: + raise ValidationError('Some devices not possible confirm.') # Change the owner for every devices for dev in data['devices']: - user_to = data['action'].user_to - dev.change_owner(user_to) + if dev.trading_for_web(lot) == 'NeedConfirmation': + user_to = data['action'].user_to + dev.change_owner(user_to) class RevokeView(ConfirmMixin): diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 961ab812..85a4f7a3 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -261,8 +261,8 @@ class LotDeviceView(LotBaseChildrenView): def delete_from_trade(lot: Lot, devices: List): - users = [lot.trade.user_from.id, lot.trade.user_to.id] - if g.user.id not in users: + users = [lot.trade.user_from, lot.trade.user_to] + if g.user not in users: # theoretically this case is impossible txt = 'This is not your trade' raise ma.ValidationError(txt) @@ -303,56 +303,3 @@ def delete_from_trade(lot: Lot, devices: List): lot.devices.difference_update(OrderedSet(drop_of_lot)) return revoke - - -def delete_from_trade2(lot: Lot, ids: Set[int]): - users = [lot.trade.user_from.id, lot.trade.user_to.id] - if not g.user.id in users: - # theoretically this case is impossible - txt = 'This is not your trade' - raise ma.ValidationError(txt) - - devices = set(Device.query.filter(Device.id.in_(ids)).filter( - Device.owner_id.in_(users))) - - # Now we need to know which devices we need extract of the lot - without_confirms = set() # set of devs without confirms of user2 - - # if the trade need confirmation, then extract all devs than - # have only one confirmation and is from the same user than try to do - # now the revoke action - if lot.trade.confirm: - 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(lot) == '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=devices) - db.session.add(revoke) - - if not lot.trade.confirm: - # if the trade is with phantom account - without_confirms = devices - - if without_confirms: - phantom = lot.trade.user_to - if lot.trade.user_to == g.user: - phantom = lot.trade.user_from - - phantom_revoke = Revoke( - action=lot.trade, - user=phantom, - devices=without_confirms - ) - db.session.add(phantom_revoke) - - lot.devices.difference_update(without_confirms) - # TODO @cayop ?? we dont need this line - lot.trade.devices = lot.devices - - return revoke From 8e47af8e27ba23ca8ea5ad429f3e0bd09ce561a1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 12 Nov 2021 10:00:43 +0100 Subject: [PATCH 11/13] refactoring trading and trading for web --- .../resources/action/views/trade.py | 4 +- ereuse_devicehub/resources/device/metrics.py | 2 +- ereuse_devicehub/resources/device/models.py | 158 ++---------------- ereuse_devicehub/resources/lot/views.py | 5 +- tests/test_action.py | 1 - 5 files changed, 15 insertions(+), 155 deletions(-) diff --git a/ereuse_devicehub/resources/action/views/trade.py b/ereuse_devicehub/resources/action/views/trade.py index 242b32ba..87a5dc81 100644 --- a/ereuse_devicehub/resources/action/views/trade.py +++ b/ereuse_devicehub/resources/action/views/trade.py @@ -184,12 +184,12 @@ class ConfirmView(ConfirmMixin): trade = data['action'] lot = trade.lot for dev in data['devices']: - if dev.trading(lot) not in ['NeedConfirmation', 'NeedConfirmRevoke']: + if dev.trading(lot, simple=True) not in ['NeedConfirmation', 'NeedConfirmRevoke']: raise ValidationError('Some devices not possible confirm.') # Change the owner for every devices for dev in data['devices']: - if dev.trading_for_web(lot) == 'NeedConfirmation': + if dev.trading(lot) == 'NeedConfirmation': user_to = data['action'].user_to dev.change_owner(user_to) diff --git a/ereuse_devicehub/resources/device/metrics.py b/ereuse_devicehub/resources/device/metrics.py index c9576fdf..f9399f95 100644 --- a/ereuse_devicehub/resources/device/metrics.py +++ b/ereuse_devicehub/resources/device/metrics.py @@ -147,7 +147,7 @@ class Metrics(MetricsMix): 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. """ - return self.device.trading(self.act.lot) + return self.device.trading(self.act.lot, simple=True) def get_trade(self): """ diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 0c3d03c7..e7297fcd 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -313,12 +313,13 @@ class Device(Thing): @property def tradings(self): - return {str(x.id): self.trading_for_web(x.lot) for x in self.actions if x.t == 'Trade'} + return {str(x.id): self.trading(x.lot) for x in self.actions if x.t == 'Trade'} - def trading_for_web(self, lot): + def trading(self, lot, simple=None): """The trading state, or None if no Trade action has ever been performed to this device. This extract the posibilities for to do. - This method is performed for show in the web.""" + This method is performed for show in the web. + If you need to do one simple and generic response you can put simple=True for that.""" if not hasattr(lot, 'trade'): return @@ -348,6 +349,9 @@ class Device(Thing): if ac.t == 'Confirm' and ac.action == trade: if status in [0, 6]: + if simple: + status = 2 + continue status = 1 last_user = ac.user if ac.user == user_from and user_to == g.user: @@ -369,6 +373,9 @@ class Device(Thing): 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: @@ -390,151 +397,6 @@ class Device(Thing): return Status[status] - def trading_for_web2(self, lot): - """The trading state, or None if no Trade action has - ever been performed to this device. This extract the posibilities for to do. - This method is performed for show in the web.""" - if not hasattr(lot, 'trade'): - return - - Status = {0: 'Trade', - 1: 'Confirm', - 2: 'NeedConfirmation', - 3: 'TradeConfirmed', - 4: 'Revoke', - 5: 'NeedConfirmRevoke', - 6: 'RevokeConfirmed'} - - trade = lot.trade - user_from = trade.user_from - user_to = trade.user_to - user_from_confirm = False - user_to_confirm = False - user_from_revoke = False - user_to_revoke = False - status = 0 - last_action = {'confirm': 0, 'revoke': 0} - - if not hasattr(trade, 'acceptances'): - return Status[status] - - for ac in self.actions: - if ac.t not in ['Confirm', 'Revoke']: - continue - - if ac.user not in [user_from, user_to]: - continue - - if ac.t == 'Confirm' and ac.action == trade: - if ac.user == user_from: - user_from_confirm = True - last_action['confirm'] = time.mktime(ac.created.timetuple()) - user_from_revoke, user_to_revoke = False, False - elif ac.user == user_to: - user_to_confirm = True - last_action['confirm'] = time.mktime(ac.created.timetuple()) - user_from_revoke, user_to_revoke = False, False - - if ac.t == 'Revoke' and ac.action == trade: - if ac.user == user_from: - user_from_revoke = True - last_action['revoke'] = time.mktime(ac.created.timetuple()) - user_from_confirm, user_to_confirm = False, False - elif ac.user == user_to: - user_to_revoke = True - last_action['revoke'] = time.mktime(ac.created.timetuple()) - user_from_confirm, user_to_confirm = False, False - - confirms = [user_from_confirm, user_to_confirm] - revokes = [user_from_revoke, user_to_revoke] - - confirm_vs_revoke = 'confirm' if last_action['confirm'] > last_action['revoke'] else 'revoke' - if any(confirms) and confirm_vs_revoke == 'confirm': - status = 1 - if user_to_confirm and user_from == g.user: - status = 2 - if user_from_confirm and user_to == g.user: - status = 2 - - if all(confirms): - status = 3 - - if any(revokes) and confirm_vs_revoke == 'revoke': - status = 4 - if user_to_revoke and user_from == g.user: - status = 5 - if user_from_revoke and user_to == g.user: - status = 5 - if all(revokes): - status = 6 - - return Status[status] - - def trading(self, lot): - """The trading state, or None if no Trade action has - ever been performed to this device. This extract the posibilities for to do. - This method is performed for show in the web.""" - if not hasattr(lot, 'trade'): - return - - Status = {0: 'Trade', - 2: 'NeedConfirmation', - 3: 'TradeConfirmed', - 5: 'NeedConfirmRevoke', - 6: 'RevokeConfirmed'} - - trade = lot.trade - user_from = trade.user_from - user_to = trade.user_to - status = 0 - last_user = None - - if not hasattr(trade, 'acceptances'): - return Status[status] - - for ac in self.actions: - if ac.t not in ['Confirm', 'Revoke']: - continue - - if ac.user not in [user_from, user_to]: - continue - - if ac.t == 'Confirm' and ac.action == trade: - if status in [0, 6]: - status = 2 - last_user = ac.user - continue - - if status == 2: - if last_user != ac.user: - status = 3 - last_user = ac.user - continue - - if status == 5: - status = 3 - last_user = ac.user - continue - - if ac.t == 'Revoke' and ac.action == trade: - if status == 3: - status = 5 - last_user = ac.user - continue - - if status == 5: - if last_user != ac.user: - status = 6 - last_user = ac.user - continue - - if status == 2: - status = 6 - last_user = ac.user - continue - - return Status[status] - @property def revoke(self): """If the actual trading state is an revoke action, this property show diff --git a/ereuse_devicehub/resources/lot/views.py b/ereuse_devicehub/resources/lot/views.py index 85a4f7a3..dce6af62 100644 --- a/ereuse_devicehub/resources/lot/views.py +++ b/ereuse_devicehub/resources/lot/views.py @@ -231,7 +231,7 @@ class LotDeviceView(LotBaseChildrenView): return devices = set(Device.query.filter(Device.id.in_(ids)).filter( - Device.owner==g.user)) + Device.owner == g.user)) lot.devices.update(devices) @@ -276,7 +276,7 @@ def delete_from_trade(lot: Lot, devices: List): drop_of_lot = [] without_confirms = [] for dev in devices: - if dev.trading_for_web(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: + if dev.trading(lot) in ['NeedConfirmation', 'Confirm', 'NeedConfirmRevoke']: drop_of_lot.append(dev) dev.reset_owner() @@ -285,7 +285,6 @@ def delete_from_trade(lot: Lot, devices: List): without_confirms.append(dev) dev.reset_owner() - revoke = Revoke(action=lot.trade, user=g.user, devices=set(devices)) db.session.add(revoke) diff --git a/tests/test_action.py b/tests/test_action.py index 4d38131a..f37d70e0 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -1828,7 +1828,6 @@ def test_trade_case2(user: UserClient, user2: UserClient): device1, device2 = trade.devices - # import pdb; pdb.set_trace() assert device1.actions[-2].t == 'Trade' assert device1.actions[-1].t == 'Confirm' assert device1.actions[-1].user == trade.user_to From 37c410bc3663fd0464c23e31aed4da549410d2ff Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 12 Nov 2021 17:46:39 +0100 Subject: [PATCH 12/13] fixing confirms tests --- tests/test_action.py | 85 ++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index f37d70e0..0e339c6d 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -1396,6 +1396,7 @@ def test_confirm_revoke(user: UserClient, user2: UserClient): user.post(res=models.Action, data=request_post) trade = models.Trade.query.one() + device = trade.devices[0] request_confirm = { 'type': 'Confirm', @@ -1416,9 +1417,10 @@ def test_confirm_revoke(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_revoke) - # You can not to do one confirmation next of one revoke - user2.post(res=models.Action, data=request_confirm, status=422) - assert len(trade.acceptances) == 3 + # You can to do one confirmation next of one revoke + user2.post(res=models.Action, data=request_confirm) + assert len(trade.acceptances) == 4 + assert device.trading(trade.lot) == "TradeConfirmed" @pytest.mark.mvp @@ -1455,7 +1457,7 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), 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 request_post = { 'type': 'Trade', @@ -1516,9 +1518,6 @@ def test_usecase_confirmation(user: UserClient, user2: UserClient): 'type': 'Confirm', 'action': trade.id, 'devices': [ - snap1['device']['id'], - snap2['device']['id'], - snap3['device']['id'], snap4['device']['id'], snap5['device']['id'], snap6['device']['id'], @@ -1782,7 +1781,7 @@ def test_trade_case1(user: UserClient, user2: UserClient): query=devices[:-1], status=200) assert device not in trade.lot.devices - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' assert device.actions[-2].t == 'Confirm' assert device.actions[-1].t == 'Revoke' assert device.actions[-1].user == trade.user_to @@ -1850,7 +1849,7 @@ def test_trade_case2(user: UserClient, user2: UserClient): assert device2.actions[-2].t == 'Confirm' assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_to - assert device1.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device1.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -1907,7 +1906,7 @@ def test_trade_case3(user: UserClient, user2: UserClient): assert device2.actions[-2].t == 'Confirm' assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_from - assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device2.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -1972,7 +1971,7 @@ def test_trade_case4(user: UserClient, user2: UserClient): assert device2.actions[-2].t == 'Confirm' assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_from - assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device2.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2038,7 +2037,7 @@ def test_trade_case5(user: UserClient, user2: UserClient): assert device2.actions[-2].t == 'Revoke' assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_to - assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device2.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2109,7 +2108,7 @@ def test_trade_case6(user: UserClient, user2: UserClient): assert device2.actions[-2].t == 'Revoke' assert device2.actions[-1].t == 'Revoke' assert device2.actions[-1].user == trade.user_from - assert device2.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device2.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2151,7 +2150,7 @@ def test_trade_case7(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' lot, _ = user.delete({}, res=Lot, @@ -2176,7 +2175,7 @@ def test_trade_case7(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_to assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2218,7 +2217,7 @@ def test_trade_case8(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2247,7 +2246,7 @@ def test_trade_case8(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_to assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2300,7 +2299,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): # Normal revoke user.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' assert device.owner == trade.user_to @@ -2329,7 +2328,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_from assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2373,7 +2372,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): device1, device = trade.devices assert device.owner == trade.user_from - # assert device.trading_for_web(trade.lot) == 'Confirm' + # assert device.trading(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2383,7 +2382,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): # Normal confirm user.post(res=models.Action, data=request_confirm) - # assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + # assert device.trading(trade.lot) == 'TradeConfirmed' assert device.owner == trade.user_to @@ -2395,7 +2394,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_revoke) - assert device.trading_for_web(trade.lot) == 'Revoke' + assert device.trading(trade.lot) == 'Revoke' request_confirm_revoke = { 'type': 'Revoke', @@ -2416,7 +2415,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): assert device.actions[-4].user == trade.user_from assert device.actions[-5].t == 'Trade' assert device.actions[-5].author == trade.user_to - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' @pytest.mark.mvp @@ -2453,7 +2452,7 @@ def test_trade_case11(user: UserClient, user2: UserClient): trade = models.Trade.query.one() device1, device = trade.devices - assert device.trading_for_web(trade.lot) == 'Confirm' + assert device.trading(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2462,13 +2461,13 @@ def test_trade_case11(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' lot, _ = user2.delete({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices[-1:], status=200) - assert device.trading_for_web(trade.lot) == 'Revoke' + assert device.trading(trade.lot) == 'Revoke' request_confirm_revoke = { 'type': 'Revoke', @@ -2477,7 +2476,7 @@ def test_trade_case11(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm_revoke) - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' assert device.actions[-1].t == 'Revoke' assert device.actions[-1].user == trade.user_to @@ -2525,7 +2524,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): trade = models.Trade.query.one() device1, device = trade.devices - assert device.trading_for_web(trade.lot) == 'Confirm' + assert device.trading(trade.lot) == 'Confirm' # Normal confirm request_confirm = { @@ -2535,7 +2534,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2545,7 +2544,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): # Normal revoke user2.post(res=models.Action, data=request_revoke) - assert device.trading_for_web(trade.lot) == 'Revoke' + assert device.trading(trade.lot) == 'Revoke' request_confirm_revoke = { 'type': 'Revoke', @@ -2554,7 +2553,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm_revoke) - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' assert device.actions[-1].t == 'Revoke' assert device.actions[-1].user == trade.user_to @@ -2607,8 +2606,8 @@ def test_trade_case13(user: UserClient, user2: UserClient): query=devices[-1:]) device1, device = trade.devices - assert device1.trading_for_web(trade.lot) == 'NeedConfirmation' - assert device.trading_for_web(trade.lot) == 'Confirm' + assert device1.trading(trade.lot) == 'NeedConfirmation' + assert device.trading(trade.lot) == 'Confirm' request_confirm = { 'type': 'Confirm', @@ -2617,15 +2616,15 @@ def test_trade_case13(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm) - assert device1.trading_for_web(trade.lot) == 'Confirm' - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device1.trading(trade.lot) == 'Confirm' + assert device.trading(trade.lot) == 'TradeConfirmed' lot, _ = user.delete({}, res=Lot, item='{}/devices'.format(lot['id']), query=devices[-1:], status=200) - assert device1.trading_for_web(trade.lot) == 'Confirm' - assert device.trading_for_web(trade.lot) == 'Revoke' + assert device1.trading(trade.lot) == 'Confirm' + assert device.trading(trade.lot) == 'Revoke' request_confirm_revoke = { 'type': 'Revoke', @@ -2634,7 +2633,7 @@ def test_trade_case13(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm_revoke) - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' assert device.actions[-1].t == 'Revoke' assert device.actions[-1].user == trade.user_from @@ -2687,8 +2686,8 @@ def test_trade_case14(user: UserClient, user2: UserClient): query=devices[-1:]) device1, device = trade.devices - assert device1.trading_for_web(trade.lot) == 'NeedConfirmation' - assert device.trading_for_web(trade.lot) == 'Confirm' + assert device1.trading(trade.lot) == 'NeedConfirmation' + assert device.trading(trade.lot) == 'Confirm' # Normal confirm request_confirm = { @@ -2698,7 +2697,7 @@ def test_trade_case14(user: UserClient, user2: UserClient): } user.post(res=models.Action, data=request_confirm) - assert device.trading_for_web(trade.lot) == 'TradeConfirmed' + assert device.trading(trade.lot) == 'TradeConfirmed' request_revoke = { 'type': 'Revoke', @@ -2708,7 +2707,7 @@ def test_trade_case14(user: UserClient, user2: UserClient): # Normal revoke user.post(res=models.Action, data=request_revoke) - assert device.trading_for_web(trade.lot) == 'Revoke' + assert device.trading(trade.lot) == 'Revoke' request_confirm_revoke = { 'type': 'Revoke', @@ -2717,7 +2716,7 @@ def test_trade_case14(user: UserClient, user2: UserClient): } user2.post(res=models.Action, data=request_confirm_revoke) - assert device.trading_for_web(trade.lot) == 'RevokeConfirmed' + assert device.trading(trade.lot) == 'RevokeConfirmed' assert device.actions[-1].t == 'Revoke' assert device.actions[-1].user == trade.user_from From a19aa66ecce2dc1afefcff77096fb12ad36269dc Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 12 Nov 2021 18:31:19 +0100 Subject: [PATCH 13/13] fixing test_workbench_server_condensed --- tests/test_workbench.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_workbench.py b/tests/test_workbench.py index 9998decc..2eb161a1 100644 --- a/tests/test_workbench.py +++ b/tests/test_workbench.py @@ -66,7 +66,7 @@ def test_workbench_server_condensed(user: UserClient): assert device['rate']['rating'] == 1 assert device['rate']['type'] == RateComputer.t # 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']]