MDL-31989 search: New search areas
[moodle.git] / mod / forum / tests / search_test.php
CommitLineData
e2be9961
DM
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/**
18 * Forum search unit tests.
19 *
20 * @package mod_forum
21 * @category test
22 * @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
30require_once($CFG->dirroot . '/mod/forum/tests/generator/lib.php');
31require_once($CFG->dirroot . '/mod/forum/lib.php');
32
33/**
34 * Provides the unit tests for forum search.
35 *
36 * @package mod_forum
37 * @category test
38 * @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class mod_forum_search_testcase extends advanced_testcase {
42
43 /**
44 * @var string Area id
45 */
46 protected $forumpostareaid = null;
47
48 public function setUp() {
49 $this->resetAfterTest(true);
50 set_config('enableglobalsearch', true);
51
52 $this->forumpostareaid = \core_search\manager::generate_areaid('mod_forum', 'post');
53
54 // Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
55 $search = testable_core_search::instance();
56 }
57
58 /**
59 * Availability.
60 *
61 * @return void
62 */
63 public function test_search_enabled() {
64
65 $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
66 list($componentname, $varname) = $searcharea->get_config_var_name();
67
68 // Enabled by default once global search is enabled.
69 $this->assertTrue($searcharea->is_enabled());
70
71 set_config('enable' . $varname, false, $componentname);
72 $this->assertFalse($searcharea->is_enabled());
73
74 set_config('enable' . $varname, true, $componentname);
75 $this->assertTrue($searcharea->is_enabled());
76 }
77
78 /**
79 * Indexing mod forum contents.
80 *
81 * @return void
82 */
83 public function test_posts_indexing() {
84 global $DB;
85
86 // Returns the instance as long as the area is supported.
87 $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
88 $this->assertInstanceOf('\mod_forum\search\post', $searcharea);
89
90 $user1 = self::getDataGenerator()->create_user();
91 $user2 = self::getDataGenerator()->create_user();
92
93 $course1 = self::getDataGenerator()->create_course();
94 $course2 = self::getDataGenerator()->create_course();
95
96 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
97 $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
98
99 $record = new stdClass();
100 $record->course = $course1->id;
101
102 // Available for both student and teacher.
103 $forum1 = self::getDataGenerator()->create_module('forum', $record);
104
105 // Create discussion1.
106 $record = new stdClass();
107 $record->course = $course1->id;
108 $record->userid = $user1->id;
109 $record->forum = $forum1->id;
110 $record->message = 'discussion';
111 $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
112
113 // Create post1 in discussion1.
114 $record = new stdClass();
115 $record->discussion = $discussion1->id;
116 $record->parent = $discussion1->firstpost;
117 $record->userid = $user2->id;
118 $record->message = 'post2';
119 $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
120
121 // All records.
122 $recordset = $searcharea->get_recordset_by_timestamp(0);
123 $this->assertTrue($recordset->valid());
124 $nrecords = 0;
125 foreach ($recordset as $record) {
126 $this->assertInstanceOf('stdClass', $record);
127 $doc = $searcharea->get_document($record);
128 $this->assertInstanceOf('\core_search\document', $doc);
129
130 // Static caches are working.
131 $dbreads = $DB->perf_get_reads();
132 $doc = $searcharea->get_document($record);
133 $this->assertEquals($dbreads, $DB->perf_get_reads());
134 $this->assertInstanceOf('\core_search\document', $doc);
135 $nrecords++;
136 }
137 // If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
138 $recordset->close();
139 $this->assertEquals(2, $nrecords);
140
141 // The +2 is to prevent race conditions.
142 $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
143
144 // No new records.
145 $this->assertFalse($recordset->valid());
146 $recordset->close();
147 }
148
149 /**
150 * Document contents.
151 *
152 * @return void
153 */
154 public function test_posts_document() {
155 global $DB;
156
157 // Returns the instance as long as the area is supported.
158 $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
159 $this->assertInstanceOf('\mod_forum\search\post', $searcharea);
160
161 $user = self::getDataGenerator()->create_user();
162 $course1 = self::getDataGenerator()->create_course();
163 $this->getDataGenerator()->enrol_user($user->id, $course1->id, 'teacher');
164
165 $record = new stdClass();
166 $record->course = $course1->id;
167 $forum1 = self::getDataGenerator()->create_module('forum', $record);
168
169 // Teacher only.
170 $forum2 = self::getDataGenerator()->create_module('forum', $record);
171 set_coursemodule_visible($forum2->cmid, 0);
172
173 // Create discussion1.
174 $record = new stdClass();
175 $record->course = $course1->id;
176 $record->userid = $user->id;
177 $record->forum = $forum1->id;
178 $record->message = 'discussion';
179 $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
180
181 // Create post1 in discussion1.
182 $record = new stdClass();
183 $record->discussion = $discussion1->id;
184 $record->parent = $discussion1->firstpost;
185 $record->userid = $user->id;
186 $record->subject = 'subject1';
187 $record->message = 'post1';
188 $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
189
190 $post1 = $DB->get_record('forum_posts', array('id' => $discussion1reply1->id));
191 $post1->forumid = $forum1->id;
192 $post1->courseid = $forum1->course;
193
194 $doc = $searcharea->get_document($post1);
195 $this->assertInstanceOf('\core_search\document', $doc);
196 $this->assertEquals($discussion1reply1->id, $doc->get('itemid'));
197 $this->assertEquals($this->forumpostareaid . '-' . $discussion1reply1->id, $doc->get('id'));
198 $this->assertEquals($course1->id, $doc->get('courseid'));
199 $this->assertEquals($user->id, $doc->get('userid'));
200 $this->assertEquals($discussion1reply1->subject, $doc->get('title'));
201 $this->assertEquals($discussion1reply1->message, $doc->get('content'));
202 }
203
204 /**
205 * Document accesses.
206 *
207 * @return void
208 */
209 public function test_posts_access() {
210 global $DB;
211
212 // Returns the instance as long as the area is supported.
213 $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
214
215 $user1 = self::getDataGenerator()->create_user();
216 $user2 = self::getDataGenerator()->create_user();
217
218 $course1 = self::getDataGenerator()->create_course();
219 $course2 = self::getDataGenerator()->create_course();
220
221 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
222 $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
223
224 $record = new stdClass();
225 $record->course = $course1->id;
226
227 // Available for both student and teacher.
228 $forum1 = self::getDataGenerator()->create_module('forum', $record);
229
230 // Teacher only.
231 $forum2 = self::getDataGenerator()->create_module('forum', $record);
232 set_coursemodule_visible($forum2->cmid, 0);
233
234 // Create discussion1.
235 $record = new stdClass();
236 $record->course = $course1->id;
237 $record->userid = $user1->id;
238 $record->forum = $forum1->id;
239 $record->message = 'discussion';
240 $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
241
242 // Create post1 in discussion1.
243 $record = new stdClass();
244 $record->discussion = $discussion1->id;
245 $record->parent = $discussion1->firstpost;
246 $record->userid = $user2->id;
247 $record->message = 'post1';
248 $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
249
250 // Create discussion2 only visible to teacher.
251 $record = new stdClass();
252 $record->course = $course1->id;
253 $record->userid = $user1->id;
254 $record->forum = $forum2->id;
255 $record->message = 'discussion';
256 $discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
257
258 // Create post2 in discussion2.
259 $record = new stdClass();
260 $record->discussion = $discussion2->id;
261 $record->parent = $discussion2->firstpost;
262 $record->userid = $user1->id;
263 $record->message = 'post2';
264 $discussion2reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
265
266 $this->setUser($user2);
267 $this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($discussion1reply1->id));
268 $this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($discussion2reply1->id));
269 }
270}