Skip to content

Commit

Permalink
test: add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BryanttV committed Mar 7, 2024
1 parent fed98f6 commit 722345a
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 7 deletions.
6 changes: 3 additions & 3 deletions openassessment/xblock/openassessmentblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1369,10 +1369,10 @@ def reset_submission(self, data, suffix=""): # pylint: disable=unused-argument
"""
try:
block_user = self.runtime.service(self, "user").get_current_user()
user = get_user_by_username_or_email(block_user.opt_attrs["edx-platform.username"])
user = get_user_by_username_or_email(block_user.opt_attrs.get("edx-platform.username"))
reset_student_attempts(self.course_id, user, self.location, user, True) # pylint: disable=no-member
except Exception:
logger.exception("An error occurred while resetting the submission.")
except Exception as error:
logger.exception(f"An error occurred while resetting the submission: {error}")
return {"success": False, "msg": self._("Error resetting submission.")}
return {"success": True, "msg": self._("Submission reset successfully.")}

Check warning on line 1378 in openassessment/xblock/openassessmentblock.py

View check run for this annotation

Codecov / codecov/patch

openassessment/xblock/openassessmentblock.py#L1378

Added line #L1378 was not covered by tests
Expand Down
22 changes: 22 additions & 0 deletions openassessment/xblock/test/data/update_from_xml.json
Original file line number Diff line number Diff line change
Expand Up @@ -654,5 +654,27 @@
"</openassessment>"
],
"show_rubric_during_response": true
},

"allow_learner_resubmissions": {
"xml": [
"<openassessment allow_learner_resubmissions=\"true\">",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"<assessment name=\"self-assessment\" start=\"2014-04-01T00:00:00\" due=\"2014-06-01T00:00:00\" />",
"</assessments>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"<criterion>",
"<name>Test criterion</name>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"0\"><name>No</name><explanation>No explanation</explanation></option>",
"<option points=\"2\"><name>Yes</name><explanation>Yes explanation</explanation></option>",
"</criterion>",
"</rubric>",
"</openassessment>"
],
"allow_learner_resubmissions": true
}
}
42 changes: 42 additions & 0 deletions openassessment/xblock/test/data/update_from_xml_error.json
Original file line number Diff line number Diff line change
Expand Up @@ -455,5 +455,47 @@
"</rubric>",
"</openassessment>"
]
},

"resubmissions_grace_period_hours_not_integer": {
"xml": [
"<openassessment resubmissions_grace_period_hours=\"not_an_int\">",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"<assessment name=\"self-assessment\" start=\"2014-04-01T00:00:00\" due=\"2014-06-01T00:00:00\" />",
"</assessments>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"<criterion>",
"<name>Test criterion</name>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"0\"><name>No</name><explanation>No explanation</explanation></option>",
"<option points=\"2\"><name>Yes</name><explanation>Yes explanation</explanation></option>",
"</criterion>",
"</rubric>",
"</openassessment>"
]
},

"resubmissions_grace_period_minutes_not_integer": {
"xml": [
"<openassessment resubmissions_grace_period_minutes=\"not_an_int\">",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"<assessment name=\"self-assessment\" start=\"2014-04-01T00:00:00\" due=\"2014-06-01T00:00:00\" />",
"</assessments>",
"<rubric>",
"<prompt>Test prompt</prompt>",
"<criterion>",
"<name>Test criterion</name>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"0\"><name>No</name><explanation>No explanation</explanation></option>",
"<option points=\"2\"><name>Yes</name><explanation>Yes explanation</explanation></option>",
"</criterion>",
"</rubric>",
"</openassessment>"
]
}
}
159 changes: 159 additions & 0 deletions openassessment/xblock/test/test_allow_resubmission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"""This module contains the tests for the allow_resubmission module."""

import datetime
import unittest

import ddt

from openassessment.xblock.utils.allow_resubmission import allow_resubmission


class ConfigDataMock:
"""Mock class for the ORAConfigAPI object."""

def __init__(self):
self.allow_learner_resubmissions = True
self.submission_due = "2029-01-01T00:00:00+00:00"
self.resubmissions_grace_period_hours = 0
self.resubmissions_grace_period_minutes = 0


class WorkflowDataMock:
"""Mock class for the WorkflowAPI object."""

def __init__(self):
self.status = "waiting"
self.status_details = {
"staff": {"complete": True, "graded": False, "skipped": False},
"peer": {
"complete": False,
"graded": False,
"skipped": True,
"peers_graded_count": 0,
"graded_by_count": 0,
},
}


@ddt.ddt
class TestAllowResubmission(unittest.TestCase):
"""Tests for the allow_resubmission module."""

def setUp(self):
self.config_data = ConfigDataMock()
self.workflow_data = WorkflowDataMock()
self.submission_data = {
"created_at": datetime.datetime.now(tz=datetime.timezone.utc)
}

def test_allow_resubmission_all_conditions_met(self):
"""
Test case for the allow_resubmission function when all conditions are met.
This test checks if the function returns True when:
- Learner resubmissions are allowed
- The submission date has not been exceeded
- The workflow has not been graded
"""
result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertTrue(result)

@ddt.data(
(1, 0),
(0, 30),
(10, 59),
(0, 0),
)
@ddt.unpack
def test_allow_resubmission_resubmissions_with_grace_period(
self, hours: int, minutes: int
):
"""
Test case for the allow_resubmission function when the resubmissions grace period is set.
"""
self.config_data.resubmissions_grace_period_hours = hours
self.config_data.resubmissions_grace_period_minutes = minutes

result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertTrue(result)

def test_allow_resubmission_resubmissions_with_grace_period_exceeded(self):
"""
Test case for the allow_resubmission function when the resubmissions grace period is exceeded.
"""
self.submission_data["created_at"] = datetime.datetime(
2020, 1, 1, tzinfo=datetime.timezone.utc
)
self.config_data.resubmissions_grace_period_hours = 1
self.config_data.resubmissions_grace_period_minutes = 30

result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertFalse(result)

def test_allow_resubmission_resubmissions_not_allowed(self):
"""
Test case for the allow_resubmission function when learner resubmissions are not allowed.
"""
self.config_data.allow_learner_resubmissions = False
result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertFalse(result)

def test_allow_resubmission_submission_date_exceeded(self):
"""
Test case for the allow_resubmission function when the submission date has been exceeded.
"""
self.config_data.submission_due = "2020-01-01T00:00:00+00:00"

result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertFalse(result)

@ddt.data("done", "cancelled")
def test_allow_resubmission_has_been_graded_or_cancelled(self, status: str):
"""
Test case for the allow_resubmission function when the
learner's response has been graded or cancelled.
"""
self.workflow_data.status = status

result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertFalse(result)

@ddt.data(
(0, True),
(1, False),
(2, False),
)
@ddt.unpack
def test_allow_resubmission_has_been_graded_by_peers(
self, count: int, expected_result: bool
):
"""
Test case for the allow_resubmission function when the
learner's response has been graded by peers.
"""
self.workflow_data.status = "self"
self.workflow_data.status_details["peer"]["graded_by_count"] = count

result = allow_resubmission(
self.config_data, self.workflow_data, self.submission_data
)

self.assertEqual(result, expected_result)
18 changes: 18 additions & 0 deletions openassessment/xblock/test/test_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,24 @@ def test_cannot_submit_in_preview_mode(self, xblock):
self.assertEqual(resp[1], "ENOPREVIEW")
self.assertIsNot(resp[2], None)

@patch("openassessment.xblock.openassessmentblock.reset_student_attempts")
@patch("openassessment.xblock.openassessmentblock.get_user_by_username_or_email")
@scenario("data/basic_scenario.xml", user_id="Bob")
def test_reset_submission(self, xblock, mock_user: Mock, mock_reset: Mock):
xblock.xmodule_runtime = Mock(course_id=COURSE_ID)
mock_user.return_value = "test-user"
mock_reset.return_value = True

resp = self.request(xblock, "reset_submission", json.dumps({}), response_format="json")
self.assertTrue(resp["success"])
self.assertEqual(resp["msg"], "Submission reset successfully.")

@scenario("data/basic_scenario.xml", user_id="Bob")
def test_reset_submission_error(self, xblock):
resp = self.request(xblock, "reset_submission", json.dumps({}), response_format="json")
self.assertFalse(resp["success"])
self.assertEqual(resp["msg"], "Error resetting submission.")

@scenario('data/over_grade_scenario.xml', user_id='Alice')
def test_closed_submissions(self, xblock):
resp = self.request(xblock, 'render_submission', json.dumps({}))
Expand Down
3 changes: 3 additions & 0 deletions openassessment/xblock/test/test_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,9 @@ def test_parse_from_xml(self, data):
'white_listed_file_types',
'allow_multiple_files',
'allow_latex',
'allow_learner_resubmissions',
'resubmissions_grace_period_hours',
'resubmissions_grace_period_minutes',
'leaderboard_show'
]
for field_name in expected_fields:
Expand Down
4 changes: 0 additions & 4 deletions openassessment/xblock/utils/allow_resubmission.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,4 @@ def has_been_graded(workflow_data) -> bool:
if graded_by_count is not None and graded_by_count > 0:
return True

# If the learner has been graded by staff
if status_details.get("staff", {}).get("graded"):
return True

return False

0 comments on commit 722345a

Please sign in to comment.