Skip to content

Commit

Permalink
Basic listing of course's assignments in the admin pages
Browse files Browse the repository at this point in the history
  • Loading branch information
marcospri committed Mar 11, 2024
1 parent 3afd623 commit 5b514e5
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 1 deletion.
5 changes: 5 additions & 0 deletions lms/models/grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ class MoodleGroup(Grouping):
class Course(Grouping):
__mapper_args__ = {"polymorphic_identity": Grouping.Type.COURSE}

assignments = sa.orm.relationship(
"Assignment", secondary="assignment_grouping", viewonly=True
)
"""Assignments that belong to this course."""

def set_group_sets(self, group_sets: list[dict]):
"""
Store this course's available group sets.
Expand Down
2 changes: 2 additions & 0 deletions lms/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ def includeme(config): # pylint:disable=too-many-statements
config.add_route("admin.courses", "/admin/courses")
config.add_route("admin.course", "/admin/course/{id_}")

config.add_route("admin.assignment", "/admin/assignment/{id_}")

config.add_route("admin.email", "/admin/email")
config.add_route(
"admin.email.preview.instructor_email_digest",
Expand Down
3 changes: 3 additions & 0 deletions lms/services/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ def upsert_assignment_groupings(
)
)

def get_by_id(self, id_: int) -> Assignment | None:
return self._db.query(Assignment).filter_by(id=id_).one_or_none()


def factory(_context, request):
return AssignmentService(
Expand Down
14 changes: 14 additions & 0 deletions lms/templates/admin/assignment/show.html.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% import "lms:templates/admin/macros.html.jinja2" as macros %}
{% extends "lms:templates/admin/base.html.jinja2" %}
{% block header %}Assignment {{ assignment.id }}{% endblock %}
{% block content %}
<div>
<fieldset>
<legend class="label has-text-centered">Assignment</legend>
{{ macros.disabled_text_field("ID", assignment.id) }}
{{ macros.disabled_text_field("Title", assignment.title) }}
{{ macros.disabled_text_field("Document", assignment.document_url) }}
{{ macros.created_updated_fields(assignment) }}
</fieldset>
</div>
{% endblock %}
6 changes: 6 additions & 0 deletions lms/templates/admin/course/show.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
{{ macros.disabled_text_field("H ID", course.authority_provided_id) }}
{{ macros.created_updated_fields(course) }}
</fieldset>

<fieldset>
<legend class="label has-text-centered">Assignments</legend>
{{ macros.assignments_table(request, course.assignments) }}
</fieldset>

<fieldset class="box mt-6">
<legend class="label has-text-centered">Application Instance</legend>
{{ macros.instance_preview(request, course.application_instance) }}
Expand Down
7 changes: 7 additions & 0 deletions lms/templates/admin/macros.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,10 @@
});
</script>
{% endmacro %}
{% macro assignments_table(request, assignments) %}
{{ object_list_table(request, 'admin.assignment', assignments,
fields=[
{"label": "Title", "name": "title"},
{"label": "Resource link id", "name": "resource_link_id"},
]) }}
{% endmacro %}
32 changes: 32 additions & 0 deletions lms/views/admin/assignment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config, view_defaults

from lms.models import Assignment
from lms.security import Permissions


@view_defaults(request_method="GET", permission=Permissions.ADMIN)
class AdminAssignmentViews:
def __init__(self, request) -> None:
self.request = request
self.assignment_service = request.find_service(name="assignment")

@view_config(
route_name="admin.assignment",
request_method="GET",
renderer="lms:templates/admin/assignment/show.html.jinja2",
permission=Permissions.STAFF,
)
def show(self):
assignment_id = self.request.matchdict["id_"]
assignment = self._get_or_404(assignment_id)

return {
"assignment": assignment,
}

def _get_or_404(self, id_) -> Assignment:
if assignment := self.assignment_service.get_by_id(id_=id_):
return assignment

raise HTTPNotFound()
6 changes: 6 additions & 0 deletions tests/unit/lms/services/assignment_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ def test_upsert_assignment_grouping(self, svc, assignment, db_session):
]
)

def test_get_by_id(self, svc, db_session):
assignment = factories.Assignment()
db_session.flush()

assert assignment == svc.get_by_id(assignment.id)

@pytest.fixture
def svc(self, db_session, misc_plugin, grouping_plugin):
return AssignmentService(db_session, misc_plugin, grouping_plugin)
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/lms/views/admin/assignment_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from unittest.mock import sentinel

import pytest
from pyramid.httpexceptions import HTTPNotFound

from lms.views.admin.assignment import AdminAssignmentViews


class TestAdminAssignmentViews:
def test_show(self, pyramid_request, assignment_service, views):
pyramid_request.matchdict["id_"] = sentinel.id_

response = views.show()

assignment_service.get_by_id.assert_called_once_with(id_=sentinel.id_)

assert response == {
"assignment": assignment_service.get_by_id.return_value,
}

def test_show_not_found(self, pyramid_request, assignment_service, views):
pyramid_request.matchdict["id_"] = sentinel.id_
assignment_service.get_by_id.return_value = None

with pytest.raises(HTTPNotFound):
views.show()

@pytest.fixture
def views(self, pyramid_request):
return AdminAssignmentViews(pyramid_request)
2 changes: 1 addition & 1 deletion tests/unit/lms/views/admin/course_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


@pytest.mark.usefixtures("course_service", "organization_service")
class TestAdminCouseViews:
class TestAdminCourseViews:
def test_show(self, pyramid_request, course_service, views):
pyramid_request.matchdict["id_"] = sentinel.id_

Expand Down

0 comments on commit 5b514e5

Please sign in to comment.