Merge branch 'MDL-53166' of https://github.com/eugeneventer/moodle-fixes
[moodle.git] / mod / forum / tests / search_test.php
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/>.
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  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
30 require_once($CFG->dirroot . '/mod/forum/tests/generator/lib.php');
31 require_once($CFG->dirroot . '/mod/forum/lib.php');
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  */
41 class mod_forum_search_testcase extends advanced_testcase {
43     /**
44      * @var string Area id
45      */
46     protected $forumpostareaid = null;
48     public function setUp() {
49         $this->resetAfterTest(true);
50         set_config('enableglobalsearch', true);
52         $this->forumpostareaid = \core_search\manager::generate_areaid('mod_forum', 'post');
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     }
58     /**
59      * Availability.
60      *
61      * @return void
62      */
63     public function test_search_enabled() {
65         $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
66         list($componentname, $varname) = $searcharea->get_config_var_name();
68         // Enabled by default once global search is enabled.
69         $this->assertTrue($searcharea->is_enabled());
71         set_config($varname . '_enabled', false, $componentname);
72         $this->assertFalse($searcharea->is_enabled());
74         set_config($varname . '_enabled', true, $componentname);
75         $this->assertTrue($searcharea->is_enabled());
76     }
78     /**
79      * Indexing mod forum contents.
80      *
81      * @return void
82      */
83     public function test_posts_indexing() {
84         global $DB;
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);
90         $user1 = self::getDataGenerator()->create_user();
91         $user2 = self::getDataGenerator()->create_user();
93         $course1 = self::getDataGenerator()->create_course();
94         $course2 = self::getDataGenerator()->create_course();
96         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
97         $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
99         $record = new stdClass();
100         $record->course = $course1->id;
102         // Available for both student and teacher.
103         $forum1 = self::getDataGenerator()->create_module('forum', $record);
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);
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);
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);
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);
141         // The +2 is to prevent race conditions.
142         $recordset = $searcharea->get_recordset_by_timestamp(time() + 2);
144         // No new records.
145         $this->assertFalse($recordset->valid());
146         $recordset->close();
147     }
149     /**
150      * Document contents.
151      *
152      * @return void
153      */
154     public function test_posts_document() {
155         global $DB;
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);
161         $user = self::getDataGenerator()->create_user();
162         $course1 = self::getDataGenerator()->create_course();
163         $this->getDataGenerator()->enrol_user($user->id, $course1->id, 'teacher');
165         $record = new stdClass();
166         $record->course = $course1->id;
167         $forum1 = self::getDataGenerator()->create_module('forum', $record);
169         // Teacher only.
170         $forum2 = self::getDataGenerator()->create_module('forum', $record);
171         set_coursemodule_visible($forum2->cmid, 0);
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);
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);
190         $post1 = $DB->get_record('forum_posts', array('id' => $discussion1reply1->id));
191         $post1->forumid = $forum1->id;
192         $post1->courseid = $forum1->course;
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     }
204     /**
205      * Document accesses.
206      *
207      * @return void
208      */
209     public function test_posts_access() {
210         global $DB;
212         // Returns the instance as long as the area is supported.
213         $searcharea = \core_search\manager::get_search_area($this->forumpostareaid);
215         $user1 = self::getDataGenerator()->create_user();
216         $user2 = self::getDataGenerator()->create_user();
218         $course1 = self::getDataGenerator()->create_course();
219         $course2 = self::getDataGenerator()->create_course();
221         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
222         $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
224         $record = new stdClass();
225         $record->course = $course1->id;
227         // Available for both student and teacher.
228         $forum1 = self::getDataGenerator()->create_module('forum', $record);
230         // Teacher only.
231         $forum2 = self::getDataGenerator()->create_module('forum', $record);
232         set_coursemodule_visible($forum2->cmid, 0);
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);
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);
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);
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);
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     }