Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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   * Tests for step.
  19   *
  20   * @package    tool_usertours
  21   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->libdir . '/formslib.php');
  29  
  30  /**
  31   * Tests for step.
  32   *
  33   * @package    tool_usertours
  34   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class step_testcase extends advanced_testcase {
  38  
  39      /**
  40       * @var moodle_database
  41       */
  42      protected $db;
  43  
  44      /**
  45       * Setup to store the DB reference.
  46       */
  47      public function setUp(): void {
  48          global $DB;
  49  
  50          $this->db = $DB;
  51      }
  52  
  53      /**
  54       * Tear down to restore the original DB reference.
  55       */
  56      public function tearDown(): void {
  57          global $DB;
  58  
  59          $DB = $this->db;
  60      }
  61  
  62      /**
  63       * Helper to mock the database.
  64       *
  65       * @return moodle_database
  66       */
  67      public function mock_database() {
  68          global $DB;
  69  
  70          $DB = $this->getMockBuilder('moodle_database')
  71              ->getMock()
  72              ;
  73  
  74          return $DB;
  75      }
  76  
  77      /**
  78       * Data provider for the dirty value tester.
  79       *
  80       * @return array
  81       */
  82      public function dirty_value_provider() {
  83          return [
  84                  'tourid' => [
  85                          'tourid',
  86                          [1],
  87                      ],
  88                  'title' => [
  89                          'title',
  90                          ['Lorem'],
  91                      ],
  92                  'content' => [
  93                          'content',
  94                          ['Lorem'],
  95                      ],
  96                  'targettype' => [
  97                          'targettype',
  98                          ['Lorem'],
  99                      ],
 100                  'targetvalue' => [
 101                          'targetvalue',
 102                          ['Lorem'],
 103                      ],
 104                  'sortorder' => [
 105                          'sortorder',
 106                          [1],
 107                      ],
 108                  'config' => [
 109                          'config',
 110                          ['key', 'value'],
 111                      ],
 112              ];
 113      }
 114  
 115      /**
 116       * Test the fetch function.
 117       */
 118      public function test_fetch() {
 119          $step = $this->getMockBuilder(\tool_usertours\step::class)
 120              ->setMethods(['reload_from_record'])
 121              ->getMock()
 122              ;
 123  
 124          $idretval = rand(1, 100);
 125          $DB = $this->mock_database();
 126          $DB->method('get_record')
 127              ->willReturn($idretval)
 128              ;
 129  
 130          $retval = rand(1, 100);
 131          $step->expects($this->once())
 132              ->method('reload_from_record')
 133              ->with($this->equalTo($idretval))
 134              ->wilLReturn($retval)
 135              ;
 136  
 137          $rc = new \ReflectionClass(\tool_usertours\step::class);
 138          $rcm = $rc->getMethod('fetch');
 139          $rcm->setAccessible(true);
 140  
 141          $id = rand(1, 100);
 142          $this->assertEquals($retval, $rcm->invoke($step, 'fetch', $id));
 143      }
 144  
 145      /**
 146       * Test that setters mark things as dirty.
 147       *
 148       * @dataProvider dirty_value_provider
 149       * @param   string  $name       The key to update
 150       * @param   string  $value      The value to set
 151       */
 152      public function test_dirty_values($name, $value) {
 153          $step = new \tool_usertours\step();
 154          $method = 'set_' . $name;
 155          call_user_func_array([$step, $method], $value);
 156  
 157          $rc = new \ReflectionClass(\tool_usertours\step::class);
 158          $rcp = $rc->getProperty('dirty');
 159          $rcp->setAccessible(true);
 160  
 161          $this->assertTrue($rcp->getValue($step));
 162      }
 163  
 164      /**
 165       * Provider for is_first_step.
 166       *
 167       * @return array
 168       */
 169      public function step_sortorder_provider() {
 170          return [
 171                  [0, 5, true, false],
 172                  [1, 5, false, false],
 173                  [4, 5, false, true],
 174              ];
 175      }
 176  
 177      /**
 178       * Test is_first_step.
 179       *
 180       * @dataProvider step_sortorder_provider
 181       * @param   int     $sortorder      The sortorder to check
 182       * @param   int     $count          Unused in this function
 183       * @param   bool    $isfirst        Whether this is the first step
 184       * @param   bool    $islast         Whether this is the last step
 185       */
 186      public function test_is_first_step($sortorder, $count, $isfirst, $islast) {
 187          $step = $this->getMockBuilder(\tool_usertours\step::class)
 188              ->setMethods(['get_sortorder'])
 189              ->getMock();
 190  
 191          $step->expects($this->once())
 192              ->method('get_sortorder')
 193              ->willReturn($sortorder)
 194              ;
 195  
 196          $this->assertEquals($isfirst, $step->is_first_step());
 197      }
 198  
 199      /**
 200       * Test is_last_step.
 201       *
 202       * @dataProvider step_sortorder_provider
 203       * @param   int     $sortorder      The sortorder to check
 204       * @param   int     $count          Total number of steps for this test
 205       * @param   bool    $isfirst        Whether this is the first step
 206       * @param   bool    $islast         Whether this is the last step
 207       */
 208      public function test_is_last_step($sortorder, $count, $isfirst, $islast) {
 209          $step = $this->getMockBuilder(\tool_usertours\step::class)
 210              ->setMethods(['get_sortorder', 'get_tour'])
 211              ->getMock();
 212  
 213          $tour = $this->getMockBuilder(\tool_usertours\tour::class)
 214              ->setMethods(['count_steps'])
 215              ->getMock();
 216  
 217          $step->expects($this->once())
 218              ->method('get_tour')
 219              ->willReturn($tour)
 220              ;
 221  
 222          $tour->expects($this->once())
 223              ->method('count_steps')
 224              ->willReturn($count)
 225              ;
 226  
 227          $step->expects($this->once())
 228              ->method('get_sortorder')
 229              ->willReturn($sortorder)
 230              ;
 231  
 232          $this->assertEquals($islast, $step->is_last_step());
 233      }
 234  
 235      /**
 236       * Test get_config with no keys provided.
 237       */
 238      public function test_get_config_no_keys() {
 239          $step = new \tool_usertours\step();
 240  
 241          $rc = new \ReflectionClass(\tool_usertours\step::class);
 242          $rcp = $rc->getProperty('config');
 243          $rcp->setAccessible(true);
 244  
 245          $allvalues = (object) [
 246                  'some' => 'value',
 247                  'another' => 42,
 248                  'key' => [
 249                      'somethingelse',
 250                  ],
 251              ];
 252  
 253          $rcp->setValue($step, $allvalues);
 254  
 255          $this->assertEquals($allvalues, $step->get_config());
 256      }
 257  
 258      /**
 259       * Data provider for get_config.
 260       *
 261       * @return array
 262       */
 263      public function get_config_provider() {
 264          $allvalues = (object) [
 265                  'some' => 'value',
 266                  'another' => 42,
 267                  'key' => [
 268                      'somethingelse',
 269                  ],
 270              ];
 271  
 272          $tourconfig = rand(1, 100);
 273          $forcedconfig = rand(1, 100);
 274  
 275          return [
 276                  'No initial config' => [
 277                          null,
 278                          null,
 279                          null,
 280                          $tourconfig,
 281                          false,
 282                          $forcedconfig,
 283                          (object) [],
 284                      ],
 285                  'All values' => [
 286                          $allvalues,
 287                          null,
 288                          null,
 289                          $tourconfig,
 290                          false,
 291                          $forcedconfig,
 292                          $allvalues,
 293                      ],
 294                  'Valid string value' => [
 295                          $allvalues,
 296                          'some',
 297                          null,
 298                          $tourconfig,
 299                          false,
 300                          $forcedconfig,
 301                          'value',
 302                      ],
 303                  'Valid array value' => [
 304                          $allvalues,
 305                          'key',
 306                          null,
 307                          $tourconfig,
 308                          false,
 309                          $forcedconfig,
 310                          ['somethingelse'],
 311                      ],
 312                  'Invalid value' => [
 313                          $allvalues,
 314                          'notavalue',
 315                          null,
 316                          $tourconfig,
 317                          false,
 318                          $forcedconfig,
 319                          $tourconfig,
 320                      ],
 321                  'Configuration value' => [
 322                          $allvalues,
 323                          'placement',
 324                          null,
 325                          $tourconfig,
 326                          false,
 327                          $forcedconfig,
 328                          $tourconfig,
 329                      ],
 330                  'Invalid value with default' => [
 331                          $allvalues,
 332                          'notavalue',
 333                          'somedefault',
 334                          $tourconfig,
 335                          false,
 336                          $forcedconfig,
 337                          'somedefault',
 338                      ],
 339                  'Value forced at target' => [
 340                          $allvalues,
 341                          'somevalue',
 342                          'somedefault',
 343                          $tourconfig,
 344                          true,
 345                          $forcedconfig,
 346                          $forcedconfig,
 347                      ],
 348              ];
 349      }
 350  
 351      /**
 352       * Test get_config with valid keys provided.
 353       *
 354       * @dataProvider get_config_provider
 355       * @param   object  $values     The config values
 356       * @param   string  $key        The key
 357       * @param   mixed   $default    The default value
 358       * @param   mixed   $tourconfig The tour config
 359       * @param   bool    $isforced   Whether the setting is forced
 360       * @param   mixed   $forcedvalue    The example value
 361       * @param   mixed   $expected   The expected value
 362       */
 363      public function test_get_config_valid_keys($values, $key, $default, $tourconfig, $isforced, $forcedvalue, $expected) {
 364          $step = $this->getMockBuilder(\tool_usertours\step::class)
 365              ->setMethods(['get_target', 'get_targettype', 'get_tour'])
 366              ->getMock();
 367  
 368          $rc = new \ReflectionClass(\tool_usertours\step::class);
 369          $rcp = $rc->getProperty('config');
 370          $rcp->setAccessible(true);
 371          $rcp->setValue($step, $values);
 372  
 373          $target = $this->getMockBuilder(\tool_usertours\local\target\base::class)
 374              ->disableOriginalConstructor()
 375              ->getMock()
 376              ;
 377  
 378          $target->expects($this->any())
 379              ->method('is_setting_forced')
 380              ->willReturn($isforced)
 381              ;
 382  
 383          $target->expects($this->any())
 384              ->method('get_forced_setting_value')
 385              ->with($this->equalTo($key))
 386              ->willReturn($forcedvalue)
 387              ;
 388  
 389          $step->expects($this->any())
 390              ->method('get_targettype')
 391              ->willReturn('type')
 392              ;
 393  
 394          $step->expects($this->any())
 395              ->method('get_target')
 396              ->willReturn($target)
 397              ;
 398  
 399          $tour = $this->getMockBuilder(\tool_usertours\tour::class)
 400              ->getMock()
 401              ;
 402  
 403          $tour->expects($this->any())
 404              ->method('get_config')
 405              ->willReturn($tourconfig)
 406              ;
 407  
 408          $step->expects($this->any())
 409              ->method('get_tour')
 410              ->willReturn($tour)
 411              ;
 412  
 413          $this->assertEquals($expected, $step->get_config($key, $default));
 414      }
 415  
 416      /**
 417       * Data provider for set_config.
 418       */
 419      public function set_config_provider() {
 420          $allvalues = (object) [
 421                  'some' => 'value',
 422                  'another' => 42,
 423                  'key' => [
 424                      'somethingelse',
 425                  ],
 426              ];
 427  
 428          $randvalue = rand(1, 100);
 429  
 430          $provider = [];
 431  
 432          $newvalues = $allvalues;
 433          $newvalues->some = 'unset';
 434          $provider['Unset an existing value'] = [
 435                  $allvalues,
 436                  'some',
 437                  null,
 438                  $newvalues,
 439              ];
 440  
 441          $newvalues = $allvalues;
 442          $newvalues->some = $randvalue;
 443          $provider['Set an existing value'] = [
 444                  $allvalues,
 445                  'some',
 446                  $randvalue,
 447                  $newvalues,
 448              ];
 449  
 450          $provider['Set a new value'] = [
 451                  $allvalues,
 452                  'newkey',
 453                  $randvalue,
 454                  (object) array_merge((array) $allvalues, ['newkey' => $randvalue]),
 455              ];
 456  
 457          return $provider;
 458      }
 459  
 460      /**
 461       * Test that set_config works in the anticipated fashion.
 462       *
 463       * @dataProvider set_config_provider
 464       * @param   mixed   $initialvalues  The inital value to set
 465       * @param   string  $key        The key to test
 466       * @param   mixed   $newvalue   The new value to set
 467       * @param   mixed   $expected   The expected value
 468       */
 469      public function test_set_config($initialvalues, $key, $newvalue, $expected) {
 470          $step = new \tool_usertours\step();
 471  
 472          $rc = new \ReflectionClass(\tool_usertours\step::class);
 473          $rcp = $rc->getProperty('config');
 474          $rcp->setAccessible(true);
 475          $rcp->setValue($step, $initialvalues);
 476  
 477          $target = $this->getMockBuilder(\tool_usertours\local\target\base::class)
 478              ->disableOriginalConstructor()
 479              ->getMock()
 480              ;
 481  
 482          $target->expects($this->any())
 483              ->method('is_setting_forced')
 484              ->willReturn(false)
 485              ;
 486  
 487          $step->set_config($key, $newvalue);
 488  
 489          $this->assertEquals($expected, $rcp->getValue($step));
 490      }
 491  
 492      /**
 493       * Ensure that non-dirty tours are not persisted.
 494       */
 495      public function test_persist_non_dirty() {
 496          $step = $this->getMockBuilder(\tool_usertours\step::class)
 497              ->setMethods([
 498                      'to_record',
 499                      'reload',
 500                  ])
 501              ->getMock()
 502              ;
 503  
 504          $step->expects($this->never())
 505              ->method('to_record')
 506              ;
 507  
 508          $step->expects($this->never())
 509              ->method('reload')
 510              ;
 511  
 512          $this->assertSame($step, $step->persist());
 513      }
 514  
 515      /**
 516       * Ensure that new dirty steps are persisted.
 517       */
 518      public function test_persist_dirty_new() {
 519          // Mock the database.
 520          $DB = $this->mock_database();
 521          $DB->expects($this->once())
 522              ->method('insert_record')
 523              ->willReturn(42)
 524              ;
 525  
 526          // Mock the tour.
 527          $step = $this->getMockBuilder(\tool_usertours\step::class)
 528              ->setMethods([
 529                      'to_record',
 530                      'calculate_sortorder',
 531                      'reload',
 532                  ])
 533              ->getMock()
 534              ;
 535  
 536          $step->expects($this->once())
 537              ->method('to_record')
 538              ->willReturn((object)['id' => 42]);
 539              ;
 540  
 541          $step->expects($this->once())
 542              ->method('calculate_sortorder')
 543              ;
 544  
 545          $step->expects($this->once())
 546              ->method('reload')
 547              ;
 548  
 549          $rc = new \ReflectionClass(\tool_usertours\step::class);
 550          $rcp = $rc->getProperty('dirty');
 551          $rcp->setAccessible(true);
 552          $rcp->setValue($step, true);
 553  
 554          $tour = $this->createMock(\tool_usertours\tour::class);
 555          $rcp = $rc->getProperty('tour');
 556          $rcp->setAccessible(true);
 557          $rcp->setValue($step, $tour);
 558  
 559          $this->assertSame($step, $step->persist());
 560      }
 561  
 562      /**
 563       * Ensure that new non-dirty, forced steps are persisted.
 564       */
 565      public function test_persist_force_new() {
 566          global $DB;
 567  
 568          // Mock the database.
 569          $DB = $this->mock_database();
 570          $DB->expects($this->once())
 571              ->method('insert_record')
 572              ->willReturn(42)
 573              ;
 574  
 575          // Mock the tour.
 576          $step = $this->getMockBuilder(\tool_usertours\step::class)
 577              ->setMethods([
 578                      'to_record',
 579                      'calculate_sortorder',
 580                      'reload',
 581                  ])
 582              ->getMock()
 583              ;
 584  
 585          $step->expects($this->once())
 586              ->method('to_record')
 587              ->willReturn((object)['id' => 42]);
 588              ;
 589  
 590          $step->expects($this->once())
 591              ->method('calculate_sortorder')
 592              ;
 593  
 594          $step->expects($this->once())
 595              ->method('reload')
 596              ;
 597  
 598          $tour = $this->createMock(\tool_usertours\tour::class);
 599          $rc = new \ReflectionClass(\tool_usertours\step::class);
 600          $rcp = $rc->getProperty('tour');
 601          $rcp->setAccessible(true);
 602          $rcp->setValue($step, $tour);
 603  
 604          $this->assertSame($step, $step->persist(true));
 605      }
 606  
 607      /**
 608       * Ensure that existing dirty steps are persisted.
 609       */
 610      public function test_persist_dirty_existing() {
 611          // Mock the database.
 612          $DB = $this->mock_database();
 613          $DB->expects($this->once())
 614              ->method('update_record')
 615              ;
 616  
 617          // Mock the tour.
 618          $step = $this->getMockBuilder(\tool_usertours\step::class)
 619              ->setMethods([
 620                      'to_record',
 621                      'calculate_sortorder',
 622                      'reload',
 623                  ])
 624              ->getMock()
 625              ;
 626  
 627          $step->expects($this->once())
 628              ->method('to_record')
 629              ->willReturn((object)['id' => 42]);
 630              ;
 631  
 632          $step->expects($this->never())
 633              ->method('calculate_sortorder')
 634              ;
 635  
 636          $step->expects($this->once())
 637              ->method('reload')
 638              ;
 639  
 640          $rc = new \ReflectionClass(\tool_usertours\step::class);
 641          $rcp = $rc->getProperty('id');
 642          $rcp->setAccessible(true);
 643          $rcp->setValue($step, 42);
 644  
 645          $rcp = $rc->getProperty('dirty');
 646          $rcp->setAccessible(true);
 647          $rcp->setValue($step, true);
 648  
 649          $tour = $this->createMock(\tool_usertours\tour::class);
 650          $rcp = $rc->getProperty('tour');
 651          $rcp->setAccessible(true);
 652          $rcp->setValue($step, $tour);
 653  
 654          $this->assertSame($step, $step->persist());
 655      }
 656  
 657      /**
 658       * Ensure that existing non-dirty, forced steps are persisted.
 659       */
 660      public function test_persist_force_existing() {
 661          global $DB;
 662  
 663          // Mock the database.
 664          $DB = $this->mock_database();
 665          $DB->expects($this->once())
 666              ->method('update_record')
 667              ;
 668  
 669          // Mock the tour.
 670          $step = $this->getMockBuilder(\tool_usertours\step::class)
 671              ->setMethods([
 672                      'to_record',
 673                      'calculate_sortorder',
 674                      'reload',
 675                  ])
 676              ->getMock()
 677              ;
 678  
 679          $step->expects($this->once())
 680              ->method('to_record')
 681              ->willReturn((object)['id' => 42]);
 682              ;
 683  
 684          $step->expects($this->never())
 685              ->method('calculate_sortorder')
 686              ;
 687  
 688          $step->expects($this->once())
 689              ->method('reload')
 690              ;
 691  
 692          $rc = new \ReflectionClass(\tool_usertours\step::class);
 693          $rcp = $rc->getProperty('id');
 694          $rcp->setAccessible(true);
 695          $rcp->setValue($step, 42);
 696  
 697          $tour = $this->createMock(\tool_usertours\tour::class);
 698          $rcp = $rc->getProperty('tour');
 699          $rcp->setAccessible(true);
 700          $rcp->setValue($step, $tour);
 701  
 702          $this->assertSame($step, $step->persist(true));
 703      }
 704  
 705      /**
 706       * Check that a tour which has never been persisted is removed correctly.
 707       */
 708      public function test_remove_non_persisted() {
 709          $step = $this->getMockBuilder(\tool_usertours\step::class)
 710              ->setMethods(null)
 711              ->getMock()
 712              ;
 713  
 714          // Mock the database.
 715          $DB = $this->mock_database();
 716          $DB->expects($this->never())
 717              ->method('delete_records')
 718              ;
 719  
 720          $this->assertNull($step->remove());
 721      }
 722  
 723      /**
 724       * Check that a tour which has been persisted is removed correctly.
 725       */
 726      public function test_remove_persisted() {
 727          $id = rand(1, 100);
 728  
 729          $tour = $this->getMockBuilder(\tool_usertours\tour::class)
 730              ->setMethods([
 731                      'reset_step_sortorder',
 732                  ])
 733              ->getMock()
 734              ;
 735  
 736          $tour->expects($this->once())
 737              ->method('reset_step_sortorder')
 738              ;
 739  
 740          $step = $this->getMockBuilder(\tool_usertours\step::class)
 741              ->setMethods([
 742                      'get_tour',
 743                  ])
 744              ->getMock()
 745              ;
 746  
 747          $step->expects($this->once())
 748              ->method('get_tour')
 749              ->willReturn($tour)
 750              ;
 751  
 752          // Mock the database.
 753          $DB = $this->mock_database();
 754          $DB->expects($this->once())
 755              ->method('delete_records')
 756              ->with($this->equalTo('tool_usertours_steps'), $this->equalTo(['id' => $id]))
 757              ;
 758  
 759          $rc = new \ReflectionClass(\tool_usertours\step::class);
 760          $rcp = $rc->getProperty('id');
 761          $rcp->setAccessible(true);
 762          $rcp->setValue($step, $id);
 763  
 764          $this->assertEquals($id, $step->get_id());
 765          $this->assertNull($step->remove());
 766      }
 767  
 768      /**
 769       * Data provider for the get_ tests.
 770       *
 771       * @return array
 772       */
 773      public function getter_provider() {
 774          return [
 775                  'id' => [
 776                          'id',
 777                          rand(1, 100),
 778                      ],
 779                  'tourid' => [
 780                          'tourid',
 781                          rand(1, 100),
 782                      ],
 783                  'title' => [
 784                          'title',
 785                          'Lorem',
 786                      ],
 787                  'content' => [
 788                          'content',
 789                          'Lorem',
 790                      ],
 791                  'targettype' => [
 792                          'targettype',
 793                          'Lorem',
 794                      ],
 795                  'targetvalue' => [
 796                          'targetvalue',
 797                          'Lorem',
 798                      ],
 799                  'sortorder' => [
 800                          'sortorder',
 801                          rand(1, 100),
 802                      ],
 803              ];
 804      }
 805  
 806      /**
 807       * Test that getters return the configured value.
 808       *
 809       * @dataProvider getter_provider
 810       * @param   string  $key        The key to test
 811       * @param   mixed   $value      The expected value
 812       */
 813      public function test_getters($key, $value) {
 814          $step = new \tool_usertours\step();
 815  
 816          $rc = new \ReflectionClass(\tool_usertours\step::class);
 817  
 818          $rcp = $rc->getProperty($key);
 819          $rcp->setAccessible(true);
 820          $rcp->setValue($step, $value);
 821  
 822          $getter = 'get_' . $key;
 823  
 824          $this->assertEquals($value, $step->$getter());
 825      }
 826  
 827      /**
 828       * Data Provider for get_string_from_input.
 829       *
 830       * @return array
 831       */
 832      public function get_string_from_input_provider() {
 833          return [
 834              'Text'  => [
 835                  'example',
 836                  'example',
 837              ],
 838              'Text which looks like a langstring' => [
 839                  'example,fakecomponent',
 840                  'example,fakecomponent',
 841              ],
 842              'Text which is a langstring' => [
 843                  'administration,core',
 844                  'Administration',
 845              ],
 846              'Text which is a langstring but uses "moodle" instead of "core"' => [
 847                  'administration,moodle',
 848                  'Administration',
 849              ],
 850              'Text which is a langstring, but with extra whitespace' => [
 851                  '  administration,moodle  ',
 852                  'Administration',
 853              ],
 854              'Looks like a langstring, but has incorrect space around comma' => [
 855                  'administration , moodle',
 856                  'administration , moodle',
 857              ],
 858          ];
 859      }
 860  
 861      /**
 862       * Ensure that the get_string_from_input function returns langstring strings correctly.
 863       *
 864       * @dataProvider get_string_from_input_provider
 865       * @param   string  $string     The string to test
 866       * @param   string  $expected   The expected result
 867       */
 868      public function test_get_string_from_input($string, $expected) {
 869          $this->assertEquals($expected, \tool_usertours\step::get_string_from_input($string));
 870      }
 871  }