Commit 3d1c54fe by Sarina Canelake

Merge pull request #5595 from Stanford-Online/caijim/resetbutton

Support and tests for adding a reset button to units
parents 98c9880d 6d19a0c8
...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes, ...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected. the top. Include a label indicating the component affected.
Common: Add configurable reset button to units
LMS: Support adding cohorts from the instructor dashboard. TNL-162 LMS: Support adding cohorts from the instructor dashboard. TNL-162
LMS: Support adding students to a cohort via the instructor dashboard. TNL-163 LMS: Support adding students to a cohort via the instructor dashboard. TNL-163
......
...@@ -13,6 +13,7 @@ MAXIMUM_ATTEMPTS = "Maximum Attempts" ...@@ -13,6 +13,7 @@ MAXIMUM_ATTEMPTS = "Maximum Attempts"
PROBLEM_WEIGHT = "Problem Weight" PROBLEM_WEIGHT = "Problem Weight"
RANDOMIZATION = 'Randomization' RANDOMIZATION = 'Randomization'
SHOW_ANSWER = "Show Answer" SHOW_ANSWER = "Show Answer"
SHOW_RESET_BUTTON = "Show Reset Button"
TIMER_BETWEEN_ATTEMPTS = "Timer Between Attempts" TIMER_BETWEEN_ATTEMPTS = "Timer Between Attempts"
MATLAB_API_KEY = "Matlab API key" MATLAB_API_KEY = "Matlab API key"
...@@ -102,6 +103,7 @@ def i_see_advanced_settings_with_values(step): ...@@ -102,6 +103,7 @@ def i_see_advanced_settings_with_values(step):
[PROBLEM_WEIGHT, "", False], [PROBLEM_WEIGHT, "", False],
[RANDOMIZATION, "Never", False], [RANDOMIZATION, "Never", False],
[SHOW_ANSWER, "Finished", False], [SHOW_ANSWER, "Finished", False],
[SHOW_RESET_BUTTON, "False", False],
[TIMER_BETWEEN_ATTEMPTS, "0", False], [TIMER_BETWEEN_ATTEMPTS, "0", False],
]) ])
......
# -*- coding: utf-8 -*-
"""
Constants for capa_base problems
"""
class SHOWANSWER:
"""
Constants for when to show answer
"""
ALWAYS = "always"
ANSWERED = "answered"
ATTEMPTED = "attempted"
CLOSED = "closed"
FINISHED = "finished"
CORRECT_OR_PAST_DUE = "correct_or_past_due"
PAST_DUE = "past_due"
NEVER = "never"
class RANDOMIZATION:
"""
Constants for problem randomization
"""
ALWAYS = "always"
ONRESET = "onreset"
NEVER = "never"
PER_STUDENT = "per_student"
""" """
Support for inheritance of fields down an XBlock hierarchy. Support for inheritance of fields down an XBlock hierarchy.
""" """
from __future__ import absolute_import
from datetime import datetime from datetime import datetime
from pytz import UTC from pytz import UTC
from xmodule.partitions.partitions import UserPartition from xmodule.partitions.partitions import UserPartition
from xblock.fields import Scope, Boolean, String, Float, XBlockMixin, Dict, Integer, List from xblock.fields import Scope, Boolean, String, Float, XBlockMixin, Dict, Integer, List
from xblock.runtime import KeyValueStore, KvsFieldData from xblock.runtime import KeyValueStore, KvsFieldData
from xmodule.fields import Date, Timedelta from xmodule.fields import Date, Timedelta
from django.conf import settings
# Make '_' a no-op so we can scrape strings # Make '_' a no-op so we can scrape strings
_ = lambda text: text _ = lambda text: text
...@@ -153,6 +154,16 @@ class InheritanceMixin(XBlockMixin): ...@@ -153,6 +154,16 @@ class InheritanceMixin(XBlockMixin):
scope=Scope.settings scope=Scope.settings
) )
reset_key = "DEFAULT_SHOW_RESET_BUTTON"
default_reset_button = getattr(settings, reset_key) if hasattr(settings, reset_key) else False
show_reset_button = Boolean(
display_name=_("Show Reset Button for Problems"),
help=_("Enter true or false. If true, problems default to displaying a 'Reset' button. This value may be "
"overriden in each problem's settings. Existing problems whose reset setting have not been changed are affected."),
scope=Scope.settings,
default=default_reset_button
)
def compute_inherited_metadata(descriptor): def compute_inherited_metadata(descriptor):
"""Given a descriptor, traverse all of its descendants and do metadata """Given a descriptor, traverse all of its descendants and do metadata
......
...@@ -72,37 +72,77 @@ Feature: LMS.Answer problems ...@@ -72,37 +72,77 @@ Feature: LMS.Answer problems
Scenario: I can reset a problem Scenario: I can reset a problem
Given I am viewing a "<ProblemType>" problem Given I am viewing a randomization "<Randomization>" "<ProblemType>" problem with reset button on
And I answer a "<ProblemType>" problem "<Correctness>ly"
When I reset the problem
Then my "<ProblemType>" answer is marked "unanswered"
And The "<ProblemType>" problem displays a "blank" answer
Examples:
| ProblemType | Correctness | Randomization |
| drop down | correct | always |
| drop down | incorrect | always |
| multiple choice | correct | always |
| multiple choice | incorrect | always |
| checkbox | correct | always |
| checkbox | incorrect | always |
| radio | correct | always |
| radio | incorrect | always |
| string | correct | always |
| string | incorrect | always |
| numerical | correct | always |
| numerical | incorrect | always |
| formula | correct | always |
| formula | incorrect | always |
| script | correct | always |
| script | incorrect | always |
| radio_text | correct | always |
| radio_text | incorrect | always |
| checkbox_text | correct | always |
| checkbox_text | incorrect | always |
| image | correct | always |
| image | incorrect | always |
Scenario: I can reset a non-randomized problem that I answer incorrectly
Given I am viewing a randomization "<Randomization>" "<ProblemType>" problem with reset button on
And I answer a "<ProblemType>" problem "<Correctness>ly" And I answer a "<ProblemType>" problem "<Correctness>ly"
When I reset the problem When I reset the problem
Then my "<ProblemType>" answer is marked "unanswered" Then my "<ProblemType>" answer is marked "unanswered"
And The "<ProblemType>" problem displays a "blank" answer And The "<ProblemType>" problem displays a "blank" answer
Examples: Examples:
| ProblemType | Correctness | | ProblemType | Correctness | Randomization |
| drop down | correct | | drop down | incorrect | never |
| drop down | incorrect | | drop down | incorrect | never |
| multiple choice | correct | | multiple choice | incorrect | never |
| multiple choice | incorrect | | checkbox | incorrect | never |
| checkbox | correct | | radio | incorrect | never |
| checkbox | incorrect | | string | incorrect | never |
| radio | correct | | numerical | incorrect | never |
| radio | incorrect | | formula | incorrect | never |
| string | correct | | script | incorrect | never |
| string | incorrect | | radio_text | incorrect | never |
| numerical | correct | | checkbox_text | incorrect | never |
| numerical | incorrect | | image | incorrect | never |
| formula | correct |
| formula | incorrect | Scenario: The reset button doesn't show up
| script | correct | Given I am viewing a randomization "<Randomization>" "<ProblemType>" problem with reset button on
| script | incorrect | And I answer a "<ProblemType>" problem "<Correctness>ly"
| radio_text | correct | Then The "Reset" button does not appear
| radio_text | incorrect |
| checkbox_text | correct |
| checkbox_text | incorrect |
| image | correct |
| image | incorrect |
Examples:
| ProblemType | Correctness | Randomization |
| drop down | correct | never |
| multiple choice | correct | never |
| checkbox | correct | never |
| radio | correct | never |
| string | correct | never |
| numerical | correct | never |
| formula | correct | never |
| script | correct | never |
| radio_text | correct | never |
| checkbox_text | correct | never |
| image | correct | never |
Scenario: I can answer a problem with one attempt correctly and not reset Scenario: I can answer a problem with one attempt correctly and not reset
Given I am viewing a "multiple choice" problem with "1" attempt Given I am viewing a "multiple choice" problem with "1" attempt
...@@ -115,6 +155,12 @@ Feature: LMS.Answer problems ...@@ -115,6 +155,12 @@ Feature: LMS.Answer problems
When I answer a "multiple choice" problem "correctly" When I answer a "multiple choice" problem "correctly"
Then The "Reset" button does appear Then The "Reset" button does appear
Scenario: I can answer a problem with multiple attempts correctly but cannot reset because randomization is off
Given I am viewing a randomization "never" "multiple choice" problem with "3" attempts with reset
Then I should see "You have used 0 of 3 submissions" somewhere in the page
When I answer a "multiple choice" problem "correctly"
Then The "Reset" button does not appear
Scenario: I can view how many attempts I have left on a problem Scenario: I can view how many attempts I have left on a problem
Given I am viewing a "multiple choice" problem with "3" attempts Given I am viewing a "multiple choice" problem with "3" attempts
Then I should see "You have used 0 of 3 submissions" somewhere in the page Then I should see "You have used 0 of 3 submissions" somewhere in the page
...@@ -165,6 +211,34 @@ Feature: LMS.Answer problems ...@@ -165,6 +211,34 @@ Feature: LMS.Answer problems
| image | correct | 1/1 point | 1 point possible | | image | correct | 1/1 point | 1 point possible |
| image | incorrect | 1 point possible | 1 point possible | | image | incorrect | 1 point possible | 1 point possible |
Scenario: I can see my score on a problem when I answer it and after I reset it
Given I am viewing a "<ProblemType>" problem with randomization "<Randomization>" with reset button on
When I answer a "<ProblemType>" problem "<Correctness>ly"
Then I should see a score of "<Score>"
When I reset the problem
Then I should see a score of "<Points Possible>"
Examples:
| ProblemType | Correctness | Score | Points Possible | Randomization |
| drop down | correct | 1/1 point | 1 point possible | never |
| drop down | incorrect | 1 point possible | 1 point possible | never |
| multiple choice | correct | 1/1 point | 1 point possible | never |
| multiple choice | incorrect | 1 point possible | 1 point possible | never |
| checkbox | correct | 1/1 point | 1 point possible | never |
| checkbox | incorrect | 1 point possible | 1 point possible | never |
| radio | correct | 1/1 point | 1 point possible | never |
| radio | incorrect | 1 point possible | 1 point possible | never |
| string | correct | 1/1 point | 1 point possible | never |
| string | incorrect | 1 point possible | 1 point possible | never |
| numerical | correct | 1/1 point | 1 point possible | never |
| numerical | incorrect | 1 point possible | 1 point possible | never |
| formula | correct | 1/1 point | 1 point possible | never |
| formula | incorrect | 1 point possible | 1 point possible | never |
| script | correct | 2/2 points | 2 points possible | never |
| script | incorrect | 2 points possible | 2 points possible | never |
| image | correct | 1/1 point | 1 point possible | never |
| image | incorrect | 1 point possible | 1 point possible | never |
Scenario: I can see my score on a problem to which I submit a blank answer Scenario: I can see my score on a problem to which I submit a blank answer
Given I am viewing a "<ProblemType>" problem Given I am viewing a "<ProblemType>" problem
When I check a problem When I check a problem
......
...@@ -26,6 +26,13 @@ def view_problem_with_attempts(step, problem_type, attempts): ...@@ -26,6 +26,13 @@ def view_problem_with_attempts(step, problem_type, attempts):
_view_problem(step, problem_type, {'max_attempts': attempts}) _view_problem(step, problem_type, {'max_attempts': attempts})
@step(u'I am viewing a randomization "([^"]*)" "([^"]*)" problem with "([^"]*)" attempts with reset')
def view_problem_attempts_reset(step, randomization, problem_type, attempts, ):
_view_problem(step, problem_type, {'max_attempts': attempts,
'rerandomize': randomization,
'show_reset_button': True})
@step(u'I am viewing a "([^"]*)" that shows the answer "([^"]*)"') @step(u'I am viewing a "([^"]*)" that shows the answer "([^"]*)"')
def view_problem_with_show_answer(step, problem_type, answer): def view_problem_with_show_answer(step, problem_type, answer):
_view_problem(step, problem_type, {'showanswer': answer}) _view_problem(step, problem_type, {'showanswer': answer})
...@@ -36,6 +43,11 @@ def view_problem(step, problem_type): ...@@ -36,6 +43,11 @@ def view_problem(step, problem_type):
_view_problem(step, problem_type) _view_problem(step, problem_type)
@step(u'I am viewing a randomization "([^"]*)" "([^"]*)" problem with reset button on')
def view_random_reset_problem(step, randomization, problem_type):
_view_problem(step, problem_type, {'rerandomize': randomization, 'show_reset_button': True})
@step(u'External graders respond "([^"]*)"') @step(u'External graders respond "([^"]*)"')
def set_external_grader_response(step, correctness): def set_external_grader_response(step, correctness):
assert(correctness in ['correct', 'incorrect']) assert(correctness in ['correct', 'incorrect'])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment