AutorÃa | 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 core\context;
use GuzzleHttp\Psr7\Response;
/**
* Trait matrix_helper_trait to generate initial setup for matrix mock and associated helpers.
*
* @package communication_matrix
* @copyright 2023 Safat Shahin <safat.shahin@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
trait matrix_test_helper_trait {
/**
* @var string $accesstoken The token for matrix connection
*/
protected string $accesstoken;
/**
* @var string $matrixhomeserverurl The server url of matrix synapse server
*/
protected string $matrixhomeserverurl;
/**
* Initialize the mock configs in settings.
*
* @return void
*/
protected function initialise_mock_configs(): void {
$this->matrixhomeserverurl = TEST_COMMUNICATION_MATRIX_MOCK_SERVER;
set_config('matrixhomeserverurl', $this->matrixhomeserverurl, 'communication_matrix');
$request = $this->request();
$response = $request->post($this->matrixhomeserverurl . '/backoffice/create-admin');
$admindata = json_decode($response->getBody());
$json = [
'identifier' => [
'type' => 'm.id.user',
'user' => $admindata->user_id,
],
'type' => 'm.login.password',
'password' => $admindata->password,
];
$request = $this->request($json);
$response = $request->post($this->matrixhomeserverurl . '/_matrix/client/r0/login');
$response = json_decode($response->getBody());
if (empty($response->access_token)) {
$this->markTestSkipped(
'The matrix mock server is not responsive, can not continue the tests'
);
}
$this->accesstoken = $response->access_token;
set_config('matrixaccesstoken', $this->accesstoken, 'communication_matrix');
}
/**
* Get the mock server url.
*
* @return string
*/
public function get_matrix_server_url(): string {
if (empty($this->matrixhomeserverurl)) {
throw new \coding_exception('Can not get this information without initializing the mock server.');
}
return $this->matrixhomeserverurl;
}
/**
* Get the matrix access token.
*
* @return string
*/
public function get_matrix_access_token(): string {
if (empty($this->accesstoken)) {
throw new \coding_exception('Can not get this information without initializing the mock server.');
}
return $this->accesstoken;
}
/**
* This test requires mock server to be present.
*
* @return void
*/
protected function initialise_mock_server(): void {
if (!defined('TEST_COMMUNICATION_MATRIX_MOCK_SERVER')) {
$this->markTestSkipped(
'The TEST_COMMUNICATION_MATRIX_MOCK_SERVER constant must be defined to run communication_matrix tests'
);
}
$this->reset_mock();
$this->initialise_mock_configs();
}
/**
* Get matrix room data from matrix server.
*
* @param string $roomid The id of the room
* @return \stdClass
*/
public function get_matrix_room_data(string $roomid): \stdClass {
$rooms = $this->backoffice_get_all_rooms();
foreach ($rooms as $room) {
if ($room->room_id === $roomid) {
return $room;
}
}
}
/**
* Get matrix user data from matrix server.
*
* @param string $roomid The id of the room
* @param string $matrixuserid The id of the user
* @return \stdClass
*/
public function get_matrix_user_data(string $roomid, string $matrixuserid): \stdClass {
$users = $this->backoffice_get_all_users();
foreach ($users as $user) {
if ($user->userid === $matrixuserid) {
return $user;
}
}
}
/**
* A backoffice call to get all registered users from our mock server.
*
* @return array
*/
public function backoffice_get_all_users(): array {
$client = new \core\http_client();
return json_decode($client->get($this->get_backoffice_uri('users'))->getBody())->users;
}
/**
* A backoffice method to create users and rooms on our mock server.
*
* @param array $users
* @param array $rooms
*/
public function backoffice_create_users_and_rooms(
array $users = [],
array $rooms = [],
): Response {
$client = new \core\http_client();
return $client->put(
$this->get_backoffice_uri('create'),
[
'json' => [
'users' => $users,
'rooms' => $rooms,
],
],
);
}
/**
* The http request for the api call.
*
* @param array $jsonarray The array of json
* @param array $headers The array of headers
* @return \core\http_client
*/
public function request(array $jsonarray = [], array $headers = []): \core\http_client {
$response = new \core\http_client([
'headers' => $headers,
'json' => $jsonarray,
]);
return $response;
}
/**
* Get the URI of a backoffice endpoint on the mock server.
*
* @param string $endpoint
* @return string
*/
protected function get_backoffice_uri(string $endpoint): string {
return $this->get_matrix_server_url() . '/backoffice/' . $endpoint;
}
/**
* Fetch all rooms from the back office.
*
* @return array
*/
public function backoffice_get_all_rooms(): array {
$client = new \core\http_client();
return json_decode($client->get($this->get_backoffice_uri('rooms'))->getBody())->rooms;
}
/**
* Return the first room from the server.
*
* In most cases there is only one room.
* @return \stdClass
*/
public function backoffice_get_room(): \stdClass {
// Fetch the room information from the server.
$rooms = $this->backoffice_get_all_rooms();
$this->assertCount(1, $rooms);
$room = reset($rooms);
return $room;
}
/**
* Reset the mock server
*
* @return void
*/
public function reset_mock(): void {
if (defined('TEST_COMMUNICATION_MATRIX_MOCK_SERVER')) {
$request = $this->request();
$response = $request->post(TEST_COMMUNICATION_MATRIX_MOCK_SERVER . '/backoffice/reset');
$response = json_decode($response->getBody());
if (empty($response->reset)) {
$this->markTestSkipped(
'The matrix mock server is not responsive, can not continue the tests'
);
}
}
}
/**
* Helper to create a room.
*
* @param null|string $component
* @param null|string $itemtype
* @param null|int $itemid
* @param null|string $roomname
* @param null|string $roomtopic
* @param null|stored_file $roomavatar
* @param array $members
* @return api
*/
protected function create_matrix_room(
?string $component = 'core_course',
?string $itemtype = 'example',
?int $itemid = 1,
?string $roomname = null,
?string $roomtopic = null,
?\stored_file $roomavatar = null,
array $members = [],
?context $context = null,
): \core_communication\api {
$context = $context ?? \core\context\system::instance();
// Create a new room.
$communication = \core_communication\api::load_by_instance(
context: $context,
component: $component,
instancetype: $itemtype,
instanceid: $itemid,
provider: 'communication_matrix',
);
$communication->create_and_configure_room(
communicationroomname: $roomname ?? 'Room name',
avatar: $roomavatar,
instance: (object) [
'matrixroomtopic' => $roomtopic ?? 'A fun topic',
],
);
$communication->add_members_to_room($members);
// Run the adhoc task.
$this->run_all_adhoc_tasks();
return \core_communication\api::load_by_instance(
context: $context,
component: $component,
instancetype: $itemtype,
instanceid: $itemid,
);
}
}