Skip to content

Commit 57701e6

Browse files
committed
mro accidental change protection tests
1 parent 5a5c1af commit 57701e6

File tree

1 file changed

+116
-3
lines changed

1 file changed

+116
-3
lines changed

tests/test_forms_v2.py

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from werkzeug.datastructures import MultiDict
66

77
wtforms = pytest.importorskip("wtforms")
8-
from flask_mongoengine.wtf import fields # noqa
8+
from wtforms import fields as wtf_fields # noqa
9+
10+
from flask_mongoengine.wtf import fields as mongo_fields # noqa
911

1012

1113
@pytest.fixture()
@@ -143,18 +145,22 @@ class TestEmptyStringIsNoneMixin:
143145
"""Special mixin to ignore empty strings **before** parent class processing."""
144146

145147
class ParentClass:
148+
"""MRO parent."""
149+
146150
def __init__(self):
147151
self.data = True
148152

149153
def process_formdata(self, valuelist):
154+
"""Status changer"""
155+
assert valuelist != ""
150156
self.data = False
151157

152-
class FakeClass(fields.EmptyStringIsNoneMixin, ParentClass):
158+
class FakeClass(mongo_fields.EmptyStringIsNoneMixin, ParentClass):
153159
"""Just MRO setter."""
154160

155161
pass
156162

157-
@pytest.mark.parametrize("value", ["", None, [], {}, (), (""), [""]])
163+
@pytest.mark.parametrize("value", ["", None, [], {}, (), "", ("",), [""]])
158164
def test__process_formdata__does_not_call_parent_method_if_value_is_empty(
159165
self, value
160166
):
@@ -171,3 +177,110 @@ def test__process_formdata__does_call_parent_method_if_value_is_not_empty(
171177
assert obj.data is True
172178
obj.process_formdata(value)
173179
assert obj.data is False
180+
181+
182+
class TestMongoEmailField:
183+
def test_email_field_mro_not_changed(self):
184+
field_mro = list(mongo_fields.MongoEmailField.__mro__[:4])
185+
assert field_mro == [
186+
mongo_fields.MongoEmailField,
187+
mongo_fields.EmptyStringIsNoneMixin,
188+
wtf_fields.EmailField,
189+
wtf_fields.StringField,
190+
]
191+
192+
193+
class TestMongoHiddenField:
194+
def test_hidden_field_mro_not_changed(self):
195+
field_mro = list(mongo_fields.MongoHiddenField.__mro__[:4])
196+
assert field_mro == [
197+
mongo_fields.MongoHiddenField,
198+
mongo_fields.EmptyStringIsNoneMixin,
199+
wtf_fields.HiddenField,
200+
wtf_fields.StringField,
201+
]
202+
203+
204+
class TestMongoPasswordField:
205+
def test_password_field_mro_not_changed(self):
206+
field_mro = list(mongo_fields.MongoPasswordField.__mro__[:4])
207+
assert field_mro == [
208+
mongo_fields.MongoPasswordField,
209+
mongo_fields.EmptyStringIsNoneMixin,
210+
wtf_fields.PasswordField,
211+
wtf_fields.StringField,
212+
]
213+
214+
215+
class TestMongoSearchField:
216+
def test_search_field_mro_not_changed(self):
217+
field_mro = list(mongo_fields.MongoSearchField.__mro__[:4])
218+
assert field_mro == [
219+
mongo_fields.MongoSearchField,
220+
mongo_fields.EmptyStringIsNoneMixin,
221+
wtf_fields.SearchField,
222+
wtf_fields.StringField,
223+
]
224+
225+
226+
class TestMongoStringField:
227+
def test__parent__process_formdata__method_included_in_mro_chain(self, db, mocker):
228+
"""Test to protect from accidental incorrect __init__ method overwrite."""
229+
base_init_spy = mocker.spy(wtf_fields.StringField, "process_formdata")
230+
mixin_init_spy = mocker.spy(
231+
mongo_fields.EmptyStringIsNoneMixin, "process_formdata"
232+
)
233+
234+
class DocumentModel(db.Document):
235+
"""Test DB model."""
236+
237+
string_field = db.StringField()
238+
239+
DocumentForm = DocumentModel.to_wtf_form()
240+
form = DocumentForm(formdata=MultiDict({"string_field": "1"}))
241+
assert form.validate()
242+
obj = form.save()
243+
mixin_init_spy.assert_called_once()
244+
base_init_spy.assert_called_once()
245+
assert obj.string_field == "1"
246+
247+
def test_string_field_mro_not_changed(self):
248+
field_mro = list(mongo_fields.MongoStringField.__mro__[:3])
249+
assert field_mro == [
250+
mongo_fields.MongoStringField,
251+
mongo_fields.EmptyStringIsNoneMixin,
252+
wtf_fields.StringField,
253+
]
254+
255+
256+
class TestMongoTelField:
257+
def test_tel_field_mro_not_changed(self):
258+
field_mro = list(mongo_fields.MongoTelField.__mro__[:4])
259+
assert field_mro == [
260+
mongo_fields.MongoTelField,
261+
mongo_fields.EmptyStringIsNoneMixin,
262+
wtf_fields.TelField,
263+
wtf_fields.StringField,
264+
]
265+
266+
267+
class TestMongoTextAreaField:
268+
def test_text_area_field_mro_not_changed(self):
269+
field_mro = list(mongo_fields.MongoTextAreaField.__mro__[:4])
270+
assert field_mro == [
271+
mongo_fields.MongoTextAreaField,
272+
mongo_fields.EmptyStringIsNoneMixin,
273+
wtf_fields.TextAreaField,
274+
wtf_fields.StringField,
275+
]
276+
277+
278+
class TestMongoURLField:
279+
def test_url_field_mro_not_changed(self):
280+
field_mro = list(mongo_fields.MongoURLField.__mro__[:4])
281+
assert field_mro == [
282+
mongo_fields.MongoURLField,
283+
mongo_fields.EmptyStringIsNoneMixin,
284+
wtf_fields.URLField,
285+
wtf_fields.StringField,
286+
]

0 commit comments

Comments
 (0)