Merge branch 'testing' into feature/new-recycling-action
This commit is contained in:
commit
007e9a96c6
|
@ -13,6 +13,7 @@ ml).
|
||||||
- [addend] #166 new action recycling and reuse
|
- [addend] #166 new action recycling and reuse
|
||||||
|
|
||||||
## [1.0.10-beta]
|
## [1.0.10-beta]
|
||||||
|
- [bugfix] #168 can to do a trade without devices.
|
||||||
|
|
||||||
## [1.0.9-beta]
|
## [1.0.9-beta]
|
||||||
- [addend] #159 external document as proof of erase of disk
|
- [addend] #159 external document as proof of erase of disk
|
||||||
|
|
|
@ -1706,7 +1706,10 @@ class MoveOnDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||||
)
|
)
|
||||||
container_from = db.relationship(
|
container_from = db.relationship(
|
||||||
'TradeDocument',
|
'TradeDocument',
|
||||||
primaryjoin='MoveOnDocument.container_from_id == TradeDocument.id',
|
backref=backref('containers_from',
|
||||||
|
lazy=True,
|
||||||
|
cascade=CASCADE_OWN),
|
||||||
|
primaryjoin='MoveOnDocument.container_from_id == TradeDocument.id'
|
||||||
)
|
)
|
||||||
container_from_id.comment = """This is the trade document used as container in a incoming lot"""
|
container_from_id.comment = """This is the trade document used as container in a incoming lot"""
|
||||||
|
|
||||||
|
@ -1717,6 +1720,9 @@ class MoveOnDocument(JoinedTableMixin, ActionWithMultipleTradeDocuments):
|
||||||
)
|
)
|
||||||
container_to = db.relationship(
|
container_to = db.relationship(
|
||||||
'TradeDocument',
|
'TradeDocument',
|
||||||
|
backref=backref('containers_to',
|
||||||
|
lazy=True,
|
||||||
|
cascade=CASCADE_OWN),
|
||||||
primaryjoin='MoveOnDocument.container_to_id == TradeDocument.id',
|
primaryjoin='MoveOnDocument.container_to_id == TradeDocument.id',
|
||||||
)
|
)
|
||||||
container_to_id.comment = """This is the trade document used as container in a outgoing lot"""
|
container_to_id.comment = """This is the trade document used as container in a outgoing lot"""
|
||||||
|
|
|
@ -751,6 +751,11 @@ class Trade(ActionWithMultipleDevices):
|
||||||
required=True,
|
required=True,
|
||||||
only_query='id')
|
only_query='id')
|
||||||
|
|
||||||
|
@pre_load
|
||||||
|
def adding_devices(self, data: dict):
|
||||||
|
if not 'devices' in data.keys():
|
||||||
|
data['devices'] = []
|
||||||
|
|
||||||
@validates_schema
|
@validates_schema
|
||||||
def validate_lot(self, data: dict):
|
def validate_lot(self, data: dict):
|
||||||
if not g.user.email in [data['user_from_email'], data['user_to_email']]:
|
if not g.user.email in [data['user_from_email'], data['user_to_email']]:
|
||||||
|
|
|
@ -382,13 +382,6 @@ class Device(Thing):
|
||||||
if action.type == 'Revoke':
|
if action.type == 'Revoke':
|
||||||
return action.id
|
return action.id
|
||||||
|
|
||||||
@property
|
|
||||||
def confirm_status(self):
|
|
||||||
"""The actual state of confirmation of one Trade, or None if no Trade action
|
|
||||||
has ever been performed to this device."""
|
|
||||||
# TODO @cayop we need implement this functionality
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def physical(self):
|
def physical(self):
|
||||||
"""The actual physical state, None otherwise."""
|
"""The actual physical state, None otherwise."""
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import copy
|
||||||
|
from contextlib import suppress
|
||||||
from citext import CIText
|
from citext import CIText
|
||||||
from flask import g
|
from flask import g
|
||||||
|
|
||||||
|
@ -101,10 +103,10 @@ class TradeDocument(Thing):
|
||||||
revoke = 'Revoke'
|
revoke = 'Revoke'
|
||||||
revoke_pending = 'Revoke Pending'
|
revoke_pending = 'Revoke Pending'
|
||||||
confirm_revoke = 'Document Revoked'
|
confirm_revoke = 'Document Revoked'
|
||||||
if not self.actions:
|
ac = self.last_action_trading()
|
||||||
|
if not ac:
|
||||||
return
|
return
|
||||||
|
|
||||||
ac = self.actions[-1]
|
|
||||||
|
|
||||||
if ac.type == 'ConfirmRevokeDocument':
|
if ac.type == 'ConfirmRevokeDocument':
|
||||||
# can to do revoke_confirmed
|
# can to do revoke_confirmed
|
||||||
|
@ -143,6 +145,18 @@ class TradeDocument(Thing):
|
||||||
|
|
||||||
return weight
|
return weight
|
||||||
|
|
||||||
|
def last_action_trading(self):
|
||||||
|
"""which is the last action trading"""
|
||||||
|
with suppress(StopIteration, ValueError):
|
||||||
|
actions = copy.copy(self.actions)
|
||||||
|
actions.sort(key=lambda x: x.created)
|
||||||
|
t_trades = ['Trade',
|
||||||
|
'Confirm',
|
||||||
|
'ConfirmRevokeDocument',
|
||||||
|
'RevokeDocument',
|
||||||
|
'ConfirmDocument']
|
||||||
|
return next(e for e in reversed(actions) if e.t in t_trades)
|
||||||
|
|
||||||
def _warning_actions(self, actions):
|
def _warning_actions(self, actions):
|
||||||
"""Show warning actions"""
|
"""Show warning actions"""
|
||||||
return sorted(ev for ev in actions if ev.severity >= Severity.Warning)
|
return sorted(ev for ev in actions if ev.severity >= Severity.Warning)
|
||||||
|
|
|
@ -1013,6 +1013,27 @@ def test_trade_endpoint(user: UserClient, user2: UserClient):
|
||||||
device2, _ = user2.get(res=Device, item=device['id'])
|
device2, _ = user2.get(res=Device, item=device['id'])
|
||||||
assert device2['id'] == device['id']
|
assert device2['id'] == device['id']
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_trade_without_device(user: UserClient, user2: UserClient):
|
||||||
|
"""Test one offer with automatic confirmation and without user to"""
|
||||||
|
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
|
||||||
|
|
||||||
|
request_post = {
|
||||||
|
'type': 'Trade',
|
||||||
|
'userFromEmail': user.email,
|
||||||
|
'userToEmail': user2.email,
|
||||||
|
'lot': lot['id'],
|
||||||
|
'confirms': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
user.post(res=models.Action, data=request_post)
|
||||||
|
|
||||||
|
trade = models.Trade.query.one()
|
||||||
|
assert str(trade.lot.id) == lot['id']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.mvp
|
@pytest.mark.mvp
|
||||||
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
def test_offer_without_to(user: UserClient):
|
def test_offer_without_to(user: UserClient):
|
||||||
|
@ -2742,3 +2763,61 @@ def test_moveOnDocument(user: UserClient, user2: UserClient):
|
||||||
assert description == mvs.description
|
assert description == mvs.description
|
||||||
tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2)
|
tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2)
|
||||||
user.post(res=models.Action, data=request_moveOn, status=422)
|
user.post(res=models.Action, data=request_moveOn, status=422)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.mvp
|
||||||
|
@pytest.mark.usefixtures(conftest.app_context.__name__)
|
||||||
|
def test_moveOnDocument_bug168(user: UserClient, user2: UserClient):
|
||||||
|
"""If you use one moveOnDocument in a trade Document. Next you can not drop this document."""
|
||||||
|
lotIn, _ = user.post({'name': 'MyLotIn'}, res=Lot)
|
||||||
|
lotOut, _ = user.post({'name': 'MyLotOut'}, res=Lot)
|
||||||
|
url = 'http://www.ereuse.org/apapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapapaapaapaapaapaapaapaapaapaapaaaa',
|
||||||
|
request_post1 = {
|
||||||
|
'filename': 'test.pdf',
|
||||||
|
'hash': 'bbbbbbbb',
|
||||||
|
'url': url,
|
||||||
|
'weight': 150,
|
||||||
|
'lot': lotIn['id']
|
||||||
|
}
|
||||||
|
tradedocument_from, _ = user.post(res=TradeDocument, data=request_post1)
|
||||||
|
id_hash = 'aaaaaaaaa'
|
||||||
|
request_post2 = {
|
||||||
|
'filename': 'test.pdf',
|
||||||
|
'hash': id_hash,
|
||||||
|
'url': url,
|
||||||
|
'weight': 0,
|
||||||
|
'lot': lotOut['id']
|
||||||
|
}
|
||||||
|
tradedocument_to, _ = user.post(res=TradeDocument, data=request_post2)
|
||||||
|
|
||||||
|
request_trade = {
|
||||||
|
'type': 'Trade',
|
||||||
|
'devices': [],
|
||||||
|
'userFromEmail': user2.email,
|
||||||
|
'userToEmail': user.email,
|
||||||
|
'price': 10,
|
||||||
|
'date': "2020-12-01T02:00:00+00:00",
|
||||||
|
'lot': lotIn['id'],
|
||||||
|
'confirms': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
user.post(res=models.Action, data=request_trade)
|
||||||
|
|
||||||
|
description = 'This is a good description'
|
||||||
|
request_moveOn = {
|
||||||
|
'type': 'MoveOnDocument',
|
||||||
|
'weight': 4,
|
||||||
|
'container_from': tradedocument_from['id'],
|
||||||
|
'container_to': id_hash,
|
||||||
|
'description': description
|
||||||
|
}
|
||||||
|
doc, _ = user.post(res=models.Action, data=request_moveOn)
|
||||||
|
trade = models.Trade.query.one()
|
||||||
|
trade_document1 = TradeDocument.query.filter_by(id=tradedocument_from['id']).one()
|
||||||
|
trade_document2 = TradeDocument.query.filter_by(id=tradedocument_to['id']).one()
|
||||||
|
assert trade_document1.total_weight == 150.0
|
||||||
|
assert trade_document2.total_weight == 4.0
|
||||||
|
assert trade_document1.trading == 'Confirm'
|
||||||
|
assert trade_document2.trading == None
|
||||||
|
|
||||||
|
tradedocument, _ = user.delete(res=TradeDocument, item=tradedocument_to['id'])
|
||||||
|
|
Reference in New Issue