Skip to content

Commit

Permalink
Disable submission auto-creation while submitting grades to Canvas
Browse files Browse the repository at this point in the history
  • Loading branch information
marcospri committed Sep 26, 2024
1 parent 42e22a7 commit b40c4a7
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 4 deletions.
10 changes: 10 additions & 0 deletions lms/models/lti_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ class LTIRegistration(CreatedUpdatedMixin, Base):
application_instances = sa.orm.relationship(
"ApplicationInstance", back_populates="lti_registration"
)

@property
def product_family(self) -> str:
"""To which LMS (Canvas, D2L, BB..) does this registration belong."""
from lms.product.family import Family # noqa: PLC0415

if self.issuer.endswith(".instructure.com"):
return Family.CANVAS

return Family.UNKNOWN
9 changes: 6 additions & 3 deletions lms/product/plugin/misc.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from typing import NotRequired, TypedDict
from typing import TYPE_CHECKING, NotRequired, TypedDict

from pyramid.request import Request

from lms.js_config_types import AutoGradingConfig
from lms.models import Assignment, LTIParams, LTIRegistration
from lms.models import Assignment, LTIParams
from lms.services.html_service import strip_html_tags

if TYPE_CHECKING:
from lms.models import LTIRegistration


class AssignmentConfig(TypedDict):
document_url: str | None
Expand Down Expand Up @@ -58,7 +61,7 @@ def is_assignment_gradable(self, lti_params: LTIParams) -> bool:
"""Check if the assignment of the current launch is gradable."""
return bool(lti_params.get("lis_outcome_service_url"))

def get_ltia_aud_claim(self, lti_registration: LTIRegistration) -> str:
def get_ltia_aud_claim(self, lti_registration: "LTIRegistration") -> str:
"""Get the value of the `aud` claim used in LTI advantage requests."""
return lti_registration.token_url

Expand Down
8 changes: 8 additions & 0 deletions lms/services/lti_grading/_v13.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ def sync_grade( # noqa: PLR0913
taking all the necessary information as parameters.
"""
payload = self._record_score_payload(score, user_grading_id, grade_timestamp)

if lti_registration.product_family == Family.CANVAS:
# By default Canvas calls to /score create a new submission
# Disable that behaviour and just submit the new grade.
# See: https://canvas.instructure.com/doc/api/score.html
payload["https://canvas.instructure.com/lti/submission"] = {
"new_submission": False
}
return self._ltia_service.request(
lti_registration,
"POST",
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/lms/models/lti_registration_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import pytest

from lms.product.family import Family
from tests import factories


class TestLTIRegistration:
@pytest.mark.parametrize(
"issuer,family",
[
("SOMEURL", Family.UNKNOWN),
("https://canvas.instructure.com", Family.CANVAS),
],
)
def test_product_family(self, issuer, family):
assert factories.LTIRegistration(issuer=issuer).product_family == family
11 changes: 10 additions & 1 deletion tests/unit/lms/services/lti_grading/_v13_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ def test_get_score_maximum_no_line_item(self, svc, ltia_http_service):

assert not svc.get_score_maximum(sentinel.resource_link_id)

def test_sync_grade(self, svc, ltia_http_service, lti_registration):
@pytest.mark.parametrize("is_canvas", [True, False])
def test_sync_grade(self, svc, ltia_http_service, lti_registration, is_canvas):
if is_canvas:
lti_registration.issuer = "https://canvas.instructure.com"

response = svc.sync_grade(
lti_registration,
"LIS_OUTCOME_SERVICE_URL",
Expand All @@ -166,6 +170,11 @@ def test_sync_grade(self, svc, ltia_http_service, lti_registration):
"activityProgress": "Completed",
"gradingProgress": "FullyGraded",
}
if is_canvas:
payload["https://canvas.instructure.com/lti/submission"] = {
"new_submission": False
}

ltia_http_service.request.assert_called_once_with(
lti_registration,
"POST",
Expand Down

0 comments on commit b40c4a7

Please sign in to comment.