def test_interpolated_name(config, client, mongo): juan = make_user('juan', 'Juan') name = 'Computes a name based on a Cow' res = client.post('/v1/execution', headers={**{ 'Content-Type': 'application/json', }, **make_auth(juan)}, data=json.dumps({ 'process_name': 'interpol', 'form_array': [{ 'ref': 'form', 'data': { 'field': 'Cow', }, }], })) # request succeeded assert res.status_code == 201 # execution has name exc = next(Execution.q().filter(status='ongoing')) assert exc.name == name # execution collection has name reg2 = next(mongo[config["EXECUTION_COLLECTION"]].find()) assert reg2['id'] == exc.id assert reg2['name'] == name # history has the name reg = next(mongo[config["POINTER_COLLECTION"]].find()) assert reg['execution']['name'] == name
def test_hidden_input(client, mocker, config, mongo): mocker.patch('cacahuate.tasks.handle.delay') juan = make_user('juan', 'Juan') res = client.post('/v1/execution', headers={ **{ 'Content-Type': 'application/json', }, **make_auth(juan) }, data=json.dumps({ 'process_name': 'input-hidden', 'form_array': [{ 'ref': 'start_form', 'data': { 'data': 'yes', }, }], })) assert res.status_code == 201 exc = next(Execution.q().filter(status='ongoing')) ptr = next(exc.pointers.q().filter(status='ongoing')) handle.delay.assert_called_once() args = handle.delay.call_args[0][0] json_message = { 'command': 'step', 'pointer_id': ptr.id, 'user_identifier': 'juan', 'input': [ Form.state_json('start_form', [ { 'label': 'data', 'type': 'text', 'value': 'yes', 'value_caption': 'yes', 'name': 'data', 'state': 'valid', 'hidden': True, }, ]) ], } assert json.loads(args) == json_message
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
def test_call_handler_delete_process(config, mongo): handler = Handler(config) pointer = make_pointer('simple.2018-02-19.xml', 'requester') execution = pointer.execution.get() body = '{"command":"cancel", "execution_id":"%s", "pointer_id":"%s"}'\ % (execution.id, pointer.id) mongo[config["EXECUTION_COLLECTION"]].insert_one({ 'started_at': datetime(2018, 4, 1, 21, 45), 'finished_at': None, 'status': 'ongoing', 'id': execution.id }) ptr_id_1 = 'RANDOMPOINTERNAME' ptr_id_2 = 'MORERANDOMNAME' ptr_id_3 = 'NOTSORANDOMNAME' mongo[config["POINTER_COLLECTION"]].insert_many([ { 'execution': { 'id': execution.id, }, 'state': 'finished', 'id': ptr_id_1, }, { 'execution': { 'id': execution.id, }, 'state': 'ongoing', 'id': ptr_id_2, }, { 'execution': { 'id': execution.id[::-1], }, 'state': 'ongoing', 'id': ptr_id_3, }, ]) handler(body) reg = next(mongo[config["EXECUTION_COLLECTION"]].find()) assert reg['id'] == execution.id assert reg['status'] == "cancelled" assert_near_date(reg['finished_at']) assert list(Execution.q().filter(status='ongoing')) == [] assert list(Pointer.q().filter(status='ongoing')) == [] assert mongo[config["POINTER_COLLECTION"]].find_one({ 'id': ptr_id_1, })['state'] == 'finished' assert mongo[config["POINTER_COLLECTION"]].find_one({ 'id': ptr_id_2, })['state'] == 'cancelled' assert mongo[config["POINTER_COLLECTION"]].find_one({ 'id': ptr_id_3, })['state'] == 'ongoing'
def test_call_node_render(config, mongo, mocker): mocker.patch('cacahuate.tasks.handle.delay') handler = Handler(config) user = make_user('juan', 'Juan') ptr = make_pointer('call-render.2020-04-24.xml', 'start_node') execution = ptr.execution.get() value = random_string() mongo[config["EXECUTION_COLLECTION"]].insert_one({ '_type': 'execution', 'id': execution.id, 'state': Xml.load(config, execution.process_name).get_state(), }) # teardown of first node and wakeup of call node handler.step({ 'command': 'step', 'pointer_id': ptr.id, 'user_identifier': user.identifier, 'input': [ Form.state_json('start_form', [ { 'name': 'data', '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 == 'call' new_ptr = next(Pointer.q().filter(node_id='start_node', status='ongoing')) # aditional rabbit call for new process args = handle.delay.call_args_list[0][0][0] assert json.loads(args) == { 'command': 'step', 'pointer_id': new_ptr.id, 'user_identifier': '__system__', 'input': [ Form.state_json('start_form', [ { 'label': 'Info', 'name': 'data', 'state': 'valid', 'type': 'text', 'value': value, 'value_caption': value, 'hidden': False, }, ]) ], } # normal rabbit call args = handle.delay.call_args_list[1][0][0] json_res = json.loads(args) # check execution_id exists assert json_res['input'][0]['inputs']['items']['execution'].pop('value') assert json_res['input'][0]['inputs']['items']['execution'].pop( 'value_caption') assert json_res == { 'command': 'step', 'pointer_id': ptr.id, 'user_identifier': '__system__', 'input': [ Form.state_json('call', [ { 'name': 'execution', 'label': 'execution', 'type': 'text', 'hidden': False, 'state': 'valid', }, ]) ], } # mongo log registry created for new process reg = next(mongo[config["POINTER_COLLECTION"]].find({ 'id': new_ptr.id, })) assert reg['node']['id'] == 'start_node' # mongo execution registry created for new process reg = next(mongo[config["EXECUTION_COLLECTION"]].find({ 'id': new_ptr.execution.get().id, })) assert reg['name'] == 'Simplest process ever started with: ' + value # teardown of the call node and end of first execution handler.step({ 'command': 'step', 'pointer_id': ptr.id, 'user_identifier': '__system__', 'input': [], }) # old execution is gone, new is here assert Execution.get(execution.id).status == 'finished' assert Pointer.get(ptr.id).status == 'finished' execution = next(Execution.q().filter(status='ongoing')) assert execution.process_name == 'simple.2018-02-19.xml'