Reputation: 1355
So I have web app where if the user is logged in, he cannot sign up. Instead he is redirected and a message saying he cannot sign up is flashed.
The problem is I can't test it for some reason.
Here is the view
@users_template.route('/signup', methods=['GET', 'POST'])
def signup():
form = RegisterationForm()
if current_user.is_authenticated and current_user.is_active: # prevent the user from seeing the register page if he's already logged in
flash('You cannot sign up while you\'re logged in')
return redirect(url_for('main.home'))
if request.method == 'POST' and form.validate_on_submit():
username = form.username.data
password = form.password.data
user = User(username=username, password=password)
if db.session.query(User).filter(User.username == username).first() is None:
current_app.logger.info('<{}> did not register before. Registering him/her now'.format(username))
db.session.add(user)
db.session.commit()
flash('Thank you for registering. Please login now')
return redirect(url_for('users.login'))
else: # the user name has been registered before
flash('You already registered')
return render_template('signup.html', form=form)
Now in my test module I have this method
def test_signup_page_requires_logout(self):
data_to_signup = {'username': 'mustafa1', 'password': 'mustafa1',
'confirm_password': 'mustafa1'}
data_to_login = {'username': 'mustafa1', 'password': 'mustafa1'}
# with statement preserves the request context for the current_user
with self.client:
self.client.post('/signup', data=data_to_signup)
self.client.post('/login', data=data_to_login)
response = self.client.get('/signup', follow_redirects=True)
assert b'You cannot sign up while you\'re logged in' in response.data
What's even more confusing is that this structure works for other methods
def test_headquarter_after_login(self):
data_to_signup = {'username': 'mustafa1', 'password': 'mustafa1',
'confirm_password': 'mustafa1'}
data_to_login = {'username': 'mustafa1', 'password': 'mustafa1'}
with self.client:
self.client.post('/signup', data=data_to_signup)
self.client.post('/login', data=data_to_login)
response = self.client.get('/headquarter')
assert b'Headquarter page' in response.data
EDIT: here is the login view
from .. import bcrypt
@users_template.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(request.form)
if form.validate_on_submit() and request.method == 'POST':
username = form.username.data
password = form.password.data
user = User.query.filter(User.username == username).first()
if user is not None and bcrypt.check_password_hash(user.password, password): # authenticate
login_user(user) # then log the user in
flash('You are logged in')
return redirect(url_for('main.home'))
else:
flash('Incorrect username or password') # if username is wrong, it will be caught by the error handling above
return render_template('login.html', form=form) # for a GET request
This is the error (I'm using py.test fyi)
assert current_user.is_active() == True
assert current_user.is_authenticated() == True
> assert b'You cannot sign up while you\'re logged in' in response.data
E AssertionError: assert b"You cannot sign up while you're logged in" in b'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8">\n <meta http-equiv="X-UA-Compatible" cont...jquery/1.12.4/jquery.min.js"></script>\n <script src="/static/js/bootstrap.min.js"> </script>\n </body>\n</html>\n'
E + where b'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8">\n <meta http-equiv="X-UA-Compatible" cont...jquery/1.12.4/jquery.min.js"></script>\n <script src="/static/js/bootstrap.min.js"> </script>\n </body>\n</html>\n' = <TestResponse 3874 bytes [200 OK]>.
This is to display the flashed messages in all my templates(It's in my "base.html" which I inherit from)
{% if get_flashed_messages() %}
{% for message in get_flashed_messages() %}
<div class='container'>
<span class='alert alert-info'>
<small>{{ message }}</small>
</span>
</div>
{% endfor %}
{% endif %}
I've made more tests using the flashed messages and it worked fine. Like this one for testing the user signup
assert b'Thank you for registering. Please login now' in response.data
Upvotes: 0
Views: 427
Reputation: 4903
Suggestion no:
Because of this line:
if current_user.is_authenticated and current_user.is_active:
current_user has his is_active
flag set as False
. If I'm not right, then please paste test error.
Another clue could be lack of flash messages in home template. Put this code below in for example flashMessages.html
:
{% macro render_flashMessages() %}
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class="list-unstyled">
{% for message in messages %}
<li><div class="alert alert-info">{{ message|safe }}</div></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% endmacro %}
then you can use it in this way in home.html
:
{% from "flashMessages.html" import render_flashMessages %}
{{ render_flashMessages() }}
Next thing to check is to use assert with something else than response.data, if you're using Flask-WebTest you can try:
assert b'You cannot sign up while you\'re logged in' in response.flashes[0][1]
Where flashes
is:
List of tuples (category, message) containing messages that were flashed during request.
But if you're not using FlaskWebTest, you can check session:
from flask import session
session['_flashes'][0][1]
Upvotes: 1