Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 39 and 403]

   1  <?php
   2  // phpcs:ignoreFile
   3  // @codeCoverageIgnoreStart
   4  
   5  // This file is part of Moodle - http://moodle.org/
   6  //
   7  // Moodle is free software: you can redistribute it and/or modify
   8  // it under the terms of the GNU General Public License as published by
   9  // the Free Software Foundation, either version 3 of the License, or
  10  // (at your option) any later version.
  11  //
  12  // Moodle is distributed in the hope that it will be useful,
  13  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  // GNU General Public License for more details.
  16  //
  17  // You should have received a copy of the GNU General Public License
  18  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  19  
  20  /**
  21   * Unit tests for behat manager.
  22   *
  23   * @package   tool_behat
  24   * @copyright  2016 Rajesh Taneja
  25   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  global $CFG;
  31  require_once($CFG->dirroot . '/' . $CFG->admin .'/tool/behat/locallib.php');
  32  require_once($CFG->libdir . '/behat/classes/util.php');
  33  require_once($CFG->libdir . '/behat/classes/behat_config_manager.php');
  34  
  35  /**
  36   * Behat manager tests.
  37   *
  38   * @package    tool_behat
  39   * @copyright  2016 Rajesh Taneja
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class tool_behat_manager_util_testcase extends advanced_testcase {
  43  
  44      /** @var array Fixtures features which are available. */
  45      private $featurepaths = array(
  46          'default' => array(
  47              'test_1.feature',
  48              'test_2.feature',
  49          ),
  50          'withfeatures' => array(
  51              'theme_test_1.feature',
  52              'theme_test_2.feature',
  53              'theme_test_3.feature',
  54              'theme_test_4.feature',
  55              'theme_test_5.feature',
  56          ),
  57          'nofeatures' => array()
  58      );
  59  
  60      /** @var array Fixture contexts which are available */
  61      private $contextspath = array(
  62          'default' => array(
  63              'behat_test_context_1',
  64              'behat_test_context_2',
  65              'behat_theme_defaulttheme_test_context_1'
  66          ),
  67          'withfeatures' => array(
  68              'behat_test_context_2',
  69              'behat_theme_withfeatures_test_context_2',
  70              'behat_theme_withfeatures_behat_test_context_1'
  71          ),
  72          'nofeatures' => array(
  73              'behat_test_context_1',
  74              'behat_theme_nofeatures_test_context_1',
  75              'behat_theme_nofeatures_behat_test_context_2'
  76          ),
  77      );
  78  
  79      /** @var array List of core features. */
  80      private $corefeatures = array('test_1_core_fixtures_tests_behat_tool' => __DIR__.'/fixtures/core/test_1.feature',
  81                                   'test_2_core_fixtures_tests_behat_tool' => __DIR__.'/fixtures/core/test_2.feature');
  82  
  83      /** @var array List of core contexts. */
  84      private $corecontexts = array('behat_test_context_1' => __DIR__.'/fixtures/core/behat_test_context_1.php',
  85                                    'behat_test_context_2' => __DIR__.'/fixtures/core/behat_test_context_2.php');
  86  
  87      /**
  88       * Setup test.
  89       */
  90      public function setUp(): void {
  91          global $CFG;
  92  
  93          $this->resetAfterTest();
  94          $CFG->behat_wwwroot = 'http://example.com/behat';
  95      }
  96  
  97      /**
  98       * Utility function to build mock object.
  99       *
 100       * @param  behat_config_util $behatconfigutil
 101       * @param bool $notheme
 102       * @return mixed
 103       */
 104      private function get_behat_config_util($behatconfigutil, $notheme = false) {
 105          // Create a map of arguments to return values.
 106          $map = array(
 107              array('withfeatures', __DIR__.'/fixtures/theme/withfeatures'),
 108              array('nofeatures', __DIR__.'/fixtures/theme/nofeatures'),
 109              array('defaulttheme', __DIR__.'/fixtures/theme/defaulttheme'),
 110          );
 111          // List of themes is const for test.
 112          if ($notheme) {
 113              $themelist = array('defaulttheme');
 114          } else {
 115              $themelist = array('withfeatures', 'nofeatures', 'defaulttheme');
 116          }
 117  
 118          $thememap = [];
 119          foreach ($themelist as $themename) {
 120              $mock = $this->getMockBuilder('theme_config');
 121              $mock->disableOriginalConstructor();
 122              $thememap[] = [$themename, $mock->getMock()];
 123          }
 124  
 125          $behatconfigutil->expects($this->any())
 126              ->method('get_list_of_themes')
 127              ->will($this->returnValue($themelist));
 128  
 129          // Theme directory for testing.
 130          $behatconfigutil->expects($this->any())
 131              ->method('get_theme_test_directory')
 132              ->will($this->returnValueMap($map));
 133  
 134          // Theme directory for testing.
 135          $behatconfigutil->expects($this->any())
 136                  ->method('get_theme_config')
 137                  ->will($this->returnValueMap($thememap));
 138  
 139          $behatconfigutil->expects($this->any())
 140              ->method('get_default_theme')
 141              ->will($this->returnValue('defaulttheme'));
 142  
 143          return $behatconfigutil;
 144      }
 145  
 146      /**
 147       * Behat config for single run.
 148       */
 149      public function test_get_config_file_contents_with_single_run() {
 150  
 151          $mockbuilder = $this->getMockBuilder('behat_config_util');
 152          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_default_theme', 'get_theme_config'));
 153  
 154          $behatconfigutil = $mockbuilder->getMock();
 155  
 156          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 157          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 158  
 159          // Two suites should be present.
 160          $suites = $config['default']['suites'];
 161          $this->assertCount(3, $suites);
 162  
 163          // Check features.
 164          foreach ($this->featurepaths as $themename => $paths) {
 165              $this->assertCount(count($paths), $suites[$themename]['paths']);
 166  
 167              foreach ($paths as $key => $feature) {
 168                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 169              }
 170          }
 171  
 172          // Check contexts.
 173          foreach ($this->contextspath as $themename => $paths) {
 174              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 175  
 176              foreach ($paths as $key => $context) {
 177                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 178              }
 179          }
 180  
 181          // There are 7 step definitions.
 182          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 183      }
 184  
 185      /**
 186       * Behat config for single run with no theme installed.
 187       */
 188      public function test_get_config_file_contents_with_single_run_no_theme() {
 189  
 190          $mockbuilder = $this->getMockBuilder('behat_config_util');
 191          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_default_theme', 'get_theme_config'));
 192  
 193          $behatconfigutil = $mockbuilder->getMock();
 194  
 195          $behatconfigutil = $this->get_behat_config_util($behatconfigutil, true);
 196          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 197  
 198          // Two suites should be present.
 199          $suites = $config['default']['suites'];
 200          $this->assertCount(1, $suites);
 201  
 202          $featurepaths = array(
 203              'default' => array(
 204                  'test_1.feature',
 205                  'test_2.feature',
 206              )
 207          );
 208  
 209          $contextspath = array(
 210              'default' => array(
 211                  'behat_test_context_1',
 212                  'behat_test_context_2',
 213                  'behat_theme_defaulttheme_test_context_1',
 214              )
 215          );
 216  
 217          // Check features.
 218          foreach ($featurepaths as $themename => $paths) {
 219              $this->assertCount(count($paths), $suites[$themename]['paths']);
 220  
 221              foreach ($paths as $key => $feature) {
 222                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 223              }
 224          }
 225  
 226          // Check contexts.
 227          foreach ($contextspath as $themename => $paths) {
 228              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 229  
 230              foreach ($paths as $key => $context) {
 231                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 232              }
 233          }
 234  
 235          // There are 3 step definitions.
 236          $this->assertCount(3, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 237      }
 238  
 239      /**
 240       * Behat config for parallel run.
 241       */
 242      public function test_get_config_file_contents_with_parallel_run() {
 243  
 244          $mockbuilder = $this->getMockBuilder('behat_config_util');
 245          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_default_theme', 'get_theme_config'));
 246  
 247          $behatconfigutil = $mockbuilder->getMock();
 248  
 249          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 250  
 251          // Test first run out of 3.
 252          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts, '', 3, 1);
 253          // Three suites should be present.
 254          $suites = $config['default']['suites'];
 255          $this->assertCount(3, $suites);
 256          // There is first feature file in first run.
 257          $featurepaths = array(
 258              'default' => array('test_1.feature'),
 259              'withfeatures' => array('theme_test_1.feature', 'theme_test_2.feature'),
 260              'nofeatures' => array()
 261          );
 262          // Check features.
 263          foreach ($featurepaths as $themename => $paths) {
 264              $this->assertCount(count($paths), $suites[$themename]['paths']);
 265  
 266              foreach ($paths as $key => $feature) {
 267                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 268              }
 269          }
 270  
 271          // Check contexts.
 272          foreach ($this->contextspath as $themename => $paths) {
 273              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 274  
 275              foreach ($paths as $key => $context) {
 276                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 277              }
 278          }
 279          // There are 7 step definitions.
 280          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 281  
 282          // Test second run out of 3.
 283          $config = $behatconfigutil->get_config_file_contents('', '', '', 3, 2);
 284          // Three suites should be present.
 285          $suites = $config['default']['suites'];
 286          $this->assertCount(3, $suites);
 287          // There is second feature file in first run.
 288          $featurepaths = array(
 289              'default' => array('test_2.feature'),
 290              'withfeatures' => array('theme_test_3.feature', 'theme_test_4.feature'),
 291              'nofeatures' => array()
 292          );
 293          // Check features.
 294          foreach ($featurepaths as $themename => $paths) {
 295              $this->assertCount(count($paths), $suites[$themename]['paths']);
 296  
 297              foreach ($paths as $key => $feature) {
 298                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 299              }
 300          }
 301          // Check contexts.
 302          foreach ($this->contextspath as $themename => $paths) {
 303              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 304  
 305              foreach ($paths as $key => $context) {
 306                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 307              }
 308          }
 309          // There are 7 step definitions.
 310          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 311  
 312          // Test third run out of 3.
 313          $config = $behatconfigutil->get_config_file_contents('', '', '', 3, 3);
 314          $suites = $config['default']['suites'];
 315          $this->assertCount(3, $suites);
 316          // There is second feature file in first run.
 317          $featurepaths = array(
 318              'default' => array(),
 319              'withfeatures' => array('theme_test_5.feature'),
 320              'nofeatures' => array()
 321          );
 322          // Check features.
 323          foreach ($featurepaths as $themename => $paths) {
 324              $this->assertCount(count($paths), $suites[$themename]['paths']);
 325  
 326              foreach ($paths as $key => $feature) {
 327                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 328              }
 329          }
 330          // Check contexts.
 331          foreach ($this->contextspath as $themename => $paths) {
 332              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 333  
 334              foreach ($paths as $key => $context) {
 335                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 336              }
 337          }
 338          // There are 7 step definitions.
 339          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 340      }
 341  
 342      /**
 343       * Behat config for parallel run.
 344       */
 345      public function test_get_config_file_contents_with_parallel_run_optimize_tags() {
 346  
 347          $mockbuilder = $this->getMockBuilder('behat_config_util');
 348          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_default_theme', 'get_theme_config'));
 349  
 350          $behatconfigutil = $mockbuilder->getMock();
 351  
 352          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 353  
 354          // Test first run out of 3.
 355          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts, '@commontag', 3, 1);
 356  
 357          // Three suites should be present.
 358          $suites = $config['default']['suites'];
 359          $this->assertCount(3, $suites);
 360          // There is first feature file in first run.
 361          $featurepaths = array(
 362              'default' => array('test_1.feature'),
 363              'withfeatures' => array('theme_test_1.feature', 'theme_test_3.feature'),
 364              'nofeatures' => array()
 365          );
 366          // Check features.
 367          foreach ($featurepaths as $themename => $paths) {
 368              $this->assertCount(count($paths), $suites[$themename]['paths']);
 369  
 370              foreach ($paths as $key => $feature) {
 371                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 372              }
 373          }
 374          // Check contexts.
 375          foreach ($this->contextspath as $themename => $paths) {
 376              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 377  
 378              foreach ($paths as $key => $context) {
 379                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 380              }
 381          }
 382          // There are 7step definitions.
 383          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 384  
 385          // Test second run out of 3.
 386          $config = $behatconfigutil->get_config_file_contents('', '', '@commontag', 3, 2);
 387  
 388          // Three suites should be present.
 389          $suites = $config['default']['suites'];
 390          $this->assertCount(3, $suites);
 391          // There is second feature file in first run.
 392          $featurepaths = array(
 393              'default' => array('test_2.feature'),
 394              'withfeatures' => array('theme_test_2.feature', 'theme_test_4.feature'),
 395              'nofeatures' => array()
 396          );
 397          // Check features.
 398          foreach ($featurepaths as $themename => $paths) {
 399              $this->assertCount(count($paths), $suites[$themename]['paths']);
 400  
 401              foreach ($paths as $key => $feature) {
 402                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 403              }
 404          }
 405          // Check contexts.
 406          foreach ($this->contextspath as $themename => $paths) {
 407              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 408  
 409              foreach ($paths as $key => $context) {
 410                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 411              }
 412          }
 413          // There are 7 step definitions.
 414          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 415  
 416          // Test third run out of 3.
 417          $config = $behatconfigutil->get_config_file_contents('', '', '', 3, 3);
 418          $suites = $config['default']['suites'];
 419          $this->assertCount(3, $suites);
 420          // There is second feature file in first run.
 421          $featurepaths = array(
 422              'default' => array(),
 423              'withfeatures' => array('theme_test_5.feature'),
 424              'nofeatures' => array()
 425          );
 426          // Check features.
 427          foreach ($featurepaths as $themename => $paths) {
 428              $this->assertCount(count($paths), $suites[$themename]['paths']);
 429  
 430              foreach ($paths as $key => $feature) {
 431                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 432              }
 433          }
 434          // Check contexts.
 435          foreach ($this->contextspath as $themename => $paths) {
 436              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 437  
 438              foreach ($paths as $key => $context) {
 439                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 440              }
 441          }
 442          // There are 7 step definitions.
 443          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 444      }
 445  
 446      /**
 447       * Test if clean features key and path is returned.
 448       * @dataProvider clean_features_path_list
 449       */
 450      public function test_get_clean_feature_key_and_path($featurepath, $key, $cleanfeaturepath) {
 451          global $CFG;
 452  
 453          // This is a hack so directory name is correctly detected in tests.
 454          //FIXME: MDL-55722 work out why this is necessary..
 455          $oldroot = $CFG->dirroot;
 456          $CFG->dirroot = 'C:';
 457  
 458          $behatconfigutil = new behat_config_util();
 459  
 460          // Fix expected directory path for OS.
 461          $cleanfeaturepath = testing_cli_fix_directory_separator($cleanfeaturepath);
 462  
 463          list($retkey, $retcleanfeaturepath) = $behatconfigutil->get_clean_feature_key_and_path($featurepath);
 464  
 465          $this->assertEquals($key, $retkey);
 466          $this->assertEquals($cleanfeaturepath, $retcleanfeaturepath);
 467          //FIXME: MDL-55722 work out why this is necessary..
 468          $CFG->dirroot = $oldroot;
 469      }
 470  
 471      public function clean_features_path_list() {
 472          return array(
 473              ['/home/test/this/that/test/behat/mod_assign.feature', 'mod_assign_behat_test_that_this_test', '/home/test/this/that/test/behat/mod_assign.feature'],
 474              ['/home/this/that/test/behat/mod_assign.feature', 'mod_assign_behat_test_that_this_home', '/home/this/that/test/behat/mod_assign.feature'],
 475              ['/home/that/test/behat/mod_assign.feature', 'mod_assign_behat_test_that_home', '/home/that/test/behat/mod_assign.feature'],
 476              ['/home/test/behat/mod_assign.feature', 'mod_assign_behat_test_home', '/home/test/behat/mod_assign.feature'],
 477              ['mod_assign.feature', 'mod_assign', 'mod_assign.feature'],
 478              ['C:\test\this\that\test\behat\mod_assign.feature', 'mod_assign_behat_test_that_this_test', 'C:\test\this\that\test\behat\mod_assign.feature'],
 479              ['C:\this\that\test\behat\mod_assign.feature', 'mod_assign_behat_test_that_this', 'C:\this\that\test\behat\mod_assign.feature'],
 480              ['C:\that\test\behat\mod_assign.feature', 'mod_assign_behat_test_that', 'C:\that\test\behat\mod_assign.feature'],
 481              ['C:\test\behat\mod_assign.feature', 'mod_assign_behat_test', 'C:\test\behat\mod_assign.feature'],
 482              ['C:\mod_assign.feature', 'mod_assign', 'C:\mod_assign.feature'],
 483          );
 484      }
 485  
 486      /**
 487       * Behat config for blacklisted tags.
 488       */
 489      public function test_get_config_file_contents_with_blacklisted_tags() {
 490  
 491          $mockbuilder = $this->getMockBuilder('behat_config_util');
 492          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_blacklisted_tests_for_theme',
 493              'get_default_theme', 'get_theme_config'));
 494  
 495          $behatconfigutil = $mockbuilder->getMock();
 496  
 497          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 498  
 499          // Blacklisted tags.
 500          $map = array(
 501              array('withfeatures', 'tags', array('@test1')),
 502              array('nofeatures', 'tags', array('@test2')),
 503              array('defaulttheme', 'tags', array()),
 504              array('withfeatures', 'features', array()),
 505              array('nofeatures', 'features', array()),
 506              array('defaulttheme', 'features', array()),
 507              array('withfeatures', 'contexts', array()),
 508              array('nofeatures', 'contexts', array()),
 509              array('defaulttheme', 'contexts', array())
 510          );
 511  
 512          $behatconfigutil->expects($this->any())
 513              ->method('get_blacklisted_tests_for_theme')
 514              ->will($this->returnValueMap($map));
 515  
 516          $behatconfigutil->set_theme_suite_to_include_core_features(true);
 517          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 518  
 519          // Three suites should be present.
 520          $suites = $config['default']['suites'];
 521          $this->assertCount(3, $suites);
 522  
 523          $featurepaths = array(
 524              'default' => array('test_1.feature', 'test_2.feature'),
 525              'withfeatures' => array('test_2.feature', 'theme_test_1.feature', 'theme_test_2.feature', 'theme_test_3.feature',
 526                  'theme_test_4.feature', 'theme_test_5.feature'),
 527              'nofeatures' => array('test_1.feature')
 528          );
 529  
 530          // Check features.
 531          foreach ($featurepaths as $themename => $paths) {
 532              $this->assertCount(count($paths), $suites[$themename]['paths']);
 533  
 534              foreach ($paths as $key => $feature) {
 535                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 536              }
 537          }
 538          // Check contexts.
 539          foreach ($this->contextspath as $themename => $paths) {
 540              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 541  
 542              foreach ($paths as $key => $context) {
 543                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 544              }
 545          }
 546          // There are 7 step definitions.
 547          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 548      }
 549  
 550      /**
 551       * Behat config for blacklisted features.
 552       */
 553      public function test_get_config_file_contents_with_blacklisted_features_contexts() {
 554  
 555          $mockbuilder = $this->getMockBuilder('behat_config_util');
 556          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_blacklisted_tests_for_theme',
 557              'get_default_theme', 'get_theme_config'));
 558  
 559          $behatconfigutil = $mockbuilder->getMock();
 560  
 561          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 562  
 563          // Blacklisted features and contexts.
 564          $map = array(
 565              array('withfeatures', 'tags', array()),
 566              array('nofeatures', 'tags', array()),
 567              array('defaulttheme', 'tags', array()),
 568              array('withfeatures', 'features', array('admin/tool/behat/tests/fixtures/core/test_1.feature')),
 569              array('nofeatures', 'features', array('admin/tool/behat/tests/fixtures/core/test_2.feature')),
 570              array('defaulttheme', 'features', array()),
 571              array('withfeatures', 'contexts', array('admin/tool/behat/tests/fixtures/core/behat_test_context_2.php')),
 572              array('nofeatures', 'contexts', array('admin/tool/behat/tests/fixtures/core/behat_test_context_1.php')),
 573              array('defaulttheme', 'contexts', array()),
 574          );
 575  
 576          $behatconfigutil->expects($this->any())
 577              ->method('get_blacklisted_tests_for_theme')
 578              ->will($this->returnValueMap($map));
 579  
 580          $behatconfigutil->set_theme_suite_to_include_core_features(true);
 581          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 582  
 583          // Three suites should be present.
 584          $suites = $config['default']['suites'];
 585          $this->assertCount(3, $suites);
 586  
 587          $featurepaths = array(
 588              'default' => array('test_1.feature', 'test_2.feature'),
 589              'withfeatures' => array('test_2.feature', 'theme_test_1.feature', 'theme_test_2.feature', 'theme_test_3.feature',
 590                  'theme_test_4.feature', 'theme_test_5.feature'),
 591              'nofeatures' => array('test_1.feature')
 592          );
 593          $contextspath = array(
 594              'default' => array(
 595                  'behat_test_context_1',
 596                  'behat_test_context_2',
 597                  'behat_theme_defaulttheme_test_context_1',
 598              ),
 599              'withfeatures' => array(
 600                  'behat_theme_withfeatures_test_context_2',
 601                  'behat_theme_withfeatures_behat_test_context_1'
 602              ),
 603              'nofeatures' => array(
 604                  'behat_theme_nofeatures_test_context_1',
 605                  'behat_theme_nofeatures_behat_test_context_2'
 606              ),
 607          );
 608  
 609          // Check features.
 610          foreach ($featurepaths as $themename => $paths) {
 611              $this->assertCount(count($paths), $suites[$themename]['paths']);
 612  
 613              foreach ($paths as $key => $feature) {
 614                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 615              }
 616          }
 617          // Check contexts.
 618          foreach ($contextspath as $themename => $paths) {
 619              $this->assertCount(count($paths), $suites[$themename]['contexts']);
 620  
 621              foreach ($paths as $key => $context) {
 622                  $this->assertTrue(in_array($context, $suites[$themename]['contexts']));
 623              }
 624          }
 625          // There are 7 step definitions.
 626          $this->assertCount(7, $config['default']['extensions']['Moodle\BehatExtension']['steps_definitions']);
 627      }
 628  
 629      /**
 630       * Behat config for blacklisted tags.
 631       */
 632      public function test_core_features_to_include_in_specified_theme() {
 633  
 634          $mockbuilder = $this->getMockBuilder('behat_config_util');
 635          $mockbuilder->onlyMethods(array('get_theme_test_directory', 'get_list_of_themes', 'get_default_theme', 'get_theme_config'));
 636  
 637          $behatconfigutil = $mockbuilder->getMock();
 638  
 639          $behatconfigutil = $this->get_behat_config_util($behatconfigutil);
 640  
 641          // Check features when, no theme is specified.
 642          $behatconfigutil->set_theme_suite_to_include_core_features('');
 643          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 644          $suites = $config['default']['suites'];
 645          foreach ($this->featurepaths as $themename => $paths) {
 646              $this->assertCount(count($paths), $suites[$themename]['paths']);
 647  
 648              foreach ($paths as $key => $feature) {
 649                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 650              }
 651          }
 652  
 653          // Check features when all themes are specified.
 654          $featurepaths = $this->featurepaths;
 655          $featurepaths['withfeatures'] = array_merge ($featurepaths['default'], $featurepaths['withfeatures']);
 656          $featurepaths['nofeatures'] = array_merge ($featurepaths['default'], $featurepaths['nofeatures']);
 657  
 658          $behatconfigutil->set_theme_suite_to_include_core_features('ALL');
 659          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 660          $suites = $config['default']['suites'];
 661          foreach ($featurepaths as $themename => $paths) {
 662              $this->assertCount(count($paths), $suites[$themename]['paths']);
 663  
 664              foreach ($paths as $key => $feature) {
 665                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 666              }
 667          }
 668  
 669          // Check features when all themes are specified.
 670          $featurepaths = $this->featurepaths;
 671          $featurepaths['withfeatures'] = array_merge ($featurepaths['default'], $featurepaths['withfeatures']);
 672          $featurepaths['nofeatures'] = array_merge ($featurepaths['default'], $featurepaths['nofeatures']);
 673  
 674          $behatconfigutil->set_theme_suite_to_include_core_features('withfeatures, nofeatures');
 675          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 676          $suites = $config['default']['suites'];
 677          foreach ($featurepaths as $themename => $paths) {
 678              $this->assertCount(count($paths), $suites[$themename]['paths']);
 679  
 680              foreach ($paths as $key => $feature) {
 681                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 682              }
 683          }
 684  
 685          // Check features when specified themes are passed..
 686          $featurepaths = $this->featurepaths;
 687          $featurepaths['nofeatures'] = array_merge ($featurepaths['default'], $featurepaths['nofeatures']);
 688  
 689          $behatconfigutil->set_theme_suite_to_include_core_features('nofeatures');
 690          $config = $behatconfigutil->get_config_file_contents($this->corefeatures, $this->corecontexts);
 691          $suites = $config['default']['suites'];
 692          foreach ($featurepaths as $themename => $paths) {
 693              $this->assertCount(count($paths), $suites[$themename]['paths']);
 694  
 695              foreach ($paths as $key => $feature) {
 696                  $this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
 697              }
 698          }
 699      }
 700  }
 701  // @codeCoverageIgnoreEnd