diff --git a/classes/export_quiz.php b/classes/export_quiz.php index 28cf745..3d52009 100644 --- a/classes/export_quiz.php +++ b/classes/export_quiz.php @@ -154,7 +154,7 @@ public function __construct(cli_helper $clihelper, array $moodleinstances) { $this->curlrequest->set_option(CURLOPT_RETURNTRANSFER, true); $this->curlrequest->set_option(CURLOPT_POST, 1); $this->curlrequest->set_option(CURLOPT_POSTFIELDS, $this->postsettings); - if (!$arguments()['subcall']) { + if (!$arguments['subcall']) { $this->listcurlrequest = $this->get_curl_request($wsurl); $this->listpostsettings = [ 'wstoken' => $token, @@ -221,6 +221,7 @@ public function export_quiz_data() { } $quizmanifestentries = []; $nonquizmanifestentries = []; + // Determine quiz info location based on loactions of manifest paths. if ($this->quizmanifestpath) { $this->filepath = cli_helper::get_quiz_structure_path($responsejson->quiz->name, dirname($this->quizmanifestpath)); $quizmanifestentries = array_column($this->quizmanifestcontents->questions, null, 'questionbankentryid'); @@ -230,6 +231,7 @@ public function export_quiz_data() { if ($this->nonquizmanifestpath) { $nonquizmanifestentries = array_column($this->nonquizmanifestcontents->questions, null, 'questionbankentryid'); } + // Convert the returned QBE ids into file locations using the manifest files to translate. foreach ($responsejson->questions as $question) { $quizmanifestentry = $quizmanifestentries["{$question->questionbankentryid}"] ?? false; $nonquizmanifestentry = $nonquizmanifestentries["{$question->questionbankentryid}"] ?? false; @@ -250,6 +252,7 @@ public function export_quiz_data() { "consider consolidating them.\n"; } } + // Save exported information (including relative file location but not QBE id so Moodle independent). file_put_contents($this->filepath, json_encode($responsejson)); echo "Quiz data exported to:\n"; echo "{$this->filepath}\n"; diff --git a/testrepoparent/testrepo/fakeexport_system_question_manifest.json b/testrepoparent/testrepo/fakeexport_system_question_manifest.json index 191eb78..5f58526 100644 --- a/testrepoparent/testrepo/fakeexport_system_question_manifest.json +++ b/testrepoparent/testrepo/fakeexport_system_question_manifest.json @@ -4,7 +4,6 @@ "coursename": "", "modulename": "", "coursecategory": "", - "qcategoryname": "/top", "instanceid": "", "defaultsubdirectory": "top\/cat-2", "defaultsubcategoryid": 5 diff --git a/testrepoparent/testrepo/fakeexportquiz_course_course-1_question_manifest.json b/testrepoparent/testrepo/fakeexportquiz_course_course-1_question_manifest.json new file mode 100644 index 0000000..5f58526 --- /dev/null +++ b/testrepoparent/testrepo/fakeexportquiz_course_course-1_question_manifest.json @@ -0,0 +1,42 @@ +{ + "context": { + "contextlevel": 10, + "coursename": "", + "modulename": "", + "coursecategory": "", + "instanceid": "", + "defaultsubdirectory": "top\/cat-2", + "defaultsubcategoryid": 5 + }, + "questions": [ + { + "questionbankentryid": 35001, + "filepath": "\/top\/cat-1\/First-Question.xml", + "importedversion": "1", + "exportedversion": "1", + "format": "xml" + }, + { + "questionbankentryid": 35002, + "filepath": "\/top\/cat-2\/subcat-2_1\/Third-Question.xml", + "importedversion": "6", + "exportedversion": "7", + "format": "xml" + }, + { + "questionbankentryid": 35004, + "filepath": "\/top\/cat-2\/subcat-2_1\/Fourth-Question.xml", + "importedversion": "1", + "exportedversion": "1", + "currentcommit": "35004test", + "format": "xml" + }, + { + "questionbankentryid": 35003, + "filepath": "\/top\/cat-2\/Second-Question.xml", + "importedversion": "1", + "exportedversion": "1", + "format": "xml" + } + ] +} \ No newline at end of file diff --git a/testrepoparent/testrepo/fakeignore_system_question_manifest.json b/testrepoparent/testrepo/fakeignore_system_question_manifest.json index c3786dc..72056c8 100644 --- a/testrepoparent/testrepo/fakeignore_system_question_manifest.json +++ b/testrepoparent/testrepo/fakeignore_system_question_manifest.json @@ -4,7 +4,6 @@ "coursename": "", "modulename": "", "coursecategory": "", - "qcategoryname": "/top", "instanceid": "", "defaultsubdirectory": "top\/cat-2", "defaultsubcategoryid": 5, diff --git a/testrepoparent/testrepo_quiz_quiz-1/fakeexportquiz_module_course-1_quiz-1_question_manifest.json b/testrepoparent/testrepo_quiz_quiz-1/fakeexportquiz_module_course-1_quiz-1_question_manifest.json new file mode 100644 index 0000000..10aec08 --- /dev/null +++ b/testrepoparent/testrepo_quiz_quiz-1/fakeexportquiz_module_course-1_quiz-1_question_manifest.json @@ -0,0 +1,20 @@ +{ + "context": { + "contextlevel": 70, + "coursename": "", + "modulename": "", + "coursecategory": "", + "instanceid": "", + "defaultsubdirectory": "top", + "defaultsubcategoryid": 5 + }, + "questions": [ + { + "questionbankentryid":"36001", + "filepath": "\/top\/Quiz-Question.xml", + "importedversion": "1", + "exportedversion": "1", + "format": "xml" + } + ] +} \ No newline at end of file diff --git a/testrepoparent/testrepo_quiz_quiz-1/top/Quiz-Question.xml b/testrepoparent/testrepo_quiz_quiz-1/top/Quiz-Question.xml new file mode 100644 index 0000000..342bae7 --- /dev/null +++ b/testrepoparent/testrepo_quiz_quiz-1/top/Quiz-Question.xml @@ -0,0 +1,25 @@ + + + + + Quiz Question + + + This is a test question.

]]>
+
+ + + + 1 + 0.3333333 + 0 + + 0 + + This is a test answer. + + + + +
+
\ No newline at end of file diff --git a/testrepoparent/testrepo_quiz_quiz-1/top/gitsync_category.xml b/testrepoparent/testrepo_quiz_quiz-1/top/gitsync_category.xml new file mode 100644 index 0000000..f5864d9 --- /dev/null +++ b/testrepoparent/testrepo_quiz_quiz-1/top/gitsync_category.xml @@ -0,0 +1,12 @@ + + + + + top/cat 1 + + + First imported folder + + + + \ No newline at end of file diff --git a/tests/export_quiz_test.php b/tests/export_quiz_test.php index 86891ab..461da14 100644 --- a/tests/export_quiz_test.php +++ b/tests/export_quiz_test.php @@ -59,7 +59,7 @@ public static function handle_abort():void { * * @covers \gitsync\export_repo::class */ -class export_repo_test extends advanced_testcase { +class export_quiz_test extends advanced_testcase { /** @var array mocked output of cli_helper->get_arguments */ public array $options; /** @var array of instance names and URLs */ @@ -68,33 +68,82 @@ class export_repo_test extends advanced_testcase { public cli_helper $clihelper; /** @var curl_request mocked curl_request */ public curl_request $curl; - /** @var export_repo mocked export_repo */ - public export_repo $exportrepo; + /** @var export_quiz mocked export_quiz */ + public export_quiz $exportquiz; /** @var curl_request mocked curl_request for question list */ public curl_request $listcurl; /** @var string root of virtual file system */ public string $rootpath; /** @var string used to store output of multiple calls to a function */ - const MOODLE = 'fakeexport'; + const MOODLE = 'fakeexportquiz'; /** Name of question to be generated and exported. */ + const QUIZNAME = 'Quiz 1'; + const QUIZINTRO = 'Quiz intro'; + const FEEDBACK = 'Quiz feedback'; + const HEADING1 = 'Heading 1'; + const HEADING2 = 'Heading 2'; + /** @var array input parameters */ + protected array $quizoutput = [ + 'quiz' => [ + 'name' => self::QUIZNAME, + 'intro' => self::QUIZINTRO, + 'introformat' => '0', + 'coursename' => null, + 'courseid' => null, + 'questionsperpage' => '0', + 'grade' => '100.00000', + 'navmethod' => 'free', + ], + 'sections' => [ + [ + 'firstslot' => '1', + 'heading' => self::HEADING1, + 'shufflequestions' => 0, + ], + [ + 'firstslot' => '2', + 'heading' => self::HEADING2, + 'shufflequestions' => 0, + ] + ], + 'questions' => [ + [ + 'questionbankentryid' => '36001', + 'slot' => '1', + 'page' => '1', + 'requireprevious' => 0, + 'maxmark' => '1.0000000', + ] + ], + 'feedback' => [ + [ + 'feedbacktext' => self::FEEDBACK, + 'feedbacktextformat' => '0', + 'mingrade' => '0.0000000', + 'maxgrade' => '50.000000', + ] + ], + ]; public function setUp(): void { global $CFG; $this->moodleinstances = [self::MOODLE => 'fakeurl.com']; // Copy test repo to virtual file stream. $root = vfsStream::setup(); - vfsStream::copyFromFileSystem($CFG->dirroot . '/question/bank/gitsync/testrepo/', $root); + vfsStream::copyFromFileSystem($CFG->dirroot . '/question/bank/gitsync/testrepoparent/', $root); $this->rootpath = vfsStream::url('root'); // Mock the combined output of command line options and defaults. $this->options = [ 'moodleinstance' => self::MOODLE, 'rootdirectory' => $this->rootpath, - 'subcategory' => null, - 'qcategoryid' => null, - 'manifestpath' => '/' . self::MOODLE . '_system' . cli_helper::MANIFEST_FILE, + 'nonquizmanifestpath' => '/testrepo/' . self::MOODLE . '_course_course-1' . cli_helper::MANIFEST_FILE, + 'quizmanifestpath' => '/testrepo_quiz_quiz-1/' . self::MOODLE . '_module_course-1_quiz-1' . cli_helper::MANIFEST_FILE, + 'coursename' => null, + 'modulename' => null, + 'instanceid' => null, 'token' => 'XXXXXX', 'help' => false, - 'ignorecat' => null, + 'subcall' => false, ]; $this->clihelper = $this->getMockBuilder(\qbank_gitsync\cli_helper::class)->onlyMethods([ 'get_arguments', 'check_context', @@ -112,38 +161,11 @@ public function setUp(): void { $this->listcurl = $this->getMockBuilder(\qbank_gitsync\curl_request::class)->onlyMethods([ 'execute', ])->setConstructorArgs(['xxxx'])->getMock(); - $this->exportrepo = $this->getMockBuilder(\qbank_gitsync\export_repo::class)->onlyMethods([ + $this->exportquiz = $this->getMockBuilder(\qbank_gitsync\export_quiz::class)->onlyMethods([ 'get_curl_request', 'call_exit', ])->setConstructorArgs([$this->clihelper, $this->moodleinstances])->getMock(); - $this->exportrepo->curlrequest = $this->curl; - $this->exportrepo->listcurlrequest = $this->listcurl; - - $this->exportrepo->postsettings = ['questionbankentryid' => null]; - } - - /** - * Redo mock set up - * - * Required if we want to change options so that they affect contructor output. - * - * @return void - */ - public function replace_mock_default() { - $this->clihelper = $this->getMockBuilder(\qbank_gitsync\cli_helper::class)->onlyMethods([ - 'get_arguments', 'check_context', - ])->setConstructorArgs([[]])->getMock(); - $this->clihelper->expects($this->any())->method('get_arguments')->will($this->returnValue($this->options)); - $this->clihelper->expects($this->any())->method('check_context')->willReturn( - json_decode('{"contextinfo":{"contextlevel": "module", "categoryname":"", "coursename":"Course 1", - "modulename":"Module 1", "instanceid":"", "qcategoryname":"top/cat 2/subcat 2_1"}, - "questions": []}') - ); - $this->exportrepo = $this->getMockBuilder(\qbank_gitsync\export_repo::class)->onlyMethods([ - 'get_curl_request', 'call_exit', - ])->setConstructorArgs([$this->clihelper, $this->moodleinstances])->getMock(); - - $this->exportrepo->curlrequest = $this->curl; - $this->exportrepo->listcurlrequest = $this->listcurl; + $this->exportquiz->curlrequest = $this->curl; + $this->exportquiz->listcurlrequest = $this->listcurl; } /** @@ -151,275 +173,18 @@ public function replace_mock_default() { */ public function test_process(): void { // Will get questions in order from manifest file in testrepo. - $this->curl->expects($this->exactly(4))->method('execute')->willReturnOnConsecutiveCalls( - '{"question": "One", "version": "10"}', - '{"question": "Three", "version": "1"}', - '{"question": "Four", "version": "1"}', - '{"question": "Two", "version": "1"}' - ); - - $this->listcurl->expects($this->exactly(2))->method('execute')->willReturnOnConsecutiveCalls( - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top"}, - "questions": [{"questionbankentryid": "35001", "name": "One", "questioncategory": ""}, - {"questionbankentryid": "35002", "name": "Two", "questioncategory": ""}, - {"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}', - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top"}, - "questions": [{"questionbankentryid": "35001", "name": "One", "questioncategory": ""}, - {"questionbankentryid": "35002", "name": "Two", "questioncategory": ""}, - {"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}' - ); - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->exportrepo->process(); - - // Check question files updated. - $this->assertStringContainsString('One', file_get_contents($this->rootpath . '/top/cat-1/First-Question.xml')); - $this->assertStringContainsString('Two', file_get_contents($this->rootpath . '/top/cat-2/Second-Question.xml')); - $this->assertStringContainsString('Three', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Third-Question.xml')); - $this->assertStringContainsString('Four', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Fourth-Question.xml')); - - // Check manifest file updated. - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->assertCount(4, $manifestcontents->questions); - - $existingentries = array_column($manifestcontents->questions, null, 'questionbankentryid'); - $this->assertArrayHasKey('35001', $existingentries); - $this->assertArrayHasKey('35002', $existingentries); - $this->assertArrayHasKey('35003', $existingentries); - $this->assertArrayHasKey('35004', $existingentries); - - $this->assertEquals('1', $existingentries['35001']->importedversion); - $this->assertEquals('10', $existingentries['35001']->exportedversion); - // Question category id should be default from manifest. - $this->assertEquals(5, $this->exportrepo->listpostsettings["qcategoryid"]); - - $this->expectOutputRegex('/^\nExported 4 previously linked questions.*Added 0 questions.\n$/s'); - } - - /** - * Test the export of questions which aren't in the manifest - * @covers \gitsync\export_trait\export_to_repo() - */ - public function test_export_to_repo(): void { - // Will get questions in order from manifest file in testrepo. - $this->curl->expects($this->exactly(4))->method('execute')->willReturnOnConsecutiveCalls( - '{"question": "One", "version": "10"}', - '{"question": "Three", "version": "1"}', - '{"question": "Four", "version": "1"}', - '{"question": "Two", "version": "1"}' - ); - - $this->listcurl->expects($this->exactly(3))->method('execute')->willReturn( - '{"contextinfo":{"contextlevel": "module", "categoryname":"", "coursename":"Course 1", - "modulename":"Module 1", "instanceid":"", "qcategoryname":"top"}, - "questions": []}' - ); - - $this->exportrepo->process(); - - // Check question files updated. - $this->assertStringContainsString('One', file_get_contents($this->rootpath . '/top/cat-1/First-Question.xml')); - $this->assertStringContainsString('Two', file_get_contents($this->rootpath . '/top/cat-2/Second-Question.xml')); - $this->assertStringContainsString('Three', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Third-Question.xml')); - $this->assertStringContainsString('Four', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Fourth-Question.xml')); - $this->expectOutputRegex('/^\nExported 4 previously linked questions.*Added 0 questions.\n$/s'); - } - - /** - * Test message if export JSON broken. - */ - public function test_broken_json_on_export(): void { - $this->curl->expects($this->any())->method('execute')->willReturn( - '{"question": One", "version": "10"}' - ); - - $this->exportrepo->export_questions_in_manifest(); - - $this->expectOutputRegex('/Broken JSON returned from Moodle:' . - '.*{"question": One<\/Name><\/Question>", "version": "10"}/s'); - } - - /** - * Test message if export exception. - */ - public function test_exception_on_export(): void { - $this->curl->expects($this->any())->method('execute')->willReturn( - '{"exception":"moodle_exception","message":"No token"}' - ); - - $this->exportrepo->export_questions_in_manifest(); - - $this->expectOutputRegex('/No token/'); - } - - /** - * Test message if manifest file update issue. - */ - public function test_manifest_file_update_error(): void { - $this->curl->expects($this->any())->method('execute')->willReturn( - '{"question": "One", "version": "10"}' - ); - - chmod($this->exportrepo->manifestpath, 0000); - - @$this->exportrepo->export_questions_in_manifest(); - $this->expectOutputRegex('/\nUnable to update manifest file.*Aborting.\n$/s'); - } - - /** - * Test message if manifest file open issue. - */ - public function test_manifest_file_open_error(): void { - chmod($this->exportrepo->manifestpath, 0000); - @$this->exportrepo->__construct($this->clihelper, $this->moodleinstances); - $this->expectOutputRegex('/^\nUnable to access or parse manifest file.*Aborting.\n$/s'); - } - - /** - * Test message if question file update issue. - */ - public function test_question_file_update_error(): void { - $this->curl->expects($this->any())->method('execute')->willReturn( - '{"question": "One", "version": "10"}' - ); - - chmod($this->rootpath . '/top/cat-1/First-Question.xml', 0000); - - @$this->exportrepo->export_questions_in_manifest(); - $this->expectOutputRegex('/^\nAccess issue.\n\/top\/cat-1\/First-Question.xml not updated.\n/s'); - } - - /** - * Test message if question reformat issue. - */ - public function test_reformat_error(): void { - $this->curl->expects($this->any())->method('execute')->willReturnOnConsecutiveCalls( - '{"question": "One", "version": "10"}', // Broken. - '{"question": "Three", "version": "1"}', - '{"question": "Four", "version": "1"}', - '{"question": "Two", "version": "1"}', - ); - - // Make sure no attempt is made to update first file. - chmod($this->rootpath . '/top/cat-1/First-Question.xml', 0000); - - @$this->exportrepo->export_questions_in_manifest(); - $this->expectOutputRegex('/^\nBroken XML\n\/top\/cat-1\/First-Question.xml not updated.\n/s'); - } - - /** - * Test the full process with subcategory name. - */ - public function test_process_with_subcategory_name(): void { - $this->options['subcategory'] = 'top/cat-2/subcat-2_1'; - $this->replace_mock_default(); - // Will get questions in order from manifest file in testrepo. - $this->curl->expects($this->exactly(2))->method('execute')->willReturnOnConsecutiveCalls( - '{"question": "Three", "version": "1"}', - '{"question": "Four", "version": "1"}' + $this->curl->expects($this->exactly(1))->method('execute')->willReturnOnConsecutiveCalls( + json_encode($this->quizoutput) ); - $this->listcurl->expects($this->exactly(2))->method('execute')->willReturnOnConsecutiveCalls( - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top/cat 2/subcat 2_1"}, - "questions": [{"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}', - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top"}, - "questions": [{"questionbankentryid": "35001", "name": "One", "questioncategory": ""}, - {"questionbankentryid": "35002", "name": "Two", "questioncategory": ""}, - {"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}' - ); - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->exportrepo->process(); + $this->exportquiz->process(); + $quizstructure = file_get_contents($this->rootpath . '/testrepo_quiz_quiz-1/' . 'quiz-1' . cli_helper::QUIZ_FILE); // Check question files updated. - $this->assertStringContainsString('First Question', file_get_contents($this->rootpath . '/top/cat-1/First-Question.xml')); - $this->assertStringContainsString('Second Question', file_get_contents($this->rootpath . '/top/cat-2/Second-Question.xml')); - $this->assertStringContainsString('Three', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Third-Question.xml')); - $this->assertStringContainsString('Four', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Fourth-Question.xml')); - - // Check manifest file updated. - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->assertCount(4, $manifestcontents->questions); - - $existingentries = array_column($manifestcontents->questions, null, 'questionbankentryid'); - $this->assertArrayHasKey('35001', $existingentries); - $this->assertArrayHasKey('35002', $existingentries); - $this->assertArrayHasKey('35003', $existingentries); - $this->assertArrayHasKey('35004', $existingentries); - $this->assertEquals(null, $this->exportrepo->listpostsettings["qcategoryid"]); + $quizstructure = json_decode($quizstructure); + $this->assertEquals('/top/Quiz-Question.xml', $quizstructure->questions[0]->quizfilepath); - $this->expectOutputRegex('/^\nExported 2 previously linked questions.*Added 0 questions.\n$/s'); - } - - /** - * Test the full process with subcategory id. - */ - public function test_process_with_subcategory_id(): void { - global $DB; - $this->options['qcategoryid'] = 17; - $this->replace_mock_default(); - - // Will get questions in order from manifest file in testrepo. - $this->curl->expects($this->exactly(2))->method('execute')->willReturnOnConsecutiveCalls( - '{"question": "Three", "version": "1"}', - '{"question": "Four", "version": "1"}' - ); - - $this->listcurl->expects($this->exactly(2))->method('execute')->willReturnOnConsecutiveCalls( - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top/cat 2/subcat 2_1"}, - "questions": [{"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}', - '{"contextinfo": {"contextlevel": "module", "categoryname": "", "coursename": "Course 1", - "modulename": "Module 1", "instanceid": "", "qcategoryname":"top"}, - "questions": [{"questionbankentryid": "35001", "name": "One", "questioncategory": ""}, - {"questionbankentryid": "35002", "name": "Two", "questioncategory": ""}, - {"questionbankentryid": "35003", "name": "Three", "questioncategory": ""}, - {"questionbankentryid": "35004", "name": "Four", "questioncategory": ""}]}' - ); - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->exportrepo->process(); - - // Check question files updated. - $this->assertStringContainsString('First Question', file_get_contents($this->rootpath . '/top/cat-1/First-Question.xml')); - $this->assertStringContainsString('Second Question', file_get_contents($this->rootpath . '/top/cat-2/Second-Question.xml')); - $this->assertStringContainsString('Three', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Third-Question.xml')); - $this->assertStringContainsString('Four', file_get_contents($this->rootpath . '/top/cat-2/subcat-2_1/Fourth-Question.xml')); - - // Check manifest file updated. - $manifestcontents = json_decode(file_get_contents($this->exportrepo->manifestpath)); - $this->assertCount(4, $manifestcontents->questions); - - $existingentries = array_column($manifestcontents->questions, null, 'questionbankentryid'); - $this->assertArrayHasKey('35001', $existingentries); - $this->assertArrayHasKey('35002', $existingentries); - $this->assertArrayHasKey('35003', $existingentries); - $this->assertArrayHasKey('35004', $existingentries); - // Question category id should be as supplied. - $this->assertEquals(17, $this->exportrepo->listpostsettings["qcategoryid"]); - - $this->expectOutputRegex('/^\nExported 2 previously linked questions.*Added 0 questions.\n$/s'); - } - - /** - * Test checking context default warning - * @covers \gitsync\cli_helper\check_context() - */ - public function test_check_content_default_warning(): void { - $clihelper = new fake_export_cli_helper([]); - $this->listcurl->expects($this->exactly(1))->method('execute')->willReturn( - '{"contextinfo":{"contextlevel": "module", "categoryname":"", "coursename":"Course 1", - "modulename":"Module 1", "instanceid":"", "qcategoryname":"top", "qcategoryid":1}, - "questions": []}', - ); - $clihelper->check_context($this->exportrepo, true, false); - $this->expectOutputRegex('/Using default question category from manifest file./'); + $this->expectOutputRegex('/^Quiz data exported to:\n.*testrepo_quiz_quiz-1\/quiz-1_quiz.json\n$/s'); } }