Skip to content

Commit

Permalink
Merge pull request #219 from edx-solutions/dsheraz/educator-4521
Browse files Browse the repository at this point in the history
use submission deadline methods to add subsection due check in DnD
  • Loading branch information
DawoudSheraz authored Jul 30, 2019
2 parents 24e094e + 5624882 commit 48754a9
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Drag and Drop XBlock changelog
==============================

Version 2.2.4 (2019-07-30)
---------------------------

* Use InheritanceMixin for submission deadline checks (PR #219)
* Submit button behavior will change in Assessment Mode and will now be impacted by subsection due date, grace period and course pacing

Version 2.2.3 (2019-04-05)
---------------------------

Expand Down
22 changes: 22 additions & 0 deletions drag_and_drop_v2/drag_and_drop_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ def items_without_answers():
"target_img_description": self.target_img_description,
"item_background_color": self.item_background_color or None,
"item_text_color": self.item_text_color or None,
"has_deadline_passed": self.has_submission_deadline_passed,
# final feedback (data.feedback.finish) is not included - it may give away answers.
}

Expand Down Expand Up @@ -624,6 +625,22 @@ def attempts_remain(self):
"""
return self.max_attempts is None or self.max_attempts == 0 or self.attempts < self.max_attempts

@property
def has_submission_deadline_passed(self):
"""
Returns a boolean indicating if the submission is past its deadline.
Using the `has_deadline_passed` method from InheritanceMixin which gets
added on the LMS/Studio, return if the submission is past its due date.
If the method not found, which happens for pure DragAndDropXblock,
return False which makes sure submission checks don't affect other
functionality.
"""
if hasattr(self, "has_deadline_passed"):
return self.has_deadline_passed() # pylint: disable=no-member
else:
return False

@XBlock.handler
def student_view_user_state(self, request, suffix=''):
""" GET all user-specific data, and any applicable feedback """
Expand All @@ -645,6 +662,11 @@ def _validate_do_attempt(self):
409,
self.i18n_service.gettext("Max number of attempts reached")
)
if self.has_submission_deadline_passed:
raise JsonHandlerError(
409,
self.i18n_service.gettext("Submission deadline has passed.")
)

def _get_feedback(self, include_item_feedback=False):
"""
Expand Down
6 changes: 5 additions & 1 deletion drag_and_drop_v2/public/js/drag_and_drop.js
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,7 @@ function DragAndDropBlock(runtime, element, configuration) {
};

var canSubmitAttempt = function() {
return Object.keys(state.items).length > 0 && attemptsRemain() && !submittingLocation();
return Object.keys(state.items).length > 0 && isPastDue() && attemptsRemain() && !submittingLocation();
};

var canReset = function() {
Expand All @@ -1846,6 +1846,10 @@ function DragAndDropBlock(runtime, element, configuration) {
return any_items_placed && (configuration.mode !== DragAndDropBlock.ASSESSMENT_MODE || attemptsRemain());
};

var isPastDue = function () {
return !configuration.has_deadline_passed;
};

var canShowAnswer = function() {
return configuration.mode === DragAndDropBlock.ASSESSMENT_MODE && !attemptsRemain();
};
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def package_data(pkg, root_list):

setup(
name='xblock-drag-and-drop-v2',
version='2.2.3',
version='2.2.4',
description='XBlock - Drag-and-Drop v2',
packages=['drag_and_drop_v2'],
install_requires=[
Expand Down
1 change: 1 addition & 0 deletions tests/unit/data/assessment/config_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"display_zone_labels": false,
"url_name": "test",
"max_items_per_zone": null,
"has_deadline_passed": false,

"zones": [
{
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/data/html/config_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"display_zone_labels": false,
"url_name": "unique_name",
"max_items_per_zone": null,

"has_deadline_passed": false,
"zones": [
{
"title": "Zone <i>1</i>",
Expand Down
1 change: 1 addition & 0 deletions tests/unit/data/old/config_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"display_zone_labels": false,
"url_name": "",
"max_items_per_zone": null,
"has_deadline_passed": false,

"zones": [
{
Expand Down
1 change: 1 addition & 0 deletions tests/unit/data/plain/config_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"display_zone_labels": false,
"url_name": "test",
"max_items_per_zone": 4,
"has_deadline_passed": false,

"zones": [
{
Expand Down
17 changes: 17 additions & 0 deletions tests/unit/test_advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,23 @@ def test_do_attempt_raises_number_of_attempts(self, attempts):
self.assertEqual(self.block.attempts, attempts + 1)
self.assertEqual(res['attempts'], self.block.attempts)

@ddt.data(
(True, 409, True),
(False, 200, False),
)
@ddt.unpack
@mock.patch('drag_and_drop_v2.DragAndDropBlock.has_submission_deadline_passed', new_callable=mock.PropertyMock)
def test_do_attempt_has_deadline_passed(self, is_past_deadline, status_code, expect_error, mock_deadline_passed):
"""
Scenario: If the submission is past its deadline date, the attempt is not possible and
409 Conflict error is thrown.
"""
mock_deadline_passed.return_value = is_past_deadline
response = self.call_handler(self.DO_ATTEMPT_HANDLER, data={}, expect_json=False)
self.assertEqual(response.status_code, status_code)
if expect_error:
self.assertIn("Submission deadline has passed.", response.body)

@ddt.data(*[random.randint(1, 50) for _ in xrange(5)]) # pylint: disable=star-args
def test_do_attempt_correct_mark_complete_and_publish_grade(self, weight):
self.block.weight = weight
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def test_student_view_data(self):
"item_background_color": None,
"item_text_color": None,
"url_name": "",
"has_deadline_passed": False,
})
self.assertEqual(zones, DEFAULT_DATA["zones"])
# Items should contain no answer data:
Expand Down

0 comments on commit 48754a9

Please sign in to comment.