Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * The module forums external functions unit tests
  20   *
  21   * @package    mod_forum
  22   * @category   external
  23   * @copyright  2013 Andrew Nicols
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  require_once (__DIR__ . '/cron_trait.php');
  30  require_once (__DIR__ . '/generator_trait.php');
  31  
  32  class mod_forum_maildigest_testcase extends advanced_testcase {
  33  
  34      // Make use of the cron tester trait.
  35      use mod_forum_tests_cron_trait;
  36  
  37      // Make use of the test generator trait.
  38      use mod_forum_tests_generator_trait;
  39  
  40      /**
  41       * Set up message and mail sinks, and set up other requirements for the
  42       * cron to be tested here.
  43       */
  44      public function setUp(): void {
  45          global $CFG;
  46  
  47          // Messaging is not compatible with transactions...
  48          $this->preventResetByRollback();
  49  
  50          // Catch all messages
  51          $this->messagesink = $this->redirectMessages();
  52          $this->mailsink = $this->redirectEmails();
  53  
  54          // Confirm that we have an empty message sink so far.
  55          $messages = $this->messagesink->get_messages();
  56          $this->assertEquals(0, count($messages));
  57  
  58          $messages = $this->mailsink->get_messages();
  59          $this->assertEquals(0, count($messages));
  60  
  61          // Tell Moodle that we've not sent any digest messages out recently.
  62          $CFG->digestmailtimelast = 0;
  63  
  64          // And set the digest sending time to a negative number - this has
  65          // the effect of making it 11pm the previous day.
  66          $CFG->digestmailtime = -1;
  67  
  68          // Forcibly reduce the maxeditingtime to a one second to ensure that
  69          // messages are sent out.
  70          $CFG->maxeditingtime = 1;
  71  
  72          // We must clear the subscription caches. This has to be done both before each test, and after in case of other
  73          // tests using these functions.
  74          \mod_forum\subscriptions::reset_forum_cache();
  75          \mod_forum\subscriptions::reset_discussion_cache();
  76      }
  77  
  78      /**
  79       * Clear the message sinks set up in this test.
  80       */
  81      public function tearDown(): void {
  82          $this->messagesink->clear();
  83          $this->messagesink->close();
  84  
  85          $this->mailsink->clear();
  86          $this->mailsink->close();
  87      }
  88  
  89      /**
  90       * Setup a user, course, and forums.
  91       *
  92       * @return stdClass containing the list of forums, courses, forumids,
  93       * and the user enrolled in them.
  94       */
  95      protected function helper_setup_user_in_course() {
  96          global $DB;
  97  
  98          $return = new stdClass();
  99          $return->courses = new stdClass();
 100          $return->forums = new stdClass();
 101          $return->forumids = array();
 102  
 103          // Create a user.
 104          $user = $this->getDataGenerator()->create_user();
 105          $return->user = $user;
 106  
 107          // Create courses to add the modules.
 108          $return->courses->course1 = $this->getDataGenerator()->create_course();
 109  
 110          // Create forums.
 111          $record = new stdClass();
 112          $record->course = $return->courses->course1->id;
 113          $record->forcesubscribe = 1;
 114  
 115          $return->forums->forum1 = $this->getDataGenerator()->create_module('forum', $record);
 116          $return->forumsids[] = $return->forums->forum1->id;
 117  
 118          $return->forums->forum2 = $this->getDataGenerator()->create_module('forum', $record);
 119          $return->forumsids[] = $return->forums->forum2->id;
 120  
 121          // Check the forum was correctly created.
 122          list ($test, $params) = $DB->get_in_or_equal($return->forumsids);
 123  
 124          // Enrol the user in the courses.
 125          // DataGenerator->enrol_user automatically sets a role for the user
 126          $this->getDataGenerator()->enrol_user($return->user->id, $return->courses->course1->id);
 127  
 128          return $return;
 129      }
 130  
 131      public function test_set_maildigest() {
 132          global $DB;
 133  
 134          $this->resetAfterTest(true);
 135  
 136          $helper = $this->helper_setup_user_in_course();
 137          $user = $helper->user;
 138          $course1 = $helper->courses->course1;
 139          $forum1 = $helper->forums->forum1;
 140  
 141          // Set to the user.
 142          self::setUser($helper->user);
 143  
 144          // Confirm that there is no current value.
 145          $currentsetting = $DB->get_record('forum_digests', array(
 146              'forum' => $forum1->id,
 147              'userid' => $user->id,
 148          ));
 149          $this->assertFalse($currentsetting);
 150  
 151          // Test with each of the valid values:
 152          // 0, 1, and 2 are valid values.
 153          forum_set_user_maildigest($forum1, 0, $user);
 154          $currentsetting = $DB->get_record('forum_digests', array(
 155              'forum' => $forum1->id,
 156              'userid' => $user->id,
 157          ));
 158          $this->assertEquals($currentsetting->maildigest, 0);
 159  
 160          forum_set_user_maildigest($forum1, 1, $user);
 161          $currentsetting = $DB->get_record('forum_digests', array(
 162              'forum' => $forum1->id,
 163              'userid' => $user->id,
 164          ));
 165          $this->assertEquals($currentsetting->maildigest, 1);
 166  
 167          forum_set_user_maildigest($forum1, 2, $user);
 168          $currentsetting = $DB->get_record('forum_digests', array(
 169              'forum' => $forum1->id,
 170              'userid' => $user->id,
 171          ));
 172          $this->assertEquals($currentsetting->maildigest, 2);
 173  
 174          // And the default value - this should delete the record again
 175          forum_set_user_maildigest($forum1, -1, $user);
 176          $currentsetting = $DB->get_record('forum_digests', array(
 177              'forum' => $forum1->id,
 178              'userid' => $user->id,
 179          ));
 180          $this->assertFalse($currentsetting);
 181  
 182          // Try with an invalid value.
 183          $this->expectException('moodle_exception');
 184          forum_set_user_maildigest($forum1, 42, $user);
 185      }
 186  
 187      public function test_get_user_digest_options_default() {
 188          global $USER, $DB;
 189  
 190          $this->resetAfterTest(true);
 191  
 192          // Set up a basic user enrolled in a course.
 193          $helper = $this->helper_setup_user_in_course();
 194          $user = $helper->user;
 195          $course1 = $helper->courses->course1;
 196          $forum1 = $helper->forums->forum1;
 197  
 198          // Set to the user.
 199          self::setUser($helper->user);
 200  
 201          // We test against these options.
 202          $digestoptions = array(
 203              '0' => get_string('emaildigestoffshort', 'mod_forum'),
 204              '1' => get_string('emaildigestcompleteshort', 'mod_forum'),
 205              '2' => get_string('emaildigestsubjectsshort', 'mod_forum'),
 206          );
 207  
 208          // The default settings is 0.
 209          $this->assertEquals(0, $user->maildigest);
 210          $options = forum_get_user_digest_options();
 211          $this->assertEquals($options[-1], get_string('emaildigestdefault', 'mod_forum', $digestoptions[0]));
 212  
 213          // Update the setting to 1.
 214          $USER->maildigest = 1;
 215          $this->assertEquals(1, $USER->maildigest);
 216          $options = forum_get_user_digest_options();
 217          $this->assertEquals($options[-1], get_string('emaildigestdefault', 'mod_forum', $digestoptions[1]));
 218  
 219          // Update the setting to 2.
 220          $USER->maildigest = 2;
 221          $this->assertEquals(2, $USER->maildigest);
 222          $options = forum_get_user_digest_options();
 223          $this->assertEquals($options[-1], get_string('emaildigestdefault', 'mod_forum', $digestoptions[2]));
 224      }
 225  
 226      public function test_get_user_digest_options_sorting() {
 227          global $USER, $DB;
 228  
 229          $this->resetAfterTest(true);
 230  
 231          // Set up a basic user enrolled in a course.
 232          $helper = $this->helper_setup_user_in_course();
 233          $user = $helper->user;
 234          $course1 = $helper->courses->course1;
 235          $forum1 = $helper->forums->forum1;
 236  
 237          // Set to the user.
 238          self::setUser($helper->user);
 239  
 240          // Retrieve the list of applicable options.
 241          $options = forum_get_user_digest_options();
 242  
 243          // The default option must always be at the top of the list.
 244          $lastoption = -2;
 245          foreach ($options as $value => $description) {
 246              $this->assertGreaterThan($lastoption, $value);
 247              $lastoption = $value;
 248          }
 249      }
 250  
 251      public function test_cron_no_posts() {
 252          global $DB;
 253  
 254          $this->resetAfterTest(true);
 255  
 256          // Initially the forum cron should generate no messages as we've made no posts.
 257          $expect = [];
 258          $this->queue_tasks_and_assert($expect);
 259      }
 260  
 261      /**
 262       * Sends several notifications to one user as:
 263       * * single messages based on a user profile setting.
 264       */
 265      public function test_cron_profile_single_mails() {
 266          global $DB;
 267  
 268          $this->resetAfterTest(true);
 269  
 270          // Set up a basic user enrolled in a course.
 271          $userhelper = $this->helper_setup_user_in_course();
 272          $user = $userhelper->user;
 273          $course1 = $userhelper->courses->course1;
 274          $forum1 = $userhelper->forums->forum1;
 275          $forum2 = $userhelper->forums->forum2;
 276  
 277          // Add 5 discussions to forum 1.
 278          $posts = [];
 279          for ($i = 0; $i < 5; $i++) {
 280              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 281              $posts[] = $post;
 282          }
 283  
 284          // Add 5 discussions to forum 2.
 285          for ($i = 0; $i < 5; $i++) {
 286              list($discussion, $post) = $this->helper_post_to_forum($forum2, $user, ['mailnow' => 1]);
 287              $posts[] = $post;
 288          }
 289  
 290          // Set the tested user's default maildigest setting.
 291          $DB->set_field('user', 'maildigest', 0, array('id' => $user->id));
 292  
 293          // Set the maildigest preference for forum1 to default.
 294          forum_set_user_maildigest($forum1, -1, $user);
 295  
 296          // Set the maildigest preference for forum2 to default.
 297          forum_set_user_maildigest($forum2, -1, $user);
 298  
 299          // No digests mails should be sent, but 10 forum mails will be sent.
 300          $expect = [
 301              (object) [
 302                  'userid' => $user->id,
 303                  'messages' => 10,
 304                  'digests' => 0,
 305              ],
 306          ];
 307          $this->queue_tasks_and_assert($expect);
 308  
 309          $this->send_notifications_and_assert($user, $posts);
 310      }
 311  
 312      /**
 313       * Sends several notifications to one user as:
 314       * * daily digests coming from the user profile setting.
 315       */
 316      public function test_cron_profile_digest_email() {
 317          global $DB, $CFG;
 318  
 319          $this->resetAfterTest(true);
 320  
 321          // Set up a basic user enrolled in a course.
 322          $userhelper = $this->helper_setup_user_in_course();
 323          $user = $userhelper->user;
 324          $course1 = $userhelper->courses->course1;
 325          $forum1 = $userhelper->forums->forum1;
 326          $forum2 = $userhelper->forums->forum2;
 327          $posts = [];
 328  
 329          // Add 5 discussions to forum 1.
 330          for ($i = 0; $i < 5; $i++) {
 331              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 332              $posts[] = $post;
 333          }
 334  
 335          // Add 5 discussions to forum 2.
 336          for ($i = 0; $i < 5; $i++) {
 337              list($discussion, $post) = $this->helper_post_to_forum($forum2, $user, ['mailnow' => 1]);
 338              $posts[] = $post;
 339          }
 340  
 341          // Set the tested user's default maildigest setting.
 342          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 343  
 344          // Set the maildigest preference for forum1 to default.
 345          forum_set_user_maildigest($forum1, -1, $user);
 346  
 347          // Set the maildigest preference for forum2 to default.
 348          forum_set_user_maildigest($forum2, -1, $user);
 349  
 350          // No digests mails should be sent, but 10 forum mails will be sent.
 351          $expect = [
 352              (object) [
 353                  'userid' => $user->id,
 354                  'messages' => 0,
 355                  'digests' => 1,
 356              ],
 357          ];
 358          $this->queue_tasks_and_assert($expect);
 359  
 360          $this->send_digests_and_assert($user, $posts);
 361      }
 362  
 363      /**
 364       * Send digests to a user who cannot view fullnames
 365       */
 366      public function test_cron_digest_view_fullnames_off() {
 367          global $DB, $CFG;
 368  
 369          $CFG->fullnamedisplay = 'lastname';
 370          $this->resetAfterTest(true);
 371  
 372          // Set up a basic user enrolled in a course.
 373          $userhelper = $this->helper_setup_user_in_course();
 374          $user = $userhelper->user;
 375          $course1 = $userhelper->courses->course1;
 376          $forum1 = $userhelper->forums->forum1;
 377          $posts = [];
 378  
 379          // Add 1 discussions to forum 1.
 380          list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 381          $posts[] = $post;
 382  
 383          // Set the tested user's default maildigest setting.
 384          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 385  
 386          // No digests mails should be sent, but 1 forum mails will be sent.
 387          $expect = [
 388              (object) [
 389                  'userid' => $user->id,
 390                  'messages' => 0,
 391                  'digests' => 1,
 392              ],
 393          ];
 394          $this->queue_tasks_and_assert($expect);
 395          $this->send_digests_and_assert($user, $posts);
 396  
 397          // The user does not, by default, have permission to view the fullname.
 398          $messagecontent = $this->messagesink->get_messages()[0]->fullmessage;
 399  
 400          // Assert that the expected name is present (lastname only).
 401          $this->assertStringContainsString(fullname($user, false), $messagecontent);
 402  
 403          // Assert that the full name is not present (firstname lastname only).
 404          $this->assertStringNotContainsString(fullname($user, true), $messagecontent);
 405      }
 406  
 407      /**
 408       * Send digests to a user who can view fullnames.
 409       */
 410      public function test_cron_digest_view_fullnames_on() {
 411          global $DB, $CFG;
 412  
 413          $CFG->fullnamedisplay = 'lastname';
 414          $this->resetAfterTest(true);
 415  
 416          // Set up a basic user enrolled in a course.
 417          $userhelper = $this->helper_setup_user_in_course();
 418          $user = $userhelper->user;
 419          $course1 = $userhelper->courses->course1;
 420          $forum1 = $userhelper->forums->forum1;
 421          $posts = [];
 422          assign_capability(
 423              'moodle/site:viewfullnames',
 424              CAP_ALLOW,
 425              $DB->get_field('role', 'id', ['shortname' => 'student']),
 426              \context_course::instance($course1->id)
 427          );
 428  
 429          // Add 1 discussions to forum 1.
 430          list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 431          $posts[] = $post;
 432  
 433          // Set the tested user's default maildigest setting.
 434          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 435  
 436          // No digests mails should be sent, but 1 forum mails will be sent.
 437          $expect = [
 438              (object) [
 439                  'userid' => $user->id,
 440                  'messages' => 0,
 441                  'digests' => 1,
 442              ],
 443          ];
 444          $this->queue_tasks_and_assert($expect);
 445          $this->send_digests_and_assert($user, $posts);
 446  
 447          // The user does not, by default, have permission to view the fullname.
 448          // However we have given the user that capability so we expect to see both firstname and lastname.
 449          $messagecontent = $this->messagesink->get_messages()[0]->fullmessage;
 450  
 451          // Assert that the expected name is present (lastname only).
 452          $this->assertStringContainsString(fullname($user, false), $messagecontent);
 453  
 454          // Assert that the full name is also present (firstname lastname only).
 455          $this->assertStringContainsString(fullname($user, true), $messagecontent);
 456      }
 457  
 458      /**
 459       * Sends several notifications to one user as:
 460       * * daily digests coming from the per-forum setting; and
 461       * * single e-mails from the profile setting.
 462       */
 463      public function test_cron_mixed_email_1() {
 464          global $DB, $CFG;
 465  
 466          $this->resetAfterTest(true);
 467  
 468          // Set up a basic user enrolled in a course.
 469          $userhelper = $this->helper_setup_user_in_course();
 470          $user = $userhelper->user;
 471          $course1 = $userhelper->courses->course1;
 472          $forum1 = $userhelper->forums->forum1;
 473          $forum2 = $userhelper->forums->forum2;
 474          $posts = [];
 475          $digests = [];
 476  
 477          // Add 5 discussions to forum 1.
 478          for ($i = 0; $i < 5; $i++) {
 479              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 480              $digests[] = $post;
 481          }
 482  
 483          // Add 5 discussions to forum 2.
 484          for ($i = 0; $i < 5; $i++) {
 485              list($discussion, $post) = $this->helper_post_to_forum($forum2, $user, ['mailnow' => 1]);
 486              $posts[] = $post;
 487          }
 488  
 489          // Set the tested user's default maildigest setting.
 490          $DB->set_field('user', 'maildigest', 0, array('id' => $user->id));
 491  
 492          // Set the maildigest preference for forum1 to digest.
 493          forum_set_user_maildigest($forum1, 1, $user);
 494  
 495          // Set the maildigest preference for forum2 to default (single).
 496          forum_set_user_maildigest($forum2, -1, $user);
 497  
 498          // One digest e-mail should be sent, and five individual notifications.
 499          $expect = [
 500              (object) [
 501                  'userid' => $user->id,
 502                  'messages' => 5,
 503                  'digests' => 1,
 504              ],
 505          ];
 506          $this->queue_tasks_and_assert($expect);
 507  
 508          $this->send_notifications_and_assert($user, $posts);
 509          $this->send_digests_and_assert($user, $digests);
 510      }
 511  
 512      /**
 513       * Sends several notifications to one user as:
 514       * * single e-mails from the per-forum setting; and
 515       * * daily digests coming from the per-user setting.
 516       */
 517      public function test_cron_mixed_email_2() {
 518          global $DB, $CFG;
 519  
 520          $this->resetAfterTest(true);
 521  
 522          // Set up a basic user enrolled in a course.
 523          $userhelper = $this->helper_setup_user_in_course();
 524          $user = $userhelper->user;
 525          $course1 = $userhelper->courses->course1;
 526          $forum1 = $userhelper->forums->forum1;
 527          $forum2 = $userhelper->forums->forum2;
 528          $posts = [];
 529          $digests = [];
 530  
 531          // Add 5 discussions to forum 1.
 532          for ($i = 0; $i < 5; $i++) {
 533              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 534              $digests[] = $post;
 535          }
 536  
 537          // Add 5 discussions to forum 2.
 538          for ($i = 0; $i < 5; $i++) {
 539              list($discussion, $post) = $this->helper_post_to_forum($forum2, $user, ['mailnow' => 1]);
 540              $posts[] = $post;
 541          }
 542  
 543          // Set the tested user's default maildigest setting.
 544          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 545  
 546          // Set the maildigest preference for forum1 to digest.
 547          forum_set_user_maildigest($forum1, -1, $user);
 548  
 549          // Set the maildigest preference for forum2 to single.
 550          forum_set_user_maildigest($forum2, 0, $user);
 551  
 552          // One digest e-mail should be sent, and five individual notifications.
 553          $expect = [
 554              (object) [
 555                  'userid' => $user->id,
 556                  'messages' => 5,
 557                  'digests' => 1,
 558              ],
 559          ];
 560          $this->queue_tasks_and_assert($expect);
 561  
 562          $this->send_notifications_and_assert($user, $posts);
 563          $this->send_digests_and_assert($user, $digests);
 564      }
 565  
 566      /**
 567       * Sends several notifications to one user as:
 568       * * daily digests coming from the per-forum setting.
 569       */
 570      public function test_cron_forum_digest_email() {
 571          global $DB, $CFG;
 572  
 573          $this->resetAfterTest(true);
 574  
 575          // Set up a basic user enrolled in a course.
 576          $userhelper = $this->helper_setup_user_in_course();
 577          $user = $userhelper->user;
 578          $course1 = $userhelper->courses->course1;
 579          $forum1 = $userhelper->forums->forum1;
 580          $forum2 = $userhelper->forums->forum2;
 581          $fulldigests = [];
 582          $shortdigests = [];
 583  
 584          // Add 5 discussions to forum 1.
 585          for ($i = 0; $i < 5; $i++) {
 586              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 587              $fulldigests[] = $post;
 588          }
 589  
 590          // Add 5 discussions to forum 2.
 591          for ($i = 0; $i < 5; $i++) {
 592              list($discussion, $post) = $this->helper_post_to_forum($forum2, $user, ['mailnow' => 1]);
 593              $shortdigests[] = $post;
 594          }
 595  
 596          // Set the tested user's default maildigest setting.
 597          $DB->set_field('user', 'maildigest', 0, array('id' => $user->id));
 598  
 599          // Set the maildigest preference for forum1 to digest (complete).
 600          forum_set_user_maildigest($forum1, 1, $user);
 601  
 602          // Set the maildigest preference for forum2 to digest (short).
 603          forum_set_user_maildigest($forum2, 2, $user);
 604  
 605          // One digest e-mail should be sent, and no individual notifications.
 606          $expect = [
 607              (object) [
 608                  'userid' => $user->id,
 609                  'digests' => 1,
 610              ],
 611          ];
 612          $this->queue_tasks_and_assert($expect);
 613  
 614          $this->send_digests_and_assert($user, $fulldigests, $shortdigests);
 615      }
 616  
 617      /**
 618       * The digest being in the past is queued til the next day.
 619       */
 620      public function test_cron_digest_previous_day() {
 621          global $DB, $CFG;
 622  
 623          $this->resetAfterTest(true);
 624  
 625          // Set up a basic user enrolled in a course.
 626          $userhelper = $this->helper_setup_user_in_course();
 627          $user = $userhelper->user;
 628          $course1 = $userhelper->courses->course1;
 629          $forum1 = $userhelper->forums->forum1;
 630          $forum2 = $userhelper->forums->forum2;
 631          $fulldigests = [];
 632          $shortdigests = [];
 633  
 634          // Add 1 discussions to forum 1.
 635          list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 636          $fulldigests[] = $post;
 637  
 638          // Set the tested user's default maildigest setting.
 639          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 640  
 641          // Set the digest time to midnight.
 642          $CFG->digestmailtime = 0;
 643          // One digest e-mail should be sent, and no individual notifications.
 644          $expect = [
 645              (object) [
 646                  'userid' => $user->id,
 647                  'digests' => 1,
 648              ],
 649          ];
 650          $this->queue_tasks_and_assert($expect);
 651  
 652          $tasks = $DB->get_records('task_adhoc');
 653          $task = reset($tasks);
 654          $this->assertGreaterThanOrEqual(time(), $task->nextruntime);
 655      }
 656  
 657      /**
 658       * The digest being in the future is queued for today.
 659       */
 660      public function test_cron_digest_same_day() {
 661          global $DB, $CFG;
 662  
 663          $this->resetAfterTest(true);
 664  
 665          // Set up a basic user enrolled in a course.
 666          $userhelper = $this->helper_setup_user_in_course();
 667          $user = $userhelper->user;
 668          $course1 = $userhelper->courses->course1;
 669          $forum1 = $userhelper->forums->forum1;
 670          $forum2 = $userhelper->forums->forum2;
 671          $fulldigests = [];
 672          $shortdigests = [];
 673  
 674          // Add 1 discussions to forum 1.
 675          list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 676          $fulldigests[] = $post;
 677  
 678          // Set the tested user's default maildigest setting.
 679          $DB->set_field('user', 'maildigest', 1, array('id' => $user->id));
 680  
 681          // Set the digest time to the future (magic, shouldn't work).
 682          $CFG->digestmailtime = 25;
 683          // One digest e-mail should be sent, and no individual notifications.
 684          $expect = [
 685              (object) [
 686                  'userid' => $user->id,
 687                  'digests' => 1,
 688              ],
 689          ];
 690          $this->queue_tasks_and_assert($expect);
 691  
 692          $tasks = $DB->get_records('task_adhoc');
 693          $task = reset($tasks);
 694          $digesttime = usergetmidnight(time(), \core_date::get_server_timezone()) + ($CFG->digestmailtime * 3600);
 695          $this->assertLessThanOrEqual($digesttime, $task->nextruntime);
 696      }
 697  
 698      /**
 699       * Tests that if a new message is posted after the days digest time,
 700       * but before that days digests are sent a new task is created.
 701       */
 702      public function test_cron_digest_queue_next_before_current_processed() {
 703          global $DB, $CFG;
 704  
 705          $this->resetAfterTest(true);
 706  
 707          // Set up a basic user enrolled in a course.
 708          $userhelper = $this->helper_setup_user_in_course();
 709          $user = $userhelper->user;
 710          $forum1 = $userhelper->forums->forum1;
 711  
 712          // Add 1 discussions to forum 1.
 713          $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 714  
 715          // Set the tested user's default maildigest setting.
 716          $DB->set_field('user', 'maildigest', 1, ['id' => $user->id]);
 717  
 718          // Set the digest time to the future (magic, shouldn't work).
 719          $CFG->digestmailtime = 25;
 720          // One digest e-mail should be sent, and no individual notifications.
 721          $expect = [
 722              (object) [
 723                  'userid' => $user->id,
 724                  'digests' => 1,
 725              ],
 726          ];
 727          $this->queue_tasks_and_assert($expect);
 728  
 729          // Set the digest time to midnight.
 730          $CFG->digestmailtime = 0;
 731  
 732          // Add another discussions to forum 1.
 733          $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 734  
 735          // One digest e-mail should be sent, and no individual notifications.
 736          $expect = [
 737              (object) [
 738                  'userid' => $user->id,
 739                  'digests' => 1,
 740              ],
 741          ];
 742          $this->queue_tasks_and_assert($expect);
 743  
 744          // There should now be two tasks queued.
 745          $tasks = $DB->get_records('task_adhoc');
 746          $this->assertCount(2, $tasks);
 747  
 748          // Add yet another another discussions to forum 1.
 749          $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 750  
 751          // One digest e-mail should be sent, and no individual notifications.
 752          $expect = [
 753              (object) [
 754                  'userid' => $user->id,
 755                  'digests' => 1,
 756              ],
 757          ];
 758          $this->queue_tasks_and_assert($expect);
 759  
 760          // There should still be two tasks queued.
 761          $tasks = $DB->get_records('task_adhoc');
 762          $this->assertCount(2, $tasks);
 763      }
 764  
 765      /**
 766       * The sending of a digest marks posts as read if automatic message read marking is set.
 767       */
 768      public function test_cron_digest_marks_posts_read() {
 769          global $DB, $CFG;
 770  
 771          $this->resetAfterTest(true);
 772  
 773          // Disable the 'Manual message read marking' option.
 774          $CFG->forum_usermarksread = false;
 775  
 776          // Set up a basic user enrolled in a course.
 777          $userhelper = $this->helper_setup_user_in_course();
 778          $user = $userhelper->user;
 779          $course1 = $userhelper->courses->course1;
 780          $forum1 = $userhelper->forums->forum1;
 781          $posts = [];
 782  
 783          // Set the tested user's default maildigest, trackforums, read tracking settings.
 784          $DB->set_field('user', 'maildigest', 1, ['id' => $user->id]);
 785          $DB->set_field('user', 'trackforums', 1, ['id' => $user->id]);
 786          set_user_preference('forum_markasreadonnotification', 1, $user->id);
 787  
 788          // Set the maildigest preference for forum1 to default.
 789          forum_set_user_maildigest($forum1, -1, $user);
 790  
 791          // Add 5 discussions to forum 1.
 792          for ($i = 0; $i < 5; $i++) {
 793              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 794              $posts[] = $post;
 795          }
 796  
 797          // There should be unread posts for the forum.
 798          $expectedposts = [
 799              $forum1->id => (object) [
 800                  'id' => $forum1->id,
 801                  'unread' => count($posts),
 802              ],
 803          ];
 804          $this->assertEquals($expectedposts, forum_tp_get_course_unread_posts($user->id, $course1->id));
 805  
 806          // One digest mail should be sent and no other messages.
 807          $expect = [
 808              (object) [
 809                  'userid' => $user->id,
 810                  'messages' => 0,
 811                  'digests' => 1,
 812              ],
 813          ];
 814          $this->queue_tasks_and_assert($expect);
 815  
 816          $this->send_digests_and_assert($user, $posts);
 817  
 818          // Verify that there are no unread posts for any forums.
 819          $this->assertEmpty(forum_tp_get_course_unread_posts($user->id, $course1->id));
 820      }
 821  
 822      /**
 823       * The sending of a digest does not mark posts as read when manual message read marking is set.
 824       */
 825      public function test_cron_digest_leaves_posts_unread() {
 826          global $DB, $CFG;
 827  
 828          $this->resetAfterTest(true);
 829  
 830          // Enable the 'Manual message read marking' option.
 831          $CFG->forum_usermarksread = true;
 832  
 833          // Set up a basic user enrolled in a course.
 834          $userhelper = $this->helper_setup_user_in_course();
 835          $user = $userhelper->user;
 836          $course1 = $userhelper->courses->course1;
 837          $forum1 = $userhelper->forums->forum1;
 838          $posts = [];
 839  
 840          // Set the tested user's default maildigest, trackforums, read tracking settings.
 841          $DB->set_field('user', 'maildigest', 1, ['id' => $user->id]);
 842          $DB->set_field('user', 'trackforums', 1, ['id' => $user->id]);
 843          set_user_preference('forum_markasreadonnotification', 1, $user->id);
 844  
 845          // Set the maildigest preference for forum1 to default.
 846          forum_set_user_maildigest($forum1, -1, $user);
 847  
 848          // Add 5 discussions to forum 1.
 849          for ($i = 0; $i < 5; $i++) {
 850              list($discussion, $post) = $this->helper_post_to_forum($forum1, $user, ['mailnow' => 1]);
 851              $posts[] = $post;
 852          }
 853  
 854          // There should be unread posts for the forum.
 855          $expectedposts = [
 856              $forum1->id => (object) [
 857                  'id' => $forum1->id,
 858                  'unread' => count($posts),
 859              ],
 860          ];
 861          $this->assertEquals($expectedposts, forum_tp_get_course_unread_posts($user->id, $course1->id));
 862  
 863          // One digest mail should be sent and no other messages.
 864          $expect = [
 865              (object) [
 866                  'userid' => $user->id,
 867                  'messages' => 0,
 868                  'digests' => 1,
 869              ],
 870          ];
 871          $this->queue_tasks_and_assert($expect);
 872  
 873          $this->send_digests_and_assert($user, $posts);
 874  
 875          // Verify that there are still the same unread posts for the forum.
 876          $this->assertEquals($expectedposts, forum_tp_get_course_unread_posts($user->id, $course1->id));
 877      }
 878  }