Failing tests with flask>=2.1.0
See original GitHub issuePrimarily around redirect paths. Likely related to https://github.com/pallets/flask/pull/4496. We’re on 4.1.3.
_______________________ test_change_invalidates_session ________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
def test_change_invalidates_session(app, client):
# Make sure that if we change our password - prior sessions are invalidated.
# changing password effectively re-logs in user - verify the signal
auths = []
@user_authenticated.connect_via(app)
def authned(myapp, user, **extra_args):
auths.append((user.email, extra_args["authn_via"]))
# No remember cookie since that also be reset and auto-login.
data = dict(email="matt@lp.com", password="password", remember="")
response = client.post("/login", data=data)
sess = get_session(response)
cur_user_id = sess.get("_user_id", sess.get("user_id"))
response = client.post(
"/change",
data={
"password": "password",
"new_password": "new strong password",
"new_password_confirm": "new strong password",
},
follow_redirects=True,
)
# First auth was the initial login above - second should be from /change
assert auths[1][0] == "matt@lp.com"
assert "change" in auths[1][1]
# Should have received a new session cookie - so should still be logged in
response = client.get("/profile", follow_redirects=True)
assert b"Profile Page" in response.data
# Now use old session - shouldn't work.
with client.session_transaction() as oldsess:
oldsess["_user_id"] = cur_user_id
oldsess["user_id"] = cur_user_id
# try to access protected endpoint - shouldn't work
response = client.get("/profile")
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/login?next=%2Fprofile"
E AssertionError: assert '/login?next=%2Fprofile' == 'http://local...xt=%2Fprofile'
E - http://localhost/login?next=%2Fprofile
E + /login?next=%2Fprofile
tests/test_changeable.py:196: AssertionError
______________________ test_change_invalidates_auth_token ______________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
def test_change_invalidates_auth_token(app, client):
# if change password, by default that should invalidate auth tokens
response = json_authenticate(client)
token = response.json["response"]["user"]["authentication_token"]
headers = {"Authentication-Token": token}
# make sure can access restricted page
response = client.get("/token", headers=headers)
assert b"Token Authentication" in response.data
response = client.post(
"/change",
data={
"password": "password",
"new_password": "new strong password",
"new_password_confirm": "new strong password",
},
follow_redirects=True,
)
assert response.status_code == 200
# authtoken should now be invalid
response = client.get("/token", headers=headers)
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/login?next=%2Ftoken"
E AssertionError: assert '/login?next=%2Ftoken' == 'http://local...next=%2Ftoken'
E - http://localhost/login?next=%2Ftoken
E + /login?next=%2Ftoken
tests/test_changeable.py:246: AssertionError
____________________ test_unauthorized_access_with_referrer ____________________
client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff2f978b0>
@pytest.mark.settings(unauthorized_view=lambda: None)
def test_unauthorized_access_with_referrer(client, get_message):
authenticate(client, "joe@lp.com")
response = client.get("/admin", headers={"referer": "/admin"})
assert response.headers["Location"] != "/admin"
client.get(response.headers["Location"])
response = client.get(
"/admin?a=b", headers={"referer": "http://localhost/admin?x=y"}
)
> assert response.headers["Location"] == "http://localhost/"
E AssertionError: assert '/' == 'http://localhost/'
E - http://localhost/
E + /
tests/test_common.py:327: AssertionError
___________________________ test_view_configuration ____________________________
client = <FlaskClient <Flask 'tests.conftest'>>
@pytest.mark.settings(
logout_url="/custom_logout",
login_url="/custom_login",
post_login_view="/post_login",
post_logout_view="/post_logout",
default_http_auth_realm="Custom Realm",
)
def test_view_configuration(client):
response = client.get("/custom_login")
assert b"<h1>Login</h1>" in response.data
response = authenticate(client, endpoint="/custom_login")
assert "location" in response.headers
> assert response.headers["Location"] == "http://localhost/post_login"
E AssertionError: assert '/post_login' == 'http://localhost/post_login'
E - http://localhost/post_login
E + /post_login
tests/test_configuration.py:27: AssertionError
___________________________ test_email_not_identity ____________________________
app = <Flask 'tests.conftest'>
sqlalchemy_datastore = <flask_security.datastore.SQLAlchemyUserDatastore object at 0x7ffff2d44be0>
get_message = <function get_message.<locals>.fn at 0x7ffff2f055e0>
@pytest.mark.registerable()
@pytest.mark.settings(
user_identity_attributes=[{"username": {"mapper": lambda x: x}}],
)
def test_email_not_identity(app, sqlalchemy_datastore, get_message):
# Test that can register/confirm with email even if it isn't an IDENTITY_ATTRIBUTE
from flask_security import ConfirmRegisterForm, Security, unique_identity_attribute
from wtforms import StringField, validators
class MyRegisterForm(ConfirmRegisterForm):
username = StringField(
"Username",
validators=[validators.data_required(), unique_identity_attribute],
)
app.config["SECURITY_CONFIRM_REGISTER_FORM"] = MyRegisterForm
security = Security(datastore=sqlalchemy_datastore)
security.init_app(app)
client = app.test_client()
with capture_registrations() as registrations:
data = dict(email="mary2@lp.com", username="mary", password="awesome sunset")
response = client.post("/register", data=data, follow_redirects=True)
assert b"mary2@lp.com" in response.data
token = registrations[0]["confirm_token"]
response = client.get("/confirm/" + token, headers={"Accept": "application/json"})
assert response.status_code == 302
> assert response.location == "http://localhost/"
E AssertionError: assert '/' == 'http://localhost/'
E - http://localhost/
E + /
tests/test_confirmable.py:525: AssertionError
_____________________________ test_authn_freshness _____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff25d78b0>
def test_authn_freshness(
app: "Flask", client: "FlaskClient", get_message: t.Callable[..., bytes]
) -> None:
"""Test freshness using default reauthn_handler"""
@auth_required(within=30, grace=0)
def myview():
return Response(status=200)
@auth_required(within=0.001, grace=0)
def myspecialview():
return Response(status=200)
app.add_url_rule("/myview", view_func=myview, methods=["GET"])
app.add_url_rule("/myspecialview", view_func=myspecialview, methods=["GET"])
authenticate(client)
# This should work and not be redirected
response = client.get("/myview", follow_redirects=False)
assert response.status_code == 200
# This should require additional authn and redirect to verify
time.sleep(0.1)
with capture_flashes() as flashes:
response = client.get("/myspecialview", follow_redirects=False)
assert response.status_code == 302
> assert (
response.location
== "http://localhost/verify?next=http%3A%2F%2Flocalhost%2Fmyspecialview"
)
E AssertionError: assert '/verify?next...myspecialview' == 'http://local...myspecialview'
E - http://localhost/verify?next=http%3A%2F%2Flocalhost%2Fmyspecialview
E ? ----------------
E + /verify?next=http%3A%2F%2Flocalhost%2Fmyspecialview
tests/test_misc.py:816: AssertionError
____________________________ test_default_authn_bp _____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
@pytest.mark.settings(url_prefix="/myprefix")
def test_default_authn_bp(app, client):
"""Test default reauthn handler with blueprint prefix"""
@auth_required(within=0.001, grace=0)
def myview():
return Response(status=200)
app.add_url_rule("/myview", view_func=myview, methods=["GET"])
authenticate(client, endpoint="/myprefix/login")
# This should require additional authn and redirect to verify
time.sleep(0.1)
response = client.get("/myview", follow_redirects=False)
assert response.status_code == 302
> assert (
response.location
== "http://localhost/myprefix/verify?next=http%3A%2F%2Flocalhost%2Fmyview"
)
E AssertionError: assert '/myprefix/ve...host%2Fmyview' == 'http://local...host%2Fmyview'
E - http://localhost/myprefix/verify?next=http%3A%2F%2Flocalhost%2Fmyview
E ? ----------------
E + /myprefix/verify?next=http%3A%2F%2Flocalhost%2Fmyview
tests/test_misc.py:899: AssertionError
___________________________ test_authn_freshness_nc ____________________________
app = <Flask 'tests.conftest'>
client_nc = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff2eda5e0>
def test_authn_freshness_nc(app, client_nc, get_message):
# If don't send session cookie - then freshness always fails
@auth_required(within=30)
def myview():
return Response(status=200)
app.add_url_rule("/myview", view_func=myview, methods=["GET"])
response = json_authenticate(client_nc)
token = response.json["response"]["user"]["authentication_token"]
h = {"Authentication-Token": token}
# This should fail - should be a redirect
response = client_nc.get("/myview", headers=h, follow_redirects=False)
assert response.status_code == 302
> assert (
response.location
== "http://localhost/verify?next=http%3A%2F%2Flocalhost%2Fmyview"
)
E AssertionError: assert '/verify?next...host%2Fmyview' == 'http://local...host%2Fmyview'
E - http://localhost/verify?next=http%3A%2F%2Flocalhost%2Fmyview
E ? ----------------
E + /verify?next=http%3A%2F%2Flocalhost%2Fmyview
tests/test_misc.py:944: AssertionError
___________________ test_post_security_with_application_root ___________________
app = <Flask 'tests.conftest'>
sqlalchemy_datastore = <flask_security.datastore.SQLAlchemyUserDatastore object at 0x7ffff283d4f0>
def test_post_security_with_application_root(app, sqlalchemy_datastore):
init_app_with_options(app, sqlalchemy_datastore, **{"APPLICATION_ROOT": "/root"})
client = app.test_client()
response = client.post(
"/login", data=dict(email="matt@lp.com", password="password")
)
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/root"
E AssertionError: assert '/root' == 'http://localhost/root'
E - http://localhost/root
E + /root
tests/test_misc.py:1109: AssertionError
______________ test_post_security_with_application_root_and_views ______________
app = <Flask 'tests.conftest'>
sqlalchemy_datastore = <flask_security.datastore.SQLAlchemyUserDatastore object at 0x7ffff1c74250>
def test_post_security_with_application_root_and_views(app, sqlalchemy_datastore):
init_app_with_options(
app,
sqlalchemy_datastore,
**{
"APPLICATION_ROOT": "/root",
"SECURITY_POST_LOGIN_VIEW": "/post_login",
"SECURITY_POST_LOGOUT_VIEW": "/post_logout",
}
)
client = app.test_client()
response = client.post(
"/login", data=dict(email="matt@lp.com", password="password")
)
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/post_login"
E AssertionError: assert '/post_login' == 'http://localhost/post_login'
E - http://localhost/post_login
E + /post_login
tests/test_misc.py:1132: AssertionError
_______________________ test_recover_invalidates_session _______________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
def test_recover_invalidates_session(app, client):
# Make sure that if we reset our password - prior sessions are invalidated.
other_client = app.test_client()
authenticate(other_client)
response = other_client.get("/profile", follow_redirects=True)
assert b"Profile Page" in response.data
# use normal client to reset password
with capture_reset_password_requests() as requests:
response = client.post(
"/reset",
json=dict(email="matt@lp.com"),
headers={"Content-Type": "application/json"},
)
assert response.headers["Content-Type"] == "application/json"
assert response.status_code == 200
token = requests[0]["token"]
# Test submitting a new password
response = client.post(
"/reset/" + token + "?include_auth_token",
json=dict(password="awesome sunset", password_confirm="awesome sunset"),
headers={"Content-Type": "application/json"},
)
assert all(
k in response.json["response"]["user"]
for k in ["email", "authentication_token"]
)
# try to access protected endpoint with old session - shouldn't work
response = other_client.get("/profile")
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/login?next=%2Fprofile"
E AssertionError: assert '/login?next=%2Fprofile' == 'http://local...xt=%2Fprofile'
E - http://localhost/login?next=%2Fprofile
E + /login?next=%2Fprofile
tests/test_recoverable.py:292: AssertionError
_____________________________ test_default_unauthn _____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
def test_default_unauthn(app, client):
"""Test default unauthn handler with and without json"""
response = client.get("/profile")
assert response.status_code == 302
> assert response.headers["Location"] == "http://localhost/login?next=%2Fprofile"
E AssertionError: assert '/login?next=%2Fprofile' == 'http://local...xt=%2Fprofile'
E - http://localhost/login?next=%2Fprofile
E + /login?next=%2Fprofile
tests/test_response.py:55: AssertionError
___________________________ test_default_unauthn_bp ____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
@pytest.mark.settings(login_url="/mylogin", url_prefix="/myprefix")
def test_default_unauthn_bp(app, client):
"""Test default unauthn handler with blueprint prefix and login url"""
response = client.get("/profile")
assert response.status_code == 302
> assert (
response.headers["Location"]
== "http://localhost/myprefix/mylogin?next=%2Fprofile"
)
E AssertionError: assert '/myprefix/my...xt=%2Fprofile' == 'http://local...xt=%2Fprofile'
E - http://localhost/myprefix/mylogin?next=%2Fprofile
E ? ----------------
E + /myprefix/mylogin?next=%2Fprofile
tests/test_response.py:71: AssertionError
_____________________________ test_two_factor_flag _____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
@pytest.mark.settings(two_factor_required=True)
def test_two_factor_flag(app, client):
# trying to verify code without going through two-factor
# first login function
wrong_code = b"000000"
response = client.post(
"/tf-validate", data=dict(code=wrong_code), follow_redirects=True
)
message = b"You currently do not have permissions to access this page"
assert message in response.data
# Test login using invalid email
data = dict(email="nobody@lp.com", password="password")
response = client.post("/login", data=data, follow_redirects=True)
assert b"Specified user does not exist" in response.data
response = client.post(
"/login",
json=data,
headers={"Content-Type": "application/json"},
follow_redirects=True,
)
assert b"Specified user does not exist" in response.data
# Test login using valid email and invalid password
data = dict(email="gal@lp.com", password="wrong_pass")
response = client.post("/login", data=data, follow_redirects=True)
assert b"Invalid password" in response.data
response = client.post(
"/login",
json=data,
headers={"Content-Type": "application/json"},
follow_redirects=True,
)
assert b"Invalid password" in response.data
# Test two-factor authentication first login
data = dict(email="matt@lp.com", password="password")
response = client.post("/login", data=data, follow_redirects=True)
message = b"Two-factor authentication adds an extra layer of security"
assert message in response.data
response = client.post(
"/tf-setup", data=dict(setup="not_a_method"), follow_redirects=True
)
assert b"Marked method is not valid" in response.data
session = get_session(response)
> assert session["tf_state"] == "setup_from_login"
E TypeError: 'NoneType' object is not subscriptable
tests/test_two_factor.py:323: TypeError
____________________________ test_admin_setup_reset ____________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff1705550>
@pytest.mark.settings(two_factor_required=True)
def test_admin_setup_reset(app, client, get_message):
# Verify can use administrative datastore method to setup SMS
# and that administrative reset removes access.
sms_sender = SmsSenderFactory.createSender("test")
data = dict(email="gene@lp.com", password="password")
response = client.post(
"/login", json=data, headers={"Content-Type": "application/json"}
)
assert response.json["response"]["tf_required"]
# we shouldn't be logged in
response = client.get("/profile", follow_redirects=False)
assert response.status_code == 302
> assert response.location == "http://localhost/login?next=%2Fprofile"
E AssertionError: assert '/login?next=%2Fprofile' == 'http://local...xt=%2Fprofile'
E - http://localhost/login?next=%2Fprofile
E + /login?next=%2Fprofile
tests/test_two_factor.py:854: AssertionError
_______________________________ test_bad_sender ________________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff25eac10>
@pytest.mark.settings(sms_service="bad")
def test_bad_sender(app, client, get_message):
# If SMS sender fails - make sure propagated
# Test form, json, x signin, setup
headers = {"Accept": "application/json", "Content-Type": "application/json"}
# test normal, already setup up login.
with capture_flashes() as flashes:
data = {"email": "gal@lp.com", "password": "password"}
response = client.post("login", data=data, follow_redirects=False)
assert response.status_code == 302
> assert response.location == "http://localhost/login"
E AssertionError: assert '/login' == 'http://localhost/login'
E - http://localhost/login
E + /login
tests/test_two_factor.py:1108: AssertionError
_________________________________ test_verify __________________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff1be3f70>
@pytest.mark.settings(freshness=timedelta(minutes=0))
def test_verify(app, client, get_message):
# Test setup when re-authenticate required
authenticate(client)
response = client.get("tf-setup", follow_redirects=False)
verify_url = response.location
> assert (
verify_url == "http://localhost/verify?next=http%3A%2F%2Flocalhost%2Ftf-setup"
)
E AssertionError: assert '/verify?next...st%2Ftf-setup' == 'http://local...st%2Ftf-setup'
E - http://localhost/verify?next=http%3A%2F%2Flocalhost%2Ftf-setup
E ? ----------------
E + /verify?next=http%3A%2F%2Flocalhost%2Ftf-setup
tests/test_two_factor.py:1190: AssertionError
_______________________________ test_verify_link _______________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff1cbd670>
@pytest.mark.settings(us_email_subject="Code For You")
def test_verify_link(app, client, get_message):
auths = []
@user_authenticated.connect_via(app)
def authned(myapp, user, **extra_args):
auths.append((user.email, extra_args["authn_via"]))
with app.mail.record_messages() as outbox:
response = client.post(
"/us-signin/send-code",
data=dict(identity="matt@lp.com", chosen_method="email"),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Sign In" in response.data
assert outbox[0].recipients == ["matt@lp.com"]
assert outbox[0].sender == "no-reply@localhost"
assert outbox[0].subject == "Code For You"
matcher = re.match(
r".*(http://[^\s*]*).*", outbox[0].body, re.IGNORECASE | re.DOTALL
)
magic_link = matcher.group(1)
# Try with no code
response = client.get("us-verify-link?email=matt@lp.com", follow_redirects=False)
> assert response.location == "http://localhost/us-signin"
E AssertionError: assert '/us-signin' == 'http://localhost/us-signin'
E - http://localhost/us-signin
E + /us-signin
tests/test_unified_signin.py:516: AssertionError
_________________________________ test_verify __________________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff130a040>
@pytest.mark.settings(freshness=timedelta(minutes=0))
def test_verify(app, client, get_message):
# Test setup when re-authenticate required
# With freshness set to 0 - the first call should require reauth (by
# redirecting); but the second should work due to grace period.
us_authenticate(client)
response = client.get("us-setup", follow_redirects=False)
verify_url = response.location
> assert (
verify_url
== "http://localhost/us-verify?next=http%3A%2F%2Flocalhost%2Fus-setup"
)
E AssertionError: assert '/us-verify?n...st%2Fus-setup' == 'http://local...st%2Fus-setup'
E - http://localhost/us-verify?next=http%3A%2F%2Flocalhost%2Fus-setup
E ? ----------------
E + /us-verify?next=http%3A%2F%2Flocalhost%2Fus-setup
tests/test_unified_signin.py:840: AssertionError
__________________________________ test_next ___________________________________
app = <Flask 'tests.conftest'>, client = <FlaskClient <Flask 'tests.conftest'>>
get_message = <function get_message.<locals>.fn at 0x7ffff1c70040>
def test_next(app, client, get_message):
with capture_send_code_requests() as requests:
response = client.post(
"/us-signin/send-code",
data=dict(identity="matt@lp.com", chosen_method="email"),
follow_redirects=True,
)
assert response.status_code == 200
response = client.post(
"/us-signin?next=/post_login",
data=dict(identity="matt@lp.com", passcode=requests[0]["token"]),
follow_redirects=False,
)
> assert response.location == "http://localhost/post_login"
E AssertionError: assert '/post_login' == 'http://localhost/post_login'
E - http://localhost/post_login
E + /post_login
tests/test_unified_signin.py:1102: AssertionError
Issue Analytics
- State:
- Created a year ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Flask failing to startup due to Jinja2 breaking change #4494
Since Jinja2 version 3.1.0 was released yesterday, Flask is failing to startup. Describe how to replicate the bug. Run a basic flask app, ......
Read more >Testing Flask Applications — Flask Documentation (1.1.x)
Flask provides a way to test your application by exposing the Werkzeug test Client and handling the context locals for you. You can...
Read more >Python unit test failing even though the expectation match
which I'm looking to test.. unittest for it look something like this. from unittest.mock import patch, call, Mock, MagicMock import json ...
Read more >Python Web Applications With Flask – Part III
A method that always returns the same datetime instance is valid and correct twice a day, but valid and incorrect all the rest...
Read more >Changelog Highlights — Locust 2.0.0b4 documentation
Upgrade to Flask 2 (2.0.0b1) https://github.com/locustio/locust/pull/1764 ... Fix an issue with custom Users calling request_success/_failure.fire() not ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Fixed - will get out a release soon.
https://github.com/Flask-Middleware/flask-security/commit/3e921aec1c9926b411e12cecb3713de51665d47b