Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>.namespace communication_matrix;use communication_matrix\local\command;use communication_matrix\local\spec\v1p7;use communication_matrix\local\spec\features;use communication_matrix\tests\fixtures\mocked_matrix_client;use core\http_client;use GuzzleHttp\Handler\MockHandler;use GuzzleHttp\HandlerStack;use GuzzleHttp\Middleware;use GuzzleHttp\Psr7\Response;use moodle_exception;defined('MOODLE_INTERNAL') || die();require_once(__DIR__ . '/matrix_client_test_trait.php');/*** Tests for the matrix_client class.** @package communication_matrix* @category test* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later* @covers \communication_matrix\matrix_client* @coversDefaultClass \communication_matrix\matrix_client*/class matrix_client_test extends \advanced_testcase {use matrix_client_test_trait;/*** Data provider for valid calls to ::instance.* @return array*/public static function instance_provider(): array {$testcases = ['Standard versions' => [null,v1p7::class,],];// Remove a couple of versions.$versions = self::get_current_versions();array_pop($versions);array_pop($versions);$testcases['Older server'] = [$versions,array_key_last($versions),];// Limited version compatibility, including newer than we support now.$testcases['Newer versions with crossover'] = [['v1.6','v1.7','v7.9',],\communication_matrix\local\spec\v1p7::class,];return $testcases;}/*** Test that the instance method returns a valid instance for the given versions.** @dataProvider instance_provider* @param array|null $versions* @param string $expectedversion*/public function test_instance(?array $versions,string $expectedversion,): void {// Create a mock and queue two responses.$mock = new MockHandler([$this->get_mocked_version_response($versions),]);$handlerstack = HandlerStack::create($mock);$container = [];$history = Middleware::history($container);$handlerstack->push($history);$client = new http_client(['handler' => $handlerstack]);mocked_matrix_client::set_client($client);$instance = mocked_matrix_client::instance('https://example.com','testtoken',);$this->assertInstanceOf(matrix_client::class, $instance);// Only the version API has been called.$this->assertCount(1, $container);$request = reset($container);$this->assertEquals('/_matrix/client/versions', $request['request']->getUri()->getPath());// The client should be a v1p7 client as that is the highest compatible version.$this->assertInstanceOf($expectedversion, $instance);}/*** Test that the instance method returns a valid instance for the given versions.*/public function test_instance_cached(): void {$mock = new MockHandler([$this->get_mocked_version_response(),$this->get_mocked_version_response(),]);$handlerstack = HandlerStack::create($mock);$container = [];$history = Middleware::history($container);$handlerstack->push($history);$client = new http_client(['handler' => $handlerstack]);mocked_matrix_client::set_client($client);$instance = mocked_matrix_client::instance('https://example.com', 'testtoken');$this->assertInstanceOf(matrix_client::class, $instance);// Only the version API has been called.$this->assertCount(1, $container);// Call the API again. It should not lead to additional fetches.$instance = mocked_matrix_client::instance('https://example.com', 'testtoken');$instance = mocked_matrix_client::instance('https://example.com', 'testtoken');$this->assertCount(1, $container);// But a different endpoint will.$instance = mocked_matrix_client::instance('https://example.org', 'testtoken');$this->assertCount(2, $container);}/*** Test that the instance method throws an appropriate exception if no support is found.*/public function test_instance_no_support(): void {// Create a mock and queue two responses.$mock = new MockHandler([$this->get_mocked_version_response(['v99.9']),]);$handlerstack = HandlerStack::create($mock);$container = [];$history = Middleware::history($container);$handlerstack->push($history);$client = new http_client(['handler' => $handlerstack]);mocked_matrix_client::set_client($client);$this->expectException(moodle_exception::class);$this->expectExceptionMessage('No supported Matrix API versions found.');mocked_matrix_client::instance('https://example.com','testtoken',);}/*** Test the feature implementation check methods.** @covers ::implements_feature* @covers ::get_supported_versions* @dataProvider implements_feature_provider* @param string $version* @param array|string $features* @param bool $expected*/public function test_implements_feature(string $version,array|string $features,bool $expected,): void {$instance = $this->get_mocked_instance_for_version($version);$this->assertEquals($expected, $instance->implements_feature($features));}/*** Test the feature implementation requirement methods.** @covers ::implements_feature* @covers ::get_supported_versions* @covers ::require_feature* @dataProvider implements_feature_provider* @param string $version* @param array|string $features* @param bool $expected*/public function test_require_feature(string $version,array|string $features,bool $expected,): void {$instance = $this->get_mocked_instance_for_version($version);if ($expected) {$this->assertEmpty($instance->require_feature($features));} else {$this->expectException('moodle_exception');$instance->require_feature($features);}}/*** Test the feature implementation requirement methods for a require all.** @covers ::implements_feature* @covers ::get_supported_versions* @covers ::require_feature* @covers ::require_features* @dataProvider require_features_provider* @param string $version* @param array|string $features* @param bool $expected*/public function test_require_features(string $version,array|string $features,bool $expected,): void {$instance = $this->get_mocked_instance_for_version($version);if ($expected) {$this->assertEmpty($instance->require_features($features));} else {$this->expectException('moodle_exception');$instance->require_features($features);}}/*** Data provider for feature implementation check tests.** @return array*/public static function implements_feature_provider(): array {return ['Basic supported feature' => ['v1.7',features\matrix\media_create_v1::class,true,],'Basic unsupported feature' => ['v1.6',features\matrix\media_create_v1::class,false,],'[supported] as array' => ['v1.6',[features\matrix\create_room_v3::class],true,],'[supported, supported] as array' => ['v1.6',[features\matrix\create_room_v3::class,features\matrix\update_room_avatar_v3::class,],true,],'[unsupported] as array' => ['v1.6',[features\matrix\media_create_v1::class,],false,],'[unsupported, supported] as array' => ['v1.6',[features\matrix\media_create_v1::class,features\matrix\update_room_avatar_v3::class,],true,],];}/*** Data provider for feature implementation check tests.** @return array*/public static function require_features_provider(): array {// We'll just add to the standard testcases.$testcases = array_map(static function (array $testcase): array {$testcase[1] = [$testcase[1]];return $testcase;}, self::implements_feature_provider());$testcases['Require many supported features'] = ['v1.6',[features\matrix\create_room_v3::class,features\matrix\update_room_avatar_v3::class,],true,];$testcases['Require many including an unsupported feature'] = ['v1.6',[features\matrix\create_room_v3::class,features\matrix\media_create_v1::class,],false,];$testcases['Require many including an unsupported feature which has an alternate'] = ['v1.6',[features\matrix\create_room_v3::class,[features\matrix\media_create_v1::class,features\matrix\update_room_avatar_v3::class,],],true,];return $testcases;}/*** Test the get_version method.** @param string $version* @param string $expectedversion* @dataProvider get_version_provider* @covers ::get_version* @covers ::get_version_from_classname*/public function test_get_version(string $version,string $expectedversion,): void {$instance = $this->get_mocked_instance_for_version($version);$this->assertEquals($expectedversion, $instance->get_version());}/*** Data provider for get_version tests.** @return array*/public static function get_version_provider(): array {return [['v1.1', '1.1'],['v1.7', '1.7'],];}/*** Tests the meets_version method.** @param string $version The version of the API to test against* @param string $testversion The version to test* @param bool $expected Whether the version meets the requirement* @dataProvider meets_version_provider* @covers ::meets_version*/public function test_meets_version(string $version,string $testversion,bool $expected,): void {$instance = $this->get_mocked_instance_for_version($version);$this->assertEquals($expected, $instance->meets_version($testversion));}/*** Tests the requires_version method.** @param string $version The version of the API to test against* @param string $testversion The version to test* @param bool $expected Whether the version meets the requirement* @dataProvider meets_version_provider* @covers ::requires_version*/public function test_requires_version(string $version,string $testversion,bool $expected,): void {$instance = $this->get_mocked_instance_for_version($version);if ($expected) {$this->assertEmpty($instance->requires_version($testversion));} else {$this->expectException('moodle_exception');$instance->requires_version($testversion);}}/*** Data provider for meets_version tests.** @return array*/public static function meets_version_provider(): array {return ['Same version' => ['v1.1', '1.1', true],'Same version latest' => ['v1.7', '1.7', true],'Newer version rejected' => ['v1.1', '1.7', false],'Older version accepted' => ['v1.7', '1.1', true],];}/*** Test the execute method with a command.** @covers ::execute*/public function test_command_is_executed(): void {$historycontainer = [];$mock = new MockHandler();$instance = $this->get_mocked_instance_for_version('v1.6', $historycontainer, $mock);$command = new command($instance,method: 'GET',endpoint: 'test/endpoint',params: ['test' => 'test',],);$mock->append(new Response(200));$rc = new \ReflectionClass($instance);$rcm = $rc->getMethod('execute');$result = $rcm->invoke($instance, $command);$this->assertEquals(200, $result->getStatusCode());$this->assertCount(1, $historycontainer);$request = array_shift($historycontainer);$this->assertEquals('GET', $request['request']->getMethod());$this->assertEquals('/test/endpoint', $request['request']->getUri()->getPath());}}