Skip to content

Commit

Permalink
tests: Add tests for solution matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
yammesicka committed Mar 24, 2024
1 parent 0f29545 commit 3908869
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lms/lmsdb/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def get_matrix(self, database: Database = database) -> dict:
}

def __str__(self):
return f'{self.name}: {self.date} - {self.end_date}'
return self.name

Check warning on line 249 in lms/lmsdb/models.py

View check run for this annotation

Codecov / codecov/patch

lms/lmsdb/models.py#L249

Added line #L249 was not covered by tests


class User(UserMixin, BaseModel):
Expand Down
24 changes: 22 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@ def enable_registration():
webapp.config['REGISTRATION_OPEN'] = True


@pytest.fixture
def user_client(student_user) -> FlaskClient:
client = webapp.test_client()
client.post('/login', data={ # noqa: S106
'username': student_user.username,
'password': FAKE_PASSWORD,
}, follow_redirects=True)
return client


@pytest.fixture
def admin_client(admin_user) -> FlaskClient:
client = webapp.test_client()
client.post('/login', data={ # noqa: S106
'username': admin_user.username,
'password': FAKE_PASSWORD,
}, follow_redirects=True)
return client


def disable_shareable_solutions():
webapp.config['SHAREABLE_SOLUTIONS'] = False

Expand Down Expand Up @@ -283,10 +303,10 @@ def create_notification(
)


def create_course(index: int = 0) -> Course:
def create_course(index: int = 0, name: str | None = None) -> Course:
return Course.create(
number=index,
name=f'course {index}',
name=name or f'course {index}',
date=datetime.datetime.now(),
)

Expand Down
67 changes: 67 additions & 0 deletions tests/test_check_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import http
from unittest import mock

from flask.testing import FlaskClient

from lms.lmsdb.models import Solution
from lms.lmsweb import routes
from tests import conftest


celery_async = (
"lms.lmstests.public.general.tasks."
"reset_solution_state_if_needed.apply_async"
)
no_celery = mock.patch(celery_async, lambda *args, **kwargs: None)


class TestCheckPages:
@classmethod
def setup_method(cls):
cls.course = conftest.create_course()
cls.user = conftest.create_user(index=1)
cls.user2 = conftest.create_user(index=2)
cls.exercise = conftest.create_exercise(cls.course, number=1)

solution = conftest.create_solution
cls.solution1 = solution(cls.exercise, cls.user, code="A")
cls.solution2 = solution(cls.exercise, cls.user, code="B")
cls.solution3 = solution(cls.exercise, cls.user2)

@classmethod
def test_start_checking(cls, admin_client: FlaskClient):
check_url = f"check/exercise/{cls.exercise.id}"

with no_celery:
# You should check the newer, not the older (same user)
response = admin_client.get(check_url, follow_redirects=True)
assert response.request.url.endswith(f"view/{cls.solution2.id}")

# First exercise should be marked as checking
response = admin_client.get(check_url, follow_redirects=True)
assert response.request.url.endswith(f"view/{cls.solution3.id}")

# All exercises are checked
response = admin_client.get(check_url, follow_redirects=True)
status_page = response.request.url.strip("/")
assert status_page.endswith(f"/{routes.STATUS.strip('/')}")

@classmethod
def test_check_solution(cls, admin_client: FlaskClient):
check_url = "check/solution/{}"
go_to = admin_client.get
solution = check_url.format

with no_celery:
response = go_to(solution(5000), follow_redirects=True)
assert response.status_code == http.HTTPStatus.NOT_FOUND

assert cls.solution1.state == Solution.STATES.CREATED.name
response = go_to(solution(cls.solution1.id), follow_redirects=True)
assert response.request.url.endswith(f"view/{cls.solution1.id}")
cls.solution1 = Solution.get_by_id(cls.solution1.id) # Must refresh
assert cls.solution1.state == Solution.STATES.IN_CHECKING.name

cls.solution1.mark_as_checked()
response = go_to(solution(cls.solution1.id), follow_redirects=True)
assert response.request.url.endswith(f"view/{cls.solution1.id}")
34 changes: 34 additions & 0 deletions tests/test_course.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from lms.lmsdb.models import Course
from lms.models import courses
from tests import conftest


class TestCourse:
@staticmethod
def test_course_exercises(course: Course):
ex1 = conftest.create_exercise(course, 0)
ex2 = conftest.create_exercise(course, 1)
exercises = course.get_exercise_ids()
assert len(exercises) == 2
assert ex1.id in exercises
assert ex2.id in exercises

@staticmethod
def test_course_name():
course = conftest.create_course(name='Test course')
assert course.name == 'Test course'

@staticmethod
def test_course_students(course: Course):
course_id = course.id
students = [conftest.create_user(index=i) for i in range(3)]

# No users in course
assert len(courses.get_students(course_id)) == 0

# Add users to course
for student in students:
conftest.create_usercourse(student, course)

discovered = courses.get_students(course_id)
assert len(discovered) == 3
4 changes: 2 additions & 2 deletions tests/test_exercise_unit_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ def _verify_comments():
assert "foo('bar') == 'barbaron'" in first.staff_message

def test_register_two_exercises_with_same_name(
self,
course: models.Course,
self,
course: models.Course,
):
ex1 = conftest.create_exercise(course, 0)
ex2 = conftest.create_exercise(course, 0)
Expand Down
22 changes: 22 additions & 0 deletions tests/test_exercises.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime

from lms.lmsdb.models import Course, Exercise, User
from lms.models import exercises
from tests import conftest


Expand Down Expand Up @@ -52,3 +53,24 @@ def test_courses_exercises(
template, _ = captured_templates[-1]
assert template.name == 'exercises.html'
assert len(list(Exercise.get_objects(student_user.id))) == 2

@staticmethod
def test_get_basic_exercises_view():
basic_view = exercises.get_basic_exercises_view
assert len(basic_view(course_id=None)) == 0

course1 = conftest.create_course(index=1)
course2 = conftest.create_course(index=2)
assert len(basic_view(course_id=None)) == 0

ex = [conftest.create_exercise(course1, i) for i in range(3)]
assert len(basic_view(course_id=None)) == 3
assert len(basic_view(course_id=course1.id)) == 3
assert len(basic_view(course_id=course2.id)) == 0
assert basic_view(course_id=None)[0].id == ex[0].id

ex2 = [conftest.create_exercise(course2, i) for i in range(3, 6)]
assert len(basic_view(course_id=None)) == 6
assert len(basic_view(course_id=course1.id)) == 3
assert len(basic_view(course_id=course2.id)) == 3
assert basic_view(course_id=2)[0].id == ex2[0].id
12 changes: 9 additions & 3 deletions tests/test_submissions_page.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from lms.lmsdb.models import Course
from tests import conftest


Expand Down Expand Up @@ -45,7 +44,14 @@ def setup_method(cls):
cls.s5 = solution(cls.ex2_1, cls.user1)

@classmethod
def test_we_get_users_x_exercises_results(cls, db_in_memory):
all_solutions = cls.course1.get_matrix(db_in_memory)
def test_we_get_users_x_exercises_results(cls, db):
all_solutions = cls.course1.get_matrix(db)
solution_count = len(cls.user_ids) * len(cls.exercise_ids)
assert len(all_solutions) == solution_count

assert len(cls.course2.get_matrix(db)) == 0

students_count = len(cls.course3.get_students())
exercise_count = len(cls.course3.get_exercise_ids())
solution_count = students_count * exercise_count
assert len(cls.course3.get_matrix(db)) == solution_count

0 comments on commit 3908869

Please sign in to comment.