Projet

Général

Profil

Bug #30942

enchainement d'actions "données de traitement" derrière une action d'édition

Ajouté par Frédéric Péters il y a environ 5 ans. Mis à jour il y a environ 5 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
-
Version cible:
-
Début:
27 février 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:

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

Révision 78799be5 (diff)
Ajouté par Frédéric Péters il y a environ 5 ans

forms: don't let old formdata get used by workflow after edit jump (#30942)

Historique

#2

Mis à jour par Frédéric Péters il y a environ 5 ans

Une fois la demande modifiée transmise, on vire tous les formdata du contexte et on y met le nouveau.

#3

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.
#4

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.

#5

Mis à jour par Benjamin Dauvergne il y a environ 5 ans

Ack pour moi, mais je laisse Thomas faire ses remarques au cas où.

#6

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.

#7

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)
#8

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

Formats disponibles : Atom PDF