Exemplo n.º 1
0
def test_patch_set_value(config, mongo):
    ''' patch and set new data '''
    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('exit_request.2018-03-20.xml', 'requester')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type': 'execution',
        'id': execution.id,
        'state': Xml.load(config, 'exit_request').get_state(),
        'values': [
            {
                '_type': 'fgroup',
                'ref': '_execution',
                'forms': [{
                    'ref': '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # requester fills the form
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [
            Form.state_json('code_form', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'kadabra',
                    'value_caption': 'kadabra',
                    'name': 'code',
                },
            ]),
            Form.state_json('exit_form', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'want to pee',
                    'value_caption': 'want to pee',
                    'name': 'reason',
                },
            ]),
        ],
    })
    ptr = next(execution.pointers.q().filter(status='ongoing'))
    assert ptr.node_id == 'manager'

    # manager says yes
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('auth_form', [
            {
                '_type': 'field',
                'state': 'valid',
                'value': 'yes',
                'value_caption': 'yes',
                'name': 'auth',
            },
        ])],
    })
    security_ptr = next(execution.pointers.q().filter(status='ongoing'))
    assert security_ptr.node_id == 'security'

    # patch request happens
    handler.patch({
        'command': 'patch',
        'execution_id': execution.id,
        'user_identifier': user.identifier,
        'comment': 'pee is not a valid reason',
        'inputs': [
            {
                'ref': 'requester.juan.1:exit_form.reason',
                'value': 'am hungry',
                'value_caption': 'am hungry',
                'state': 'valid',
            },
            {
                'ref': 'requester.juan.0:code_form.code',
                'value': 'alakazam',
                'value_caption': 'alakazam',
                'state': 'valid',
            },
        ],
    })
    ptr = next(execution.pointers.q().filter(status='ongoing'))

    # pointer is in the manager's node
    assert ptr.node_id == 'manager'

    # nodes with pointers are marked as unfilled or invalid in execution state
    exc_state = mongo[config['EXECUTION_COLLECTION']].find_one({
        'id': execution.id,
    })

    # values sent are set
    actor = exc_state['state']['items']['requester']['actors']['items']['juan']

    _input_0 = actor['forms'][0]['inputs']['items']['code']

    assert _input_0['value'] == 'alakazam'
    assert _input_0['value_caption'] == 'alakazam'

    _input_1 = actor['forms'][1]['inputs']['items']['reason']

    assert _input_1['value'] == 'am hungry'
    assert _input_1['value_caption'] == 'am hungry'

    execution = mongo[config["EXECUTION_COLLECTION"]].find_one({
        'id': execution.id,
    })

    values = execution.pop('values')

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'auth_form': [{}],
        'code_form': [{
            'code': 'alakazam',
            'get_code_display': 'alakazam',
        }],
        'exit_form': [{
            'reason': 'am hungry',
            'get_reason_display': 'am hungry',
        }],
    }

    assert {
        k: list(v.all()) for k, v in eval_context.items()
    } == expected_context

    expected_actor_map = {
        '_execution': [
            {
                'name': {
                    'actor': '__system__'
                },
                'description': {
                    'actor': '__system__'
                },
            }
        ],
        'auth_form': [{}],
        'code_form': [
            {
                'code': {
                    'actor': 'juan'
                }
            }
        ],
        'exit_form': [
            {
                'reason': {
                    'actor': 'juan'
                },
            }
        ],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map
Exemplo n.º 2
0
def test_patch_set_value_multiple(config, mongo):
    ''' patch and set new data (multiple)'''
    handler = Handler(config)
    user = make_user('kysxd', 'KYSXD')
    ptr = make_pointer('gift-request.2020-04-05.xml', 'solicitud')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type': 'execution',
        'id': execution.id,
        'state': Xml.load(config, 'gift-request').get_state(),
        'values': [
            {
                '_type': 'fgroup',
                'ref': '_execution',
                'forms': [{
                    'ref': '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # requester fills the form
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [
            Form.state_json('viaticos', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'yes',
                    'value_caption': 'Si',
                    'name': 'galletas',
                },
            ]),
            Form.state_json('condicionales', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'bueno',
                    'value_caption': 'Si',
                    'name': 'comportamiento',
                },
            ]),
            Form.state_json('regalos', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'Max Iron',
                    'value_caption': 'Max Iron',
                    'name': 'regalo',
                },
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 350.0,
                    'value_caption': 350.0,
                    'name': 'costo',
                },
            ]),
            Form.state_json('regalos', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'Mega boy',
                    'value_caption': 'Mega boy',
                    'name': 'regalo',
                },
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 120.0,
                    'value_caption': 120.0,
                    'name': 'costo',
                },
            ]),
            Form.state_json('regalos', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'Brobocop',
                    'value_caption': 'Brobocop',
                    'name': 'regalo',
                },
            ]),
        ],
    })
    ptr = next(execution.pointers.q().filter(status='ongoing'))
    assert ptr.node_id == 'if_malo'

    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('if_malo', [
            {
                'name': 'condition',
                'state': 'valid',
                'type': 'bool',
                'value': False,
                'value_caption': 'False',
            },
        ])],
    })
    auth_ptr = next(execution.pointers.q().filter(status='ongoing'))
    assert auth_ptr.node_id == 'preparacion'

    # patch request happens
    handler.patch({
        'command': 'patch',
        'execution_id': execution.id,
        'user_identifier': user.identifier,
        'comment': 'Informacion equivocada',
        'inputs': [
            {
                'ref': 'solicitud.kysxd.3:regalos.regalo',
                'value': 'Mega bro',
                'value_caption': 'Mega bro',
            },
            {
                'ref': 'solicitud.kysxd.2:regalos.regalo',
                'value': 'Action bro',
                'value_caption': 'Action bro',
            },
            {
                'ref': 'solicitud.kysxd.2:regalos.costo',
                'value': 10.0,
                'value_caption': 10.0,
            },
        ],
    })
    ptr = next(execution.pointers.q().filter(status='ongoing'))

    assert ptr.node_id == 'if_malo'

    # nodes with pointers are marked as unfilled or invalid in execution state
    e_state = mongo[config['EXECUTION_COLLECTION']].find_one({
        'id': execution.id,
    })

    # values sent are set
    actor = e_state['state']['items']['solicitud']['actors']['items']['kysxd']

    # sanity check for the non-multiple forms
    _form = actor['forms'][0]
    _input = _form['inputs']['items']['galletas']
    assert _input['value'] == 'yes'
    assert _input['value_caption'] == 'Si'

    _form = actor['forms'][1]
    _input = _form['inputs']['items']['comportamiento']
    assert _input['value'] == 'bueno'
    assert _input['value_caption'] == 'Si'

    # check multiforms
    # first
    _form = actor['forms'][2]
    _input = _form['inputs']['items']['regalo']
    assert _input['value'] == 'Action bro'
    assert _input['value_caption'] == 'Action bro'

    _form = actor['forms'][2]
    _input = _form['inputs']['items']['costo']
    assert _input['value'] == 10.0
    assert _input['value_caption'] == 10.0

    # second
    _form = actor['forms'][3]
    _input = _form['inputs']['items']['regalo']
    assert _input['value'] == 'Mega bro'
    assert _input['value_caption'] == 'Mega bro'

    _form = actor['forms'][3]
    _input = _form['inputs']['items']['costo']
    assert _input['value'] == 120.0
    assert _input['value_caption'] == 120.0

    # third
    _form = actor['forms'][4]
    _input = _form['inputs']['items']['regalo']
    assert _input['value'] == 'Brobocop'
    assert _input['value_caption'] == 'Brobocop'

    # unexistant key doesn't update
    assert 'costo' not in _form['inputs']['items']

    values = e_state.pop('values')

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        "_env": [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'viaticos': [{
            'galletas': 'yes',
            'get_galletas_display': 'Si',
        }],
        'condicionales': [{
            'comportamiento': 'bueno',
            'get_comportamiento_display': 'Si',
        }],
        'if_malo': [{
            'condition': False,
            'get_condition_display': 'False',
        }],
        'regalos': [
            {
                'regalo': 'Action bro',
                'get_regalo_display': 'Action bro',
                'costo': 10.0,
                'get_costo_display': 10.0,
            },
            {
                'regalo': 'Mega bro',
                'get_regalo_display': 'Mega bro',
                'costo': 120.0,
                'get_costo_display': 120.0,
            },
            {
                'regalo': 'Brobocop',
                'get_regalo_display': 'Brobocop',
            },
        ],
    }

    assert {
        k: list(v.all()) for k, v in eval_context.items()
    } == expected_context

    expected_actor_map = {
        '_execution': [
            {
                'name': {
                    'actor': '__system__',
                },
                'description': {
                    'actor': '__system__',
                },
            }
        ],
        'viaticos': [
            {
                'galletas': {
                    'actor': 'kysxd',
                }
            }
        ],
        'condicionales': [
            {
                'comportamiento': {
                    'actor': 'kysxd'
                }
            }
        ],
        'if_malo': [
            {
                'condition': {
                    'actor': 'kysxd'
                },
            }
        ],
        'regalos': [
            {
                'regalo': {
                    'actor': 'kysxd'
                },
                'costo': {
                    'actor': 'kysxd'
                },
            },
            {
                'regalo': {
                    'actor': 'kysxd'
                },
                'costo': {
                    'actor': 'kysxd'
                },
            },
            {
                'regalo': {
                    'actor': 'kysxd'
                },
            }
        ],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map
Exemplo n.º 3
0
def test_reject(config, mongo):
    ''' tests that a rejection moves the pointer to a backward position '''
    # test setup
    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('validation.2018-05-09.xml', 'approval_node')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["POINTER_COLLECTION"]].insert_one({
        'id': ptr.id,
        'started_at': datetime(2018, 4, 1, 21, 45),
        'finished_at': None,
        'execution': {
            'id': execution.id,
        },
        'node': {
            'id': 'approval_node',
        },
        'actors': {
            '_type': ':map',
            'items': {},
        },
        'actor_list': [],
    })

    state = Xml.load(config, 'validation.2018-05-09').get_state()

    state['items']['start_node']['state'] = 'valid'
    state['items']['start_node']['actors']['items']['juan'] = {
        '_type': 'actor',
        'state': 'valid',
        'user': {
            '_type': 'user',
            'identifier': 'juan',
            'fullname': 'Juan',
            'email': None,
        },
        'forms': [Form.state_json('work', [
            {
                'name': 'task',
                '_type': 'field',
                'state': 'valid',
                'value': '2',
            },
        ])],
    }

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type': 'execution',
        'id': execution.id,
        'state': state,
        'values': [
            {
                '_type': 'fgroup',
                'ref': '_execution',
                'forms': [{
                    'ref': '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
            {
                '_type': 'fgroup',
                'ref': 'work',
                'forms': [{
                    'ref': 'work',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'task',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': 'juan',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # will teardown the approval node
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('approval_node', [
            {
                'name': 'response',
                'value': 'reject',
                'value_caption': 'reject',
                'state': 'valid',
            },
            {
                'name': 'comment',
                'value': 'I do not like it',
                'value_caption': 'I do not like it',
                'state': 'valid',
            },
            {
                'name': 'inputs',
                'value': [{
                    'ref': 'start_node.juan.0:work.task',
                }],
                'value_caption': '',
                'state': 'valid',
            },
        ])],
    })

    # assertions
    assert Pointer.get(ptr.id).status == 'finished'

    new_ptr = next(Pointer.q().filter(status='ongoing'))
    assert new_ptr.node_id == 'start_node'

    assert new_ptr in user.tasks

    # data is invalidated
    state = next(mongo[config["EXECUTION_COLLECTION"]].find({
        'id': execution.id,
    }))

    del state['_id']

    values = state.pop('values')

    assert state == {
        '_type': 'execution',
        'id': execution.id,
        'name': '',
        'description': '',
        'state': {
            '_type': ':sorted_map',
            'items': {
                'start_node': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'start_node',
                    'state': 'ongoing',
                    'comment': 'I do not like it',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('work', [
                                    {
                                        'name': 'task',
                                        '_type': 'field',
                                        'state': 'invalid',
                                        'value': '2',
                                    },
                                ], state='invalid')],
                                'state': 'invalid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Primer paso',
                    'description': 'Resolver una tarea',
                },

                'approval_node': {
                    '_type': 'node',
                    'type': 'validation',
                    'id': 'approval_node',
                    'state': 'invalid',
                    'comment': 'I do not like it',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('approval_node', [
                                    {
                                        'name': 'response',
                                        'state': 'invalid',
                                        'value': 'reject',
                                        'value_caption': 'reject',
                                    },
                                    {
                                        'name': 'comment',
                                        'value': 'I do not like it',
                                        'value_caption': 'I do not like it',
                                        'state': 'valid',
                                    },
                                    {
                                        'name': 'inputs',
                                        'value': [{
                                            'ref': 'start_node.'
                                                   'juan.0:work.task',
                                        }],
                                        'value_caption': '',
                                        'state': 'valid',
                                    },
                                ], state='invalid')],
                                'state': 'invalid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Aprobación gerente reserva',
                    'description': 'aprobar reserva',
                },

                'final_node': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'final_node',
                    'state': 'unfilled',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {},
                    },
                    'milestone': False,
                    'name': '',
                    'description': '',
                },
            },
            'item_order': ['start_node', 'approval_node', 'final_node'],
        },
        'actors': {
            'approval_node': 'juan',
        },
    }

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'work': [{}],
        'approval_node': [{
            'comment': 'I do not like it',
            'get_comment_display': 'I do not like it',
            'response': 'reject',
            'get_response_display': 'reject',
            'inputs': [{'ref': 'start_node.juan.0:work.task'}],
            'get_inputs_display': [{'ref': 'start_node.juan.0:work.task'}],
        }],
    }

    assert {
        k: list(v.all()) for k, v in eval_context.items()
    } == expected_context

    expected_actor_map = {
        '_execution': [
            {
                'name': {
                    'actor': '__system__',
                },
                'description': {
                    'actor': '__system__',
                },
            }
        ],
        'work': [{}],
        'approval_node': [
            {
                'comment': {
                    'actor': 'juan',
                },
                'response': {
                    'actor': 'juan',
                },
                'inputs': {
                    'actor': 'juan',
                },
            }
        ],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map

    # mongo has the data
    reg = next(mongo[config["POINTER_COLLECTION"]].find())

    assert reg['started_at'] == datetime(2018, 4, 1, 21, 45)
    assert (reg['finished_at'] - datetime.now()).total_seconds() < 2
    assert reg['execution']['id'] == new_ptr.execution.get().id
    assert reg['node']['id'] == 'approval_node'
    assert reg['actor_list'] == [
        {
            'form': 'approval_node',
            'actor': {
                '_type': 'user',
                'fullname': 'Juan',
                'identifier': 'juan',
                'email': None,
            },
        },
    ]
    assert reg['actors'] == {
        '_type': ':map',
        'items': {
            'juan': {
                '_type': 'actor',
                'forms': [Form.state_json('approval_node', [
                    {
                        'name': 'response',
                        'value': 'reject',
                        'value_caption': 'reject',
                        'state': 'valid',
                    },
                    {
                        'name': 'comment',
                        'value': 'I do not like it',
                        'value_caption': 'I do not like it',
                        'state': 'valid',
                    },
                    {
                        'name': 'inputs',
                        'value': [{
                            'ref': 'start_node.juan.0:work.task',
                        }],
                        'value_caption': '',
                        'state': 'valid',
                    },
                ])],
                'state': 'valid',
                'user': {
                    '_type': 'user',
                    'identifier': 'juan',
                    'fullname': 'Juan',
                    'email': None,
                },
            },
        },
    }
Exemplo n.º 4
0
def test_reject_with_dependencies(config, mongo):
    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('validation-reloaded.2018-05-17.xml', 'node1')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type': 'execution',
        'id': execution.id,
        'state': Xml.load(config, 'validation-reloaded').get_state(),
        'values': [
            {
                '_type': 'fgroup',
                'ref': '_execution',
                'forms': [{
                    'ref': '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # first call to node1
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form1', [
            {
                'name': 'task',
                'value': '1',
                'value_caption': '1',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node2'

    # first call to node2
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form2', [
            {
                'name': 'task',
                'value': '1',
                'value_caption': '1',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node3'

    # first call to node3
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form3', [
            {
                'name': 'task',
                'value': '1',
                'value_caption': '1',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node4'

    # first call to validation
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('node4', [
            {
                'name': 'response',
                'value': 'reject',
                'value_caption': 'reject',
                'state': 'valid',
            },
            {
                'name': 'comment',
                'value': 'I do not like it',
                'value_caption': 'I do not like it',
                'state': 'valid',
            },
            {
                'name': 'inputs',
                'value': [{
                    'ref': 'node1.juan.0:form1.task',
                }],
                'value_caption': '',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node1'

    # second call to node1
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form1', [
            {
                'name': 'task',
                'value': '2',
                'value_caption': '2',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node2'

    # second call to node2
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form2', [
            {
                'name': 'task',
                'value': '2',
                'value_caption': '2',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node4'

    # second call to validation
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('node4', [
            {
                'name': 'response',
                'value': 'accept',
                'value_caption': 'accept',
                'state': 'valid',
            },
            {
                'name': 'comment',
                'value': 'I like it',
                'value_caption': 'I like it',
                'state': 'valid',
            },
            {
                'name': 'inputs',
                'value': None,
                'value_caption': 'None',
                'state': 'valid',
            },
        ])],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id == 'node5'

    # first call to last node
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('form5', [
            {
                'name': 'task',
                'value': '1',
                'value_caption': '1',
                'state': 'valid',
            },
        ])],
    })
    assert list(Pointer.q().filter(status='ongoing')) == []

    # state is coherent
    state = next(mongo[config["EXECUTION_COLLECTION"]].find({
        'id': execution.id,
    }))

    del state['_id']
    del state['finished_at']

    values = state.pop('values')

    assert state == {
        '_type': 'execution',
        'id': execution.id,
        'name': '',
        'description': '',
        'state': {
            '_type': ':sorted_map',
            'items': {
                'node1': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'node1',
                    'state': 'valid',
                    'comment': 'I do not like it',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('form1', [
                                    {
                                        'name': 'task',
                                        'value': '2',
                                        'value_caption': '2',
                                        'state': 'valid',
                                    },
                                ])],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Primer paso',
                    'description': 'información original',
                },

                'node2': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'node2',
                    'state': 'valid',
                    'comment': 'I do not like it',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('form2', [
                                    {
                                        'name': 'task',
                                        'value': '2',
                                        'value_caption': '2',
                                        'state': 'valid',
                                    },
                                ])],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Segundo paso',
                    'description': 'depender de la info',
                },

                'node3': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'node3',
                    'state': 'valid',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('form3', [
                                    {
                                        'name': 'task',
                                        'value': '1',
                                        'value_caption': '1',
                                        'state': 'valid',
                                    },
                                ])],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Tercer paso',
                    'description': 'no depender de nada',
                },

                'node4': {
                    '_type': 'node',
                    'type': 'validation',
                    'id': 'node4',
                    'state': 'valid',
                    'comment': 'I do not like it',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('node4', [
                                    {
                                        'name': 'response',
                                        'value': 'accept',
                                        'value_caption': 'accept',
                                        'state': 'valid',
                                    },
                                    {
                                        'name': 'comment',
                                        'value': 'I like it',
                                        'value_caption': 'I like it',
                                        'state': 'valid',
                                    },
                                    {
                                        'name': 'inputs',
                                        'value': None,
                                        'value_caption': 'None',
                                        'state': 'valid',
                                    },
                                ])],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Cuarto paso',
                    'description': 'validar',
                },

                'node5': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'node5',
                    'state': 'valid',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [Form.state_json('form5', [
                                    {
                                        'name': 'task',
                                        'value': '1',
                                        'value_caption': '1',
                                        'state': 'valid',
                                    },
                                ])],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Quinto paso',
                    'description': 'terminar',
                },
            },
            'item_order': ['node1', 'node2', 'node3', 'node4', 'node5'],
        },
        'status': 'finished',
        'actors': {
            'node1': 'juan',
            'node2': 'juan',
            'node3': 'juan',
            'node4': 'juan',
            'node5': 'juan',
        },
    }

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'node4': [{
            'comment': 'I like it',
            'get_comment_display': 'I like it',
            'inputs': None,
            'get_inputs_display': 'None',
            'response': 'accept',
            'get_response_display': 'accept',
        }],
        'form1': [{
            'task': '2',
            'get_task_display': '2',
        }],
        'form2': [{
            'task': '2',
            'get_task_display': '2',
        }],
        'form3': [{
            'task': '1',
            'get_task_display': '1',
        }],
        'form5': [{
            'task': '1',
            'get_task_display': '1',
        }],
    }

    assert {
        k: list(v.all()) for k, v in eval_context.items()
    } == expected_context

    expected_actor_map = {
        '_execution': [
            {
                'name': {
                    'actor': '__system__',
                },
                'description': {
                    'actor': '__system__',
                },
            }
        ],
        'node4': [
            {
                'comment': {
                    'actor': 'juan',
                },
                'response': {
                    'actor': 'juan',
                },
                'inputs': {
                    'actor': 'juan',
                },
            }
        ],
        'form1': [
            {
                'task': {
                    'actor': 'juan',
                },
            },
        ],
        'form2': [
            {
                'task': {
                    'actor': 'juan',
                },
            },
        ],
        'form3': [
            {
                'task': {
                    'actor': 'juan',
                },
            },
        ],
        'form5': [
            {
                'task': {
                    'actor': 'juan',
                },
            },
        ],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map
Exemplo n.º 5
0
def test_approve(config, mongo):
    ''' tests that a validation node can go forward on approval '''
    # test setup
    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('validation.2018-05-09.xml', 'approval_node')

    mongo[config["POINTER_COLLECTION"]].insert_one({
        'id': ptr.id,
        'started_at': datetime(2018, 4, 1, 21, 45),
        'finished_at': None,
        'execution': {
            'id': ptr.execution.get().id,
        },
        'node': {
            'id': 'approval_node',
        },
        'actors': {
            '_type': ':map',
            'items': {},
        },
        'actor_list': [],
    })

    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type': 'execution',
        'id': execution.id,
        'state': Xml.load(config, 'validation.2018-05-09').get_state(),
        'actors': {
            'start_node': 'juan',
        },
        'values': [
            {
                '_type': 'fgroup',
                'ref': '_execution',
                'forms': [{
                    'ref': '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
            {
                '_type': 'fgroup',
                'ref': 'work',
                'forms': [{
                    'ref': 'work',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'task',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': 'juan',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # thing to test
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [Form.state_json('approval_node', [
            {
                'name': 'response',
                'value': 'accept',
                'value_caption': 'accept',
                'state': 'valid',
            },
            {
                'name': 'comment',
                'value': 'I like it',
                'value_caption': 'I like it',
                'state': 'valid',
            },
            {
                'name': 'inputs',
                'value': [{
                    'ref': 'start_node.juan.0.task',
                }],
                'value_caption': '',
                'state': 'valid',
            },
        ])],
    })

    # assertions
    assert Pointer.get(ptr.id).status == 'finished'

    new_ptr = next(Pointer.q().filter(status='ongoing'))
    assert new_ptr.node_id == 'final_node'

    reg = next(mongo[config["POINTER_COLLECTION"]].find())

    assert reg['started_at'] == datetime(2018, 4, 1, 21, 45)
    assert_near_date(reg['finished_at'])
    assert reg['execution']['id'] == new_ptr.execution.get().id
    assert reg['node']['id'] == 'approval_node'
    assert reg['actor_list'] == [
        {
            'form': 'approval_node',
            'actor': {
                '_type': 'user',
                'fullname': 'Juan',
                'identifier': 'juan',
                'email': None,
            },
        },
    ]
    assert reg['actors'] == {
        '_type': ':map',
        'items': {
            'juan': {
                '_type': 'actor',
                'state': 'valid',
                'user': {
                    '_type': 'user',
                    'identifier': 'juan',
                    'fullname': 'Juan',
                    'email': None,
                },
                'forms': [Form.state_json('approval_node', [
                    {
                        'name': 'response',
                        'name': 'response',
                        'value': 'accept',
                        'value_caption': 'accept',
                        'state': 'valid',
                    },
                    {
                        'name': 'comment',
                        'name': 'comment',
                        'value': 'I like it',
                        'value_caption': 'I like it',
                        'state': 'valid',
                    },
                    {
                        'name': 'inputs',
                        'name': 'inputs',
                        'value': [{
                            'ref': 'start_node.juan.0.task',
                        }],
                        'value_caption': '',
                        'state': 'valid',
                    },
                ])],
            },
        },
    }

    # data is invalidated
    state = next(mongo[config["EXECUTION_COLLECTION"]].find({
        'id': ptr.execution.get().id,
    }))

    del state['_id']

    values = state.pop('values')

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'work': [{
            'task': '',
            'get_task_display': '',
        }],
        'approval_node': [{
            'comment': 'I like it',
            'get_comment_display': 'I like it',
            'response': 'accept',
            'get_response_display': 'accept',
            'inputs': [{'ref': 'start_node.juan.0.task'}],
            'get_inputs_display': [{'ref': 'start_node.juan.0.task'}],
        }],
    }

    assert {
        k: list(v.all()) for k, v in eval_context.items()
    } == expected_context

    expected_actor_map = {
        '_execution': [
            {
                'name': {
                    'actor': '__system__',
                },
                'description': {
                    'actor': '__system__',
                },
            }
        ],
        'work': [
            {
                'task': {
                    'actor': 'juan',
                },
            },
        ],
        'approval_node': [
            {
                'comment': {
                    'actor': 'juan',
                },
                'response': {
                    'actor': 'juan',
                },
                'inputs': {
                    'actor': 'juan',
                },
            }
        ],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map
Exemplo n.º 6
0
def test_store_data_from_response(config, mocker, mongo):
    mocker.patch('cacahuate.tasks.handle.delay')

    expected_name = random_string()
    expected_age_1 = randint(0, 100)
    expected_age_2 = randint(0, 100)

    request_response = {
        'params': {
            'name': expected_name,
        },
        'items': [
            [
                {
                    'age': expected_age_1,
                },
                {
                    'age': expected_age_2,
                },
            ],
        ],
    }
    request_response_s = json.dumps(request_response)

    class ResponseMock:
        status_code = 200
        text = request_response_s

        def json(self):
            return request_response

    mock = MagicMock(return_value=ResponseMock())

    mocker.patch('requests.request', new=mock)

    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('request-captures.2019-08-08.xml', 'start_node')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()
    value = random_string()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type':
        'execution',
        'id':
        execution.id,
        'state':
        Xml.load(config, 'request-captures').get_state(),
        'values': [
            {
                '_type':
                'fgroup',
                'ref':
                '_execution',
                'forms': [{
                    'ref':
                    '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'label': 'name',
                            'hidden': False,
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'label': 'description',
                            'hidden': False,
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # teardown of first node and wakeup of request node
    handler.step({
        'command':
        'step',
        'pointer_id':
        ptr.id,
        'user_identifier':
        user.identifier,
        'input': [
            Form.state_json('request', [
                {
                    'name': 'data',
                    'value': value,
                    'value_caption': value,
                    'state': 'valid',
                },
            ])
        ],
    })
    assert Pointer.get(ptr.id).status == 'finished'
    ptr = next(execution.pointers.q().filter(status='ongoing'))
    assert ptr.node_id == 'request_node'

    # assert requests is called
    requests.request.assert_called_once()
    args, kwargs = requests.request.call_args

    assert args[0] == 'GET'
    assert args[1] == 'http://localhost/'

    assert kwargs['data'] == ''
    assert kwargs['headers'] == {
        'content-type': 'application/json',
    }

    # aditional rabbit call for new process
    args = handle.delay.call_args[0][0]

    expected_inputs = [
        Form.state_json('request_node', [
            {
                'name': 'status_code',
                'state': 'valid',
                'type': 'int',
                'value': 200,
                'value_caption': '200',
                'hidden': False,
                'label': 'Status Code',
            },
            {
                'name': 'raw_response',
                'state': 'valid',
                'type': 'text',
                'value': request_response_s,
                'value_caption': request_response_s,
                'hidden': False,
                'label': 'Response',
            },
        ]),
        Form.state_json('capture1', [
            {
                'name': 'name',
                'state': 'valid',
                'type': 'text',
                'value': expected_name,
                'value_caption': expected_name,
                'hidden': False,
                'label': 'Nombre',
            },
        ]),
        Form.state_json('capture2', [
            {
                'name': 'age',
                'state': 'valid',
                'type': 'int',
                'value': expected_age_1,
                'value_caption': str(expected_age_1),
                'hidden': False,
                'label': 'Edad',
            },
        ]),
        Form.state_json('capture2', [
            {
                'name': 'age',
                'state': 'valid',
                'type': 'int',
                'value': expected_age_2,
                'value_caption': str(expected_age_2),
                'hidden': False,
                'label': 'Edad',
            },
        ]),
    ]

    assert json.loads(args) == {
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': '__system__',
        'input': expected_inputs,
    }

    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': '__system__',
        'input': expected_inputs,
    })

    state = mongo[config["EXECUTION_COLLECTION"]].find_one({
        'id': execution.id,
    })

    assert state['state']['items']['request_node'] == {
        '_type': 'node',
        'type': 'request',
        'id': 'request_node',
        'comment': '',
        'state': 'valid',
        'actors': {
            '_type': ':map',
            'items': {
                '__system__': {
                    '_type': 'actor',
                    'state': 'valid',
                    'user': {
                        '_type': 'user',
                        'fullname': 'System',
                        'identifier': '__system__',
                        'email': None,
                    },
                    'forms': expected_inputs,
                },
            },
        },
        'milestone': False,
        'name': 'Request request_node',
        'description': 'Request request_node',
    }

    values = state.pop('values')

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
        'capture1': [{
            'name': expected_name,
            'get_name_display': expected_name,
        }],
        'capture2': [
            {
                'age': expected_age_1,
                'get_age_display': str(expected_age_1),
            },
            {
                'age': expected_age_2,
                'get_age_display': str(expected_age_2),
            },
        ],
        'request': [{
            'data': value,
            'get_data_display': value,
        }],
        'request_node': [{
            'raw_response': request_response_s,
            'get_raw_response_display': request_response_s,
            'status_code': 200,
            'get_status_code_display': '200',
        }],
    }

    assert {k: list(v.all())
            for k, v in eval_context.items()} == expected_context

    expected_actor_map = {
        '_execution': [{
            'name': {
                'actor': '__system__',
            },
            'description': {
                'actor': '__system__',
            },
        }],
        'capture1': [{
            'name': {
                'actor': '__system__',
            },
        }],
        'capture2': [{
            'age': {
                'actor': '__system__',
            },
        }, {
            'age': {
                'actor': '__system__',
            },
        }],
        'request': [{
            'data': {
                'actor': 'juan',
            },
        }],
        'request_node': [{
            'raw_response': {
                'actor': '__system__',
            },
            'status_code': {
                'actor': '__system__',
            },
        }],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')
    assert eval_actor_map == expected_actor_map
Exemplo n.º 7
0
def test_make_actor_map():
    execution = {
        'values': [{
            'ref':
            'form1',
            'forms': [
                {
                    'fields': [{
                        'name': 'input1',
                        'state': 'valid',
                        'actor': {
                            'identifier': 'juan',
                        },
                        'set_at': '2020-10-01T00:00:00',
                    }, {
                        'name': 'input2',
                        'state': 'invalid',
                        'actor': {
                            'identifier': 'juan',
                        },
                        'set_at': '2020-10-01T00:00:00',
                    }],
                },
                {
                    'fields': [
                        {
                            'name': 'input1',
                            'state': 'valid',
                            'actor': {
                                'identifier': 'pepe',
                            },
                            'set_at': '2020-10-01T00:00:00',
                        },
                        {
                            'name': 'input2',
                            'state': 'valid',
                            'actor': {
                                'identifier': 'pepe',
                            },
                            'set_at': '2020-10-01T00:00:00',
                        },
                    ],
                },
            ],
        }],
    }

    actor_map = make_actor_map(execution)

    assert actor_map == {
        'form1': [
            {
                'input1': {
                    'actor': 'juan',
                    'set_at': '2020-10-01T00:00:00',
                },
            },
            {
                'input1': {
                    'actor': 'pepe',
                    'set_at': '2020-10-01T00:00:00',
                },
                'input2': {
                    'actor': 'pepe',
                    'set_at': '2020-10-01T00:00:00',
                },
            },
        ],
    }
Exemplo n.º 8
0
def test_teardown(config, mongo):
    ''' second and last stage of a node's lifecycle '''
    # test setup
    handler = Handler(config)

    p_0 = make_pointer('simple.2018-02-19.xml', 'mid_node')
    execution = p_0.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    User(identifier='juan').save()
    manager = User(identifier='manager').save()
    manager2 = User(identifier='manager2').save()

    assert manager not in execution.actors.all()
    assert execution not in manager.activities.all()

    manager.tasks.set([p_0])
    manager2.tasks.set([p_0])

    state = Xml.load(config, execution.process_name).get_state()
    state['items']['start_node']['state'] = 'valid'

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type':
        'execution',
        'id':
        execution.id,
        'state':
        state,
        'values': [
            {
                '_type':
                'fgroup',
                'ref':
                '_execution',
                'forms': [{
                    'ref':
                    '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
        'actors': {
            'start_node': 'juan',
        },
    })

    mongo[config["POINTER_COLLECTION"]].insert_one({
        'id':
        p_0.id,
        'started_at':
        datetime(2018, 4, 1, 21, 45),
        'finished_at':
        None,
        'execution': {
            'id': execution.id,
        },
        'node': {
            'id': p_0.node_id,
        },
        'actors': {
            '_type': ':map',
            'items': {},
        },
        'actor_list': [],
    })

    # will teardown mid_node
    handler.step({
        'command':
        'step',
        'pointer_id':
        p_0.id,
        'user_identifier':
        manager.identifier,
        'input': [
            Form.state_json('mid_form', [
                {
                    '_type': 'field',
                    'state': 'valid',
                    'value': 'yes',
                    'value_caption': 'yes',
                    'name': 'data',
                },
            ])
        ],
    })

    # assertions
    assert Pointer.get(p_0.id).status == 'finished'
    ptrs = list(Pointer.q().filter(status='ongoing'))
    assert len(ptrs) == 1
    assert ptrs[0].node_id == 'final_node'

    # mongo has a registry
    reg = next(mongo[config["POINTER_COLLECTION"]].find())

    assert reg['started_at'] == datetime(2018, 4, 1, 21, 45)
    assert_near_date(reg['finished_at'])
    assert reg['execution']['id'] == execution.id
    assert reg['node']['id'] == p_0.node_id
    assert reg['actors'] == {
        '_type': ':map',
        'items': {
            'manager': {
                '_type':
                'actor',
                'state':
                'valid',
                'user': {
                    '_type': 'user',
                    'identifier': 'manager',
                    'fullname': None,
                    'email': None,
                },
                'forms': [
                    Form.state_json('mid_form', [
                        {
                            '_type': 'field',
                            'state': 'valid',
                            'value': 'yes',
                            'value_caption': 'yes',
                            'name': 'data',
                        },
                    ])
                ],
            },
        },
    }
    assert reg['actor_list'] == [
        {
            'form': 'mid_form',
            'actor': {
                '_type': 'user',
                'fullname': None,
                'identifier': 'manager',
                'email': None,
            },
        },
    ]

    # tasks where deleted from user
    assert list(manager.tasks.q().filter(status='ongoing')) == []
    assert list(manager2.tasks.q().filter(status='ongoing')) == []

    # state
    reg = next(mongo[config["EXECUTION_COLLECTION"]].find())

    assert reg['state'] == {
        '_type': ':sorted_map',
        'items': {
            'start_node': {
                '_type': 'node',
                'type': 'action',
                'id': 'start_node',
                'state': 'valid',
                'comment': '',
                'actors': {
                    '_type': ':map',
                    'items': {},
                },
                'milestone': False,
                'name': 'Primer paso',
                'description': 'Resolver una tarea',
            },
            'mid_node': {
                '_type': 'node',
                'type': 'action',
                'id': 'mid_node',
                'state': 'valid',
                'comment': '',
                'actors': {
                    '_type': ':map',
                    'items': {
                        'manager': {
                            '_type':
                            'actor',
                            'state':
                            'valid',
                            'user': {
                                '_type': 'user',
                                'identifier': 'manager',
                                'fullname': None,
                                'email': None,
                            },
                            'forms': [
                                Form.state_json('mid_form', [
                                    {
                                        '_type': 'field',
                                        'state': 'valid',
                                        'value': 'yes',
                                        'value_caption': 'yes',
                                        'name': 'data',
                                    },
                                ])
                            ],
                        },
                    },
                },
                'milestone': False,
                'name': 'Segundo paso',
                'description': 'añadir información',
            },
            'final_node': {
                '_type': 'node',
                'type': 'action',
                'id': 'final_node',
                'state': 'ongoing',
                'comment': '',
                'actors': {
                    '_type': ':map',
                    'items': {},
                },
                'milestone': False,
                'name': '',
                'description': '',
            },
        },
        'item_order': [
            'start_node',
            'mid_node',
            'final_node',
        ],
    }

    values = reg['values']

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'description': '',
            'get_name_display': '',
            'get_description_display': '',
        }],
        'mid_form': [{
            'data': 'yes',
            'get_data_display': 'yes'
        }],
    }

    assert {k: list(v.all())
            for k, v in eval_context.items()} == expected_context

    expected_actor_map = {
        '_execution': [{
            'name': {
                'actor': '__system__',
            },
            'description': {
                'actor': '__system__',
            },
        }],
        'mid_form': [{
            'data': {
                'actor': 'manager',
            },
        }],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')

    assert eval_actor_map == expected_actor_map

    assert reg['actors'] == {
        'start_node': 'juan',
        'mid_node': 'manager',
    }

    assert manager in execution.actors
    assert execution in manager.activities
Exemplo n.º 9
0
def test_exit_interaction(config, mongo, mocker):
    mocker.patch('cacahuate.tasks.handle.delay')

    handler = Handler(config)
    user = make_user('juan', 'Juan')
    ptr = make_pointer('exit.2018-05-03.xml', 'start_node')
    execution = ptr.execution.get()
    execution.started_at = datetime(2018, 4, 1, 21, 45)
    execution.save()

    mongo[config["EXECUTION_COLLECTION"]].insert_one({
        '_type':
        'execution',
        'id':
        execution.id,
        'state':
        Xml.load(config, execution.process_name).get_state(),
        'values': [
            {
                '_type':
                'fgroup',
                'ref':
                '_execution',
                'forms': [{
                    'ref':
                    '_execution',
                    'fields': [
                        {
                            '_type': 'field',
                            'name': 'name',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                        {
                            '_type': 'field',
                            'name': 'description',
                            'value': '',
                            'value_caption': '',
                            'state': 'valid',
                            'actor': {
                                'identifier': '__system__',
                            },
                            'set_at': execution.started_at,
                        },
                    ],
                }],
            },
        ],
    })

    # first node
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': user.identifier,
        'input': [],
    })
    ptr = next(Pointer.q().filter(status='ongoing'))
    assert ptr.node_id

    args = handle.delay.call_args[0][0]

    assert json.loads(args) == {
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': '__system__',
        'input': [],
    }

    # exit node
    handler.step({
        'command': 'step',
        'pointer_id': ptr.id,
        'user_identifier': '__system__',
        'input': [],
    })

    assert list(Pointer.q().filter(status='ongoing')) == []
    assert list(Execution.q().filter(status='ongoing')) == []

    # state is coherent
    state = next(mongo[config["EXECUTION_COLLECTION"]].find({
        'id': execution.id,
    }))

    del state['_id']
    del state['finished_at']

    values = state.pop('values')

    assert state == {
        '_type': 'execution',
        'id': execution.id,
        'name': '',
        'description': '',
        'state': {
            '_type': ':sorted_map',
            'items': {
                'start_node': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'start_node',
                    'state': 'valid',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            'juan': {
                                '_type': 'actor',
                                'forms': [],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': 'juan',
                                    'fullname': 'Juan',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': '',
                    'description': '',
                },
                'exit': {
                    '_type': 'node',
                    'type': 'exit',
                    'id': 'exit',
                    'state': 'valid',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {
                            '__system__': {
                                '_type': 'actor',
                                'forms': [],
                                'state': 'valid',
                                'user': {
                                    '_type': 'user',
                                    'identifier': '__system__',
                                    'fullname': 'System',
                                    'email': None,
                                },
                            },
                        },
                    },
                    'milestone': False,
                    'name': 'Exit exit',
                    'description': 'Exit exit',
                },
                'final_node': {
                    '_type': 'node',
                    'type': 'action',
                    'id': 'final_node',
                    'state': 'unfilled',
                    'comment': '',
                    'actors': {
                        '_type': ':map',
                        'items': {},
                    },
                    'milestone': False,
                    'name': '',
                    'description': '',
                },
            },
            'item_order': ['start_node', 'exit', 'final_node'],
        },
        'status': 'finished',
        'actors': {
            'exit': '__system__',
            'start_node': 'juan',
        },
    }

    eval_context = make_context({'values': values}, {})
    eval_actor_map = make_actor_map({'values': values})

    expected_context = {
        '_env': [{}],
        '_execution': [{
            'name': '',
            'get_name_display': '',
            'description': '',
            'get_description_display': '',
        }],
    }

    assert {k: list(v.all())
            for k, v in eval_context.items()} == expected_context

    expected_actor_map = {
        '_execution': [{
            'name': {
                'actor': '__system__',
            },
            'description': {
                'actor': '__system__',
            },
        }],
    }

    for frms in eval_actor_map.values():
        for frm in frms:
            for fld in frm.values():
                assert fld.pop('set_at')

    assert eval_actor_map == expected_actor_map