first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,33 @@
@core @core_course @tool_generator
Feature: Admins can create test courses
In order to create testing information
As an admin
I need to create testing courses quickly
@javascript
Scenario: 'Auto-enrol admin in new courses' setting when creating a test course as admin
Given I log in as "admin"
And the following config values are set as admin:
| enroladminnewcourse | 0 |
And I navigate to "Development > Make test course" in site administration
And I set the following fields to these values:
| Size of course | XS |
| Course full name | Fake course for testing |
| Course short name | fake |
And I press "Create course"
And I click on "Continue" "link"
And I navigate to course participants
Then I should not see "Teacher"
And I should not see "Nothing to display"
And the following config values are set as admin:
| enroladminnewcourse | 1 |
And I navigate to "Courses > Add a new course" in site administration
And I navigate to "Development > Make test course" in site administration
And I set the following fields to these values:
| Size of course | XS |
| Course full name | New fake course for testing |
| Course short name | newfake |
And I press "Create course"
And I click on "Continue" "link"
And I navigate to course participants
And I should see "Teacher"
@@ -0,0 +1,64 @@
@tool @tool_generator @_file_upload
Feature: Create testing scenarios using generators
In order to execute manual tests
As a developer
I need to use a feature file to execute generators into the current instance
@javascript
Scenario: Create a testing scenario with a course enrolled users and activities
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario.feature" file to "Feature file" filemanager
And I press "Import"
And I should see "Scenario: Create course content"
Then I am on the "C1" "Course" page
And I should see "Activity sample 1" in the "Section 1" "section"
And I should see "Activity sample 2" in the "Section 1" "section"
And I navigate to course participants
And I should see "Teacher Test1"
And I should see "Student Test1"
And I should see "Student Test2"
And I should see "Student Test3"
And I should see "Student Test4"
And I should see "Student Test5"
@javascript
Scenario: Prevent creating a testing scenario with no steps to execute
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario_wrongempty.feature" file to "Feature file" filemanager
And I press "Import"
Then I should see "There are no steps to execute in the file."
@javascript
Scenario: Prevent creating a testing scenario with only background steps to execute
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario_wrongonlybackground.feature" file to "Feature file" filemanager
And I press "Import"
Then I should see "There are no steps to execute in the file."
@javascript
Scenario: Prevent creating a testing scenario with a wrong file format
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario_wrongformat.feature" file to "Feature file" filemanager
And I press "Import"
Then I should see "Error parsing feature file"
@javascript
Scenario: Prevent creating a testing scenario with non generator steps
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario_wrongstep.feature" file to "Feature file" filemanager
And I press "Import"
Then I should see "The file format is not valid or contains invalid steps"
@javascript
Scenario: Prevent creating a testing scenario from a scenario outline
Given I log in as "admin"
And I navigate to "Development > Create testing scenarios" in site administration
When I upload "admin/tool/generator/tests/fixtures/testscenario/scenario_wrongoutline.feature" file to "Feature file" filemanager
And I press "Import"
Then I should see "Scenario outlines are not supported"
Then I should see "There are no steps to execute in the file"
@@ -0,0 +1,28 @@
Feature: Prepare scenario for testing
Scenario: Create course content
Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |
| numsections | 3 |
| initsections | 1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible |
| assign | Activity sample 1 | Test assignment description | C1 | sample1 | 1 | 1 |
| assign | Activity sample 2 | Test assignment description | C1 | sample2 | 1 | 0 |
Scenario: Create users
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Test1 | sample@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And "5" "users" exist with the following data:
| username | student[count] |
| firstname | Student |
| lastname | Test[count] |
| email | student[count]@example.com |
And "5" "course enrolments" exist with the following data:
| user | student[count] |
| course | C1 |
| role | student |
@@ -0,0 +1,3 @@
Feature: Prepare scenario for testing
Scenario: only empty scenario 1.
Scenario: only empty scenario 2.
@@ -0,0 +1,5 @@
This is not a valid feature file.
However: it has lines
indented and stuff
like if it was.
@@ -0,0 +1,11 @@
Feature: Invalid texting because background is not compatible
Background:
Given the following "course" exists:
| fullname | Course 1 |
| shortname | C1 |
| category | 0 |
| numsections | 3 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible |
| assign | Activity sample 1 | Test assignment description | C1 | sample1 | 1 | 1 |
| assign | Activity sample 2 | Test assignment description | C1 | sample2 | 1 | 0 |
@@ -0,0 +1,14 @@
Feature: Prepare scenario for testing
Scenario Outline: test outline scenarios are not supported yet
Given the following "course" exists:
| fullname | <name> |
| shortname | <shortname> |
| category | 0 |
| numsections | 3 |
Examples:
| name | shortname |
| Course 1 | C1 |
| Course 2 | C2 |
| Course 3 | C3 |
@@ -0,0 +1,13 @@
Feature: Contains wrong steps
Scenario: Scenario with non generator steps
Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |
| numsections | 3 |
And the following "activities" exist:
| activity | name | intro | course | idnumber | section | visible |
| assign | Activity sample 1 | Test assignment description | C1 | sample1 | 1 | 1 |
| assign | Activity sample 2 | Test assignment description | C1 | sample2 | 1 | 0 |
And I click on "Tokens filter" "link"
@@ -0,0 +1,216 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_generator\local\testscenario;
/**
* Tests for parsedfeature class.
*
* @package tool_generator
* @copyright 2023 Ferran Recio <ferran@moodel.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \tool_generator\local\testscenario\parsedfeature
*/
class parsedfeature_test extends \advanced_testcase {
/**
* Get a parsed feature from a content.
* @param string $content the feature content.
* @return parsedfeature the parsed feature.
*/
private function get_feature_from_content(string $content): parsedfeature {
$runner = new runner();
$runner->init();
return $runner->parse_feature($content);
}
/**
* Test for parse_feature.
* @covers ::get_general_error
* @covers ::add_scenario
* @covers ::add_step
*/
public function test_general_error(): void {
$nosteps = get_string('testscenario_nosteps', 'tool_generator');
$invalidfile = get_string('testscenario_invalidfile', 'tool_generator');
$parsedfeature = new parsedfeature();
$this->assertEquals($nosteps, $parsedfeature->get_general_error());
$parsedfeature->add_scenario('Scenario', 'Test scenario');
$this->assertEquals($nosteps, $parsedfeature->get_general_error());
// Add some valid step.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Create users
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Test1 | sample@example.com |
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step);
$this->assertEquals('', $parsedfeature->get_general_error());
// Only generator methods are allowed.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Not generator
Given I am in a course
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step);
$this->assertEquals($invalidfile, $parsedfeature->get_general_error());
}
/**
* Test for parse_feature.
* @covers ::is_valid
* @covers ::add_scenario
* @covers ::add_step
*/
public function test_is_valid(): void {
$parsedfeature = new parsedfeature();
$this->assertFalse($parsedfeature->is_valid());
$parsedfeature->add_scenario('Scenario', 'Test scenario');
$this->assertFalse($parsedfeature->is_valid());
// Add some valid step.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Create users
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Test1 | sample@example.com |
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step);
$this->assertTrue($parsedfeature->is_valid());
// Only generator methods are allowed.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Not generator
Given I am in a course
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step);
$this->assertFalse($parsedfeature->is_valid());
}
/**
* Test for ading steps into scenarios.
* @covers ::add_step
* @covers ::add_scenario
* @covers ::get_all_steps
* @covers ::get_scenarios
*/
public function test_add_step(): void {
$parsedfeature = new parsedfeature();
$this->assertEquals(0, count($parsedfeature->get_all_steps()));
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Create users
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Test1 | sample@example.com |
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step);
$this->assertEquals(1, count($parsedfeature->get_all_steps()));
// Should create a default scenario.
$scenarios = $parsedfeature->get_scenarios();
$this->assertEquals(1, count($scenarios));
$this->assertEquals('scenario', $scenarios[0]->type);
$this->assertEquals('', $scenarios[0]->name);
$this->assertEquals(1, count($scenarios[0]->steps));
$this->assertEquals($step, $scenarios[0]->steps[0]);
$this->assertEquals('', $scenarios[0]->error);
// Add a second step.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Not generator
Given I am in a course
');
$step2 = $extrafeature->get_all_steps()[0];
$parsedfeature->add_step($step2);
$scenarios = $parsedfeature->get_scenarios();
$this->assertEquals(1, count($scenarios));
$this->assertEquals('scenario', $scenarios[0]->type);
$this->assertEquals('', $scenarios[0]->name);
$this->assertEquals(2, count($scenarios[0]->steps));
$this->assertEquals($step, $scenarios[0]->steps[0]);
$this->assertEquals($step2, $scenarios[0]->steps[1]);
$this->assertEquals('', $scenarios[0]->error);
// Create a new scenario.
$parsedfeature->add_scenario('scenario', 'Test scenario 2');
$parsedfeature->add_step($step2);
$scenarios = $parsedfeature->get_scenarios();
$this->assertEquals(2, count($scenarios));
// Scenario 1.
$this->assertEquals('scenario', $scenarios[0]->type);
$this->assertEquals('', $scenarios[0]->name);
$this->assertEquals(2, count($scenarios[0]->steps));
$this->assertEquals($step, $scenarios[0]->steps[0]);
$this->assertEquals($step2, $scenarios[0]->steps[1]);
$this->assertEquals('', $scenarios[0]->error);
// Scenario 2.
$this->assertEquals('scenario', $scenarios[1]->type);
$this->assertEquals('Test scenario 2', $scenarios[1]->name);
$this->assertEquals(1, count($scenarios[1]->steps));
$this->assertEquals($step2, $scenarios[1]->steps[0]);
$this->assertEquals('', $scenarios[1]->error);
}
/**
* Test for ading errors into scenarios.
* @covers ::add_error
* @covers ::add_scenario
* @covers ::add_step
* @covers ::get_scenarios
*/
public function test_add_error(): void {
$parsedfeature = new parsedfeature();
// Add some valid step.
$extrafeature = $this->get_feature_from_content('Feature: Test feature
Scenario: Create users
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | Test1 | sample@example.com |
');
$step = $extrafeature->get_all_steps()[0];
$parsedfeature->add_scenario('scenario', 'Test scenario 1');
$parsedfeature->add_step($step);
$parsedfeature->add_error('Error message');
$parsedfeature->add_scenario('scenario', 'Test scenario 2');
$parsedfeature->add_step($step);
$scenarios = $parsedfeature->get_scenarios();
$this->assertEquals(2, count($scenarios));
// Scenario 1.
$this->assertEquals('scenario', $scenarios[0]->type);
$this->assertEquals('Test scenario 1', $scenarios[0]->name);
$this->assertEquals(1, count($scenarios[0]->steps));
$this->assertEquals($step, $scenarios[0]->steps[0]);
$this->assertEquals('Error message', $scenarios[0]->error);
// Scenario 2.
$this->assertEquals('scenario', $scenarios[1]->type);
$this->assertEquals('Test scenario 2', $scenarios[1]->name);
$this->assertEquals(1, count($scenarios[1]->steps));
$this->assertEquals($step, $scenarios[1]->steps[0]);
$this->assertEquals('', $scenarios[1]->error);
}
}
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_generator\local\testscenario;
/**
* Tests for runner class.
*
* @package tool_generator
* @copyright 2023 Ferran Recio <ferran@moodel.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \tool_generator\local\testscenario\runner
*/
class runner_test extends \advanced_testcase {
/**
* Test for parse_feature.
* @covers ::parse_feature
* @covers ::execute
*/
public function test_parse_and_execute_feature(): void {
global $CFG, $DB;
$this->resetAfterTest();
$this->setAdminUser();
// Call the init method to include all behat libraries and attributes.
$runner = new runner();
$runner->init();
$featurefile = $CFG->dirroot . '/admin/tool/generator/tests/fixtures/testscenario/scenario.feature';
$contents = file_get_contents($featurefile);
$feature = $runner->parse_feature($contents);
$this->assertEquals(2, count($feature->get_scenarios()));
$this->assertEquals(6, count($feature->get_all_steps()));
$this->assertTrue($feature->is_valid());
$result = $runner->execute($feature);
$this->assertTrue($result);
// Validate everything is created.
$this->assertEquals(
1,
$DB->count_records('course', ['shortname' => 'C1'])
);
$course = $DB->get_record('course', ['shortname' => 'C1']);
$this->assertEquals(
2,
$DB->count_records('course_modules', ['course' => $course->id])
);
$this->assertEquals(
1,
$DB->count_records('user', ['firstname' => 'Teacher'])
);
$this->assertEquals(
5,
$DB->count_records('user', ['firstname' => 'Student'])
);
$context = \context_course::instance($course->id);
$this->assertEquals(
6,
$DB->count_records('role_assignments', ['contextid' => $context->id])
);
}
/**
* Test for parse_feature.
* @covers ::parse_feature
* @covers ::execute
*/
public function test_parse_and_execute_wrong_feature(): void {
global $CFG, $DB;
$this->resetAfterTest();
$this->setAdminUser();
// Call the init method to include all behat libraries and attributes.
$runner = new runner();
$runner->init();
$featurefile = $CFG->dirroot . '/admin/tool/generator/tests/fixtures/testscenario/scenario_wrongstep.feature';
$contents = file_get_contents($featurefile);
$feature = $runner->parse_feature($contents);
$this->assertEquals(1, count($feature->get_scenarios()));
$this->assertEquals(3, count($feature->get_all_steps()));
$this->assertFalse($feature->is_valid());
$result = $runner->execute($feature);
$this->assertFalse($result);
$this->assertEquals(0, $DB->count_records('course', ['shortname' => 'C1']));
}
}
@@ -0,0 +1,238 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_generator\local\testscenario;
use behat_data_generators;
use Behat\Gherkin\Parser;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Keywords\ArrayKeywords;
use Behat\Gherkin\Node\StepNode;
/**
* Tests for steprunner class.
*
* @package tool_generator
* @copyright 2023 Ferran Recio <ferran@moodel.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \tool_generator\local\testscenario\steprunner
*/
class steprunner_test extends \advanced_testcase {
public static function setUpBeforeClass(): void {
// Call the init method to include all behat libraries and attributes.
$runner = new runner();
$runner->init();
}
/**
* Get a step node from a string.
* @param string $step the step string.
* @return StepNode the step node.
*/
private function get_step(string $step): StepNode {
$content = 'Feature: Test feature
Scenario: Test scenario
' . $step . '
';
$method = new \ReflectionMethod(runner::class, 'get_parser');
$parser = $method->invoke(new runner());
$feature = $parser->parse($content);
$scenario = $feature->getScenarios()[0];
$steps = $scenario->getSteps();
return $steps[0];
}
/**
* Test for parse_feature.
* @covers ::is_valid
* @param string $step the step to validate.
* @param bool $expected if the step is expected to be valid.
* @dataProvider execute_steps_provider
*/
public function test_is_valid(string $step, bool $expected): void {
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$step = $this->get_step($step);
$steprunner = new steprunner($generator, $validsteps, $step);
$this->assertEquals($expected, $steprunner->is_valid());
}
/**
* Test for execute step.
*
* @covers ::is_executed
* @covers ::execute
* @param string $step the step to execute.
* @param bool $expected if the step is expected to be executed.
* @dataProvider execute_steps_provider
*/
public function test_execute(string $step, bool $expected): void {
global $DB;
$this->resetAfterTest();
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$step = $this->get_step($step);
$steprunner = new steprunner($generator, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
$result = $steprunner->execute();
$this->assertEquals($expected, $result);
$this->assertEquals($expected, $steprunner->is_executed());
if ($expected) {
// Validate everything is created.
$this->assertEquals(
1,
$DB->count_records('course', ['shortname' => 'C1'])
);
}
}
/**
* Data provider for test_execute.
* @return array the data.
*/
public static function execute_steps_provider(): array {
return [
'Following exists' => [
'step' => 'Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |',
'expected' => true,
],
'Following exist' => [
'step' => 'Given the following "course" exist:
| fullname | shortname | category |
| Course test | C1 | 0 |',
'expected' => true,
],
'Repeated entities' => [
'step' => 'Given "1" "courses" exist with the following data:
| fullname | Course test |
| shortname | C[count] |
| category | 0 |
| numsections | 3 |',
'expected' => true,
],
'Invalid step' => [
'step' => 'Given I click on "Tokens filter" "link"',
'expected' => false,
],
];
}
/**
* Test for execute step.
* @covers ::is_executed
* @covers ::execute
* @covers ::get_error
*/
public function test_execute_duplicated(): void {
global $DB;
$this->resetAfterTest();
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$step = $this->get_step('Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |');
$steprunner = new steprunner($generator, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
$result = $steprunner->execute();
$this->assertTrue($result);
$this->assertTrue($steprunner->is_executed());
$this->assertEquals('', $steprunner->get_error());
// Validate everything is created.
$this->assertEquals(
1,
$DB->count_records('course', ['shortname' => 'C1'])
);
// Execute the same course creation.
$steprunner = new steprunner($generator, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
$result = $steprunner->execute();
$this->assertFalse($result);
$this->assertTrue($steprunner->is_executed());
$this->assertEquals(get_string('shortnametaken', 'error', 'C1'), $steprunner->get_error());
}
/**
* Test for parse_feature.
* @covers ::get_text
* @covers ::get_arguments_string
*/
public function test_get_step_content(): void {
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$step = $this->get_step('Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |
| numsections | 3 |');
$steprunner = new steprunner($generator, $validsteps, $step);
$this->assertEquals(
'the following "course" exists:',
$steprunner->get_text()
);
$data = [
'| fullname | Course test |',
'| shortname | C1 |',
'| category | 0 |',
'| numsections | 3 |',
];
$arguments = explode("\n", $steprunner->get_arguments_string());
$this->assertEquals(
$data,
$arguments
);
}
}
@@ -0,0 +1,230 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_generator;
use tool_generator_course_backend;
/**
* Automated unit testing. This tests the 'make large course' backend,
* using the 'XS' option so that it completes quickly.
*
* @package tool_generator
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class maketestcourse_test extends \advanced_testcase {
/**
* Creates a small test course and checks all the components have been put in place.
*/
public function test_make_xs_course(): void {
global $DB;
$this->resetAfterTest();
$this->setAdminUser();
$expectedshortname = 'TOOL_MAKELARGECOURSE_XS';
$expectedfullname = 'Ridiculous fullname';
$expectedsummary = 'who even knows what this is about';
// Create the XS course.
$backend = new tool_generator_course_backend(
$expectedshortname,
0,
false,
false,
false,
$expectedfullname,
$expectedsummary
);
$courseid = $backend->make();
// Get course details.
$course = get_course($courseid);
$context = \context_course::instance($courseid);
$modinfo = get_fast_modinfo($course);
// Check course names.
$this->assertEquals($expectedshortname, $course->shortname);
$this->assertEquals($expectedfullname, $course->fullname);
// Check course summary.
$this->assertEquals($expectedsummary, $course->summary);
// Check sections (just section 0 plus one other).
$this->assertEquals(2, count($modinfo->get_section_info_all()));
// Check user is enrolled.
// enroladminnewcourse is enabled by default, so admin is also enrolled as teacher.
$users = get_enrolled_users($context);
$this->assertEquals(2, count($users));
$usernames = array_map(function($user) {
return $user->username;
}, $users);
$this->assertTrue(in_array('admin', $usernames));
$this->assertTrue(in_array('tool_generator_000001', $usernames));
// Check there's a page on the course.
$pages = $modinfo->get_instances_of('page');
$this->assertEquals(1, count($pages));
// Check there are small files.
$resources = $modinfo->get_instances_of('resource');
$ok = false;
foreach ($resources as $resource) {
if ($resource->sectionnum == 0) {
// The one in section 0 is the 'small files' resource.
$ok = true;
break;
}
}
$this->assertTrue($ok);
// Check it contains 2 files (the default txt and a dat file).
$fs = get_file_storage();
$resourcecontext = \context_module::instance($resource->id);
$files = $fs->get_area_files($resourcecontext->id, 'mod_resource', 'content', false, 'filename', false);
$files = array_values($files);
$this->assertEquals(2, count($files));
$this->assertEquals('resource1.txt', $files[0]->get_filename());
$this->assertEquals('smallfile0.dat', $files[1]->get_filename());
// Check there's a single 'big' file (it's actually only 8KB).
$ok = false;
foreach ($resources as $resource) {
if ($resource->sectionnum == 1) {
$ok = true;
break;
}
}
$this->assertTrue($ok);
// Check it contains 2 files.
$resourcecontext = \context_module::instance($resource->id);
$files = $fs->get_area_files($resourcecontext->id, 'mod_resource', 'content', false, 'filename', false);
$files = array_values($files);
$this->assertEquals(2, count($files));
$this->assertEquals('bigfile0.dat', $files[0]->get_filename());
$this->assertEquals('resource2.txt', $files[1]->get_filename());
// Get forum and count the number of posts on it.
$forums = $modinfo->get_instances_of('forum');
$forum = reset($forums);
$posts = $DB->count_records_sql("
SELECT
COUNT(1)
FROM
{forum_posts} fp
JOIN {forum_discussions} fd ON fd.id = fp.discussion
WHERE
fd.forum = ?", array($forum->instance));
$this->assertEquals(2, $posts);
}
/**
* Creates an small test course with fixed data set and checks the used sections and users.
*/
public function test_fixed_data_set(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Create the S course (more sections and activities than XS).
$backend = new tool_generator_course_backend('TOOL_S_COURSE_1', 1, true, false, false);
$courseid = $backend->make();
// Get course details.
$course = get_course($courseid);
$modinfo = get_fast_modinfo($course);
// Check module instances belongs to section 1.
$instances = $modinfo->get_instances_of('page');
foreach ($instances as $instance) {
$this->assertEquals(1, $instance->sectionnum);
}
// Users that started discussions are the same.
$forums = $modinfo->get_instances_of('forum');
$discussions = forum_get_discussions(reset($forums), 'd.timemodified ASC');
$lastusernumber = 0;
$discussionstarters = array();
foreach ($discussions as $discussion) {
$usernumber = \core_user::get_user($discussion->userid, 'id, idnumber')->idnumber;
// Checks that the users are odd numbers.
$this->assertEquals(1, $usernumber % 2);
// Checks that the users follows an increasing order.
$this->assertGreaterThan($lastusernumber, $usernumber);
$lastusernumber = $usernumber;
$discussionstarters[$discussion->userid] = $discussion->subject;
}
}
/**
* Creates a small test course specifying a maximum size and checks the generated files size is limited.
*/
public function test_filesize_limit(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Limit.
$filesizelimit = 100;
// Create a limited XS course.
$backend = new tool_generator_course_backend('TOOL_XS_LIMITED', 0, false, $filesizelimit, false);
$courseid = $backend->make();
$course = get_course($courseid);
$modinfo = get_fast_modinfo($course);
// Check there are small files.
$fs = get_file_storage();
$resources = $modinfo->get_instances_of('resource');
foreach ($resources as $resource) {
$resourcecontext = \context_module::instance($resource->id);
$files = $fs->get_area_files($resourcecontext->id, 'mod_resource', 'content', false, 'filename', false);
foreach ($files as $file) {
if ($file->get_mimetype() == 'application/octet-stream') {
$this->assertLessThanOrEqual($filesizelimit, $file->get_filesize());
}
}
}
// Create a non-limited XS course.
$backend = new tool_generator_course_backend('TOOL_XS_NOLIMITS', 0, false, false, false);
$courseid = $backend->make();
$course = get_course($courseid);
$modinfo = get_fast_modinfo($course);
// Check there are small files.
$fs = get_file_storage();
$resources = $modinfo->get_instances_of('resource');
foreach ($resources as $resource) {
$resourcecontext = \context_module::instance($resource->id);
$files = $fs->get_area_files($resourcecontext->id, 'mod_resource', 'content', false, 'filename', false);
foreach ($files as $file) {
if ($file->get_mimetype() == 'application/octet-stream') {
$this->assertGreaterThan($filesizelimit, (int)$file->get_filesize());
}
}
}
}
}
@@ -0,0 +1,108 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit test for the site generator
*
* @package tool_generator
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_generator;
use tool_generator_site_backend;
defined('MOODLE_INTERNAL') || die();
/**
* Unit test for the site generator
*
* @package tool_generator
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class maketestsite_test extends \advanced_testcase {
/**
* Checks that site courses shortnames are properly generated.
*/
public function test_shortnames_generation(): void {
$this->resetAfterTest();
$this->setAdminUser();
$generator = $this->getDataGenerator();
// Shortname common prefix.
$prefix = tool_generator_site_backend::SHORTNAMEPREFIX;
$record = array();
// Without courses will be 0.
$lastshortname = testable_tool_generator_site_backend::get_last_testcourse_id();
$this->assertEquals(0, $lastshortname);
// Without {$prefix} + {no integer} courses will be 0.
$record['shortname'] = $prefix . 'AA';
$generator->create_course($record);
$record['shortname'] = $prefix . '__';
$generator->create_course($record);
$record['shortname'] = $prefix . '12.2';
$generator->create_course($record);
$lastshortname = testable_tool_generator_site_backend::get_last_testcourse_id();
$this->assertEquals(0, $lastshortname);
// With {$prefix} + {integer} courses will be the higher one.
$record['shortname'] = $prefix . '2';
$generator->create_course($record);
$record['shortname'] = $prefix . '20';
$generator->create_course($record);
$record['shortname'] = $prefix . '8';
$generator->create_course($record);
$lastshortname = testable_tool_generator_site_backend::get_last_testcourse_id();
$this->assertEquals(20, $lastshortname);
// Numeric order.
for ($i = 9; $i < 14; $i++) {
$record['shortname'] = $prefix . $i;
$generator->create_course($record);
}
$lastshortname = testable_tool_generator_site_backend::get_last_testcourse_id();
$this->assertEquals(20, $lastshortname);
}
}
/**
* Silly class to access site_backend internal methods.
*
* @copyright 2013 David Monllaó
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class testable_tool_generator_site_backend extends tool_generator_site_backend {
/**
* Public accessor.
*
* @return int
*/
public static function get_last_testcourse_id() {
return parent::get_last_testcourse_id();
}
}