aurweb/test/test_accounts_routes.py
Kevin Morris 9fdbe3f775 add authenticated User LangPreference tracking
+ Use User.LangPreference when there is no set AURSID
  if request.user.is_authenticated is true.
+ Updated post /language to update LangPreference when
  request.user.is_authenticated.
+ Restore language during test where we change it.
+ Added the user attribute to aurweb.testing.requests.Request.

Signed-off-by: Kevin Morris <kevr@0cost.org>
2021-06-05 20:11:17 -07:00

222 lines
6.9 KiB
Python

from http import HTTPStatus
import pytest
from fastapi.testclient import TestClient
from aurweb.asgi import app
from aurweb.db import query
from aurweb.models.account_type import AccountType
from aurweb.models.session import Session
from aurweb.models.user import User
from aurweb.testing import setup_test_db
from aurweb.testing.models import make_user
from aurweb.testing.requests import Request
# Some test global constants.
TEST_USERNAME = "test"
TEST_EMAIL = "test@example.org"
# Global mutables.
client = TestClient(app)
user = None
@pytest.fixture(autouse=True)
def setup():
global user
setup_test_db("Users", "Sessions", "Bans")
account_type = query(AccountType,
AccountType.AccountType == "User").first()
user = make_user(Username=TEST_USERNAME, Email=TEST_EMAIL,
RealName="Test User", Passwd="testPassword",
AccountType=account_type)
def test_get_passreset_authed_redirects():
sid = user.login(Request(), "testPassword")
assert sid is not None
with client as request:
response = request.get("/passreset", cookies={"AURSID": sid},
allow_redirects=False)
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/"
def test_get_passreset():
with client as request:
response = request.get("/passreset")
assert response.status_code == int(HTTPStatus.OK)
def test_get_passreset_translation():
# Test that translation works; set it to de.
with client as request:
response = request.get("/passreset", cookies={"AURLANG": "de"})
# The header title should be translated.
assert "Passwort zurücksetzen".encode("utf-8") in response.content
# The form input label should be translated.
assert "Benutzername oder primäre E-Mail-Adresse eingeben:".encode(
"utf-8") in response.content
# And the button.
assert "Weiter".encode("utf-8") in response.content
# Restore english.
with client as request:
response = request.get("/passreset", cookies={"AURLANG": "en"})
def test_get_passreset_with_resetkey():
with client as request:
response = request.get("/passreset", data={"resetkey": "abcd"})
assert response.status_code == int(HTTPStatus.OK)
def test_post_passreset_authed_redirects():
sid = user.login(Request(), "testPassword")
assert sid is not None
with client as request:
response = request.post("/passreset",
cookies={"AURSID": sid},
data={"user": "blah"},
allow_redirects=False)
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/"
def test_post_passreset_user():
# With username.
with client as request:
response = request.post("/passreset", data={"user": TEST_USERNAME})
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/passreset?step=confirm"
# With e-mail.
with client as request:
response = request.post("/passreset", data={"user": TEST_EMAIL})
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/passreset?step=confirm"
def test_post_passreset_resetkey():
from aurweb.db import session
user.session = Session(UsersID=user.ID, SessionID="blah",
LastUpdateTS=datetime.utcnow().timestamp())
session.commit()
# Prepare a password reset.
with client as request:
response = request.post("/passreset", data={"user": TEST_USERNAME})
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/passreset?step=confirm"
# Now that we've prepared the password reset, prepare a POST
# request with the user's ResetKey.
resetkey = user.ResetKey
post_data = {
"user": TEST_USERNAME,
"resetkey": resetkey,
"password": "abcd1234",
"confirm": "abcd1234"
}
with client as request:
response = request.post("/passreset", data=post_data)
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/passreset?step=complete"
def test_post_passreset_error_invalid_email():
# First, test with a user that doesn't even exist.
with client as request:
response = request.post("/passreset", data={"user": "invalid"})
assert response.status_code == int(HTTPStatus.NOT_FOUND)
error = "Invalid e-mail."
assert error in response.content.decode("utf-8")
# Then, test with an invalid resetkey for a real user.
_ = make_resetkey()
post_data = make_passreset_data("fake")
post_data["password"] = "abcd1234"
post_data["confirm"] = "abcd1234"
with client as request:
response = request.post("/passreset", data=post_data)
assert response.status_code == int(HTTPStatus.NOT_FOUND)
assert error in response.content.decode("utf-8")
def make_resetkey():
with client as request:
response = request.post("/passreset", data={"user": TEST_USERNAME})
assert response.status_code == int(HTTPStatus.SEE_OTHER)
assert response.headers.get("location") == "/passreset?step=confirm"
return user.ResetKey
def make_passreset_data(resetkey):
return {
"user": user.Username,
"resetkey": resetkey
}
def test_post_passreset_error_missing_field():
# Now that we've prepared the password reset, prepare a POST
# request with the user's ResetKey.
resetkey = make_resetkey()
post_data = make_passreset_data(resetkey)
with client as request:
response = request.post("/passreset", data=post_data)
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
error = "Missing a required field."
assert error in response.content.decode("utf-8")
def test_post_passreset_error_password_mismatch():
resetkey = make_resetkey()
post_data = make_passreset_data(resetkey)
post_data["password"] = "abcd1234"
post_data["confirm"] = "mismatched"
with client as request:
response = request.post("/passreset", data=post_data)
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
error = "Password fields do not match."
assert error in response.content.decode("utf-8")
def test_post_passreset_error_password_requirements():
resetkey = make_resetkey()
post_data = make_passreset_data(resetkey)
passwd_min_len = User.minimum_passwd_length()
assert passwd_min_len >= 4
post_data["password"] = "x"
post_data["confirm"] = "x"
with client as request:
response = request.post("/passreset", data=post_data)
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
error = f"Your password must be at least {passwd_min_len} characters."
assert error in response.content.decode("utf-8")