Skip to content

Commit

Permalink
completed unit tests for logout()
Browse files Browse the repository at this point in the history
  • Loading branch information
Morgan-Sell committed Nov 18, 2024
1 parent 2cdbdd6 commit 5c26c79
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/controller/auth_controller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import Blueprint, flash, redirect, render_template, url_for, current_app
from flask import Blueprint, current_app, flash, redirect, render_template, url_for
from flask_login import login_required, login_user, logout_user

from src.forms.user_forms import LogInForm, RegisterForm
Expand All @@ -16,7 +16,7 @@ def login():
if form.validate_on_submit():
username = form.username.data
password = form.password.data

# Enables connection to different databases, e.g., test & prod
session = current_app.session
user_repo = UsersRepository(session)
Expand Down
12 changes: 6 additions & 6 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import pytest
from flask import Flask
from flask.testing import FlaskClient
from flask_login import AnonymousUserMixin, LoginManager
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from src.config import TaskStatus
from src.controller.auth_controller import auth_blueprint
from src.controller.tasks_controller import tasks_blueprint
from src.models import Base, Tasks, Users
from src.repository.tasks_repository import TasksRespository
from src.repository.users_repository import UsersRepository
from src.security import generate_password_hash

from flask_login import LoginManager, AnonymousUserMixin
from src.controller.tasks_controller import tasks_blueprint
from flask.testing import FlaskClient

@pytest.fixture(scope="function")
def test_db():
Expand Down Expand Up @@ -99,14 +99,14 @@ def app(test_db):
app.config["APPLICATION_ROOT"] = "/"
app.config["SECRET_KEY"] = "shhhh_dont_tell_anyone"
app.config["WTF_CSRF_ENABLED"] = False

# Attach test_db session for testing
app.session = test_db

# Initialize Flask-login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
login_manager.login_view = "auth.login"

# Enable the loading of users during the test
@login_manager.user_loader
Expand Down
77 changes: 66 additions & 11 deletions tests/test_controller/test_auth_controller.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from urllib.parse import urlparse

from src.models import Users, Tasks
from src.repository.users_repository import UsersRepository
from flask import url_for
from flask_login import login_user

from unittest.mock import patch, MagicMock

from src.models import Tasks, Users
from src.repository.users_repository import UsersRepository
from src.security import check_password_hash, generate_password_hash


# -- LOGIN TEST CASES --
def test_login_page_load_success(client, app):
with app.app_context():
mock_user = MagicMock()
Expand All @@ -23,8 +22,8 @@ def test_login_page_load_success(client, app):
# perform the request
response = client.get(url_for("auth.login"))
assert response.status_code == 200
assert b'LOGIN' in response.data
assert b'Peak Performer' in response.data
assert b"LOGIN" in response.data
assert b"Peak Performer" in response.data


def test_login_valid_credentails(client, app):
Expand All @@ -33,12 +32,12 @@ def test_login_valid_credentails(client, app):
response = client.post(
url_for("auth.login"),
data={"username": "Will_Smith", "password": "fresh_password"},
follow_redirects=False, # prevents the test client from retriev view_tasks.html content
follow_redirects=False, # prevents the test client from retriev view_tasks.html content
)

# Assert
assert response.status_code == 302 # Redirect
assert response.status_code == 302 # Redirect

# Ensure only paths are compared. Ignore protocl and hostname differences.
response_path = urlparse(response.location).path
expected_path = url_for("tasks.view_tasks", user_id=1, _external=False)
Expand Down Expand Up @@ -84,4 +83,60 @@ def test_login_form_validation(client, app):

# Assert that validation errors are displayed
assert response.status_code == 200
assert b"Because you're always on top of the mountain (or at least your to-do list)" in response.data
assert (
b"Because you're always on top of the mountain (or at least your to-do list)"
in response.data
)


# -- LOG OUT TEST CASES --
def test_logout_redirects_to_login_page(client, app):
with app.app_context():
# simulate a logged-in user
with client:
response = client.get(url_for("auth.logout"), follow_redirects=False)

# Assert
assert response.status_code == 302 # Redirect

# Ensure only paths are compared. Ignore protocl and hostname differences.
response_path = urlparse(response.location).path
expected_path = url_for("auth.login", _external=False)
assert response_path == expected_path


def test_logout_flash_message(client, app, users_repository):
with app.app_context():
with client:
user = users_repository.find_user_by_username("Carlton_Banks")
# Log in the user via session transaction
with client.session_transaction() as session:
session["_user_id"] = str(user.id)

response = client.get(url_for("auth.logout"), follow_redirects=True)

# Assert
assert response.status_code == 200
# Check for flash message
assert b"You have successfully logged out." in response.data


def test_logout_protected_route_after_logout(client, app, users_repository):
with app.app_context():
user = users_repository.find_user_by_username("Carlton_Banks")

with client:
# Log in the user via session transaction
with client.session_transaction() as session:
session["_user_id"] = str(user.id)

# Assert: successful logout
response = client.get(url_for("auth.logout"), follow_redirects=True)
assert response.status_code == 200

# Assert: Prevent logged out user from accessing protected route
protect_response = client.get(
url_for("tasks.view_tasks", user_id=user.id), follow_redirects=True
)
assert response.status_code == 200
assert b"LOGIN" in protect_response.data

0 comments on commit 5c26c79

Please sign in to comment.