I wrote some forms using flask-wtf that use FieldList
and FormField
, and I want to test them using pytest
. It's a bulk insertion of data from an uploaded CSV
These are my forms:
# myapp/admin/forms.py
from wtforms import Form as NoCsrfForm
class SimpleRegistrationForm(NoCsrfForm):
email = StringField('Email')
username = StringField('Username')
password = StringField('Password')
from flask_wtf import FlaskForm
class BulkUserCreationForm(FlaskForm):
users = FieldList(FormField(SimpleRegistrationForm))
submitted = HiddenField()
submit = SubmitField('Register all')
def is_submitted(self):
from flask import request
return super().is_submitted() and 'submitted' in request.form
Note that I'm skipping imports and other stuff. Also, I used submitted
to stop my @app.route
from passing validate_on_submit()
.
This is a part of my test:
# a part of a test
# (...) mumble mumble
from myapp.admin.forms import (
BulkUserCreationForm, SimpleRegistrationForm)
usr_form_1 = SimpleRegistrationForm(username="user1",
email="user1@mail.com",
password="pwd1",)
usr_form_2 = SimpleRegistrationForm(username="user2",
email="user2@mail.com",
password="pwd2",)
usr_form_full = BulkUserCreationForm(
users=[usr_form_1, usr_form_2])
# user issues a POST request
rv = client.post(
url_for('bulk-import-users.edit_users')
follow_redirects=True,
data=usr_form_full.data)
assert something_happened()
I'm struggling on how to craft the data
part. So far I've read three approaches
- This solution uses data as tuples, but I don't understand the binding between tuples and forms for something like
BulkUserCreationForm.users
-
This solution relies on the
data
attribute of a form instance, which returns a dictionary. In the post it seems to work, but in my case (and for the code I show) I'm getting an error of the form:/src/venv/lib/python3.6/site-packages/werkzeug/test.py:349: DeprecationWarning: it's no longer possible to pass dicts as `data`. Use tuples or FileStorage objects instead
-
Googling this error returned this (and not much more). This solution uses hardcoded values, so instead I went for something more or less better:
data_full = {field.label.field_id: field.data for form in usr_form_full.users for field in form}
and passed this to the data
attribute. It didn't work. For some reason the rendered .data
attribute does not behave like expected, returning a different repr
(I expected to see the actual value).
>>> print(data_full)
{'users-0-email': <wtforms.fields.core.StringField object at 0x7f1704f68cc0>, 'users-0-username': <wtforms.fields.core.StringField object at 0x7f1704fa5e10>, 'users-0-password': <wtforms.fields.core.StringField object at 0x7f1704f539e8>, 'users-1-email': <wtforms.fields.core.StringField object at 0x7f1704f26a90>, 'users-1-username': <wtforms.fields.core.StringField object at 0x7f1704f26f98>, 'users-1-password': <wtforms.fields.core.StringField object at 0x7f1704f26828>}
In short, none of the above approaches worked in my test. What's the right approach? Do I need to pass submit
and submitted
values to my form instance as well?
Aucun commentaire:
Enregistrer un commentaire