| 1 | efrain | 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 | namespace core;
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | use PHPUnit\Framework\MockObject\Stub;
 | 
        
           |  |  | 20 | use Psr\Container\ContainerInterface;
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 | /**
 | 
        
           |  |  | 23 |  * Tests for Moodle's Container.
 | 
        
           |  |  | 24 |  *
 | 
        
           |  |  | 25 |  * @package   core
 | 
        
           |  |  | 26 |  * @copyright 2024 Andrew Nicols <andrew@nicols.co.uk>
 | 
        
           |  |  | 27 |  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 28 |  * @covers    \core\di
 | 
        
           |  |  | 29 |  */
 | 
        
           | 1441 | ariadna | 30 | final class di_test extends \advanced_testcase {
 | 
        
           | 1 | efrain | 31 |     /**
 | 
        
           |  |  | 32 |      * Test that the get_container method returns the Container Instance and stores it statically.
 | 
        
           |  |  | 33 |      */
 | 
        
           |  |  | 34 |     public function test_get_container(): void {
 | 
        
           |  |  | 35 |         $container = di::get_container();
 | 
        
           |  |  | 36 |         $this->assertInstanceOf(ContainerInterface::class, $container);
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 |         $this->assertTrue($container === di::get_container());
 | 
        
           |  |  | 39 |     }
 | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 |     /**
 | 
        
           |  |  | 42 |      * Test that the reset_container method resets the container such that a different instance is returned.
 | 
        
           |  |  | 43 |      */
 | 
        
           |  |  | 44 |     public function test_reset_container(): void {
 | 
        
           |  |  | 45 |         $instance = di::get_container();
 | 
        
           |  |  | 46 |         $this->assertInstanceOf(ContainerInterface::class, $instance);
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |         di::reset_container();
 | 
        
           |  |  | 49 |         $this->assertFalse($instance === di::get_container());
 | 
        
           |  |  | 50 |     }
 | 
        
           |  |  | 51 |   | 
        
           |  |  | 52 |     /**
 | 
        
           |  |  | 53 |      * This test just ensures that a container can return an autowired client.
 | 
        
           |  |  | 54 |      *
 | 
        
           |  |  | 55 |      * This is standard behaviour for a Container, but we want to actually check it.
 | 
        
           |  |  | 56 |      */
 | 
        
           |  |  | 57 |     public function test_autowired_client(): void {
 | 
        
           |  |  | 58 |         $container = di::get_container();
 | 
        
           |  |  | 59 |         $client = $container->get(http_client::class);
 | 
        
           |  |  | 60 |   | 
        
           |  |  | 61 |         $this->assertInstanceOf(http_client::class, $client);
 | 
        
           |  |  | 62 |   | 
        
           |  |  | 63 |         // Fetching the same again.
 | 
        
           |  |  | 64 |         $this->assertEquals(
 | 
        
           |  |  | 65 |             $client,
 | 
        
           |  |  | 66 |             $container->get(http_client::class),
 | 
        
           |  |  | 67 |         );
 | 
        
           |  |  | 68 |     }
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 |     /**
 | 
        
           |  |  | 71 |      * Test that we can mock a client and set it in the container for other consumers to get.
 | 
        
           |  |  | 72 |      */
 | 
        
           |  |  | 73 |     public function test_mocked_client(): void {
 | 
        
           |  |  | 74 |         $container = di::get_container();
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 |         // Create a mocked http_client.
 | 
        
           |  |  | 77 |         $mockedclient = $this->createStub(http_client::class);
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 |         // Set it in the container.
 | 
        
           |  |  | 80 |         di::set(http_client::class, $mockedclient);
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 |         // Fetching it out will give us the same mocked client.
 | 
        
           |  |  | 83 |         $client = $container->get(http_client::class);
 | 
        
           |  |  | 84 |         $this->assertEquals(
 | 
        
           |  |  | 85 |             $mockedclient,
 | 
        
           |  |  | 86 |             $client,
 | 
        
           |  |  | 87 |         );
 | 
        
           |  |  | 88 |   | 
        
           |  |  | 89 |         // And the returned client will of course still be an http_client and a Stub.
 | 
        
           |  |  | 90 |         $this->assertInstanceOf(http_client::class, $client);
 | 
        
           |  |  | 91 |         $this->assertInstanceOf(Stub::class, $client);
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |         // Even after getting a new container instance.
 | 
        
           |  |  | 94 |         $this->assertEquals(
 | 
        
           |  |  | 95 |             di::get_container()->get(http_client::class),
 | 
        
           |  |  | 96 |             $client,
 | 
        
           |  |  | 97 |         );
 | 
        
           |  |  | 98 |   | 
        
           |  |  | 99 |         // Resetting the container will give us a new, unmocked, instance.
 | 
        
           |  |  | 100 |         di::reset_container();
 | 
        
           |  |  | 101 |   | 
        
           |  |  | 102 |         $client = di::get_container()->get(http_client::class);
 | 
        
           |  |  | 103 |         $this->assertInstanceOf(http_client::class, $client);
 | 
        
           |  |  | 104 |         $this->assertNotInstanceOf(Stub::class, $client);
 | 
        
           |  |  | 105 |         $this->assertNotEquals(
 | 
        
           |  |  | 106 |             $mockedclient,
 | 
        
           |  |  | 107 |             $client,
 | 
        
           |  |  | 108 |         );
 | 
        
           |  |  | 109 |     }
 | 
        
           |  |  | 110 |   | 
        
           |  |  | 111 |     /**
 | 
        
           |  |  | 112 |      * Test that a mocked client can be set in one test, but is not preserved across tests.
 | 
        
           |  |  | 113 |      *
 | 
        
           |  |  | 114 |      * @return Stub The mocked client to pass to the dependant test
 | 
        
           |  |  | 115 |      */
 | 
        
           |  |  | 116 |     public function test_mocked_client_test_one(): Stub {
 | 
        
           |  |  | 117 |         di::set(http_client::class, $this->createStub(http_client::class));
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 |         $mockedclient = di::get_container()->get(http_client::class);
 | 
        
           |  |  | 120 |         $this->assertInstanceOf(http_client::class, $mockedclient);
 | 
        
           |  |  | 121 |         $this->assertInstanceOf(Stub::class, $mockedclient);
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |         return $mockedclient;
 | 
        
           |  |  | 124 |     }
 | 
        
           |  |  | 125 |   | 
        
           |  |  | 126 |     /**
 | 
        
           |  |  | 127 |      * Test that a client mocked in a previous test does not bleed.
 | 
        
           |  |  | 128 |      *
 | 
        
           |  |  | 129 |      * @depends test_mocked_client_test_one
 | 
        
           |  |  | 130 |      */
 | 
        
           |  |  | 131 |     public function test_mocked_client_test_two(Stub $mockedclient): void {
 | 
        
           |  |  | 132 |         $client = di::get_container()->get(http_client::class);
 | 
        
           |  |  | 133 |         $this->assertInstanceOf(http_client::class, $client);
 | 
        
           |  |  | 134 |         $this->assertNotInstanceOf(Stub::class, $client);
 | 
        
           |  |  | 135 |         $this->assertNotEquals($mockedclient, $client);
 | 
        
           |  |  | 136 |     }
 | 
        
           |  |  | 137 |   | 
        
           |  |  | 138 |     /**
 | 
        
           |  |  | 139 |      * Test that the container will return the $DB global as a moodle_database instance.
 | 
        
           |  |  | 140 |      */
 | 
        
           |  |  | 141 |     public function test_fetch_moodle_database(): void {
 | 
        
           |  |  | 142 |         global $DB;
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 |         $this->assertEquals($DB, di::get(\moodle_database::class));
 | 
        
           |  |  | 145 |     }
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 |     /**
 | 
        
           |  |  | 148 |      * Test that the hook manager is in the container.
 | 
        
           |  |  | 149 |      */
 | 
        
           |  |  | 150 |     public function test_fetch_hook_manager(): void {
 | 
        
           |  |  | 151 |         $manager = di::get(hook\manager::class);
 | 
        
           |  |  | 152 |         $this->assertEquals($manager, hook\manager::get_instance());
 | 
        
           |  |  | 153 |     }
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 |     public function test_fetch_string_manager(): void {
 | 
        
           |  |  | 156 |         $stringmanager = di::get(\core_string_manager::class);
 | 
        
           |  |  | 157 |         $this->assertEquals(
 | 
        
           |  |  | 158 |             get_string_manager(),
 | 
        
           |  |  | 159 |             $stringmanager,
 | 
        
           |  |  | 160 |         );
 | 
        
           |  |  | 161 |     }
 | 
        
           |  |  | 162 | }
 |