Skip to content

Commit

Permalink
Base test class to handle auth (#153)
Browse files Browse the repository at this point in the history
* Adding auth tokens

* Setup for auth tests

* Fixing tests

* Cleanup

* Spelling

* Remove unnecessary commit
  • Loading branch information
JarneClauw authored Apr 1, 2024
1 parent e43bf95 commit 0aea3a3
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 6 deletions.
36 changes: 36 additions & 0 deletions backend/test_auth_server/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
index_bp = Blueprint("index", __name__)
index_endpoint = Api(index_bp)

# Take the key the same as the id, uid can then be used in backend
token_dict = {
"teacher1":{
"id":"Gunnar",
Expand Down Expand Up @@ -44,6 +45,41 @@
"admin1":{
"id":"admin_person",
"jobTitle":"admin"
},
# Lowest authorized user to test login requirement
"login": {
"id": "login",
"jobTitle": None
},
# Student authorization access, associated with valid_...
"student": {
"id": "student",
"jobTitle": None
},
# Student authorization access, other
"student_other": {
"id": "student_other",
"jobTitle": None
},
# Teacher authorization access, associated with valid_...
"teacher": {
"id": "teacher",
"jobTitle": "teacher"
},
# Teacher authorization access, other
"teacher_other": {
"id": "teacher_other",
"jobTitle": "teacher"
},
# Admin authorization access, associated with valid_...
"admin": {
"id": "admin",
"jobTitle": "admin"
},
# Admin authorization access, other
"admin_other": {
"id": "admin_other",
"jobTitle": "admin"
}
}

Expand Down
23 changes: 20 additions & 3 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
from pytest import fixture
from project.sessionmaker import engine, Session
from project.db_in import db
from project.models.course import Course
Expand All @@ -11,7 +11,7 @@
from project.models.course_relation import CourseStudent,CourseAdmin
from project.models.submission import Submission, SubmissionStatus

@pytest.fixture
@fixture
def db_session():
"""Create a new database session for a test.
After the test, all changes are rolled back and the session is closed."""
Expand Down Expand Up @@ -123,7 +123,22 @@ def submissions(session):
)
]

@pytest.fixture
### AUTHENTICATION & AUTHORIZATION ###
def auth_tokens():
"""Add the authenticated users to the database"""

return [
User(uid="login", role=Role.STUDENT),
User(uid="student", role=Role.STUDENT),
User(uid="student_other", role=Role.STUDENT),
User(uid="teacher", role=Role.TEACHER),
User(uid="teacher_other", role=Role.TEACHER),
User(uid="admin", role=Role.ADMIN),
User(uid="admin_other", role=Role.ADMIN)
]

### SESSION ###
@fixture
def session():
"""Create a new database session for a test.
After the test, all changes are rolled back and the session is closed."""
Expand All @@ -132,6 +147,8 @@ def session():
session = Session()

try:
session.add_all(auth_tokens())

# Populate the database
session.add_all(users())
session.commit()
Expand Down
18 changes: 18 additions & 0 deletions backend/tests/endpoints/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
from pytest import fixture, FixtureRequest
from flask.testing import FlaskClient
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError
from project.models.user import User,Role
Expand All @@ -15,7 +17,23 @@
from project.models.submission import Submission, SubmissionStatus
from project.models.project import Project

### AUTHENTICATION & AUTHORIZATION ###
@fixture
def auth_test(request: FixtureRequest, client: FlaskClient, valid_course_entry):
"""Add concrete test data"""
# endpoint, parameters, method, token, status
endpoint, parameters, method, *other = request.param

d = {
"course_id": valid_course_entry.course_id
}

for index, parameter in enumerate(parameters):
endpoint = endpoint.replace(f"@{index}", str(d[parameter]))

return endpoint, getattr(client, method), *other

### OTHER ###
@pytest.fixture
def valid_submission(valid_user_entry, valid_project_entry):
"""
Expand Down
56 changes: 56 additions & 0 deletions backend/tests/endpoints/endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Base class for endpoint tests"""

from typing import List, Tuple
from pytest import param

def authentication_tests(tests: List[Tuple[str, List[str], List[str]]]) -> List[any]:
"""Transform the format to single authentication tests"""

single_tests = []
for test in tests:
endpoint, parameters, methods = test
for method in methods:
single_tests.append(param(
(endpoint, parameters, method),
id = f"{endpoint} {method}"
))
return single_tests

def authorization_tests(tests: List[Tuple[str, List[str], str, List[str], List[str]]]) -> List[any]:
"""Transform the format to single authorization tests"""

single_tests = []
for test in tests:
endpoint, parameters, method, allowed_tokens, disallowed_tokens = test
for token in (allowed_tokens + disallowed_tokens):
allowed = token in allowed_tokens
single_tests.append(param(
(endpoint, parameters, method, token, allowed),
id = f"{endpoint} {method} {token} {'allowed' if allowed else 'disallowed'}"
))
return single_tests

class TestEndpoint:
"""Base class for endpoint tests"""

def authentication(self, authentication_parameter: Tuple[str, any]):
"""Test if the authentication for the given enpoint works"""

endpoint, method = authentication_parameter

response = method(endpoint)
assert response.status_code == 401

response = method(endpoint, headers = {"Authorization": "0123456789"})
assert response.status_code == 401

response = method(endpoint, headers = {"Authorization": "login"})
assert response.status_code != 401

def authorization(self, auth_parameter: Tuple[str, any, str, bool]):
"""Test if the authorization for the given endpoint works"""

endpoint, method, token, allowed = auth_parameter

response = method(endpoint, headers = {"Authorization": token})
assert allowed == (response.status_code != 403)
6 changes: 3 additions & 3 deletions backend/tests/models/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ def test_create_user(self, session: Session):
session.add(user)
session.commit()
assert session.get(User, "user01") is not None
assert session.query(User).count() == 5
assert session.query(User).count() == 12

def test_query_user(self, session: Session):
"""Test if a user can be queried"""
assert session.query(User).count() == 4
assert session.query(User).count() == 11
teacher = session.query(User).filter_by(uid="brinkmann").first()
assert teacher is not None
assert teacher.role == Role.ADMIN
Expand All @@ -36,7 +36,7 @@ def test_delete_user(self, session: Session):
session.delete(user)
session.commit()
assert session.get(User, user.uid) is None
assert session.query(User).count() == 3
assert session.query(User).count() == 10

@mark.parametrize("property_name", ["uid"])
def test_property_not_nullable(self, session: Session, property_name: str):
Expand Down

0 comments on commit 0aea3a3

Please sign in to comment.