How would I pytest a flask wtforms custom validator?

99 Views Asked by At

I tried the code below.

But the problem is I am getting an error when I run the code. Do I have the right arguments in make_password_contain_capital?

Here is the custom validator.

auth/functions.py

def make_password_contain_capital(form, field):
    '''
    This works if the password contains a capital Char 
    and raises an ValidationError if it does not.
    This runs in the class RegistrationForm in passwordfield + confirmpasswordfield column
    ''' 
    password_form = field.data   
    word = password_form
    # any returns True when any value of char is True
    # loops through each word into a char and if any char is an uppercase return True else return False
    letter = [char for char in word if char.isupper()]
    # if the string returns a value then the string has an capital  
    if letter: 
        flash("Success password does contain a capital")
        return None    
    # else executes if "letter" is an empyty string
    else: 
        raise ValidationError("Please include a capital letter in the password field"

tests/non_db_functions/login_routes.py

from app.auth.functions import make_password_contain_capital
from wsgi import app

from app.auth.forms import LoginForm
from wtforms.validators import ValidationError

@pytest.fixture
def plaintext_password_contains_capital_form():
    password_form ='Aejfpwo;fkjeo;'
    return password_form


def test_password(plaintext_password_contains_capital_form)

    with app.test_request_context():
        form = LoginForm()
        field = plaintext_password_contains_capital_form
        with pytest.raises(ValidationError):
            make_password_contain_capital(form, field)

The error I am getting is below.



plaintext_password_contains_capital_form = 'Aejfpwo;fkjeo;'


    def test_password(plaintext_password_contains_capital_form ):

        with app.test_request_context():
            form = LoginForm()
            field = plaintext_password_contains_capital_form 
            with pytest.raises(ValidationError):
>               make_password_contain_capital(form, field)

app\tests\non_db_functions\login_routes.py:68:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  

form = <app.auth.forms.LoginForm object at 0x000002045E5EC5E0>, field = 'Aejfpwo;fkjeo;'

    def make_password_contain_capital(form, field):
        '''
        This works if the password contains a capital Char
        and raises an ValidationError if it does not.
        This runs in the class RegistrationForm in passwordfield + confirmpasswordfield column
        '''
>       password_form = field.data
E       AttributeError: 'str' object has no attribute 'data'

app\auth\functions.py:16: AttributeError
============================================================ short test summary info ============================================================= 
FAILED app/tests/non_db_functions/login_routes.py::test_password - AttributeError: 'str' object has no attribute 'data'

How do I fix this?

I am importing app from wsgi.py and I have an individual PytestConfig class that is why so I run >>$env:FLASK_ENV="pytest" >>pytest -q --capture=no . Though there are other ways to do this

Thanks you to anyone who responds.

1

There are 1 best solutions below

3
Diego Torres Milano On

You are invoking

make_password_contain_capital(form, field)

with field containing plaintext_password_contains_capital_form (a str).

Then you try to access data on it which does not exist.

You can create a mock for it

...
field = MagicMock(name="field")
field.data = plaintext_password_contains_capital_form
...