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 core\moodlenet;use context_course;use core\http_client;use core\oauth2\issuer;use GuzzleHttp\Exception\ClientException;use GuzzleHttp\Handler\MockHandler;use GuzzleHttp\HandlerStack;use GuzzleHttp\Psr7\Response;use PHPUnit\Framework\MockObject\MockObject;use Psr\Http\Message\ResponseInterface;use ReflectionMethod;use stdClass;use testing_data_generator;/*** Test coverage for moodlenet course sender.** @package core* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later* @coversDefaultClass \core\moodlenet\course_sender*/class course_sender_test extends \advanced_testcase {/** @var testing_data_generator Data generator. */private testing_data_generator $generator;/** @var stdClass Course object. */private stdClass $course;/** @var context_course Course context instance. */private context_course $coursecontext;/** @var issuer $issuer Dummy issuer. */private issuer $issuer;/** @var MockObject $mockoauthclient Mock OAuth client. */private MockObject $mockoauthclient;public static function setUpBeforeClass(): void {parent::setUpBeforeClass();require_once(__DIR__ . '/helpers.php');}/*** Set up function for tests.*/protected function setUp(): void {parent::setUp();$this->resetAfterTest();// Get data generator.$this->generator = $this->getDataGenerator();// Create course.$this->course = $this->generator->create_course(['shortname' => 'testcourse']);$this->coursecontext = context_course::instance($this->course->id);// Create mock issuer.$this->issuer = helpers::get_mock_issuer(1);// Create mock builder for OAuth2 client.$mockbuilder = $this->getMockBuilder('core\oauth2\client');$mockbuilder->onlyMethods(['get_issuer', 'is_logged_in', 'get_accesstoken']);$mockbuilder->setConstructorArgs([$this->issuer, '', '']);// Get the OAuth2 client mock.$this->mockoauthclient = $mockbuilder->getMock();}/*** Test prepare_share_contents method.** @covers ::prepare_share_contents*/public function test_prepare_share_contents(): void {global $USER;$this->setAdminUser();// Set get_file method accessibility.$method = new ReflectionMethod(course_sender::class, 'prepare_share_contents');// Test with invalid share format.$this->expectException(\moodle_exception::class);$this->expectExceptionMessage(get_string('moodlenet:invalidshareformat', 'error'));$httpclient = new http_client();$moodlenetclient = new moodlenet_client($httpclient, $this->mockoauthclient);$coursesender = new course_sender(random_int(5, 30),$USER->id,$moodlenetclient,$this->mockoauthclient,random_int(5, 30));$coursesender = $method->invoke(new course_sender($this->course->id,$USER->id,$moodlenetclient,$this->mockoauthclient,resource_sender::SHARE_FORMAT_BACKUP));// Test with valid share format and invalid course module.$package = $method->invoke(new course_sender($this->course->id,$USER->id,$moodlenetclient,$this->mockoauthclient,resource_sender::SHARE_FORMAT_BACKUP));$this->assertEmpty($package);// Test with valid share format and valid course module.$package = $method->invoke(new course_sender($this->course->id,$USER->id,$moodlenetclient,$this->mockoauthclient,resource_sender::SHARE_FORMAT_BACKUP));$this->assertNotEmpty($package);// Confirm the expected stored_file object is returned.$this->assertInstanceOf(\stored_file::class, $package);}/*** Test get_resource_description method.** @covers ::get_resource_description*/public function test_get_resource_description(): void {global $USER;$this->setAdminUser();$course = $this->generator->create_course(['summary' => '<p>This is an example Moodle course description.</p><p> </p><p>This is a formatted intro</p><p> </p><p>This thing has many lines.</p><p> </p><p>The last word of this sentence is in <strong>bold</strong></p>']);// Set get_resource_description method accessibility.$method = new ReflectionMethod(course_sender::class, 'get_resource_description');// Test the processed description.$httpclient = new http_client();$moodlenetclient = new moodlenet_client($httpclient, $this->mockoauthclient);$processeddescription = $method->invoke(new course_sender($course->id,$USER->id,$moodlenetclient,$this->mockoauthclient,resource_sender::SHARE_FORMAT_BACKUP), $this->coursecontext);$this->assertEquals('This is an example Moodle course description.This is a formatted introThis thing has many lines.The last word of this sentence is in bold', $processeddescription);}/*** Test share_resource() method.** @dataProvider share_resource_provider* @covers ::share_resource* @covers ::log_event* @covers \core\moodlenet\moodlenet_client::create_resource_from_stored_file* @covers \core\moodlenet\moodlenet_client::prepare_file_share_request_data* @param ResponseInterface $httpresponse* @param array $expected*/public function test_share_resource(ResponseInterface $httpresponse, array $expected): void {global $CFG, $USER;$this->setAdminUser();// Enable the experimental flag.$CFG->enablesharingtomoodlenet = true;// Set OAuth 2 service in the outbound setting to the dummy issuer.set_config('oauthservice', $this->issuer->get('id'), 'moodlenet');// Generate access token for the mock.$accesstoken = new stdClass();$accesstoken->token = random_string(64);// Get the OAuth2 client mock and set the return value for necessary methods.$this->mockoauthclient->method('get_issuer')->will($this->returnValue($this->issuer));$this->mockoauthclient->method('is_logged_in')->will($this->returnValue(true));$this->mockoauthclient->method('get_accesstoken')->will($this->returnValue($accesstoken));// Create Guzzle mock.$mockguzzlehandler = new MockHandler([$httpresponse]);$handlerstack = HandlerStack::create($mockguzzlehandler);$httpclient = new http_client(['handler' => $handlerstack]);// Create events sink.$sink = $this->redirectEvents();// Create sender.$moodlenetclient = new moodlenet_client($httpclient, $this->mockoauthclient);$coursesender = new course_sender($this->course->id,$USER->id,$moodlenetclient,$this->mockoauthclient,resource_sender::SHARE_FORMAT_BACKUP);if (isset($expected['exception'])) {$this->expectException(ClientException::class);$this->expectExceptionMessage($expected['exception']);}// Call the API.$result = $coursesender->share_resource();// Verify the result.$this->assertEquals($expected['response_code'], $result['responsecode']);$this->assertEquals($expected['resource_url'], $result['drafturl']);// Verify the events.$events = $sink->get_events();$event = end($events);$this->assertInstanceOf('\core\event\moodlenet_resource_exported', $event);$this->assertEquals($USER->id, $event->userid);if ($result['responsecode'] == 201) {$description = "The user with id '{$USER->id}' successfully shared course to MoodleNet with the " ."following course id, from context with id '{$this->coursecontext->id}': '{$this->course->id}'.";} else {$description = "The user with id '{$USER->id}' failed to share course to MoodleNet with the " ."following course id, from context with id '{$this->coursecontext->id}': '{$this->course->id}'.";}$this->assertEquals($description, $event->get_description());}/*** Provider for test share_resource().** @return array Test data.*/public function share_resource_provider(): array {return ['Success' => ['http_response' => new Response(201,['Content-Type' => 'application/json'],json_encode(['homepage' => 'https://moodlenet.example.com/drafts/view/testcourse_backup_1.mbz',]),),'expected' => ['response_code' => 201,'resource_url' => 'https://moodlenet.example.com/drafts/view/testcourse_backup_1.mbz',],],'Fail with 200 status code' => ['http_response' => new Response(200,['Content-Type' => 'application/json'],json_encode(['homepage' => 'https://moodlenet.example.com/drafts/view/testcourse_backup_2.mbz',]),),'expected' => ['response_code' => 200,'resource_url' => 'https://moodlenet.example.com/drafts/view/testcourse_backup_2.mbz',],],'Fail with 401 status code' => ['http_response' => new Response(401,),'expected' => ['response_code' => 401,'resource_url' => '','exception' => 'Client error: ' .'`POST https://moodlenet.example.com/.pkg/@moodlenet/ed-resource/basic/v1/create` ' .'resulted in a `401 Unauthorized` response',],],'Fail with 404 status code' => ['http_response' => new Response(404,),'expected' => ['response_code' => 404,'resource_url' => '','exception' => 'Client error: '.'`POST https://moodlenet.example.com/.pkg/@moodlenet/ed-resource/basic/v1/create` ' .'resulted in a `404 Not Found` response',],],];}}