Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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   * Glossary lib tests.
  19   *
  20   * @package    mod_glossary
  21   * @copyright  2015 Frédéric Massart - FMCorz.net
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->dirroot . '/mod/glossary/lib.php');
  29  require_once($CFG->dirroot . '/mod/glossary/locallib.php');
  30  
  31  /**
  32   * Glossary lib testcase.
  33   *
  34   * @package    mod_glossary
  35   * @copyright  2015 Frédéric Massart - FMCorz.net
  36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class mod_glossary_lib_testcase extends advanced_testcase {
  39  
  40      public function test_glossary_view() {
  41          global $CFG;
  42          $origcompletion = $CFG->enablecompletion;
  43          $CFG->enablecompletion = true;
  44          $this->resetAfterTest(true);
  45  
  46          // Generate all the things.
  47          $c1 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
  48          $g1 = $this->getDataGenerator()->create_module('glossary', array(
  49              'course' => $c1->id,
  50              'completion' => COMPLETION_TRACKING_AUTOMATIC,
  51              'completionview' => 1
  52          ));
  53          $g2 = $this->getDataGenerator()->create_module('glossary', array(
  54              'course' => $c1->id,
  55              'completion' => COMPLETION_TRACKING_AUTOMATIC,
  56              'completionview' => 1
  57          ));
  58          $u1 = $this->getDataGenerator()->create_user();
  59          $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
  60          $modinfo = course_modinfo::instance($c1->id);
  61          $cm1 = $modinfo->get_cm($g1->cmid);
  62          $cm2 = $modinfo->get_cm($g2->cmid);
  63          $ctx1 = $cm1->context;
  64          $completion = new completion_info($c1);
  65  
  66          $this->setUser($u1);
  67  
  68          // Confirm what we've set up.
  69          $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
  70          $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
  71          $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
  72          $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
  73  
  74          // Simulate the view call.
  75          $sink = $this->redirectEvents();
  76          glossary_view($g1, $c1, $cm1, $ctx1, 'letter');
  77          $events = $sink->get_events();
  78  
  79          // Assertions.
  80          $this->assertCount(3, $events);
  81          $this->assertEquals('\core\event\course_module_completion_updated', $events[0]->eventname);
  82          $this->assertEquals('\core\event\course_module_completion_updated', $events[1]->eventname);
  83          $this->assertEquals('\mod_glossary\event\course_module_viewed', $events[2]->eventname);
  84          $this->assertEquals($g1->id, $events[2]->objectid);
  85          $this->assertEquals('letter', $events[2]->other['mode']);
  86          $this->assertEquals(COMPLETION_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
  87          $this->assertEquals(COMPLETION_COMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
  88          $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
  89          $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
  90  
  91          // Tear down.
  92          $sink->close();
  93          $CFG->enablecompletion = $origcompletion;
  94      }
  95  
  96      public function test_glossary_entry_view() {
  97          $this->resetAfterTest(true);
  98  
  99          // Generate all the things.
 100          $gg = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
 101          $c1 = $this->getDataGenerator()->create_course();
 102          $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id));
 103          $e1 = $gg->create_content($g1);
 104          $u1 = $this->getDataGenerator()->create_user();
 105          $ctx = context_module::instance($g1->cmid);
 106          $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
 107  
 108          // Assertions.
 109          $sink = $this->redirectEvents();
 110          glossary_entry_view($e1, $ctx);
 111          $events = $sink->get_events();
 112          $this->assertCount(1, $events);
 113          $this->assertEquals('\mod_glossary\event\entry_viewed', $events[0]->eventname);
 114          $this->assertEquals($e1->id, $events[0]->objectid);
 115          $sink->close();
 116      }
 117  
 118      public function test_glossary_core_calendar_provide_event_action() {
 119          $this->resetAfterTest();
 120          $this->setAdminUser();
 121  
 122          // Create the activity.
 123          $course = $this->getDataGenerator()->create_course();
 124          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
 125  
 126          // Create a calendar event.
 127          $event = $this->create_action_event($course->id, $glossary->id,
 128              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 129  
 130          // Create an action factory.
 131          $factory = new \core_calendar\action_factory();
 132  
 133          // Decorate action event.
 134          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory);
 135  
 136          // Confirm the event was decorated.
 137          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
 138          $this->assertEquals(get_string('view'), $actionevent->get_name());
 139          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
 140          $this->assertEquals(1, $actionevent->get_item_count());
 141          $this->assertTrue($actionevent->is_actionable());
 142      }
 143  
 144      public function test_glossary_core_calendar_provide_event_action_as_non_user() {
 145          global $CFG;
 146  
 147          $this->resetAfterTest();
 148          $this->setAdminUser();
 149  
 150          // Create the activity.
 151          $course = $this->getDataGenerator()->create_course();
 152          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
 153  
 154          // Create a calendar event.
 155          $event = $this->create_action_event($course->id, $glossary->id,
 156                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 157  
 158          // Now log out.
 159          $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
 160          $this->setUser();
 161  
 162          // Create an action factory.
 163          $factory = new \core_calendar\action_factory();
 164  
 165          // Decorate action event for the student.
 166          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory);
 167  
 168          // Confirm the event is not shown at all.
 169          $this->assertNull($actionevent);
 170      }
 171  
 172      public function test_glossary_core_calendar_provide_event_action_for_user() {
 173          global $CFG;
 174  
 175          $this->resetAfterTest();
 176          $this->setAdminUser();
 177  
 178          // Create a course.
 179          $course = $this->getDataGenerator()->create_course();
 180  
 181          // Create a student.
 182          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 183  
 184          // Create the activity.
 185          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
 186  
 187          // Create a calendar event.
 188          $event = $this->create_action_event($course->id, $glossary->id,
 189                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 190  
 191          // Now log out.
 192          $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
 193          $this->setUser();
 194  
 195          // Create an action factory.
 196          $factory = new \core_calendar\action_factory();
 197  
 198          // Decorate action event for the student.
 199          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory, $student->id);
 200  
 201          // Confirm the event was decorated.
 202          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
 203          $this->assertEquals(get_string('view'), $actionevent->get_name());
 204          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
 205          $this->assertEquals(1, $actionevent->get_item_count());
 206          $this->assertTrue($actionevent->is_actionable());
 207      }
 208  
 209      public function test_glossary_core_calendar_provide_event_action_in_hidden_section() {
 210          $this->resetAfterTest();
 211          $this->setAdminUser();
 212  
 213          // Create a course.
 214          $course = $this->getDataGenerator()->create_course();
 215  
 216          // Create a student.
 217          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 218  
 219          // Create the activity.
 220          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
 221  
 222          // Create a calendar event.
 223          $event = $this->create_action_event($course->id, $glossary->id,
 224                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 225  
 226          // Set sections 0 as hidden.
 227          set_section_visible($course->id, 0, 0);
 228  
 229          // Create an action factory.
 230          $factory = new \core_calendar\action_factory();
 231  
 232          // Decorate action event for the student.
 233          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory, $student->id);
 234  
 235          // Confirm the event is not shown at all.
 236          $this->assertNull($actionevent);
 237      }
 238  
 239      public function test_glossary_core_calendar_provide_event_action_already_completed() {
 240          global $CFG;
 241  
 242          $this->resetAfterTest();
 243          $this->setAdminUser();
 244  
 245          $CFG->enablecompletion = 1;
 246  
 247          // Create the activity.
 248          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 249          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id),
 250              array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 251  
 252          // Get some additional data.
 253          $cm = get_coursemodule_from_instance('glossary', $glossary->id);
 254  
 255          // Create a calendar event.
 256          $event = $this->create_action_event($course->id, $glossary->id,
 257              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 258  
 259          // Mark the activity as completed.
 260          $completion = new completion_info($course);
 261          $completion->set_module_viewed($cm);
 262  
 263          // Create an action factory.
 264          $factory = new \core_calendar\action_factory();
 265  
 266          // Decorate action event.
 267          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory);
 268  
 269          // Ensure result was null.
 270          $this->assertNull($actionevent);
 271      }
 272  
 273      public function test_glossary_core_calendar_provide_event_action_already_completed_for_user() {
 274          global $CFG;
 275  
 276          $this->resetAfterTest();
 277          $this->setAdminUser();
 278  
 279          $CFG->enablecompletion = 1;
 280  
 281          // Create a course.
 282          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 283  
 284          // Create a student.
 285          $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
 286  
 287          // Create the activity.
 288          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id),
 289                  array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 290  
 291          // Get some additional data.
 292          $cm = get_coursemodule_from_instance('glossary', $glossary->id);
 293  
 294          // Create a calendar event.
 295          $event = $this->create_action_event($course->id, $glossary->id,
 296                  \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 297  
 298          // Mark the activity as completed for the user.
 299          $completion = new completion_info($course);
 300          $completion->set_module_viewed($cm, $student->id);
 301  
 302          // Create an action factory.
 303          $factory = new \core_calendar\action_factory();
 304  
 305          // Decorate action event.
 306          $actionevent = mod_glossary_core_calendar_provide_event_action($event, $factory, $student->id);
 307  
 308          // Ensure result was null.
 309          $this->assertNull($actionevent);
 310      }
 311  
 312      /**
 313       * Creates an action event.
 314       *
 315       * @param int $courseid The course id.
 316       * @param int $instanceid The instance id.
 317       * @param string $eventtype The event type.
 318       * @return bool|calendar_event
 319       */
 320      private function create_action_event($courseid, $instanceid, $eventtype) {
 321          $event = new stdClass();
 322          $event->name = 'Calendar event';
 323          $event->modulename  = 'glossary';
 324          $event->courseid = $courseid;
 325          $event->instance = $instanceid;
 326          $event->type = CALENDAR_EVENT_TYPE_ACTION;
 327          $event->eventtype = $eventtype;
 328          $event->timestart = time();
 329  
 330          return calendar_event::create($event);
 331      }
 332  
 333      /**
 334       * Test the callback responsible for returning the completion rule descriptions.
 335       * This function should work given either an instance of the module (cm_info), such as when checking the active rules,
 336       * or if passed a stdClass of similar structure, such as when checking the the default completion settings for a mod type.
 337       */
 338      public function test_mod_glossary_completion_get_active_rule_descriptions() {
 339          $this->resetAfterTest();
 340          $this->setAdminUser();
 341  
 342          // Two activities, both with automatic completion. One has the 'completionsubmit' rule, one doesn't.
 343          $course = $this->getDataGenerator()->create_course(['enablecompletion' => 2]);
 344          $glossary1 = $this->getDataGenerator()->create_module('glossary', [
 345              'course' => $course->id,
 346              'completion' => 2,
 347              'completionentries' => 3
 348          ]);
 349          $glossary2 = $this->getDataGenerator()->create_module('glossary', [
 350              'course' => $course->id,
 351              'completion' => 2,
 352              'completionentries' => 0
 353          ]);
 354          $cm1 = cm_info::create(get_coursemodule_from_instance('glossary', $glossary1->id));
 355          $cm2 = cm_info::create(get_coursemodule_from_instance('glossary', $glossary2->id));
 356  
 357          // Data for the stdClass input type.
 358          // This type of input would occur when checking the default completion rules for an activity type, where we don't have
 359          // any access to cm_info, rather the input is a stdClass containing completion and customdata attributes, just like cm_info.
 360          $moddefaults = new stdClass();
 361          $moddefaults->customdata = ['customcompletionrules' => ['completionentries' => 3]];
 362          $moddefaults->completion = 2;
 363  
 364          $activeruledescriptions = [get_string('completionentriesdesc', 'glossary', $glossary1->completionentries)];
 365          $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($cm1), $activeruledescriptions);
 366          $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($cm2), []);
 367          $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions($moddefaults), $activeruledescriptions);
 368          $this->assertEquals(mod_glossary_get_completion_active_rule_descriptions(new stdClass()), []);
 369      }
 370  
 371      public function test_mod_glossary_get_tagged_entries() {
 372          global $DB;
 373  
 374          $this->resetAfterTest();
 375          $this->setAdminUser();
 376  
 377          // Setup test data.
 378          $glossarygenerator = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
 379          $course3 = $this->getDataGenerator()->create_course();
 380          $course2 = $this->getDataGenerator()->create_course();
 381          $course1 = $this->getDataGenerator()->create_course();
 382  
 383          // Create and enrol a student.
 384          $student = self::getDataGenerator()->create_user();
 385          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 386          $this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id, 'manual');
 387          $this->getDataGenerator()->enrol_user($student->id, $course2->id, $studentrole->id, 'manual');
 388  
 389          // Create glossaries and entries.
 390          $glossary1 = $this->getDataGenerator()->create_module('glossary', array('course' => $course1->id));
 391          $glossary2 = $this->getDataGenerator()->create_module('glossary', array('course' => $course2->id));
 392          $glossary3 = $this->getDataGenerator()->create_module('glossary', array('course' => $course3->id));
 393          $entry11 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats', 'Dogs')));
 394          $entry12 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats', 'mice')));
 395          $entry13 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats')));
 396          $entry14 = $glossarygenerator->create_content($glossary1);
 397          $entry15 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats')));
 398          $entry16 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats'), 'approved' => false));
 399          $entry17 = $glossarygenerator->create_content($glossary1, array('tags' => array('Cats'), 'approved' => false, 'userid' => $student->id));
 400          $entry21 = $glossarygenerator->create_content($glossary2, array('tags' => array('Cats')));
 401          $entry22 = $glossarygenerator->create_content($glossary2, array('tags' => array('Cats', 'Dogs')));
 402          $entry23 = $glossarygenerator->create_content($glossary2, array('tags' => array('mice', 'Cats')));
 403          $entry31 = $glossarygenerator->create_content($glossary3, array('tags' => array('mice', 'Cats')));
 404  
 405          $tag = core_tag_tag::get_by_name(0, 'Cats');
 406  
 407          // Admin can see everything.
 408          // Get first page of tagged entries (first 5 entries).
 409          $res = mod_glossary_get_tagged_entries($tag, /*$exclusivemode = */false,
 410              /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$entry = */0);
 411          $this->assertRegExp('/'.$entry11->concept.'</', $res->content);
 412          $this->assertRegExp('/'.$entry12->concept.'</', $res->content);
 413          $this->assertRegExp('/'.$entry13->concept.'</', $res->content);
 414          $this->assertNotRegExp('/'.$entry14->concept.'</', $res->content);
 415          $this->assertRegExp('/'.$entry15->concept.'</', $res->content);
 416          $this->assertRegExp('/'.$entry16->concept.'</', $res->content);
 417          $this->assertNotRegExp('/'.$entry17->concept.'</', $res->content);
 418          $this->assertNotRegExp('/'.$entry21->concept.'</', $res->content);
 419          $this->assertNotRegExp('/'.$entry22->concept.'</', $res->content);
 420          $this->assertNotRegExp('/'.$entry23->concept.'</', $res->content);
 421          $this->assertNotRegExp('/'.$entry31->concept.'</', $res->content);
 422          $this->assertEmpty($res->prevpageurl);
 423          $this->assertNotEmpty($res->nextpageurl);
 424          // Get second page of tagged entries (second 5 entries).
 425          $res = mod_glossary_get_tagged_entries($tag, /*$exclusivemode = */false,
 426              /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$entry = */1);
 427          $this->assertNotRegExp('/'.$entry11->concept.'</', $res->content);
 428          $this->assertNotRegExp('/'.$entry12->concept.'</', $res->content);
 429          $this->assertNotRegExp('/'.$entry13->concept.'</', $res->content);
 430          $this->assertNotRegExp('/'.$entry14->concept.'</', $res->content);
 431          $this->assertNotRegExp('/'.$entry15->concept.'</', $res->content);
 432          $this->assertNotRegExp('/'.$entry16->concept.'</', $res->content);
 433          $this->assertRegExp('/'.$entry17->concept.'</', $res->content);
 434          $this->assertRegExp('/'.$entry21->concept.'</', $res->content);
 435          $this->assertRegExp('/'.$entry22->concept.'</', $res->content);
 436          $this->assertRegExp('/'.$entry23->concept.'</', $res->content);
 437          $this->assertRegExp('/'.$entry31->concept.'</', $res->content);
 438          $this->assertNotEmpty($res->prevpageurl);
 439          $this->assertEmpty($res->nextpageurl);
 440  
 441          $this->setUser($student);
 442          core_tag_index_builder::reset_caches();
 443  
 444          // User can not see entries in course 3 because he is not enrolled.
 445          $res = mod_glossary_get_tagged_entries($tag, /*$exclusivemode = */false,
 446              /*$fromctx = */0, /*$ctx = */0, /*$rec = */1, /*$entry = */1);
 447          $this->assertRegExp('/'.$entry22->concept.'/', $res->content);
 448          $this->assertRegExp('/'.$entry23->concept.'/', $res->content);
 449          $this->assertNotRegExp('/'.$entry31->concept.'/', $res->content);
 450  
 451          // User can search glossary entries inside a course.
 452          $coursecontext = context_course::instance($course1->id);
 453          $res = mod_glossary_get_tagged_entries($tag, /*$exclusivemode = */false,
 454              /*$fromctx = */0, /*$ctx = */$coursecontext->id, /*$rec = */1, /*$entry = */0);
 455          $this->assertRegExp('/'.$entry11->concept.'/', $res->content);
 456          $this->assertRegExp('/'.$entry12->concept.'/', $res->content);
 457          $this->assertRegExp('/'.$entry13->concept.'/', $res->content);
 458          $this->assertNotRegExp('/'.$entry14->concept.'/', $res->content);
 459          $this->assertRegExp('/'.$entry15->concept.'/', $res->content);
 460          $this->assertNotRegExp('/'.$entry21->concept.'/', $res->content);
 461          $this->assertNotRegExp('/'.$entry22->concept.'/', $res->content);
 462          $this->assertNotRegExp('/'.$entry23->concept.'/', $res->content);
 463          $this->assertEmpty($res->nextpageurl);
 464  
 465          // User cannot see unapproved entries unless he is an author.
 466          $this->assertNotRegExp('/'.$entry16->concept.'/', $res->content);
 467          $this->assertRegExp('/'.$entry17->concept.'/', $res->content);
 468      }
 469  
 470      public function test_glossary_get_entries_search() {
 471          $this->resetAfterTest();
 472          $this->setAdminUser();
 473          // Turn on glossary autolinking (usedynalink).
 474          set_config('glossary_linkentries', 1);
 475          $glossarygenerator = $this->getDataGenerator()->get_plugin_generator('mod_glossary');
 476          $course = $this->getDataGenerator()->create_course();
 477          $glossary = $this->getDataGenerator()->create_module('glossary', array('course' => $course->id));
 478          // Note this entry is not case sensitive by default (casesensitive = 0).
 479          $entry = $glossarygenerator->create_content($glossary);
 480          // Check that a search for the concept return the entry.
 481          $concept = $entry->concept;
 482          $search = glossary_get_entries_search($concept, $course->id);
 483          $this->assertCount(1, $search);
 484          $foundentry = array_shift($search);
 485          $this->assertEquals($foundentry->concept, $entry->concept);
 486          // Now try the same search but with a lowercase term.
 487          $concept = strtolower($entry->concept);
 488          $search = glossary_get_entries_search($concept, $course->id);
 489          $this->assertCount(1, $search);
 490          $foundentry = array_shift($search);
 491          $this->assertEquals($foundentry->concept, $entry->concept);
 492  
 493          // Make an entry that is case sensitive (casesensitive = 1).
 494          set_config('glossary_casesensitive', 1);
 495          $entry = $glossarygenerator->create_content($glossary);
 496          $concept = $entry->concept;
 497          $search = glossary_get_entries_search($concept, $course->id);
 498          $this->assertCount(1, $search);
 499          $foundentry = array_shift($search);
 500          $this->assertEquals($foundentry->concept, $entry->concept);
 501          // Now try the same search but with a lowercase term.
 502          $concept = strtolower($entry->concept);
 503          $search = glossary_get_entries_search($concept, $course->id);
 504          $this->assertCount(0, $search);
 505      }
 506  }