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 * Unit tests for core\notification.
19 *
20 * @package   core
21 * @category  phpunit
22 * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk>
23 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28/**
29 * Unit tests for core\notification.
30 *
31 * @package   core
32 * @category  phpunit
33 * @category  phpunit
34 * @copyright 2016 Andrew Nicols <andrew@nicols.co.uk>
35 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class core_notification_testcase extends advanced_testcase {
38
39    /**
40     * Setup required for all notification tests.
41     *
42     * This includes emptying the list of notifications on the session, resetting any session which exists, and setting
43     * up a new moodle_page object.
44     */
45    public function setUp(): void {
46        global $PAGE, $SESSION;
47
48        parent::setUp();
49        $PAGE = new moodle_page();
50        \core\session\manager::init_empty_session();
51        $SESSION->notifications = [];
52    }
53
54    /**
55     * Tear down required for all notification tests.
56     *
57     * This includes emptying the list of notifications on the session, resetting any session which exists, and setting
58     * up a new moodle_page object.
59     */
60    public function tearDown(): void {
61        global $PAGE, $SESSION;
62
63        $PAGE = null;
64        \core\session\manager::init_empty_session();
65        $SESSION->notifications = [];
66        parent::tearDown();
67    }
68
69    /**
70     * Test the way in which notifications are added to the session in different stages of the page load.
71     */
72    public function test_add_during_output_stages() {
73        global $PAGE, $SESSION;
74
75        \core\notification::add('Example before header', \core\notification::INFO);
76        $this->assertCount(1, $SESSION->notifications);
77
78        $PAGE->set_state(\moodle_page::STATE_PRINTING_HEADER);
79        \core\notification::add('Example during header', \core\notification::INFO);
80        $this->assertCount(2, $SESSION->notifications);
81
82        $PAGE->set_state(\moodle_page::STATE_IN_BODY);
83        \core\notification::add('Example in body', \core\notification::INFO);
84        $this->expectOutputRegex('/Example in body/');
85        $this->assertCount(2, $SESSION->notifications);
86
87        $PAGE->set_state(\moodle_page::STATE_DONE);
88        \core\notification::add('Example after page', \core\notification::INFO);
89        $this->assertCount(2, $SESSION->notifications);
90        $this->expectOutputRegex('/Example after page/');
91
92        \core\session\manager::write_close();
93        \core\notification::add('Example after write_close', \core\notification::INFO);
94        $this->assertCount(2, $SESSION->notifications);
95        $this->expectOutputRegex('/Example after write_close/');
96
97        // Simulate shutdown handler which calls fetch.
98        $this->assertCount(2, \core\notification::fetch());
99    }
100
101    /**
102     * Test fetching of notifications from the session.
103     */
104    public function test_fetch() {
105        // Initially there won't be any notifications.
106        $this->assertCount(0, \core\notification::fetch());
107
108        // Adding a notification should make one available to fetch.
109        \core\notification::success('Notification created');
110        $this->assertCount(1, \core\notification::fetch());
111        $this->assertCount(0, \core\notification::fetch());
112    }
113
114    /**
115     * Test that session notifications are persisted across session clears.
116     */
117    public function test_session_persistance() {
118        global $PAGE, $SESSION;
119
120        // Initially there won't be any notifications.
121        $this->assertCount(0, $SESSION->notifications);
122
123        // Adding a notification should make one available to fetch.
124        \core\notification::success('Notification created');
125        $this->assertCount(1, $SESSION->notifications);
126
127        // Re-creating the session will not empty the notification bag.
128        \core\session\manager::init_empty_session();
129        $this->assertCount(1, $SESSION->notifications);
130    }
131}
132