ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç aws_helper.php000064400000007373152267213230007423 0ustar00. namespace core\aws; use Aws\CommandInterface; use Aws\AwsClient; use Psr\Http\Message\RequestInterface; /** * This class contains functions that help plugins to interact with the AWS SDK. * * @copyright 2020 Catalyst IT * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @deprecated Since Moodle 4.5 * @todo MDL-82459 Final deprecation in Moodle 6.0. */ class aws_helper { /** * This creates a proxy string suitable for use with the AWS SDK. * * @return string the string to use for proxy settings. * @deprecated Since Moodle 4.5 */ #[\core\attribute\deprecated( since: '4.5', mdl: 'MDL-80962', )] public static function get_proxy_string(): string { \core\deprecation::emit_deprecation([static::class, __FUNCTION__]); global $CFG; $proxy = ''; if (empty($CFG->proxytype)) { return $proxy; } if ($CFG->proxytype === 'SOCKS5') { // If it is a SOCKS proxy, append the protocol info. $protocol = 'socks5://'; } else { $protocol = ''; } if (!empty($CFG->proxyhost)) { $proxy = $CFG->proxyhost; if (!empty($CFG->proxyport)) { $proxy .= ':'. $CFG->proxyport; } if (!empty($CFG->proxyuser) && !empty($CFG->proxypassword)) { $proxy = $protocol . $CFG->proxyuser . ':' . $CFG->proxypassword . '@' . $proxy; } } return $proxy; } /** * Configure the provided AWS client to route traffic via the moodle proxy for any hosts not excluded. * * @param AwsClient $client * @return AwsClient * @deprecated Since Moodle 4.5 */ #[\core\attribute\deprecated( since: '4.5', mdl: 'MDL-80962', )] public static function configure_client_proxy(AwsClient $client): AwsClient { \core\deprecation::emit_deprecation([static::class, __FUNCTION__]); $client->getHandlerList()->appendBuild(self::add_proxy_when_required(), 'proxy_bypass'); return $client; } /** * Generate a middleware higher order function to wrap the handler and append proxy configuration based on target. * * @return callable Middleware high order callable. * @deprecated Since Moodle 4.5 */ #[\core\attribute\deprecated( since: '4.5', mdl: 'MDL-80962', )] protected static function add_proxy_when_required(): callable { \core\deprecation::emit_deprecation([static::class, __FUNCTION__]); return function (callable $fn) { return function (CommandInterface $command, ?RequestInterface $request = null) use ($fn) { if (isset($request)) { $target = (string) $request->getUri(); if (!is_proxybypass($target)) { $command['@http']['proxy'] = self::get_proxy_string(); } } $promise = $fn($command, $request); return $promise; }; }; } } client_factory.php000064400000004616152267213230010274 0ustar00. namespace core\aws; use Aws\AwsClient; /** * AWS Client factory. Retrieves a client with moodle specific HTTP configuration. * * @copyright 2022 Catalyst IT * @author Peter Burnett * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @deprecated Since Moodle 4.5 * @todo MDL-82459 Final deprecation in Moodle 6.0. */ class client_factory { /** * Get an AWS client with moodle specific HTTP configuration. * * @param string $class Fully qualified AWS classname e.g. \Aws\S3\S3Client * @param array $opts array of constructor options for AWS Client. * @return AwsClient * @deprecated Since Moodle 4.5 */ #[\core\attribute\deprecated( 'aws_helper::configure_client_proxy()', since: '4.5', mdl: 'MDL-80962', )] public static function get_client(string $class, array $opts): AwsClient { \core\deprecation::emit_deprecation([static::class, __FUNCTION__]); // Modify the opts to add HTTP timeouts. if (empty($opts['http'])) { $opts['http'] = ['connect_timeout' => HOURSECS]; } else if (!array_key_exists('connect_timeout', $opts['http'])) { // Try not to override existing settings. $opts['http']['connect_timeout'] = HOURSECS; } // Blindly trust the call here. If it exceptions, the raw message is the most useful. $client = new $class($opts); if (!$client instanceof \Aws\AwsClient) { throw new \moodle_exception('clientnotfound', 'factor_sms'); } // Now we can configure the proxy with the routing aware middleware. return aws_helper::configure_client_proxy($client); } } admin_settings_aws_region.php000064400000005242152267213230012510 0ustar00. namespace core\aws; defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/lib/adminlib.php'); /** * Admin setting for a list of AWS regions. * * @package core * @copyright 2020 Catalyst IT * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @deprecated Since Moodle 4.5 * @todo MDL-82459 Final deprecation in Moodle 6.0. */ class admin_settings_aws_region extends \admin_setting_configtext { /** * Return part of form with setting. * * @param mixed $data array or string depending on setting * @param string $query * @return string * @deprecated Since Moodle 4.5 */ #[\core\attribute\deprecated( 'admin_settings_aws_region::output_html()', since: '4.5', mdl: 'MDL-80962', )] public function output_html($data, $query='') { \core\deprecation::emit_deprecation([$this, __FUNCTION__]); global $CFG, $OUTPUT; $default = $this->get_defaultsetting(); $options = []; // We do require() not require_once() here, as the file returns a value and we may need to get // this value more than once. $all = require($CFG->dirroot . '/lib/aws-sdk/src/data/endpoints.json.php'); $ends = $all['partitions'][0]['regions']; if ($ends) { foreach ($ends as $key => $value) { $options[] = [ 'value' => $key, 'label' => $key . ' - ' . $value['description'], ]; } } $context = [ 'list' => $this->get_full_name(), 'name' => $this->get_full_name(), 'id' => $this->get_id(), 'value' => $data, 'size' => $this->size, 'options' => $options, ]; $element = $OUTPUT->render_from_template('core/aws/setting_aws_region', $context); return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $default, $query); } } db/hooks.php000064400000002203152271662200006765 0ustar00. /** * Hook listener callbacks for aws sms gateway. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $callbacks = [ [ 'hook' => \core_sms\hook\after_sms_gateway_form_hook::class, 'callback' => \smsgateway_aws\hook_listener::class . '::set_form_definition_for_aws_sms_gateway', ], ]; lang/en/smsgateway_aws.php000064400000002624152271662200011645 0ustar00. /** * Strings for component smsgateway_aws, language 'en'. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ $string['api_key'] = 'Access key'; $string['api_region'] = 'Amazon API gateway region'; $string['api_secret'] = 'Secret access key'; $string['aws_information'] = 'Complete the following fields using the information provided by AWS'; $string['aws_sns'] = 'AWS SNS'; $string['gateway'] = 'AWS service'; $string['pluginname'] = 'AWS'; $string['privacy:metadata'] = 'The AWS SMS gateway plugin does not store any personal data.'; $string['usecredchain'] = 'Find AWS credentials using the default provider chain'; version.php000064400000002073152271662200006747 0ustar00. /** * Version information for smsgateway_aws. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'smsgateway_aws'; $plugin->version = 2025041400; $plugin->requires = 2025040800; $plugin->maturity = MATURITY_STABLE; classes/privacy/provider.php000064400000002245152271662200012227 0ustar00. namespace smsgateway_aws\privacy; use core_privacy\local\metadata\null_provider; /** * Privacy Subsystem for smsgateway_aws implementing null_provider. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @codeCoverageIgnore */ class provider implements null_provider { #[\Override] public static function get_reason(): string { return 'privacy:metadata'; } } classes/local/aws_sms_service_provider.php000064400000003014152271662200015113 0ustar00. namespace smsgateway_aws\local; use core_sms\message_status; use stdClass; /** * AWS SMS service provider interface to provide a standard interface for different aws service providers like sns, sqs etc. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ interface aws_sms_service_provider { /** * Sends an SMS message using the selected aws service provider. * * @param string $messagecontent the content to send in the SMS message. * @param string $phonenumber the destination for the message. * @return message_status Status of the message. */ public static function send_sms_message( string $messagecontent, string $phonenumber, stdclass $config, ): message_status; } classes/local/service/aws_sns.php000064400000005726152271662200013136 0ustar00. namespace smsgateway_aws\local\service; use core_sms\message_status; use smsgateway_aws\helper; use smsgateway_aws\local\aws_sms_service_provider; use stdClass; /** * AWS SNS service provider. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class aws_sns implements aws_sms_service_provider { /** * Include the required calls. */ private static function require(): void { global $CFG; require_once($CFG->libdir . '/aws-sdk/src/functions.php'); } #[\Override] public static function send_sms_message( string $messagecontent, string $phonenumber, stdclass $config, ): message_status { global $SITE; self::require(); // Setup client params and instantiate client. $params = [ 'version' => 'latest', 'region' => $config->api_region, 'http' => ['proxy' => helper::get_proxy_string()], ]; if (!property_exists($config, 'usecredchain') || !$config->usecredchain) { $params['credentials'] = [ 'key' => $config->api_key, 'secret' => $config->api_secret, ]; } $client = new \Aws\Sns\SnsClient($params); // Set up the sender information. $senderid = $SITE->shortname; // Remove spaces and non-alphanumeric characters from ID. $senderid = preg_replace("/[^A-Za-z0-9]/", '', trim($senderid)); // We have to truncate the senderID to 11 chars. $senderid = substr($senderid, 0, 11); try { // These messages need to be transactional. $client->SetSMSAttributes([ 'attributes' => [ 'DefaultSMSType' => 'Transactional', 'DefaultSenderID' => $senderid, ], ]); // Actually send the message. $client->publish([ 'Message' => $messagecontent, 'PhoneNumber' => $phonenumber, ]); return \core_sms\message_status::GATEWAY_SENT; } catch (\Aws\Exception\AwsException $e) { return \core_sms\message_status::GATEWAY_NOT_AVAILABLE; } } } classes/hook_listener.php000064400000006751152271662200011573 0ustar00. namespace smsgateway_aws; use core_sms\hook\after_sms_gateway_form_hook; /** * Hook listener for aws sms gateway. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class hook_listener { /** * Hook listener for the sms gateway setup form. * * @param after_sms_gateway_form_hook $hook The hook to add to sms gateway setup. */ public static function set_form_definition_for_aws_sms_gateway(after_sms_gateway_form_hook $hook): void { if ($hook->plugin !== 'smsgateway_aws') { return; } $mform = $hook->mform; $mform->addElement('static', 'information', get_string('aws_information', 'smsgateway_aws')); $gateways = [ 'aws_sns' => get_string('aws_sns', 'smsgateway_aws'), ]; $mform->addElement( 'select', 'gateway', get_string('gateway', 'smsgateway_aws'), $gateways, ); $mform->setDefault( elementName: 'gateway', defaultValue: 'aws_sns', ); // Remove this if more aws gateway implemented, eg sqs. $mform->hardFreeze('gateway'); $mform->addElement( 'checkbox', 'usecredchain', get_string('usecredchain', 'smsgateway_aws'), ' ', ); $mform->setDefault( elementName: 'usecredchain', defaultValue: 0, ); $mform->addElement( 'text', 'api_key', get_string('api_key', 'smsgateway_aws'), 'maxlength="255" size="20"', ); $mform->setType('api_key', PARAM_TEXT); $mform->addRule('api_key', get_string('maximumchars', '', 255), 'maxlength', 255); $mform->setDefault( elementName: 'api_key', defaultValue: '', ); $mform->addElement( 'passwordunmask', 'api_secret', get_string('api_secret', 'smsgateway_aws'), 'maxlength="255" size="20"', ); $mform->setType('api_secret', PARAM_TEXT); $mform->addRule('api_secret', get_string('maximumchars', '', 255), 'maxlength', 255); $mform->setDefault( elementName: 'api_secret', defaultValue: '', ); $mform->addElement( 'text', 'api_region', get_string('api_region', 'smsgateway_aws'), 'maxlength="255" size="20"', ); $mform->setType('api_region', PARAM_TEXT); $mform->addRule('api_region', get_string('maximumchars', '', 255), 'maxlength', 255); $mform->setDefault( elementName: 'api_region', defaultValue: 'ap-southeast-2', ); } } classes/helper.php000064400000003515152271662200010200 0ustar00. namespace smsgateway_aws; /** * AWS SMS gateway helpers. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class helper { /** * This creates a proxy string suitable for use with the AWS SDK. * * @return string the string to use for proxy settings. */ public static function get_proxy_string(): string { global $CFG; $proxy = ''; if (empty($CFG->proxytype)) { return $proxy; } if ($CFG->proxytype === 'SOCKS5') { // If it is a SOCKS proxy, append the protocol info. $protocol = 'socks5://'; } else { $protocol = ''; } if (!empty($CFG->proxyhost)) { $proxy = $CFG->proxyhost; if (!empty($CFG->proxyport)) { $proxy .= ':'. $CFG->proxyport; } if (!empty($CFG->proxyuser) && !empty($CFG->proxypassword)) { $proxy = $protocol . $CFG->proxyuser . ':' . $CFG->proxypassword . '@' . $proxy; } } return $proxy; } } classes/gateway.php000064400000004413152271662200010360 0ustar00. namespace smsgateway_aws; use core_sms\manager; use core_sms\message; use MoodleQuickForm; /** * AWS SMS gateway. * * @package smsgateway_aws * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class gateway extends \core_sms\gateway { #[\Override] public function send( message $message, ): message { global $DB; // Get the config from the message record. $awsconfig = $DB->get_field( table: 'sms_gateways', return: 'config', conditions: ['id' => $message->gatewayid, 'enabled' => 1, 'gateway' => 'smsgateway_aws\gateway',], ); $status = \core_sms\message_status::GATEWAY_NOT_AVAILABLE; if ($awsconfig) { $config = (object)json_decode($awsconfig, true, 512, JSON_THROW_ON_ERROR); $class = '\smsgateway_aws\local\service\\' . $config->gateway; $recipientnumber = manager::format_number( phonenumber: $message->recipientnumber, countrycode: isset($config->countrycode) ?? null, ); if (class_exists($class)) { $status = call_user_func( $class . '::send_sms_message', $message->content, $recipientnumber, $config, ); } } return $message->with( status: $status, ); } #[\Override] public function get_send_priority(message $message): int { return 50; } } tests/helper_test.php000064400000006774152271662200010756 0ustar00. namespace smsgateway_aws; /** * AWS SMS gateway helper tests. * * @package smsgateway_aws * @category test * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \smsgateway_aws\helper */ final class helper_test extends \advanced_testcase { /** * Data provider for test_format_number(). * * @return array of different country codes and phone numbers. */ public static function format_number_provider(): array { return [ 'Phone number with local format' => [ 'phonenumber' => '0123456789', 'expected' => '+34123456789', 'countrycode' => '34', ], 'Phone number with international format' => [ 'phonenumber' => '+39123456789', 'expected' => '+39123456789', ], 'Phone number with spaces using international format' => [ 'phonenumber' => '+34 123 456 789', 'expected' => '+34123456789', ], 'Phone number with spaces using local format with country code' => [ 'phonenumber' => '0 123 456 789', 'expected' => '+34123456789', 'countrycode' => '34', ], 'Phone number with spaces using local format without country code' => [ 'phonenumber' => '0 123 456 789', 'expected' => '123456789', ], ]; } /** * Test format number with different phones and different country codes. * * @dataProvider format_number_provider * @param string $phonenumber Phone number. * @param string $expected Expected value. * @param string|null $countrycode Country code. */ public function test_format_number( string $phonenumber, string $expected, ?string $countrycode = null, ): void { $this->resetAfterTest(); $this->assertEquals($expected, \core_sms\manager::format_number($phonenumber, $countrycode)); } /** * Test the proxy strings. */ public function test_get_proxy_string(): void { global $CFG; $this->resetAfterTest(); // Confirm with no config an empty string is returned. $CFG->proxyhost = ''; $this->assertEquals('', helper::get_proxy_string()); // Now set some configs. $CFG->proxyhost = '127.0.0.1'; $CFG->proxyuser = 'user'; $CFG->proxypassword = 'password'; $CFG->proxyport = '1337'; $this->assertEquals('user:password@127.0.0.1:1337', helper::get_proxy_string()); // Now change to SOCKS proxy. $CFG->proxytype = 'SOCKS5'; $this->assertEquals('socks5://user:password@127.0.0.1:1337', helper::get_proxy_string()); } } tests/gateway_test.php000064400000004720152271662200011125 0ustar00. namespace smsgateway_aws; use core_sms\message; /** * AWS SMS gateway tests. * * @package smsgateway_aws * @category test * @copyright 2024 Safat Shahin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \smsgateway_aws\gateway */ final class gateway_test extends \advanced_testcase { public function test_update_message_status(): void { $this->resetAfterTest(); $config = new \stdClass(); $config->api_key = 'test_api_key'; $manager = \core\di::get(\core_sms\manager::class); $gw = $manager->create_gateway_instance( classname: gateway::class, name: 'aws', enabled: true, config: $config, ); $othergw = $manager->create_gateway_instance( classname: gateway::class, name: 'aws', enabled: true, config: $config, ); $message = new message( recipientnumber: '1234567890', content: 'Hello, world!', component: 'smsgateway_aws', messagetype: 'test', recipientuserid: null, issensitive: false, gatewayid: $gw->id, ); $message2 = new message( recipientnumber: '1234567890', content: 'Hello, world!', component: 'smsgateway_aws', messagetype: 'test', recipientuserid: null, issensitive: false, gatewayid: $gw->id, ); $updatedmessages = $gw->update_message_statuses([$message, $message2]); $this->assertEquals([$message, $message2], $updatedmessages); $this->expectException(\coding_exception::class); $othergw->update_message_status($message); } }