Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace qbank_bulkmove;
18
 
19
use core_question\local\bank\question_edit_contexts;
20
 
21
defined('MOODLE_INTERNAL') || die();
22
 
23
global $CFG;
24
require_once($CFG->dirroot . '/question/editlib.php');
25
 
26
/**
27
 * Bulk move helper tests.
28
 *
29
 * @package    qbank_bulkmove
30
 * @copyright  2021 Catalyst IT Australia Pty Ltd
31
 * @author     Safat Shahin <safatshahin@catalyst-au.net>
32
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 * @coversDefaultClass \qbank_bulkmove\helper
34
 */
35
class helper_test extends \advanced_testcase {
36
 
37
    /**
38
     * @var false|object|\stdClass|null $cat
39
     */
40
    protected $cat;
41
 
42
    /**
43
     * @var \stdClass $questiondata1
44
     */
45
    protected $questiondata1;
46
 
47
    /**
48
     * @var \stdClass $questiondata2
49
     */
50
    protected $questiondata2;
51
 
52
    /**
53
     * @var bool|\context|\context_course $context
54
     */
55
    protected $context;
56
 
57
    /**
58
     * @var \core_question\local\bank\question_edit_contexts $contexts
59
     */
60
    protected $contexts;
61
 
62
    /**
63
     * @var \stdClass $course
64
     */
65
    protected $course;
66
 
67
    /**
68
     * @var array $rawdata
69
     */
70
    protected $rawdata;
71
 
72
    /**
73
     * @var object $secondcategory
74
     */
75
    protected $secondcategory;
76
 
77
    /**
78
     * Setup the test.
79
     */
80
    protected function helper_setup(): void {
81
        $this->resetAfterTest();
82
        $this->setAdminUser();
83
        $generator = $this->getDataGenerator();
84
        /** @var \core_question_generator $questiongenerator */
85
        $questiongenerator = $generator->get_plugin_generator('core_question');
86
 
87
        // Create a course.
88
        $this->course = $generator->create_course();
89
        $this->context = \context_course::instance($this->course->id);
90
 
91
        // Create a question in the default category.
92
        $this->contexts = new question_edit_contexts($this->context);
93
        $this->cat = question_make_default_categories($this->contexts->all());
94
        $this->questiondata1 = $questiongenerator->create_question('numerical', null,
95
            ['name' => 'Example question', 'category' => $this->cat->id]);
96
 
97
        // Create a second category to move questions.
98
        $this->secondcategory = $questiongenerator->create_question_category(['contextid' => $this->context->id,
99
            'parent' => $this->cat->id]);
100
 
101
        // Ensure the question is not in the cache.
102
        $cache = \cache::make('core', 'questiondata');
103
        $cache->delete($this->questiondata1->id);
104
 
105
        $this->questiondata2 = $questiongenerator->create_question('numerical', null,
106
            ['name' => 'Example question second', 'category' => $this->cat->id]);
107
 
108
        // Ensure the question is not in the cache.
109
        $cache = \cache::make('core', 'questiondata');
110
        $cache->delete($this->questiondata2->id);
111
 
112
        // Posted raw data.
113
        $this->rawdata = [
114
            'courseid' => $this->course->id,
115
            'cat' => "{$this->cat->id},{$this->context->id}",
116
            'qpage' => '0',
117
            "q{$this->questiondata1->id}" => '1',
118
            "q{$this->questiondata2->id}" => '1',
119
            'move' => 'Move to'
120
        ];
121
    }
122
 
123
    /**
124
     * Count how many questions in the list belong to the given category.
125
     *
126
     * @param string $categoryid a category id
127
     * @param array $questionids list of question ids
128
     * @return int
129
     */
130
    private function count_category_questions(string $categoryid, array $questionids): int {
131
        global $DB;
132
        $this->assertNotEmpty($questionids);
133
        list($insql, $inparams) = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED);
134
        $sql = "SELECT COUNT(q.id)
135
                  FROM {question} q
136
                  JOIN {question_versions} qv ON qv.questionid = q.id
137
                  JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid
138
                  JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid
139
                 WHERE qc.id = :categoryid
140
                   AND q.id $insql";
141
 
142
        return $DB->count_records_sql($sql, array_merge(['categoryid' => $categoryid], $inparams));
143
    }
144
 
145
    /**
146
     * Assert that the given category contains following questions
147
     *
148
     * @param string $categoryid a category id
149
     * @param array $questionids list of question ids
150
     * @return void
151
     */
152
    protected function assert_category_contains_questions(string $categoryid, array $questionids) {
153
        // The category need to contain all the questions.
154
        $this->assertEquals(count($questionids), $this->count_category_questions($categoryid, $questionids));
155
    }
156
 
157
    /**
158
     * Assert that the given category does not contain following questions
159
     *
160
     * @param string $categoryid a category id
161
     * @param array $questionids list of question ids
162
     * @return void
163
     */
164
    protected function assert_category_does_not_contain_questions(string $categoryid, array $questionids) {
165
        // The category does not contain any question.
166
        $this->assertEquals(0, $this->count_category_questions($categoryid, $questionids));
167
    }
168
 
169
    /**
170
     * Test bulk move of questions.
171
     *
172
     * @covers ::bulk_move_questions
173
     */
11 efrain 174
    public function test_bulk_move_questions(): void {
1 efrain 175
        global $DB;
176
        $this->helper_setup();
177
 
178
        // Get the processed question ids.
179
        $questionlist = $this->process_question_ids_test();
180
        $questionids = array_map('intval', explode(',', $questionlist));
181
 
182
        // Verify that the questions are available in the current view.
183
        $this->assert_category_contains_questions($this->cat->id, $questionids);
184
        helper::bulk_move_questions($questionlist, $this->secondcategory);
185
 
186
        // Verify the questions are not in the current category.
187
        $this->assert_category_does_not_contain_questions($this->cat->id, $questionids);
188
 
189
        // Verify the questions are in the new category.
190
        $this->assert_category_contains_questions($this->secondcategory->id, $questionids);
191
    }
192
 
193
    /**
194
     * Test the question processing and return the question list.
195
     *
196
     * @return mixed
197
     * @covers ::process_question_ids
198
     */
199
    protected function process_question_ids_test() {
200
        // Test the raw data processing.
201
        list($questionids, $questionlist) = helper::process_question_ids($this->rawdata);
202
        $this->assertEquals([$this->questiondata1->id, $this->questiondata2->id], $questionids);
203
        $this->assertEquals("{$this->questiondata1->id},{$this->questiondata2->id}", $questionlist);
204
        return $questionlist;
205
    }
206
 
207
    /**
208
     * Test the question displaydata.
209
     *
210
     * @covers ::get_displaydata
211
     */
11 efrain 212
    public function test_get_displaydata(): void {
1 efrain 213
        $this->helper_setup();
214
        $coursecontext = \context_course::instance($this->course->id);
215
        $contexts = new question_edit_contexts($coursecontext);
216
        $addcontexts = $contexts->having_cap('moodle/question:add');
217
        $url = new \moodle_url('/question/bank/bulkmove/move.php');
218
        $displaydata = \qbank_bulkmove\helper::get_displaydata($addcontexts, $url, $url);
219
        $this->assertStringContainsString('Test question category 1', $displaydata['categorydropdown']);
220
        $this->assertStringContainsString('Default for Category 1', $displaydata['categorydropdown']);
221
        $this->assertEquals($url, $displaydata ['moveurl']);
222
        $this->assertEquals($url, $displaydata ['returnurl']);
223
    }
224
}