diff --git a/test/test_auth_routes.py b/test/test_auth_routes.py index 0157fcc8..a8d0db11 100644 --- a/test/test_auth_routes.py +++ b/test/test_auth_routes.py @@ -8,11 +8,12 @@ from fastapi.testclient import TestClient import aurweb.config +from aurweb import db from aurweb.asgi import app -from aurweb.db import begin, create, query -from aurweb.models.account_type import AccountType +from aurweb.models.account_type import USER_ID from aurweb.models.session import Session from aurweb.models.user import User +from aurweb.testing.requests import Request # Some test global constants. TEST_USERNAME = "test" @@ -21,30 +22,32 @@ TEST_REFERER = { "referer": aurweb.config.get("options", "aur_location") + "/login", } -# Global mutables. -user = client = None - @pytest.fixture(autouse=True) def setup(db_test): - global user, client + return - account_type = query(AccountType, - AccountType.AccountType == "User").first() - with begin(): - user = create(User, Username=TEST_USERNAME, Email=TEST_EMAIL, - RealName="Test User", Passwd="testPassword", - AccountType=account_type) - - client = TestClient(app) +@pytest.fixture +def client() -> TestClient: + client = TestClient(app=app) # Necessary for forged login CSRF protection on the login route. Set here # instead of only on the necessary requests for convenience. client.headers.update(TEST_REFERER) + yield client -def test_login_logout(): +@pytest.fixture +def user() -> User: + with db.begin(): + user = db.create(User, Username=TEST_USERNAME, Email=TEST_EMAIL, + RealName="Test User", Passwd="testPassword", + AccountTypeID=USER_ID) + yield user + + +def test_login_logout(client: TestClient, user: User): post_data = { "user": "test", "passwd": "testPassword", @@ -83,7 +86,7 @@ def mock_getboolean(a, b): @mock.patch("aurweb.config.getboolean", side_effect=mock_getboolean) -def test_secure_login(mock): +def test_secure_login(getboolean: bool, client: TestClient, user: User): """ In this test, we check to verify the course of action taken by starlette when providing secure=True to a response cookie. This is achieved by mocking aurweb.config.getboolean to return @@ -94,11 +97,11 @@ def test_secure_login(mock): on such a request. """ # Create a local TestClient here since we mocked configuration. - client = TestClient(app) + # client = TestClient(app) # Necessary for forged login CSRF protection on the login route. Set here # instead of only on the necessary requests for convenience. - client.headers.update(TEST_REFERER) + # client.headers.update(TEST_REFERER) # Data used for our upcoming http post request. post_data = { @@ -126,18 +129,19 @@ def test_secure_login(mock): # Let's make sure we actually have a session relationship # with the AURSID we ended up with. - record = query(Session, Session.SessionID == cookie.value).first() + record = db.query(Session, Session.SessionID == cookie.value).first() assert record is not None and record.User == user assert user.session == record -def test_authenticated_login(): +def test_authenticated_login(client: TestClient, user: User): post_data = { "user": "test", "passwd": "testPassword", "next": "/" } + cookies = {"AURSID": user.login(Request(), "testPassword")} with client as request: # Try to login. response = request.post("/login", data=post_data, @@ -149,12 +153,13 @@ def test_authenticated_login(): # when requesting GET /login as an authenticated user. # Now, let's verify that we receive 403 Forbidden when we # try to get /login as an authenticated user. - response = request.get("/login", allow_redirects=False) + response = request.get("/login", cookies=cookies, + allow_redirects=False) assert response.status_code == int(HTTPStatus.OK) assert "Logged-in as: test" in response.text -def test_unauthenticated_logout_unauthorized(): +def test_unauthenticated_logout_unauthorized(client: TestClient): with client as request: # Alright, let's verify that attempting to /logout when not # authenticated returns 401 Unauthorized. @@ -163,7 +168,7 @@ def test_unauthenticated_logout_unauthorized(): assert response.headers.get("location").startswith("/login") -def test_login_missing_username(): +def test_login_missing_username(client: TestClient): post_data = { "passwd": "testPassword", "next": "/" @@ -179,7 +184,7 @@ def test_login_missing_username(): assert "checked" not in content -def test_login_remember_me(): +def test_login_remember_me(client: TestClient, user: User): post_data = { "user": "test", "passwd": "testPassword", @@ -197,16 +202,15 @@ def test_login_remember_me(): "options", "persistent_cookie_timeout") expected_ts = datetime.utcnow().timestamp() + cookie_timeout - _session = query(Session, - Session.UsersID == user.ID).first() + session = db.query(Session).filter(Session.UsersID == user.ID).first() # Expect that LastUpdateTS was within 5 seconds of the expected_ts, # which is equal to the current timestamp + persistent_cookie_timeout. - assert _session.LastUpdateTS > expected_ts - 5 - assert _session.LastUpdateTS < expected_ts + 5 + assert session.LastUpdateTS > expected_ts - 5 + assert session.LastUpdateTS < expected_ts + 5 -def test_login_incorrect_password_remember_me(): +def test_login_incorrect_password_remember_me(client: TestClient, user: User): post_data = { "user": "test", "passwd": "badPassword", @@ -218,15 +222,14 @@ def test_login_incorrect_password_remember_me(): response = request.post("/login", data=post_data) assert "AURSID" not in response.cookies - # Make sure username is prefilled, password isn't prefilled, and remember_me - # is checked. - content = response.content.decode() - assert post_data["user"] in content - assert post_data["passwd"] not in content - assert "checked" in content + # Make sure username is prefilled, password isn't prefilled, + # and remember_me is checked. + assert post_data["user"] in response.text + assert post_data["passwd"] not in response.text + assert "checked" in response.text -def test_login_missing_password(): +def test_login_missing_password(client: TestClient): post_data = { "user": "test", "next": "/" @@ -237,12 +240,11 @@ def test_login_missing_password(): assert "AURSID" not in response.cookies # Make sure username is prefilled and remember_me isn't checked. - content = response.content.decode() - assert post_data["user"] in content - assert "checked" not in content + assert post_data["user"] in response.text + assert "checked" not in response.text -def test_login_incorrect_password(): +def test_login_incorrect_password(client: TestClient): post_data = { "user": "test", "passwd": "badPassword", @@ -253,15 +255,14 @@ def test_login_incorrect_password(): response = request.post("/login", data=post_data) assert "AURSID" not in response.cookies - # Make sure username is prefilled, password isn't prefilled and remember_me - # isn't checked. - content = response.content.decode() - assert post_data["user"] in content - assert post_data["passwd"] not in content - assert "checked" not in content + # Make sure username is prefilled, password isn't prefilled + # and remember_me isn't checked. + assert post_data["user"] in response.text + assert post_data["passwd"] not in response.text + assert "checked" not in response.text -def test_login_bad_referer(): +def test_login_bad_referer(client: TestClient): post_data = { "user": "test", "passwd": "testPassword",