Bug #30942
enchainement d'actions "données de traitement" derrière une action d'édition
0%
Description
cf #30926 pour le cas réel; simplifié le bug serait identifié via :
def test_form_edit_and_backoffice_field_change(pub): create_user(pub) formdef = create_formdef() formdef.fields = [fields.PageField(id='0', label='1st page', type='page'), fields.StringField(id='1', label='string', varname='foo'), fields.PageField(id='2', label='2nd page', type='page') ] formdef.store() formdef.data_class().wipe() Workflow.wipe() workflow = Workflow(name='test') workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow) workflow.backoffice_fields_formdef.fields = [ fields.StringField(id='bo1', label='bo field 1', type='string', varname='plop'), ] st1 = workflow.add_status('Status1', 'st1') setbo = SetBackofficeFieldsWorkflowStatusItem() setbo.parent = st1 setbo.fields = [{'field_id': 'bo1', 'value': '=form_var_foo'}] setbo2 = SetBackofficeFieldsWorkflowStatusItem() setbo2.parent = st1 setbo2.fields = [{'field_id': 'bo1', 'value': '="foo" + form_var_plop'}] jump = JumpWorkflowStatusItem() jump.status = 'st2' st1.items = [setbo, setbo2, jump] st2 = workflow.add_status('Status2', 'st2') editable = EditableWorkflowStatusItem() editable.id = '_editable' editable.by = ['_submitter'] st2.items.append(editable) editable.parent = st2 editable.status = st1.id workflow.store() formdef.workflow_id = workflow.id formdef.store() formdef.data_class().wipe() resp = login(get_app(pub), username='foo', password='foo').get('/test/') resp.form['f1'] = 'bar' resp = resp.form.submit('submit') # -> page 2 resp = resp.form.submit('submit') # -> validation resp = resp.form.submit('submit').follow() # -> submitted assert 'The form has been recorded' in resp.body data_id = formdef.data_class().select()[0].id assert formdef.data_class().get(data_id).data['bo1'] == 'foobar' app = login(get_app(pub), username='foo', password='foo') resp = app.get('/test/%s/' % data_id) assert 'button_editable-button' in resp.body resp = resp.form.submit('button_editable') resp = resp.follow() assert resp.form['f1'].value == 'bar' resp.form['f1'].value == 'baz' resp = resp.form.submit('submit') # -> page 2 resp = resp.form.submit('submit').follow() # -> saved assert formdef.data_class().get(data_id).data['bo1'] == 'foobaz'
Ça échoue sur la fin avec :
E AssertionError: assert 'foofoobar' == 'foobaz' E - foofoobar E + foobaz
Dans le déroulé, ça veut dire que :
setbo.fields = [{'field_id': 'bo1', 'value': '=form_var_foo'}]
setbo2.fields = [{'field_id': 'bo1', 'value': '="foo" + form_var_plop'}]
Exécute le second est bien exécuté mais sans prendre en compte la valeur modifiée posée juste avant.
Fichiers
Révisions associées
Historique
Mis à jour par Frédéric Péters il y a environ 5 ans
- Fichier 0001-forms-don-t-let-old-formdata-get-used-by-workflow-af.patch 0001-forms-don-t-let-old-formdata-get-used-by-workflow-af.patch ajouté
- Statut changé de Nouveau à Solution proposée
- Patch proposed changé de Non à Oui
Une fois la demande modifiée transmise, on vire tous les formdata du contexte et on y met le nouveau.
Mis à jour par Benjamin Dauvergne il y a environ 5 ans
<mode pedantman>j'aurai appelé cmp_function plutôt predicate</mode>
- bon sinon ce qui fait qu'on se retrouve avec deux instances du même FormData m'échappe un peu mais soit (ça viendrait des histoires de transient formdata?); est-ce que ça ne marcherai pas sans le unfeed en fait ? il suffit que existing_formdata soit sur le dessus de la pile, non ? à moins que des variables disparaissent entre les deux, c'est vrai.
Mis à jour par Frédéric Péters il y a environ 5 ans
<mode pedantman>j'aurai appelé cmp_function plutôt predicate</mode>
Je peux changer ces lignes.
bon sinon ce qui fait qu'on se retrouve avec deux instances du même FormData m'échappe un peu mais soit (ça viendrait des histoires de transient formdata?);
Oui ça vient des transient formdata, ils sont ajoutés pour les autres moments du formulaire, genre pour avoir les étapes correctes. Pour le moment du submit final, ils ne servent à rien (et posent donc même problème), mais ça serait bien intrusif et compliqué.
est-ce que ça ne marcherai pas sans le unfeed en fait ? il suffit que existing_formdata soit sur le dessus de la pile, non ? à moins que des variables disparaissent entre les deux, c'est vrai.
Yep, si les variables disparaissent ça peut foirer; aussi c'est toujours ça de gagné de réduire le nombre d'éléments là-dedans.
Mis à jour par Benjamin Dauvergne il y a environ 5 ans
Ack pour moi, mais je laisse Thomas faire ses remarques au cas où.
Mis à jour par Thomas Noël il y a environ 5 ans
- Statut changé de Solution proposée à Solution validée
Moi ça me va, bon s'il faut aussi faire l'intéressant j'aurais sans doute posé le lambda dans unfeed, genre avec un «unfeed(self, klass):», mais c'est bien aussi ainsi.
Mis à jour par Frédéric Péters il y a environ 5 ans
- Statut changé de Solution validée à Résolu (à déployer)
Moi ça me va, bon s'il faut aussi faire l'intéressant j'aurais sans doute posé le lambda dans unfeed, genre avec un «unfeed(self, klass):», mais c'est bien aussi ainsi.
C'est parce qu'à l'origine j'avais un lambda qui regardait aussi le statut.
commit 78799be5627e3d164199b23a22d1afc5d86f4474 Author: Frédéric Péters <fpeters@entrouvert.com> Date: Wed Feb 27 15:09:32 2019 +0100 forms: don't let old formdata get used by workflow after edit jump (#30942)
Mis à jour par Frédéric Péters il y a environ 5 ans
- Statut changé de Résolu (à déployer) à Solution déployée
forms: don't let old formdata get used by workflow after edit jump (#30942)