From b072bc3b57208113bfe1b9b2413ba68af1ac0447 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Thu, 26 Nov 2020 18:44:08 +0100 Subject: [PATCH] change allocate and deallocate --- .../e93aec8fc41f_added_assigned_action.py | 3 +- ereuse_devicehub/resources/action/models.py | 2 +- ereuse_devicehub/resources/action/schemas.py | 61 ++++++++--------- tests/test_action.py | 66 ++++++++++++++++--- 4 files changed, 90 insertions(+), 42 deletions(-) diff --git a/ereuse_devicehub/migrations/versions/e93aec8fc41f_added_assigned_action.py b/ereuse_devicehub/migrations/versions/e93aec8fc41f_added_assigned_action.py index 08d6c52c..b1f6aa4f 100644 --- a/ereuse_devicehub/migrations/versions/e93aec8fc41f_added_assigned_action.py +++ b/ereuse_devicehub/migrations/versions/e93aec8fc41f_added_assigned_action.py @@ -31,7 +31,7 @@ def upgrade(): op.drop_table('allocate', schema=f'{get_inv()}') op.create_table('allocate', sa.Column('code', citext.CIText(), nullable=True, comment=' This is a internal code for mainteing the secrets of the personal datas of the new holder '), - sa.Column('end_users', sa.Numeric(precision=4), nullable=False), + sa.Column('end_users', sa.Numeric(precision=4), nullable=True), sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), sa.PrimaryKeyConstraint('id'), @@ -41,6 +41,7 @@ def upgrade(): # Deallocate action op.drop_table('deallocate', schema=f'{get_inv()}') op.create_table('deallocate', + sa.Column('code', citext.CIText(), nullable=True, comment=' This is a internal code for mainteing the secrets of the personal datas of the new holder '), sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), sa.ForeignKeyConstraint(['id'], [f'{get_inv()}.action.id'], ), sa.PrimaryKeyConstraint('id'), diff --git a/ereuse_devicehub/resources/action/models.py b/ereuse_devicehub/resources/action/models.py index a32ebbdd..936298d7 100644 --- a/ereuse_devicehub/resources/action/models.py +++ b/ereuse_devicehub/resources/action/models.py @@ -315,7 +315,7 @@ class Allocate(JoinedTableMixin, ActionWithMultipleDevices): """ code = Column(CIText(), default='', nullable=True) code.comment = """ This is a internal code for mainteing the secrets of the personal datas of the new holder """ - end_users = Column(Numeric(precision=4), check_range('end_users', 0), nullable=False) + end_users = Column(Numeric(precision=4), check_range('end_users', 0), nullable=True) class Deallocate(JoinedTableMixin, ActionWithMultipleDevices): diff --git a/ereuse_devicehub/resources/action/schemas.py b/ereuse_devicehub/resources/action/schemas.py index f7952ae9..168bcb3e 100644 --- a/ereuse_devicehub/resources/action/schemas.py +++ b/ereuse_devicehub/resources/action/schemas.py @@ -1,3 +1,5 @@ +from datetime import datetime, timedelta +from dateutil.tz import tzutc from flask import current_app as app from marshmallow import Schema as MarshmallowSchema, ValidationError, fields as f, validates_schema from marshmallow.fields import Boolean, DateTime, Decimal, Float, Integer, Nested, String, \ @@ -65,58 +67,57 @@ class Remove(ActionWithOneDevice): class Allocate(ActionWithMultipleDevices): __doc__ = m.Allocate.__doc__ - agent = NestedOn(s_agent.Agent, only_query='id', required=False, comment=m.Trade.to_comment) - description = SanitizedStr(default='', description=m.Action.description.comment) - start_time = DateTime(data_key='start_time', description=m.Action.start_time.comment) + start_time = DateTime(data_key='start_time', required=True, + description=m.Action.start_time.comment) end_time = DateTime(data_key='end_time', required=False, description=m.Action.end_time.comment) - code = SanitizedStr(data_key='Transaction', validate=Length(min=1, max=STR_BIG_SIZE), + code = SanitizedStr(data_key='transaction', validate=Length(min=1, max=STR_BIG_SIZE), required=False, description='The code of the agent to assigned.') - end_users = Integer(validate=[Range(min=1, error="Value must be greater than 0")], - required=True) + end_users = Integer(validate=[Range(min=1, error="Value must be greater than 0")]) @validates_schema def validate_allocate(self, data: dict): + txt = "You need to allocate for a day before today" + delay = timedelta(days=1) + today = datetime.now().replace(tzinfo=tzutc()) + delay + start_time = data['start_time'].replace(tzinfo=tzutc()) + if start_time > today: + raise ValidationError(txt) + txt = "You need deallocate before allocate this device again" for device in data['devices']: - if device.allocated == False: - device.allocated = True - continue - - actions = [a for a in device.actions] - actions.sort(key=lambda x: x.created) - actions.reverse() - - for allocate in actions: - if isinstance(allocate, m.Allocate): - same_allocate = [ - allocate.code == data['code'], - allocate.start_time == data['start_time'], - allocate.end_users == data['end_users'] - ] - if not all(same_allocate): - raise ValidationError(txt) - if isinstance(allocate, m.Deallocate): - break + if device.allocated: + raise ValidationError(txt) device.allocated = True class Deallocate(ActionWithMultipleDevices): __doc__ = m.Deallocate.__doc__ - start_time = DateTime(data_key='start_time', description=m.Action.start_time.comment) + start_time = DateTime(data_key='start_time', required=True, + description=m.Action.start_time.comment) + code = SanitizedStr(data_key='transaction', validate=Length(min=1, max=STR_BIG_SIZE), + required=False, + description='The code of the agent to assigned.') @validates_schema def validate_deallocate(self, data: dict): - txt = "Sorry some of this devices are actually deallocate" + txt = "You need to deallocate for a day before today" + import pdb; pdb.set_trace() + delay = timedelta(days=1) + today = datetime.now().replace(tzinfo=tzutc()) + delay + start_time = data['start_time'].replace(tzinfo=tzutc()) + if start_time > today: + raise ValidationError(txt) + txt = "Sorry some of this devices are actually deallocate" for device in data['devices']: - if hasattr(device, 'allocated') and device.allocated: - device.allocated = False - else: + if not device.allocated: raise ValidationError(txt) + device.allocated = False + class EraseBasic(ActionWithOneDevice): __doc__ = m.EraseBasic.__doc__ diff --git a/tests/test_action.py b/tests/test_action.py index 4d2a7231..410fb265 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -2,7 +2,7 @@ import ipaddress import copy import pytest -from datetime import timedelta +from datetime import datetime, timedelta from decimal import Decimal from typing import Tuple, Type @@ -278,21 +278,22 @@ def test_allocate(user: UserClient): """ Tests allocate """ snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) device_id = snapshot['device']['id'] - post_request = {"Transaction": "ccc", "name": "John", "end_users": 1, - "devices": [device_id], "description": "aaa", + post_request = {"transaction": "ccc", + "name": "John", + "severity": "Info", + "end_users": 1, + "devices": [device_id], + "description": "aaa", "start_time": "2020-11-01T02:00:00+00:00", "end_time": "2020-12-01T02:00:00+00:00" } allocate, _ = user.post(res=models.Allocate, data=post_request) - allocate_get, _ = user.get(res=models.Action, item=allocate['id']) - for f in ('name', 'Transaction', 'created', 'start_time', 'end_users'): - assert allocate_get[f] == allocate[f] # Normal allocate device, _ = user.get(res=Device, item=device_id) assert device['allocated'] == True action = [a for a in device['actions'] if a['type'] == 'Allocate'][0] - assert action['Transaction'] == allocate['Transaction'] + assert action['transaction'] == allocate['transaction'] assert action['created'] == allocate['created'] assert action['start_time'] == allocate['start_time'] assert action['end_users'] == allocate['end_users'] @@ -303,7 +304,7 @@ def test_allocate(user: UserClient): post_bad_request2 = copy.copy(post_request) post_bad_request2['start_time'] = "2020-11-01T02:00:00+00:01" post_bad_request3 = copy.copy(post_request) - post_bad_request3['Transaction'] = "aaa" + post_bad_request3['transaction'] = "aaa" res1, _ = user.post(res=models.Allocate, data=post_bad_request1, status=422) res2, _ = user.post(res=models.Allocate, data=post_bad_request2, status=422) res3, _ = user.post(res=models.Allocate, data=post_bad_request3, status=422) @@ -312,6 +313,28 @@ def test_allocate(user: UserClient): assert r['type'] == 'ValidationError' +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_allocate_bad_dates(user: UserClient): + """ Tests allocate """ + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + device_id = snapshot['device']['id'] + delta = timedelta(days=30) + future = datetime.now() + delta + post_request = {"transaction": "ccc", + "name": "John", + "severity": "Info", + "end_users": 1, + "devices": [device_id], + "description": "aaa", + "start_time": future, + } + + res, _ = user.post(res=models.Allocate, data=post_request, status=422) + assert res['code'] == 422 + assert res['type'] == 'ValidationError' + + @pytest.mark.mvp @pytest.mark.usefixtures(conftest.app_context.__name__) def test_deallocate(user: UserClient): @@ -319,12 +342,13 @@ def test_deallocate(user: UserClient): snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) device_id = snapshot['device']['id'] post_deallocate = {"start_time": "2020-11-01T02:00:00+00:00", - "devices": [device_id] + "transaction": "ccc", + "devices": [device_id] } res, _ = user.post(res=models.Deallocate, data=post_deallocate, status=422) assert res['code'] == 422 assert res['type'] == 'ValidationError' - post_allocate = {"Transaction": "ccc", "name": "John", "end_users": 1, + post_allocate = {"transaction": "ccc", "name": "John", "end_users": 1, "devices": [device_id], "description": "aaa", "start_time": "2020-11-01T02:00:00+00:00", "end_time": "2020-12-01T02:00:00+00:00" @@ -342,6 +366,28 @@ def test_deallocate(user: UserClient): assert res['type'] == 'ValidationError' +@pytest.mark.mvp +@pytest.mark.usefixtures(conftest.app_context.__name__) +def test_deallocate_bad_dates(user: UserClient): + """ Tests deallocate with bad date of start_time """ + snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) + device_id = snapshot['device']['id'] + delta = timedelta(days=30) + future = datetime.now() + delta + post_deallocate = {"start_time": future, + "devices": [device_id] + } + post_allocate = {"devices": [device_id], "description": "aaa", + "start_time": "2020-11-01T02:00:00+00:00" + } + + import pdb; pdb.set_trace() + user.post(res=models.Allocate, data=post_allocate) + res, _ = user.post(res=models.Deallocate, data=post_deallocate, status=400) + assert res['code'] == 422 + assert res['type'] == 'ValidationError' + + @pytest.mark.mvp @pytest.mark.parametrize('action_model_state', (pytest.param(ams, id=ams[0].__name__)