Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions common/lib/capa/capa/tests/response_xml_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,24 +314,43 @@ def build_xml(self, **kwargs):
return super(CodeResponseXMLFactory, self).build_xml(**kwargs)

def create_response_element(self, **kwargs):
""" Create a <coderesponse> XML element:
"""
Create a <coderesponse> XML element.

Uses **kwargs:
Uses **kwargs:

*initial_display*: The code that initially appears in the textbox
[DEFAULT: "Enter code here"]
*answer_display*: The answer to display to the student
[DEFAULT: "This is the correct answer!"]
*grader_payload*: A JSON-encoded string sent to the grader
[DEFAULT: empty dict string]
*allowed_files*: A space-separated string of file names.
[DEFAULT: None]
*required_files*: A space-separated string of file names.
[DEFAULT: None]

*initial_display*: The code that initially appears in the textbox
[DEFAULT: "Enter code here"]
*answer_display*: The answer to display to the student
[DEFAULT: "This is the correct answer!"]
*grader_payload*: A JSON-encoded string sent to the grader
[DEFAULT: empty dict string]
"""
# Get **kwargs
initial_display = kwargs.get("initial_display", "Enter code here")
answer_display = kwargs.get("answer_display", "This is the correct answer!")
grader_payload = kwargs.get("grader_payload", '{}')
allowed_files = kwargs.get("allowed_files", None)
required_files = kwargs.get("required_files", None)

# Create the <coderesponse> element
response_element = etree.Element("coderesponse")

# If files are involved, create the <filesubmission> element.
has_files = allowed_files or required_files
if has_files:
filesubmission_element = etree.SubElement(response_element, "filesubmission")
if allowed_files:
filesubmission_element.set("allowed_files", allowed_files)
if required_files:
filesubmission_element.set("required_files", required_files)

# Create the <codeparam> element.
codeparam_element = etree.SubElement(response_element, "codeparam")

# Set the initial display text
Expand All @@ -347,8 +366,9 @@ def create_response_element(self, **kwargs):
grader_element.text = str(grader_payload)

# Create the input within the response
input_element = etree.SubElement(response_element, "textbox")
input_element.set("mode", "python")
if not has_files:
input_element = etree.SubElement(response_element, "textbox")
input_element.set("mode", "python")

return response_element

Expand Down
61 changes: 60 additions & 1 deletion lms/djangoapps/courseware/tests/test_submitting_problems.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

# text processing dependancies
import json
import os
from textwrap import dedent

from mock import patch

from django.conf import settings
from django.contrib.auth.models import User
from django.test.client import RequestFactory
from django.core.urlresolvers import reverse
Expand All @@ -18,7 +22,10 @@
#import factories and parent testcase modules
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from capa.tests.response_xml_factory import OptionResponseXMLFactory, CustomResponseXMLFactory, SchematicResponseXMLFactory
from capa.tests.response_xml_factory import (
OptionResponseXMLFactory, CustomResponseXMLFactory, SchematicResponseXMLFactory,
CodeResponseXMLFactory,
)
from courseware.tests.helpers import LoginEnrollmentTestCase
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
from lms.lib.xblock.runtime import quote_slashes
Expand Down Expand Up @@ -547,6 +554,58 @@ def test_dropping_all_correct(self):
self.assertEqual(self.score_for_hw('homework3'), [1.0, 1.0])


class ProblemWithUploadedFilesTest(TestSubmittingProblems):
"""Tests of problems with uploaded files."""

def setUp(self):
super(ProblemWithUploadedFilesTest, self).setUp()
self.section = self.add_graded_section_to_course('section')

def problem_setup(self, name, files):
"""
Create a CodeResponse problem with files to upload.
"""

xmldata = CodeResponseXMLFactory().build_xml(
allowed_files=files, required_files=files,
)
ItemFactory.create(
parent_location=self.section.location,
category='problem',
display_name=name,
data=xmldata
)

# re-fetch the course from the database so the object is up to date
self.refresh_course()

def test_three_files(self):
# Open the test files, and arrange to close them later.
filenames = "prog1.py prog2.py prog3.py"
fileobjs = [
open(os.path.join(settings.COMMON_TEST_DATA_ROOT, "capa", filename))
for filename in filenames.split()
]
for fileobj in fileobjs:
self.addCleanup(fileobj.close)

self.problem_setup("the_problem", filenames)
with patch('courseware.module_render.xqueue_interface.session') as mock_session:
resp = self.submit_question_answer("the_problem", {'2_1': fileobjs})

self.assertEqual(resp.status_code, 200)
json_resp = json.loads(resp.content)
self.assertEqual(json_resp['success'], "incorrect")

# See how post got called.
name, args, kwargs = mock_session.mock_calls[0]
self.assertEqual(name, "post")
self.assertEqual(len(args), 1)
self.assertTrue(args[0].endswith("/submit/"))
self.assertItemsEqual(kwargs.keys(), ["files", "data"])
self.assertItemsEqual(kwargs['files'].keys(), filenames.split())


class TestPythonGradedResponse(TestSubmittingProblems):
"""
Check that we can submit a schematic and custom response, and it answers properly.
Expand Down