Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.
   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  /**
  18   * Unit tests for the WSDL class.
  19   *
  20   * @package    webservice_soap
  21   * @category   test
  22   * @copyright  2016 Jun Pataleta <jun@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  namespace webservice_soap;
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  require_once($CFG->dirroot . '/webservice/soap/classes/wsdl.php');
  30  
  31  /**
  32   * Unit tests for the WSDL class.
  33   *
  34   * @package    webservice_soap
  35   * @category   test
  36   * @copyright  2016 Jun Pataleta <jun@moodle.com>
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class wsdl_test extends \advanced_testcase {
  40  
  41      /**
  42       * Test generated WSDL with no added complex types nor functions.
  43       */
  44      public function test_minimum_wsdl() {
  45          $this->resetAfterTest();
  46  
  47          $serviceclass = 'testserviceclass';
  48          $namespace = 'testnamespace';
  49          $wsdl = new wsdl($serviceclass, $namespace);
  50  
  51          // Test definitions node.
  52          $definitions = new \SimpleXMLElement($wsdl->to_xml());
  53          $defattrs = $definitions->attributes();
  54          $this->assertEquals($serviceclass, $defattrs->name);
  55          $this->assertEquals($namespace, $defattrs->targetNamespace);
  56  
  57          // Test types node and attributes.
  58          $this->assertNotNull($definitions->types);
  59          $this->assertEquals($namespace, $definitions->types->children('xsd', true)->schema->attributes()->targetNamespace);
  60  
  61          // Test portType node and attributes.
  62          $this->assertNotNull($definitions->portType);
  63          $this->assertEquals($serviceclass . wsdl::PORT, $definitions->portType->attributes()->name);
  64  
  65          // Test binding node and attributes.
  66          $this->assertNotNull($definitions->binding);
  67          $this->assertEquals($serviceclass . wsdl::BINDING, $definitions->binding->attributes()->name);
  68          $this->assertEquals('tns:' . $serviceclass . wsdl::PORT, $definitions->binding->attributes()->type);
  69  
  70          $bindingattrs = $definitions->binding->children('soap', true)->binding->attributes();
  71          $this->assertNotEmpty('rpc', $bindingattrs);
  72          $this->assertEquals('rpc', $bindingattrs->style);
  73          $this->assertEquals(wsdl::NS_SOAP_TRANSPORT, $bindingattrs->transport);
  74  
  75          // Test service node.
  76          $this->assertNotNull($definitions->service);
  77          $this->assertEquals($serviceclass . wsdl::SERVICE, $definitions->service->attributes()->name);
  78  
  79          $serviceport = $definitions->service->children()->port;
  80          $this->assertNotEmpty($serviceport);
  81          $this->assertEquals($serviceclass . wsdl::PORT, $serviceport->attributes()->name);
  82          $this->assertEquals('tns:' . $serviceclass . wsdl::BINDING, $serviceport->attributes()->binding);
  83  
  84          $serviceportaddress = $serviceport->children('soap', true)->address;
  85          $this->assertNotEmpty($serviceportaddress);
  86          $this->assertEquals($namespace, $serviceportaddress->attributes()->location);
  87      }
  88  
  89      /**
  90       * Test output WSDL with complex type added.
  91       */
  92      public function test_add_complex_type() {
  93          $this->resetAfterTest();
  94  
  95          $classname = 'testcomplextype';
  96          $classattrs = array(
  97              'doubleparam' => array(
  98                  'type' => 'double',
  99                  'nillable' => true
 100              ),
 101              'stringparam' => array(
 102                  'type' => 'string',
 103                  'nillable' => true
 104              ),
 105              'intparam' => array(
 106                  'type' => 'int',
 107                  'nillable' => true
 108              ),
 109              'boolparam' => array(
 110                  'type' => 'int',
 111                  'nillable' => true
 112              ),
 113              'classparam' => array(
 114                  'type' => 'teststruct'
 115              ),
 116              'arrayparam' => array(
 117                  'type' => 'array',
 118                  'nillable' => true
 119              ),
 120          );
 121  
 122          $serviceclass = 'testserviceclass';
 123          $namespace = 'testnamespace';
 124          $wsdl = new wsdl($serviceclass, $namespace);
 125          $wsdl->add_complex_type($classname, $classattrs);
 126  
 127          $definitions = new \SimpleXMLElement($wsdl->to_xml());
 128  
 129          // Test types node and attributes.
 130          $this->assertNotNull($definitions->types);
 131          $this->assertEquals($namespace, $definitions->types->children('xsd', true)->schema->attributes()->targetNamespace);
 132          $complextype = $definitions->types->children('xsd', true)->schema->children('xsd', true);
 133          $this->assertNotEmpty($complextype);
 134  
 135          // Test the complex type's attributes.
 136          foreach ($complextype->children('xsd', true)->all->children('xsd', true) as $element) {
 137              foreach ($classattrs as $name => $options) {
 138                  if (strcmp($name, $element->attributes()->name) != 0) {
 139                      continue;
 140                  }
 141                  switch ($options['type']) {
 142                      case 'double':
 143                      case 'int':
 144                      case 'string':
 145                          $this->assertEquals('xsd:' . $options['type'], $element->attributes()->type);
 146                          break;
 147                      case 'array':
 148                          $this->assertEquals('soap-enc:' . ucfirst($options['type']), $element->attributes()->type);
 149                          break;
 150                      default:
 151                          $this->assertEquals('tns:' . $options['type'], $element->attributes()->type);
 152                          break;
 153                  }
 154                  if (!empty($options['nillable'])) {
 155                      $this->assertEquals('true', $element->attributes()->nillable);
 156                  }
 157                  break;
 158              }
 159          }
 160      }
 161  
 162      /**
 163       * Test output WSDL when registering a web service function.
 164       */
 165      public function test_register() {
 166          $this->resetAfterTest();
 167  
 168          $serviceclass = 'testserviceclass';
 169          $namespace = 'testnamespace';
 170          $wsdl = new wsdl($serviceclass, $namespace);
 171  
 172          $functionname = 'testfunction';
 173          $documentation = 'This is a test function';
 174          $in = array(
 175              'doubleparam' => array(
 176                  'type' => 'double'
 177              ),
 178              'stringparam' => array(
 179                  'type' => 'string'
 180              ),
 181              'intparam' => array(
 182                  'type' => 'int'
 183              ),
 184              'boolparam' => array(
 185                  'type' => 'int'
 186              ),
 187              'classparam' => array(
 188                  'type' => 'teststruct'
 189              ),
 190              'arrayparam' => array(
 191                  'type' => 'array'
 192              )
 193          );
 194          $out = array(
 195              'doubleparam' => array(
 196                  'type' => 'double'
 197              ),
 198              'stringparam' => array(
 199                  'type' => 'string'
 200              ),
 201              'intparam' => array(
 202                  'type' => 'int'
 203              ),
 204              'boolparam' => array(
 205                  'type' => 'int'
 206              ),
 207              'classparam' => array(
 208                  'type' => 'teststruct'
 209              ),
 210              'arrayparam' => array(
 211                  'type' => 'array'
 212              ),
 213              'return' => array(
 214                  'type' => 'teststruct2'
 215              )
 216          );
 217          $wsdl->register($functionname, $in, $out, $documentation);
 218  
 219          $definitions = new \SimpleXMLElement($wsdl->to_xml());
 220  
 221          // Test portType operation node.
 222          $porttypeoperation = $definitions->portType->operation;
 223          $this->assertEquals($documentation, $porttypeoperation->documentation);
 224          $this->assertEquals('tns:' . $functionname . wsdl::IN, $porttypeoperation->input->attributes()->message);
 225          $this->assertEquals('tns:' . $functionname . wsdl::OUT, $porttypeoperation->output->attributes()->message);
 226  
 227          // Test binding operation nodes.
 228          $bindingoperation = $definitions->binding->operation;
 229          $soapoperation = $bindingoperation->children('soap', true)->operation;
 230          $this->assertEquals($namespace . '#' . $functionname, $soapoperation->attributes()->soapAction);
 231          $inputbody = $bindingoperation->input->children('soap', true);
 232          $this->assertEquals('encoded', $inputbody->attributes()->use);
 233          $this->assertEquals(wsdl::NS_SOAP_ENC, $inputbody->attributes()->encodingStyle);
 234          $this->assertEquals($namespace, $inputbody->attributes()->namespace);
 235          $outputbody = $bindingoperation->output->children('soap', true);
 236          $this->assertEquals('encoded', $outputbody->attributes()->use);
 237          $this->assertEquals(wsdl::NS_SOAP_ENC, $outputbody->attributes()->encodingStyle);
 238          $this->assertEquals($namespace, $outputbody->attributes()->namespace);
 239  
 240          // Test messages.
 241          $messagein = $definitions->message[0];
 242          $this->assertEquals($functionname . wsdl::IN, $messagein->attributes()->name);
 243          foreach ($messagein->children() as $part) {
 244              foreach ($in as $name => $options) {
 245                  if (strcmp($name, $part->attributes()->name) != 0) {
 246                      continue;
 247                  }
 248                  switch ($options['type']) {
 249                      case 'double':
 250                      case 'int':
 251                      case 'string':
 252                          $this->assertEquals('xsd:' . $options['type'], $part->attributes()->type);
 253                          break;
 254                      case 'array':
 255                          $this->assertEquals('soap-enc:' . ucfirst($options['type']), $part->attributes()->type);
 256                          break;
 257                      default:
 258                          $this->assertEquals('tns:' . $options['type'], $part->attributes()->type);
 259                          break;
 260                  }
 261                  break;
 262              }
 263          }
 264          $messageout = $definitions->message[1];
 265          $this->assertEquals($functionname . wsdl::OUT, $messageout->attributes()->name);
 266          foreach ($messageout->children() as $part) {
 267              foreach ($out as $name => $options) {
 268                  if (strcmp($name, $part->attributes()->name) != 0) {
 269                      continue;
 270                  }
 271                  switch ($options['type']) {
 272                      case 'double':
 273                      case 'int':
 274                      case 'string':
 275                          $this->assertEquals('xsd:' . $options['type'], $part->attributes()->type);
 276                          break;
 277                      case 'array':
 278                          $this->assertEquals('soap-enc:' . ucfirst($options['type']), $part->attributes()->type);
 279                          break;
 280                      default:
 281                          $this->assertEquals('tns:' . $options['type'], $part->attributes()->type);
 282                          break;
 283                  }
 284                  break;
 285              }
 286          }
 287      }
 288  
 289      /**
 290       * Test output WSDL when registering a web service function with no input parameters.
 291       */
 292      public function test_register_without_input() {
 293          $this->resetAfterTest();
 294  
 295          $serviceclass = 'testserviceclass';
 296          $namespace = 'testnamespace';
 297          $wsdl = new wsdl($serviceclass, $namespace);
 298  
 299          $functionname = 'testfunction';
 300          $documentation = 'This is a test function';
 301  
 302          $out = array(
 303              'return' => array(
 304                  'type' => 'teststruct2'
 305              )
 306          );
 307          $wsdl->register($functionname, null, $out, $documentation);
 308  
 309          $definitions = new \SimpleXMLElement($wsdl->to_xml());
 310  
 311          // Test portType operation node.
 312          $porttypeoperation = $definitions->portType->operation;
 313          $this->assertEquals($documentation, $porttypeoperation->documentation);
 314          $this->assertFalse(isset($porttypeoperation->input));
 315          $this->assertTrue(isset($porttypeoperation->output));
 316  
 317          // Test binding operation nodes.
 318          $bindingoperation = $definitions->binding->operation;
 319          // Confirm that there is no input node.
 320          $this->assertFalse(isset($bindingoperation->input));
 321          $this->assertTrue(isset($bindingoperation->output));
 322  
 323          // Test messages.
 324          // Assert there's only the output message node.
 325          $this->assertEquals(1, count($definitions->message));
 326          $messageout = $definitions->message[0];
 327          $this->assertEquals($functionname . wsdl::OUT, $messageout->attributes()->name);
 328  
 329      }
 330  
 331      /**
 332       * Test output WSDL when registering a web service function with no output parameters.
 333       */
 334      public function test_register_without_output() {
 335          $this->resetAfterTest();
 336  
 337          $serviceclass = 'testserviceclass';
 338          $namespace = 'testnamespace';
 339          $wsdl = new wsdl($serviceclass, $namespace);
 340  
 341          $functionname = 'testfunction';
 342          $documentation = 'This is a test function';
 343  
 344          $in = array(
 345              'return' => array(
 346                  'type' => 'teststruct2'
 347              )
 348          );
 349          $wsdl->register($functionname, $in, null, $documentation);
 350  
 351          $definitions = new \SimpleXMLElement($wsdl->to_xml());
 352  
 353          // Test portType operation node.
 354          $porttypeoperation = $definitions->portType->operation;
 355          $this->assertEquals($documentation, $porttypeoperation->documentation);
 356          $this->assertTrue(isset($porttypeoperation->input));
 357          $this->assertFalse(isset($porttypeoperation->output));
 358  
 359          // Test binding operation nodes.
 360          $bindingoperation = $definitions->binding->operation;
 361          // Confirm that there is no input node.
 362          $this->assertTrue(isset($bindingoperation->input));
 363          $this->assertFalse(isset($bindingoperation->output));
 364  
 365          // Test messages.
 366          // Assert there's only the output message node.
 367          $this->assertEquals(1, count($definitions->message));
 368          $messagein = $definitions->message[0];
 369          $this->assertEquals($functionname . wsdl::IN, $messagein->attributes()->name);
 370  
 371      }
 372  }