From 5af5ee7687e375d096eb7f3f5789784792112142 Mon Sep 17 00:00:00 2001 From: Daniel Thee Roperto Date: Mon, 3 Oct 2016 18:23:06 +1100 Subject: [PATCH] MDL-56233 forms library: Fixed form identifier when mocking a form. If the plugin is using namespaces instead of frankenstyle class name, get_called_class() will return 'type\name' instead of 'type_name'. Added code to replace backslashes to underscores and fix that issue. --- lib/formslib.php | 1 + lib/tests/fixtures/namespaced_form.php | 49 ++++++++++++++++++++++++++ lib/tests/formslib_test.php | 17 +++++++++ 3 files changed, 67 insertions(+) create mode 100644 lib/tests/fixtures/namespaced_form.php diff --git a/lib/formslib.php b/lib/formslib.php index 0ee1e82d08f..0b88c92a8c8 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -1362,6 +1362,7 @@ abstract class moodleform { $_FILES = $simulatedsubmittedfiles; if ($formidentifier === null) { $formidentifier = get_called_class(); + $formidentifier = str_replace('\\', '_', $formidentifier); // See MDL-56233 for more information. } $simulatedsubmitteddata['_qf__'.$formidentifier] = 1; $simulatedsubmitteddata['sesskey'] = sesskey(); diff --git a/lib/tests/fixtures/namespaced_form.php b/lib/tests/fixtures/namespaced_form.php new file mode 100644 index 00000000000..f6e63b19cb3 --- /dev/null +++ b/lib/tests/fixtures/namespaced_form.php @@ -0,0 +1,49 @@ +. + +/** + * A form inside a namespace to be used by unit tests. + * + * See issue MDL-56233 + * + * @package core + * @author Daniel Thee Roperto + * @copyright 2016 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace local_unittests\namespaced_form; + +defined('MOODLE_INTERNAL') || die(); + +/** + * exampleform class. + * + * @package core + * @author Daniel Thee Roperto + * @copyright 2016 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class exampleform extends \moodleform { + /** + * Create a simple form definition. + */ + public function definition() { + $mform = $this->_form; + $mform->addElement('text', 'title', 'title_value'); + $mform->setType('title', PARAM_TEXT); + } +} diff --git a/lib/tests/formslib_test.php b/lib/tests/formslib_test.php index f7c5ed90cd5..03690ca0d06 100644 --- a/lib/tests/formslib_test.php +++ b/lib/tests/formslib_test.php @@ -625,6 +625,23 @@ class core_formslib_testcase extends advanced_testcase { $this->assertFalse($form->is_validated()); $this->assertNull($form->get_data()); } + + /** + * MDL-56233 - Tests mocking a form inside a namespace. + */ + public function test_mock_submit() { + require_once(__DIR__.'/fixtures/namespaced_form.php'); + \local_unittests\namespaced_form\exampleform::mock_submit(['title' => 'Mocked Value']); + $form = new \local_unittests\namespaced_form\exampleform(); + + // Here is the problem, this is the expected hidden field name. + $expected = '_qf__local_unittests_namespaced_form_exampleform'; + self::assertArrayHasKey($expected, $_POST); + + // This should work now, before it would fail. + self::assertTrue($form->is_submitted()); + self::assertSame('Mocked Value', $form->get_data()->title); + } }