Skip to content

Commit

Permalink
Add test for register
Browse files Browse the repository at this point in the history
  • Loading branch information
fangpenlin committed Sep 21, 2020
1 parent cdfd873 commit e04d3bd
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 102 deletions.
2 changes: 1 addition & 1 deletion sampleapp/utils.py
Expand Up @@ -37,7 +37,7 @@ def is_safe_url(target):
return test_url.scheme in ("http", "https") and ref_url.netloc == test_url.netloc


def login_user(user, remember):
def login_user(user, remember=True):
flask_login.login_user(user, remember=remember)
flask_principal.identity_changed.send(
current_app._get_current_object(), identity=flask_principal.Identity(user.id)
Expand Down
102 changes: 102 additions & 0 deletions tests/functional/test_forgot_password.py
@@ -0,0 +1,102 @@
import datetime
import re

import jwt
from flask import url_for
from freezegun import freeze_time

from sampleapp.extensions import mail


def test_forgot_password(testapp, user):
testapp.app.config["FORGOT_PASSWORD_COOLDOWN_TIME_SECONDS"] = 60 * 10
testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"] = 123

res = testapp.get(url_for("public.forgot_password"))
form = res.form
form["email"] = user.email
with mail.record_messages() as outbox:
res = form.submit()
assert len(outbox) == 1
match = re.search("reset-password\\?token=([0-9a-zA-Z.\\-_]+)", outbox[0].body)
raw_token = match.group(1)
token = jwt.decode(
raw_token, key=testapp.app.config["SECRET_KEY"], algorithms=["HS256"],
)
user_id = token["user_id"]
expires_at = datetime.datetime.utcfromtimestamp(token["expires_at"])
assert user_id == str(user.id)
assert user.sent_reset_password_at is not None
assert expires_at == user.sent_reset_password_at + datetime.timedelta(
seconds=testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"]
)
assert "Please check your mailbox for reset password email" in res


def test_forgot_password_cooldown_period(testapp, db, user):
testapp.app.config["FORGOT_PASSWORD_COOLDOWN_TIME_SECONDS"] = 60 * 10
testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"] = 123

now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
with freeze_time(now):
user.sent_reset_password_at = now
db.session.add(user)
db.session.commit()

res = testapp.get(url_for("public.forgot_password"))
form = res.form
form["email"] = user.email
with freeze_time(now + datetime.timedelta(seconds=(60 * 10) - 1)):
res = form.submit().follow()
assert "We just sent a reset password email to you, please try again later" in res

with freeze_time(
now + datetime.timedelta(seconds=60 * 10)
), mail.record_messages() as outbox:
form.submit()
assert len(outbox) == 1


def test_reset_password_invalid_token(testapp, user):
res = testapp.get(url_for("public.reset_password", token="foobar")).follow()
assert "Invalid token" in res


def test_reset_password(testapp, user, default_password):
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
token = jwt.encode(
dict(
user_id=str(user.id),
expires_at=(now + datetime.timedelta(seconds=10)).timestamp(),
created_at=now.timestamp(),
),
key=testapp.app.config["SECRET_KEY"],
algorithm="HS256",
)

# Ensure reset password link expires
with freeze_time(now):
testapp.get(url_for("public.reset_password", token=token), status=200)

with freeze_time(now + datetime.timedelta(seconds=10)):
testapp.get(url_for("public.reset_password", token=token), status=200)

with freeze_time(now + datetime.timedelta(seconds=11)):
res = testapp.get(url_for("public.reset_password", token=token)).follow()
assert "Your reset password link has expired" in res

# Reset password
new_password = "new" + default_password
with freeze_time(now + datetime.timedelta(seconds=5)):
res = testapp.get(url_for("public.reset_password", token=token), status=200)
form = res.form
form["password"] = new_password
form["confirm"] = new_password
res = form.submit().follow()
assert "Your password is reset" in res
assert user.check_password(new_password)

# See if the link expires after we have reset the password already
with freeze_time(now):
res = testapp.get(url_for("public.reset_password", token=token)).follow()
assert "Your reset password link has expired" in res
101 changes: 0 additions & 101 deletions tests/functional/test_login.py
@@ -1,11 +1,4 @@
import datetime
import re

import jwt
from flask import url_for
from freezegun import freeze_time

from sampleapp.extensions import mail


def test_can_log_in_returns_200(testapp, user, default_password):
Expand Down Expand Up @@ -55,97 +48,3 @@ def test_sees_error_message_if_username_doesnt_exist(testapp, user, default_pass
form["password"] = default_password
res = form.submit()
assert "Invalid email or password" in res


def test_forgot_password(testapp, user):
testapp.app.config["FORGOT_PASSWORD_COOLDOWN_TIME_SECONDS"] = 60 * 10
testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"] = 123

res = testapp.get(url_for("public.forgot_password"))
form = res.form
form["email"] = user.email
with mail.record_messages() as outbox:
res = form.submit()
assert len(outbox) == 1
match = re.search("reset-password\\?token=([0-9a-zA-Z.\\-_]+)", outbox[0].body)
raw_token = match.group(1)
token = jwt.decode(
raw_token, key=testapp.app.config["SECRET_KEY"], algorithms=["HS256"],
)
user_id = token["user_id"]
expires_at = datetime.datetime.utcfromtimestamp(token["expires_at"])
assert user_id == str(user.id)
assert user.sent_reset_password_at is not None
assert expires_at == user.sent_reset_password_at + datetime.timedelta(
seconds=testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"]
)
assert "Please check your mailbox for reset password email" in res


def test_forgot_password_cooldown_period(testapp, db, user):
testapp.app.config["FORGOT_PASSWORD_COOLDOWN_TIME_SECONDS"] = 60 * 10
testapp.app.config["RESET_PASSWORD_LINK_VALID_SECONDS"] = 123

now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
with freeze_time(now):
user.sent_reset_password_at = now
db.session.add(user)
db.session.commit()

res = testapp.get(url_for("public.forgot_password"))
form = res.form
form["email"] = user.email
with freeze_time(now + datetime.timedelta(seconds=(60 * 10) - 1)):
res = form.submit().follow()
assert "We just sent a reset password email to you, please try again later" in res

with freeze_time(
now + datetime.timedelta(seconds=60 * 10)
), mail.record_messages() as outbox:
form.submit()
assert len(outbox) == 1


def test_reset_password_invalid_token(testapp, user):
res = testapp.get(url_for("public.reset_password", token="foobar")).follow()
assert "Invalid token" in res


def test_reset_password(testapp, user, default_password):
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
token = jwt.encode(
dict(
user_id=str(user.id),
expires_at=(now + datetime.timedelta(seconds=10)).timestamp(),
created_at=now.timestamp(),
),
key=testapp.app.config["SECRET_KEY"],
algorithm="HS256",
)

# Ensure reset password link expires
with freeze_time(now):
testapp.get(url_for("public.reset_password", token=token), status=200)

with freeze_time(now + datetime.timedelta(seconds=10)):
testapp.get(url_for("public.reset_password", token=token), status=200)

with freeze_time(now + datetime.timedelta(seconds=11)):
res = testapp.get(url_for("public.reset_password", token=token)).follow()
assert "Your reset password link has expired" in res

# Reset password
new_password = "new" + default_password
with freeze_time(now + datetime.timedelta(seconds=5)):
res = testapp.get(url_for("public.reset_password", token=token), status=200)
form = res.form
form["password"] = new_password
form["confirm"] = new_password
res = form.submit().follow()
assert "Your password is reset" in res
assert user.check_password(new_password)

# See if the link expires after we have reset the password already
with freeze_time(now):
res = testapp.get(url_for("public.reset_password", token=token)).follow()
assert "Your reset password link has expired" in res
16 changes: 16 additions & 0 deletions tests/functional/test_register.py
@@ -0,0 +1,16 @@
from flask import url_for

from sampleapp.models.accounts import User


def test_register(testapp):
res = testapp.get(url_for("public.register"))
form = res.form
form["email"] = "foo@bar.com"
form["password"] = "secret"
form["confirm"] = "secret"
form["agree_terms"] = "1"
res = form.submit().follow()
assert res.status_code == 200
user = User.query.filter_by(email="foo@bar.com").first()
assert user is not None

0 comments on commit e04d3bd

Please sign in to comment.