diff --git a/api/util/StackQuestionLoader.php b/api/util/StackQuestionLoader.php
index f659abbff38b5f0e0546e966ee15f4b87299af4b..ac3c0565fed4eac7f01dd2efc5eeecd6781f94fe 100644
--- a/api/util/StackQuestionLoader.php
+++ b/api/util/StackQuestionLoader.php
@@ -77,6 +77,8 @@ class StackQuestionLoader {
$question->questionnote = (string) $xmldata->question->questionnote->text;
$question->specificfeedback = (string) $xmldata->question->specificfeedback->text;
$question->specificfeedbackformat = (string) $xmldata->question->specificfeedback['format'];
+ $question->questiondescription = (string) $xmldata->question->questiondescription;
+ $question->questiondescriptionformat = (string) $xmldata->question->questiondescription['format'];
if (isset($xmldata->question->prtcorrect->text)) {
$question->prtcorrect = (string) $xmldata->question->prtcorrect->text;
$question->prtcorrectformat = (string) $xmldata->question->prtcorrect['format'];
diff --git a/tests/api_controller_test.php b/tests/api_controller_test.php
index 1f8a28498ad4e24cfab3a17d19ac603a2348a42d..348d76d05977c55e0ca7972fe12a22eae7f508fd 100644
--- a/tests/api_controller_test.php
+++ b/tests/api_controller_test.php
@@ -40,25 +40,17 @@ use api\controller\TestController;
use api\util\StackIframeHolder;
use stack_api_test_data;
use Psr\Http\Message\ResponseInterface as ResponseInt;
+use Psr\Http\Message\StreamInterface as StreamInt;
use Psr\Http\Message\ServerRequestInterface as RequestInt;
use qtype_stack_testcase;
-/**
- * Class to fake the response output object and store the actual JSON
- */
-class MockBody {
- public object $output;
- public function write() {
- $this->output = json_decode(func_get_args()[0]);
- return $this->output;
- }
-}
-
/**
* @group qtype_stack
* @covers \qtype_stack
*/
class api_controller_test extends qtype_stack_testcase {
+ /** @var object used to store output */
+ public object $output;
/** @var object used to store output */
public object $result;
/** @var array the api call data */
@@ -113,11 +105,27 @@ class api_controller_test extends qtype_stack_testcase {
->setMethods($methods)
->getMock();
- $this->result = new MockBody();
+ $reflection = new \ReflectionClass(StreamInt::class);
+ $methods = [];
+ foreach ($reflection->getMethods() as $method) {
+ $methods[] = $method->name;
+ }
+
+ $this->result = $this->getMockBuilder(StreamInt::class)
+ ->setMockClassName('StreamInterface')
+ ->setMethods($methods)
+ ->getMock();
+
+ $this->result->expects($this->any())->method('write')->will($this->returnCallback(
+ function() {
+ $this->output = json_decode(func_get_args()[0]);
+ return 1;
+ })
+ );
- // The controllers call getBody() on the response object but then call write() on the result.
- // We return a MockBody object with a write method which updates the test's result property
- // so we can actually perform some asserts.
+ // The controllers call getBody() on the response object but then call write() on the result
+ // so we have to mock both. We override the write method to write to a propery of the testsuite
+ // so we have something easily accessible to perform some asserts on.
$this->response->expects($this->any())->method('getBody')->will($this->returnCallback(
function() {
return $this->result;
@@ -140,18 +148,18 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['questionDefinition'] = stack_api_test_data::get_question_string('matrices');
$rc = new RenderController();
$rc->__invoke($this->request, $this->response, []);
- $this->assertMatchesRegularExpression('/^<p>Calculate/', $this->result->output->questionrender);
- $this->assertEquals(86, $this->result->output->questionseed);
- $this->assertEquals('matrix([35,30],[28,24])', $this->result->output->questioninputs->ans1->samplesolution->_val);
+ $this->assertMatchesRegularExpression('/^<p>Calculate/', $this->output->questionrender);
+ $this->assertEquals(86, $this->output->questionseed);
+ $this->assertEquals('matrix([35,30],[28,24])', $this->output->questioninputs->ans1->samplesolution->_val);
$this->assertMatchesRegularExpression('/^<div class="matrixsquarebrackets"><table class="matrixtable"/',
- $this->result->output->questioninputs->ans1->render);
- $this->assertMatchesRegularExpression('/^<p>To multiply matrices/', $this->result->output->questionsamplesolutiontext);
- $this->assertEquals(0, count((array)$this->result->output->questionassets));
- $this->assertContains(86, $this->result->output->questionvariants);
- $this->assertContains(219862533, $this->result->output->questionvariants);
- $this->assertContains(1167893775, $this->result->output->questionvariants);
- $this->assertEquals(3, count($this->result->output->questionvariants));
- $this->assertEquals(0, count($this->result->output->iframes));
+ $this->output->questioninputs->ans1->render);
+ $this->assertMatchesRegularExpression('/^<p>To multiply matrices/', $this->output->questionsamplesolutiontext);
+ $this->assertEquals(0, count((array)$this->output->questionassets));
+ $this->assertContains(86, $this->output->questionvariants);
+ $this->assertContains(219862533, $this->output->questionvariants);
+ $this->assertContains(1167893775, $this->output->questionvariants);
+ $this->assertEquals(3, count($this->output->questionvariants));
+ $this->assertEquals(0, count($this->output->iframes));
}
public function test_render_specified_seed() {
@@ -159,33 +167,33 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['questionDefinition'] = stack_api_test_data::get_question_string('matrices');
$rc = new RenderController();
$rc->__invoke($this->request, $this->response, []);
- $this->assertMatchesRegularExpression('/^<p>Calculate/', $this->result->output->questionrender);
- $this->assertEquals(219862533, $this->result->output->questionseed);
+ $this->assertMatchesRegularExpression('/^<p>Calculate/', $this->output->questionrender);
+ $this->assertEquals(219862533, $this->output->questionseed);
}
public function test_render_plots() {
$this->requestdata['questionDefinition'] = stack_api_test_data::get_question_string('plots');
$rc = new RenderController();
$rc->__invoke($this->request, $this->response, []);
- $this->assertEquals(4, count((array)$this->result->output->questionassets));
- $this->assertEquals(true, isset($this->result->output->questionassets->{'input-ans1-1-0.svg'}));
- $this->assertEquals(true, isset($this->result->output->questionassets->{'input-ans1-2-0.svg'}));
- $this->assertEquals(true, isset($this->result->output->questionassets->{'input-ans1-3-0.svg'}));
- $this->assertEquals(true, isset($this->result->output->questionassets->{'input-ans1-4-0.svg'}));
+ $this->assertEquals(4, count((array)$this->output->questionassets));
+ $this->assertEquals(true, isset($this->output->questionassets->{'input-ans1-1-0.svg'}));
+ $this->assertEquals(true, isset($this->output->questionassets->{'input-ans1-2-0.svg'}));
+ $this->assertEquals(true, isset($this->output->questionassets->{'input-ans1-3-0.svg'}));
+ $this->assertEquals(true, isset($this->output->questionassets->{'input-ans1-4-0.svg'}));
}
public function test_render_iframes() {
$this->requestdata['questionDefinition'] = stack_api_test_data::get_question_string('iframes');
$rc = new RenderController();
$rc->__invoke($this->request, $this->response, []);
- $this->assertEquals(1, count($this->result->output->iframes));
+ $this->assertEquals(1, count($this->output->iframes));
}
public function test_render_download() {
$this->requestdata['questionDefinition'] = stack_api_test_data::get_question_string('download');
$rc = new RenderController();
$rc->__invoke($this->request, $this->response, []);
- $this->assertMatchesRegularExpression('/javascript\:download\(\'data.csv\'\, 1\)/s', $this->result->output->questionrender);
+ $this->assertMatchesRegularExpression('/javascript\:download\(\'data.csv\'\, 1\)/s', $this->output->questionrender);
}
public function test_validation() {
@@ -195,8 +203,8 @@ class api_controller_test extends qtype_stack_testcase {
$vc = new ValidationController();
$vc->__invoke($this->request, $this->response, []);
$this->assertMatchesRegularExpression('/\\\[ \\\left\[\\begin\{array\}\{cc\} 1 & 2 \\\\ 3 & 4 \\end{array}\\right\] \\\]/s',
- $this->result->output->validation);
- $this->assertEquals(0, count($this->result->output->iframes));
+ $this->output->validation);
+ $this->assertEquals(0, count($this->output->iframes));
}
public function test_grade() {
@@ -205,17 +213,17 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['inputName'] = 'ans1';
$gc = new GradingController();
$gc->__invoke($this->request, $this->response, []);
- $this->assertEquals(true, $this->result->output->isgradable);
- $this->assertEquals(1, $this->result->output->score);
- $this->assertEquals(1, $this->result->output->scores->prt1);
- $this->assertEquals(1, $this->result->output->scores->total);
- $this->assertEquals(1, $this->result->output->scoreweights->prt1);
- $this->assertEquals(5, $this->result->output->scoreweights->total);
- $this->assertEquals('<p>[[feedback:prt1]]</p>', $this->result->output->specificfeedback);
- $this->assertStringContainsString('correct', $this->result->output->prts->prt1);
- $this->assertEquals(0, count((array)$this->result->output->gradingassets));
- $this->assertEquals('Seed: 86; ans1: matrix([35,30],[28,24]) [valid]; prt1: !', $this->result->output->responsesummary);
- $this->assertEquals(0, count($this->result->output->iframes));
+ $this->assertEquals(true, $this->output->isgradable);
+ $this->assertEquals(1, $this->output->score);
+ $this->assertEquals(1, $this->output->scores->prt1);
+ $this->assertEquals(1, $this->output->scores->total);
+ $this->assertEquals(1, $this->output->scoreweights->prt1);
+ $this->assertEquals(5, $this->output->scoreweights->total);
+ $this->assertEquals('<p>[[feedback:prt1]]</p>', $this->output->specificfeedback);
+ $this->assertStringContainsString('correct', $this->output->prts->prt1);
+ $this->assertEquals(0, count((array)$this->output->gradingassets));
+ $this->assertEquals('Seed: 86; ans1: matrix([35,30],[28,24]) [valid]; prt1: !', $this->output->responsesummary);
+ $this->assertEquals(0, count($this->output->iframes));
}
public function test_grade_scores() {
@@ -224,18 +232,18 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['inputName'] = 'ans1';
$gc = new GradingController();
$gc->__invoke($this->request, $this->response, []);
- $this->assertEquals(true, $this->result->output->isgradable);
- $this->assertEqualsWithDelta(0.9, $this->result->output->score, 0.0001);
- $this->assertEquals(1, $this->result->output->scores->prt1);
- $this->assertEquals(1, $this->result->output->scores->prt2);
- $this->assertEquals(0, $this->result->output->scores->prt3);
- $this->assertEquals(1, $this->result->output->scores->prt4);
- $this->assertEqualsWithDelta(0.9, $this->result->output->scores->total, 0.0001);
- $this->assertEqualsWithDelta(0.7, $this->result->output->scoreweights->prt1, 0.0001);
- $this->assertEqualsWithDelta(0.1, $this->result->output->scoreweights->prt2, 0.0001);
- $this->assertEqualsWithDelta(0.1, $this->result->output->scoreweights->prt3, 0.0001);
- $this->assertEqualsWithDelta(0.1, $this->result->output->scoreweights->prt4, 0.0001);
- $this->assertEquals(10, $this->result->output->scoreweights->total);
+ $this->assertEquals(true, $this->output->isgradable);
+ $this->assertEqualsWithDelta(0.9, $this->output->score, 0.0001);
+ $this->assertEquals(1, $this->output->scores->prt1);
+ $this->assertEquals(1, $this->output->scores->prt2);
+ $this->assertEquals(0, $this->output->scores->prt3);
+ $this->assertEquals(1, $this->output->scores->prt4);
+ $this->assertEqualsWithDelta(0.9, $this->output->scores->total, 0.0001);
+ $this->assertEqualsWithDelta(0.7, $this->output->scoreweights->prt1, 0.0001);
+ $this->assertEqualsWithDelta(0.1, $this->output->scoreweights->prt2, 0.0001);
+ $this->assertEqualsWithDelta(0.1, $this->output->scoreweights->prt3, 0.0001);
+ $this->assertEqualsWithDelta(0.1, $this->output->scoreweights->prt4, 0.0001);
+ $this->assertEquals(10, $this->output->scoreweights->total);
}
public function test_download() {
@@ -258,7 +266,7 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['filepath'] = 'testpath/test.xml';
$tc = new TestController();
$tc->__invoke($this->request, $this->response, []);
- $results = $this->result->output;
+ $results = $this->output;
$this->assertEquals('test_3_matrix', $results->name);
$this->assertEquals(false, $results->isupgradeerror);
$this->assertEquals(true, $results->isgeneralfeedback );
@@ -278,7 +286,7 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['filepath'] = 'testpath/test.xml';
$tc = new TestController();
$tc->__invoke($this->request, $this->response, []);
- $results = $this->result->output;
+ $results = $this->output;
$this->assertEquals('Algebraic input', $results->name);
$this->assertEquals(false, $results->isupgradeerror);
$this->assertEquals(false, $results->isgeneralfeedback );
@@ -299,7 +307,7 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['filepath'] = 'testpath/test.xml';
$tc = new TestController();
$tc->__invoke($this->request, $this->response, []);
- $results = $this->result->output;
+ $results = $this->output;
$this->assertEquals('Algebraic input', $results->name);
$this->assertEquals(true, $results->isupgradeerror);
$this->assertEquals(false, $results->isgeneralfeedback );
@@ -315,7 +323,7 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['filepath'] = 'testpath/test.xml';
$tc = new TestController();
$tc->__invoke($this->request, $this->response, []);
- $results = $this->result->output;
+ $results = $this->output;
$this->assertEquals('Algebraic input', $results->name);
$this->assertEquals(false, $results->isupgradeerror);
$this->assertEquals(false, $results->isgeneralfeedback );
@@ -333,7 +341,7 @@ class api_controller_test extends qtype_stack_testcase {
$this->requestdata['filepath'] = 'testpath/test.xml';
$tc = new TestController();
$tc->__invoke($this->request, $this->response, []);
- $results = $this->result->output;
+ $results = $this->output;
$this->assertEquals('Algebraic input', $results->name);
$this->assertEquals(false, $results->isupgradeerror);
$this->assertEquals(false, $results->isgeneralfeedback );
diff --git a/vle_specific.php b/vle_specific.php
index fbd4e7ff261399e0bafa532b78044a6017d579c5..d62e8172170c4e15db9a25b0747d2729a9bd7f47 100644
--- a/vle_specific.php
+++ b/vle_specific.php
@@ -204,7 +204,7 @@ function stack_get_mathjax_url(): string {
$urlstring = substr($mathjaxconfigurl, 0, $questionpos);
parse_str($querystring, $queryparams);
$queryparams = array_merge(['config' => 'TeX-AMS-MML_HTMLorMML'], $queryparams);
- $querystring = http_build_query($queryparams, null, '&', PHP_QUERY_RFC3986);
+ $querystring = http_build_query($queryparams, '', '&', PHP_QUERY_RFC3986);
$url = $urlstring . '?' . $querystring;
} else {
$url = $mathjaxconfigurl . '?config=TeX-AMS-MML_HTMLorMML';