Compare commits

...

365 Commits

Author SHA1 Message Date
Jun Pataleta b90b0e6a8a Moodle release 3.9.21 2023-04-22 16:22:34 +08:00
Eloy Lafuente (stronk7) 58a55fcd40 weekly release 3.9.20+ 2023-04-21 19:19:36 +02:00
Jun Pataleta c37dd0ecbd Merge branch 'MDL-77927-39' of https://github.com/stevandoMoodle/moodle into MOODLE_39_STABLE 2023-04-21 16:51:14 +08:00
Jun Pataleta 84462c3e71 MDL-77927 core: mod_assignment subplugins environment check 2023-04-21 15:58:22 +08:00
Andrew Nicols 129b2186ac Merge branch 'MDL-77128-39' of https://github.com/mackensen/moodle into MOODLE_39_STABLE 2023-04-20 10:22:35 +08:00
Paul Holden 7eb6482266 MDL-77187 mod_wiki: validate external method sort parameters. 2023-04-19 12:57:22 +00:00
Paul Holden 9e4c3f858f Merge branch 'MDL-77960-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-04-19 13:41:36 +01:00
Paul Holden a7bbba41bf Merge branch 'MDL-77944-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-04-19 13:06:44 +01:00
Simey Lameze bfc911b928 MDL-77960 behat: make verification steps more specific 2023-04-19 13:33:59 +08:00
Andrew Nicols 9766906cc5 weekly release 3.9.20+ 2023-04-18 22:28:25 +08:00
Charles Fulton 0864e3adb3 MDL-77128 upgrade: Fix incompatible check in upgrade to match docs
Backport of MDL-72324
2023-04-18 09:07:34 -04:00
Andrew Nicols 86de73cb14 Merge branch 'MDL-77829-39' of https://github.com/stevandoMoodle/moodle into MOODLE_39_STABLE 2023-04-18 12:33:14 +08:00
Andrew Nicols b3e6ce7cfe MDL-77944 behat: Rename chrome options for w3c support
From Selenium 4.8.0, support for non-w3c browser control has ended.

We only use W3C browser control these days, and this was missed as part
of the move to W3C. All browser options must be vendor-prefixed.
2023-04-18 09:40:16 +08:00
Sara Arjona 94836d56b6 weekly release 3.9.20+ 2023-04-14 10:50:22 +02:00
Sara Arjona 3477b9c1c5 Merge branch 'MDL-73610_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-04-12 18:20:10 +02:00
Sara Arjona 6ee405e107 Merge branch 'MDL-77837-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-04-11 12:13:38 +02:00
Stevani Andolo 869b26f3e3 MDL-77829 core: Added environment check for mod_assignment
Decided to add an environment check before uninstalling the
mod_assignment plugin to prevent data lost.
2023-04-10 13:56:09 +08:00
Andrew Nicols d1f085a771 MDL-77837 core: Improve usage docs for cron_setup_user 2023-04-06 23:21:29 +08:00
Andrew Nicols 22ac74f686 MDL-77837 phpunit: Ensure that the cron user setter is used
When running an adhoc task in a unit test we should use the cron variant
of the set user method to mimic the behaviour of a real cron run.
2023-04-06 23:21:29 +08:00
Andrew Nicols 72a51148e9 MDL-77837 cron: Ensure user is set when running tasks
We should be proactive in ensuring that the environment is clean when
running a task. We already ensure that we have a clean renderer and
other parts of the output chain, but we were not setting a clean user.

This change adds a call to setup the cron user before each task is
actually executed.
2023-04-06 23:21:29 +08:00
Eloy Lafuente (stronk7) 7e6d3caab7 MDL-73610 nodejs: Small updates to required packages
The main goal of this issue is to avoid scanners (Dependabot
and friends), reporting about security issues with the current
xmldom 0.6.0 package.

Note that this doesn't affect prod at all, because it's a dev
dependency, hardly exploitable. So it's not a security fix, just
a security_benefit, if something.

So here, we are updating from xmldom 0.6.0 to @xmldom/xmldom 0.8.7
(note that the package was renamed in 0.7.0, so it's the very same)

Also, when proceeding with the changes, it was detected that we
are incorrectly declaring @babel/eslint-parser as a normal dependency
instead of a development one, so we are also fixing that little detail.

The commands executed to get the changes above applied have been:

- nvm use
- npm install @xmldom/xmldom@^0.8.7 --save-dev
- npm uninstall xmldom
- npm install @babel/eslint-parser@^7.17.0 --save-dev

(we haven't run a complete re-install because we only want to modify
the minimum possible at this stage).
2023-04-06 15:00:14 +02:00
Sara Arjona 0b15830a44 weekly release 3.9.20+ 2023-04-06 14:02:40 +02:00
Andrew Nicols 6c34850db6 Merge branch 'MDL-77584-39' of https://github.com/ewallah/moodle into MOODLE_39_STABLE 2023-04-04 12:08:26 +08:00
Paul Holden ed81c8df64 Merge branch 'MDL-75906-39' of https://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2023-04-03 14:54:07 +01:00
Michael Hawkins efa1cab75a MDL-75906 core: Updated security.txt expiry 2023-04-03 17:28:04 +08:00
Paul Holden aa99d2ebac weekly release 3.9.20+ 2023-03-31 18:12:03 +01:00
Sara Arjona 9c4d90cb52 Merge branch 'MDL-77761-39' of https://github.com/junpataleta/moodle into MOODLE_39_STABLE 2023-03-30 17:53:39 +02:00
Jun Pataleta 6a15f3890e Merge branch 'MDL-77333_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-03-30 19:03:17 +08:00
Jun Pataleta 4a4bf70e8b MDL-77761 core_form: Add label for editor format selector 2023-03-28 23:35:24 +08:00
Eloy Lafuente (stronk7) 3aba658a40 MDL-77333 mod_resource: fixes generator uploading files + tests
MDL-76499 revealed a few problems with resource generators:

1. We were not covering with unit tests the upload of files from disk
   (and here it's where the problem was).
2. There was a little of confusion between disk paths (only needed
   to upload files) and file_area paths (the generator only creates
   or uploads files to the root directory of the file area.
3. It was possible to request the upload of a file to the generator
   without that file effectively existing.

This commit fixes those points  and covers 99% of the generator code.
2023-03-26 11:45:05 +02:00
Sara Arjona ed154e71b0 weekly release 3.9.20+ 2023-03-24 13:59:44 +01:00
Jun Pataleta 06d46b875b Merge branch 'MDL-77669-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-24 11:50:48 +08:00
Paul Holden 478b7146e5 Merge branch 'MDL-77691-39' of https://github.com/roland04/moodle into MOODLE_39_STABLE 2023-03-23 11:43:45 +00:00
Mikel Martín 5febdbe6a2 MDL-77691 behat: Add step to navigate to profile page directly
Co-authored-by: Simey Lameze <simey@moodle.com>
2023-03-23 08:28:43 +01:00
Ilya Tregubov 09e068e8bb weekly release 3.9.20+ 2023-03-22 09:37:21 +08:00
Meirza d17d7263fd MDL-77669 dml: Added extrainfo in the DB options config.
extrainfo is an extra information for the DB driver, e.g. SQL Server,
has additional configuration according to its environment,
which the administrator can specify to alter and override any connection options.

Co-authored-by: LukeCarrier <luke@carrier.im>

This is a backport of MDL-64153.
2023-03-21 08:48:08 +08:00
Sara Arjona 0afaaad6dd Merge branch 'MDL-77574-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-03-20 17:06:41 +01:00
info@eWallah.net 556cdde71a MDL-77584 currencies: Fix outdated ISO 4217 code for Zambian Kwacha
On 2013-01-01 the ZMK code got replaced by the new ZMW code.

AMOS BEGIN
 MOV [ZMK,core_currencies],[ZMW,core_currencies]
AMOS END
2023-03-16 19:53:28 +01:00
Eloy Lafuente (stronk7) f24eb73cc5 weekly release 3.9.20+ 2023-03-14 16:07:54 +01:00
Jun Pataleta 01576f2100 Merge branch 'MDL-76680/39' of https://github.com/skodak/moodle into MOODLE_39_STABLE 2023-03-14 11:56:45 +08:00
Simey Lameze f39e564141 MDL-77574 myoverview: wait until next button exists before clicking 2023-03-13 14:19:10 +08:00
Petr Skoda ef1ecd2ad3 MDL-76680 core: disable $USER->ignoresesskey on next page 2023-03-11 10:37:56 +01:00
Jun Pataleta c7e549cda4 Moodle release 3.9.20 2023-03-11 13:10:32 +08:00
Jun Pataleta 5ab0e5351b weekly release 3.9.19+ 2023-03-10 22:10:07 +08:00
Ilya Tregubov 1eacff88b1 Merge branch 'MDL-77429-39-fix' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-10 14:49:32 +08:00
Andrew Nicols e3189a8d18 MDL-77429 course: Change course date to previous day
When a test runs just after midnight, and the user time zone is not the
same as the server timezone, and the course is created using a generator
(which runs in server time zone) but the UI presented in the user
timezone, the course start time is still in the future.

We need to create the course a day earlier to ensure that the "This
week" indicator is in the correct day.
2023-03-10 14:11:23 +08:00
Andrew Nicols c7a9221ef2 Merge branch 'MDL-77429-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-09 22:13:06 +08:00
Andrew Nicols c95773e2e3 Merge branch 'MDL-77463-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-09 22:06:03 +08:00
Jun Pataleta b61fae245c Merge branch 'MDL-77559-39-2' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-09 15:43:24 +08:00
Angelia Dela Cruz a69cf7f929 MDL-77429 Behat: Add coverage for changing course format as teacher 2023-03-09 14:31:30 +08:00
Angelia Dela Cruz 147b16d552 MDL-77463 Behat: Coverage for assign submission notification to teacher 2023-03-09 12:47:32 +08:00
Andrew Nicols ce1a7659bc MDL-77559 js: Rebuild all JS with Node 16 2023-03-09 08:22:29 +08:00
Andrew Nicols 6c7b5a35a6 MDL-77559 js: Revert "MDL-75012 core: Bump NodeJS version requirements"
This reverts commit f6559c6eaf.
2023-03-09 08:21:19 +08:00
Andrew Nicols 601e5c6d83 MDL-77559 js: Revert "MDL-75012 js: Bump standard dependencies"
This reverts commit 0872d00857.
2023-03-09 08:21:15 +08:00
Andrew Nicols 89b16e0bef MDL-77559 js: Revert "MDL-75012 js: Remove grunt-contrib-uglify"
This reverts commit d6ac705d63.
2023-03-09 08:21:12 +08:00
Andrew Nicols dc1d2cbc73 MDL-77559 js: Revert "MDL-75012 js: Bump stylelint and components"
This reverts commit 2cfb12db0e.
2023-03-09 08:21:07 +08:00
Andrew Nicols 6be0f7be06 MDL-77559 js: Revert "MDL-75012 js: Update browserslist"
This reverts commit 4f2e19bb73.
2023-03-09 08:21:03 +08:00
Andrew Nicols 78fd0486c8 MDL-77559 js: Revert "MDL-75012 js: Bump node-sass"
This reverts commit daa7fe6afa.
2023-03-09 08:20:57 +08:00
Andrew Nicols 88e822b7aa MDL-77559 js: Revert "MDL-75012 js: Audit fix"
This reverts commit e2c7dd3d43.
2023-03-09 08:20:53 +08:00
Andrew Nicols ba484e50c8 MDL-77559 js: Revert "MDL-75012 js: Bump shifter to new version"
This reverts commit 3bf5ec446f.
2023-03-09 08:20:49 +08:00
Andrew Nicols 3667cf8429 MDL-77559 js: Revert "MDL-75012 js: Put shifter on a diet"
This reverts commit 7d58caa23a.
2023-03-09 08:20:45 +08:00
Andrew Nicols 6de86a8a2b MDL-77559 js: Revert "MDL-75012 js: Remove unused babel-preset-minify"
This reverts commit 8ed6cc973c.
2023-03-09 08:20:42 +08:00
Andrew Nicols 3521e03fd2 MDL-77559 js: Revert "MDL-75012 js: Bump Babel dependencies"
This reverts commit bf99f67aae.
2023-03-09 08:20:13 +08:00
Ilya Tregubov 16534d538e Merge branch 'MDL-77414-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-08 17:06:48 +08:00
Angelia Dela Cruz 5c32629d04 MDL-77414 Behat: Coverage for "Require all group members submit" setting 2023-03-08 14:57:18 +08:00
Petr Skoda f99ae1651a MDL-77524 filter_algebra: fix error message 2023-03-08 11:27:53 +08:00
Paul Holden d4389e4a0e MDL-75517 report_participation: filter report by viewable roles only. 2023-03-08 10:38:51 +08:00
Michael Hawkins 11acdd8532 MDL-77204 mod_wiki: Clean filename in Moodle1 backup 2023-03-08 10:34:44 +08:00
Paul Holden 5a9cc63733 MDL-77046 availability: validate profile field in condition. 2023-03-08 10:24:52 +08:00
Paul Holden 1632e59179 MDL-76809 gradereport_history: pre-filter report userids filter.
Ensure current user is able to access each of the provided userids.
2023-03-08 10:01:55 +08:00
Ilya Tregubov 1056e8ba25 Merge branch 'MDL-77446-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-08 09:20:38 +08:00
Petr Skoda bb7163fc2b MDL-76645 filter_data: fix link title attribute 2023-03-07 14:55:07 +00:00
Lars Bonczek eb5037adaf MDL-75659 core: Don't render component argument twice in mustache pix helper 2023-03-07 14:55:07 +00:00
Angelia Dela Cruz e25151c437 MDL-77446 Behat: Add coverage for changing uploaded file details 2023-03-07 16:15:44 +08:00
Jun Pataleta 9d3320dd6f Merge branch 'MDL-77428-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-03 16:34:44 +08:00
Jake Dallimore 2f8fd40195 weekly release 3.9.19+ 2023-03-03 11:08:50 +08:00
Angelia Dela Cruz 72f1926ed9 MDL-77428 Behat: Add coverage for forum post word count 2023-03-02 13:50:04 +08:00
Jun Pataleta 121012741d Merge branch 'MDL-75012-39-5' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-02 12:22:35 +08:00
Jake Dallimore 457d2b5e2e Merge branch 'MDL-77461-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-03-02 11:43:33 +08:00
Andrew Nicols c696306936 MDL-77461 behat: Use get_course_id instead of DB fetch 2023-03-02 11:08:12 +08:00
Jun Pataleta ef80cb5890 Merge branch 'MDL-77413-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-03-02 09:45:35 +08:00
Jun Pataleta 5ecae9254a Merge branch 'MDL-77417_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-03-01 23:52:58 +08:00
Andrew Nicols 05f35b612d Merge branch 'MDL-72727-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-03-01 10:48:20 +08:00
Andrew Nicols 45947bca5f MDL-75012 js: Full build of all grunt things 2023-02-28 23:30:56 +08:00
Andrew Nicols bf99f67aae MDL-75012 js: Bump Babel dependencies
Please note that whilst some dependencies have higher versions
available, these are not compatible at this time.
2023-02-28 23:19:40 +08:00
Angelia Dela Cruz 6cd8ffb6c0 MDL-77413 Behat: Minor changes to optimise the existing tests 2023-02-28 17:40:49 +08:00
Angelia Dela Cruz b64c2aeb13 MDL-77413 Behat: Add coverage to verify groups can have a picture 2023-02-28 17:39:46 +08:00
Andrew Nicols 8ed6cc973c MDL-75012 js: Remove unused babel-preset-minify 2023-02-28 11:10:35 +08:00
Andrew Nicols 7d58caa23a MDL-75012 js: Put shifter on a diet
This commit switches to a new custom version of Shifter which sees it
put on a massive diet.

Many of the standard Shifter features are totally unused by Moodle, but
they add dependency spaghetti. Some of those dependencies will start to
cause us issues as they have not been updated for a very long time, are
no longer maintained, and are no longer compatible with anything
resembling a recent version of NodeJS.
2023-02-28 11:10:34 +08:00
Andrew Nicols 3bf5ec446f MDL-75012 js: Bump shifter to new version
This resolves an issue identified in 77083 which identified that GitHub
hashes shouldn't be treated as repeatable.

Whilst GitHub have reverted this change, it's still worth making this
change.
2023-02-28 11:10:34 +08:00
Andrew Nicols e2c7dd3d43 MDL-75012 js: Audit fix 2023-02-28 11:10:34 +08:00
Andrew Nicols daa7fe6afa MDL-75012 js: Bump node-sass 2023-02-28 11:10:34 +08:00
Andrew Nicols 4f2e19bb73 MDL-75012 js: Update browserslist 2023-02-28 11:10:34 +08:00
Paul Holden 81ad3f094d MDL-72727 mod_forum: prevent default favourite toggle click event.
Allow the repository call to the web service method to complete before
re-directing, otherwise the call may not complete and/or races against
the page reload causing random Behat errors.
2023-02-27 23:32:23 +00:00
Eloy Lafuente (stronk7) 9f83c03275 MDL-77417 behat: behat_error_handler meets deprecation error types
Right now, any E_DEPRECATED, E_USER_DEPRECATED error type leads
to exception in behat runs, because the behat error handled is
not aware of them. See MDL-38041 for the initial implementation.

We don't want that to happen and they must behave like other "low"
error types (notices, warnings...), that will be reported in logs
or output, but won't trigger any exception, so the test can continue.

This commit just adds those 2 "new" error types to the handler,
providing the very same behaviour for them than the rest.
2023-02-27 09:39:01 +01:00
Andrew Nicols 2cfb12db0e MDL-75012 js: Bump stylelint and components 2023-02-27 15:03:16 +08:00
Andrew Nicols d6ac705d63 MDL-75012 js: Remove grunt-contrib-uglify
We stopped using this when we updated our processes to support ESMs in
MDL-62497. Removal of the dependency was missed at the time.
2023-02-27 15:03:16 +08:00
Andrew Nicols 0872d00857 MDL-75012 js: Bump standard dependencies
This change bumps dependencies which have no impact upon the build
process
2023-02-27 15:03:16 +08:00
Andrew Nicols f6559c6eaf MDL-75012 core: Bump NodeJS version requirements 2023-02-27 15:03:16 +08:00
Jun Pataleta 9ebd08c452 weekly release 3.9.19+ 2023-02-24 15:43:39 +08:00
Matt Porritt e1a05fd2ee MDL-77376 Licensing: Update trademark.txt
Update Trademark policy in TRADEMARK.txt to
be in line with advice from the Moodle HQ
legal team
2023-02-24 12:37:37 +08:00
Andrew Nicols 260d45cdb1 Merge branch 'MDL-76843_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2023-02-23 11:53:45 +08:00
Andrew Nicols 63c3cb0312 Merge branch 'MDL-77271-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-02-23 11:49:59 +08:00
Tim Hunt 9e1671f1ea MDL-76843 questions behat: enhancements requried to test this issue
* New steps to set up certian sorts of broken test data.
* Fix qtype_essay_question::un_summarise_response().
2023-02-22 15:34:41 +00:00
Simey Lameze a20cab3aad MDL-77271 behat: verify user licence preference is remembered 2023-02-22 09:31:58 +08:00
Ilya Tregubov 687f8a8479 weekly release 3.9.19+ 2023-02-17 09:12:36 +08:00
Ilya Tregubov f3dc49171b Merge branch 'MDL-75230-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-15 16:13:56 +08:00
Ilya Tregubov bc72c006b1 Merge branch 'MDL-77189-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-02-13 13:45:06 +08:00
Simey Lameze 75103c45dc MDL-77189 behat: basic coverage for wikimedia repository 2023-02-13 13:24:10 +08:00
Paul Holden a0e0aaadcc weekly release 3.9.19+ 2023-02-10 13:47:43 +00:00
Angelia Dela Cruz 7f6ea348ef MDL-75230 behat: Lesson Behat tests optimised
Replace steps that manually add Lesson instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2023-02-10 08:42:16 +08:00
Andrew Nicols 3977956e75 Merge branch 'MDL-76499-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-09 10:08:23 +08:00
Jun Pataleta 34d69085c0 Merge branch 'MDL-74905_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-02-08 17:19:03 +08:00
Andrew Nicols 88cef90bec Merge branch 'MDL-77132-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-02-07 10:47:27 +08:00
Paul Holden f077d83df1 Merge branch 'MDL-77078-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-06 13:33:11 +00:00
Angelia Dela Cruz 0a7e544418 MDL-77078 Behat: Coverage for assignment submission statement 2023-02-06 12:36:36 +08:00
Andrew Nicols b235008ebe Merge branch 'MDL-76662-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-02-04 21:53:37 +08:00
Eloy Lafuente (stronk7) 9c13055211 MDL-74905 ci: travis and gha, some adjustments
Apply for some of the improvements made for 4.2:
- Use our own moodlehq/mysql-action
- Define the tmpfs size and ensure that binlogs are disabled.
2023-02-03 19:48:20 +01:00
Eloy Lafuente (stronk7) 28bbf01761 MDL-74905 environment: Apply agreed changes:
- PHP 8.0 required.
- Moodle 3.11.8 required (first minor supporting PHP 8.0 officially).
- MySQL 8.0 required.
- MariaDB 10.6.7 required.
- PostgreSQL 13 required.
- php-sodium extension required.
- 64-bit PHP required.
2023-02-03 19:48:20 +01:00
Eloy Lafuente (stronk7) 33467d709c MDL-74905 environment: 4.2 base information
This is a direct copy of the 4.1 information, to
have all the real changes under control in next commit(s).
2023-02-03 19:48:20 +01:00
Paul Holden f3142c10a7 MDL-77132 phpunit: fix data provider method names.
Orginally missed in 1d74ef12 when only the notation was updated,
excluding the actual provider method names.
2023-02-03 10:57:07 +00:00
Jun Pataleta e23d81ca40 weekly release 3.9.19+ 2023-02-03 15:43:51 +08:00
Angelia Dela Cruz 1f81646cbb MDL-76499 behat: Resource Behat tests optimised
Replace steps that manually add resource instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.

Co-authored-by: David Woloszyn <david.woloszyn@moodle.com>
2023-02-03 14:34:42 +08:00
Andrew Nicols 6417d9c239 Merge branch 'MDL-75830-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-02 11:59:16 +08:00
Andrew Nicols 398323186d Merge branch 'MDL-76675_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2023-02-02 11:05:03 +08:00
Andrew Nicols 7e0858ce24 Merge branch 'MDL-75912-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-02 09:45:20 +08:00
Angelia Dela Cruz 1f0b64e4b8 MDL-75830 behat: Book behat tests optimised
Replace steps that manually add Book instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
Additionally, performed Behat cleanup and optimisation to affected
files.
2023-02-02 08:59:47 +08:00
Paul Holden 2170957e21 Merge branch 'MDL-76658-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-02-01 16:34:47 +00:00
Ilya Tregubov 47c28805bf Merge branch 'MDL-76587-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-02-01 13:27:30 +08:00
Angelia Dela Cruz 52705b73f5 MDL-75912 behat: Wiki Behat tests optimised
Behat cleanup and optimisation
2023-02-01 11:38:00 +08:00
Angelia Dela Cruz cd4916f0e7 MDL-76658 Behat: Coverage for course cohort enrolment groups
Co-authored-by: Simey Lameze <simey@moodle.com>
2023-01-31 20:04:58 +08:00
Simey Lameze 8f942e6e59 MDL-76587 behat: make grading page wider to avoid 'out of bounds' fail
This is because on classic theme the navigation block pushes the content
to the right and once behat changes the grades the 'Save changes' button
is no longer visible.
2023-01-31 11:21:38 +08:00
Andrew Nicols 2fb08b1a82 Merge branch 'MDL-77040-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-01-30 12:28:49 +08:00
Eloy Lafuente (stronk7) f4be9af77e MDL-76675 date: Only test all TZ names with PHPUNIT_LONGTEST enabled
It happens often that some timezone is renamed, split, added to the
IANAs list of timezones (that, for PHP is kept updated by the
php-timezonedb PECL extension).

When the information coming from the extension changes, all the
PHPUnit jobs in the world start failing (that's when CIs update
their PHP images, when devs update their packages, ...).

So, what we are doing here is to move that test that check for
every single string existing to be run only when PHPUNIT_LONGTEST
is enabled. That way only places running all tests will run that
one. And every other run just will skip it.

This corresponds to point 1 & 2 of the issue, lower impact in general
and, still be able to enable the tests to run.
2023-01-27 08:50:44 +01:00
Paul Holden 9c06ad7c0e MDL-77040 core: assert types of returned Geoplugin data, not values.
The results we get from these tests are beyond our control, and are
unreliable for use in testing.

See also previous change 215cd2d8 in similar tests.
2023-01-26 13:24:21 +00:00
Paul Holden 98b361c489 MDL-76662 tool_log: correct supported reports test assertions. 2023-01-26 13:08:55 +00:00
Sara Arjona 0f635409c2 weekly release 3.9.19+ 2023-01-26 09:59:25 +01:00
Jun Pataleta b4489cb423 Merge branch 'MDL-76977-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-01-25 16:08:22 +08:00
Jun Pataleta c0b23f5e20 Merge branch 'MDL-77036-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-01-25 16:00:09 +08:00
Simey Lameze 9f5c27e117 MDL-77036 core_iplookup: update test_ipv4 test expectations 2023-01-25 15:27:22 +08:00
Jun Pataleta 9f02db13e2 Merge branch 'MDL-76639-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-01-24 18:59:01 +08:00
Jun Pataleta 3cd414a328 Merge branch 'MDL-76655-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2023-01-24 18:26:39 +08:00
Angelia Dela Cruz e675506687 MDL-76655 behat: Coverage for workshop grading strategies 2023-01-24 10:21:53 +08:00
Paul Holden b460bbc0c5 MDL-76977 phpunit: ensure unique data provider keys in mustache test. 2023-01-20 17:31:32 +00:00
Ilya Tregubov cf48a979ae weekly release 3.9.19+ 2023-01-20 09:41:53 +08:00
Ilya Tregubov 873fbf39c7 Merge branch 'MDL-76870-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2023-01-19 11:17:12 +08:00
Andrew Nicols 138ff31ef0 Merge branch 'MDL-76841-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-01-19 08:56:02 +08:00
Andrew Nicols d8e2154b8c Merge branch 'MDL-70070-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-01-19 08:51:57 +08:00
Paul Holden b3da8767ad MDL-76841 tool_mobile: improve potential config issues test.
Avoid certificate checking of the default test site (`example.com`),
and update the assertion so we get clearer failures in the future.
2023-01-16 08:30:23 +00:00
Paul Holden 1d74ef1255 MDL-70070 phpunit: correct data provider method names.
They should not be prefixed `test_` because that's how actual
test methods containing assertions are identified by PHPUnit.
2023-01-16 08:28:14 +00:00
Jun Pataleta fc01a52823 Moodle release 3.9.19 2023-01-14 14:16:56 +08:00
Simey Lameze 70bb1b7d0a MDL-76870 question: change assertion to assertEqualsCanonicalizing
By using that assertion the arrays will be sorted before comparison
preventing any Oracle sorting related failures.

Credits for the solution go to Tim Hunt!
2023-01-13 18:13:32 +08:00
Angelia Dela Cruz 871e392987 MDL-76639 behat: Add Behat test coverage for quiz with limited attempts 2023-01-13 16:34:59 +08:00
Jun Pataleta d84283e8cc weekly release 3.9.18+ 2023-01-13 10:52:29 +08:00
Jake Dallimore 9f1768c098 MDL-76862 user: Unit test for setting user home page preferences 2023-01-12 11:25:57 +08:00
Paul Holden 4babd8cdb7 MDL-76862 user: ensure user can only update own preferred start page. 2023-01-12 11:17:25 +08:00
Tim Hunt 312318201b MDL-76810 redirect handling: ensure return URLs are properly sanitised 2023-01-11 11:44:41 +08:00
Paul Holden 3d9ac7137e Merge branch 'MDL-76811-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2023-01-10 16:40:08 +00:00
Andrew Nicols 838e230d54 MDL-76811 mod_data: Remove duplicate tests 2023-01-10 11:19:14 +08:00
Andrew Nicols c26ac2e85d MDL-76811 mod_data: strpos check should be strict 2023-01-10 11:19:13 +08:00
Andrew Nicols ee3504f673 MDL-76811 mod_data: Generator test cleanup 2023-01-10 11:19:13 +08:00
Paul Holden 31256fae74 weekly release 3.9.18+ 2023-01-05 10:53:18 +00:00
Sara Arjona 0c91f5a454 Merge branch 'MDL-76375-39' of https://github.com/lucaboesch/moodle into MOODLE_39_STABLE 2023-01-04 16:22:07 +01:00
Luca Bösch 1ab21607a5 MDL-76375 quiz generator: Allow more than one attempt by Behat tests. 2023-01-04 15:15:57 +01:00
Sara Arjona 05fc7360c9 Merge branch 'MDL-76760-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2023-01-02 12:27:59 +01:00
Sara Arjona 4c3211871d weekly release 3.9.18+ 2022-12-29 12:58:01 +01:00
Sara Arjona 95f7d16801 Merge branch 'MDL-76399-patch-39' of https://github.com/ilyatregubov/moodle into MOODLE_39_STABLE 2022-12-29 09:13:54 +01:00
Ilya Tregubov 400b2086ff MDL-76399 behat: switch to appropriate Behat step for selects. 2022-12-29 14:33:55 +07:00
Ilya Tregubov 7ef99eb8cf Merge branch 'MDL-76399-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2022-12-29 09:44:59 +07:00
Paul Holden ab4b2404c7 MDL-76760 tool_behat: defer library loading until service execution.
Ensures that API documentation can be generated without requiring
the presence of the `vendor/` directory.
2022-12-28 10:47:59 +00:00
Ilya Tregubov d859c2875c Merge branch 'MDL-76731_39' of https://github.com/PhilippImhof/moodle into MOODLE_39_STABLE 2022-12-28 15:15:31 +07:00
Philipp Imhof d14ff96dfa MDL-76731 behat: add steps to check for version
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2022-12-22 17:10:57 +01:00
Ilya Tregubov bc53f961e7 weekly release 3.9.18+ 2022-12-22 19:16:44 +07:00
Andrew Nicols 91b2170fdb MDL-75105 tool_behat: Coding style fixes 2022-12-22 12:34:07 +07:00
Andrew Nicols fadadf8a64 Merge branch 'MDL-75105_39_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_39_STABLE 2022-12-22 12:34:07 +07:00
Mark Johnson 65be624c43 MDL-75105 tool_behat: List available data generators
This will find all data generators that can be used in behat via the
'the following "something" exist:' step, and display them in a select
list on the step definitions page.

When a generator is selected, it will fetch the required fields for that
generator and display them on the page.
2022-12-21 08:38:49 +00:00
Paul Holden 3e5d4ba208 MDL-76399 question: switch to appropriate Behat step for selects. 2022-12-16 13:14:02 +00:00
Paul Holden dfea1a4f0d MDL-76399 behat: improvements to "should exist in" thrown exception. 2022-12-16 12:29:06 +00:00
Andrew Nicols 2409994d32 weekly release 3.9.18+ 2022-12-16 09:06:07 +08:00
Sara Arjona 05dd1161a4 Merge branch 'MDL-76674_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-12-14 18:35:14 +01:00
Eloy Lafuente (stronk7) 7ed61f310b MDL-76674 core_lang: Add string for new America/Ciudad_Juarez 2022-12-14 15:52:36 +01:00
Paul Holden 15b8b5cdf0 Merge branch 'MDL-76666_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-12-14 13:22:11 +00:00
Eloy Lafuente (stronk7) e6eb619c08 MDL-76666 local_langimport: Better handling of long locales
Under some linux versions, and depending of the configured
locale categories, it's possible to get a current locally
which length > 255 when calling to setlocale(LC_ALL, 0).

Later, if that long locale is tried to be restored, there
is a "setlocale(): Specified locale name is too long" warning
error.

When that happens we need to split the long locale into
individual chunks and set all the (six) locale categories
supported one by one.

Covered with tests, note that, in practice, this only
happens with linux because it supports 12 locale categories
@ OS level. Both BSD (6) and Windows (5) hardly can reach the limit.

No matter of that, the tests have been designed to ensure that
they pass on all OSs, just the new code only will be executed
on linux.
2022-12-14 12:40:38 +01:00
Andrew Nicols 8826294d5d Merge branch 'MDL-76398-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2022-12-11 20:21:33 +08:00
Sara Arjona cf2780d5c2 weekly release 3.9.18+ 2022-12-09 08:57:16 +01:00
Jun Pataleta 154bf3d9f5 Merge branch 'MDL-73017-M39_add-environment-check-for-versions-not-supporting-php-8-1' of https://github.com/ziegenberg/moodle into MOODLE_39_STABLE 2022-12-07 13:47:35 +08:00
Ilya Tregubov 768d683beb Merge branch 'MDL-76490-39' of https://github.com/paulholden/moodle into MOODLE_39_STABLE 2022-12-06 13:11:31 +03:00
Andrew Nicols 7f8aca035d Merge branch 'MDL-75446-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-12-06 15:21:49 +08:00
Paul Holden 8db1cdf462 MDL-76490 behat: use defined step for interaction with autocomplete. 2022-12-05 14:27:46 +00:00
Marina Glancy 48dc7ef01e MDL-76490 behat: correct step for opening autocomplete in container. 2022-12-05 14:22:08 +00:00
Daniel Ziegenberg d782e76640 MDL-73017 env: Moodle 3.9.x, 3.11.x and 4.0.x do not support PHP 8.1
This commit adds an additional environment check for the unsupported
PHP 8.1 version to Moodle 3.9.x, 3.11.x and 4.0.x.

It also updates the lang string for unsupported PHP version.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-12-05 11:44:03 +01:00
Angelia Dela Cruz e693c811f0 MDL-75446 behat: Workshop behat generators use UI
Replace steps that manually add Workshop instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2022-12-05 17:56:43 +08:00
Sara Arjona d2f37aab56 weekly release 3.9.18+ 2022-12-01 16:08:12 +01:00
Jun Pataleta 8d08094ac3 Merge branch 'MDL-76429_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-11-30 10:52:21 +08:00
Andrew Nicols 8483f7adef Merge branch 'MDL-75960-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-11-29 17:06:06 +08:00
info@eWallah.net 4cffe42b56 MDL-65939 phpunit: Maildigest tests can query a wrong adhoc task 2022-11-29 15:43:45 +08:00
Andrew Nicols 84935b9585 Merge branch 'MDL-76058-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2022-11-29 15:38:39 +08:00
Angelia Dela Cruz bf8f9164c0 MDL-75960 behat: Survey behat generators use UI
Replace steps that manually add Survey instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2022-11-28 10:22:29 +08:00
Eloy Lafuente (stronk7) 64b5af4b58 MDL-76429 composer: Bump to phpwebdriver 1.2.1 for php81 compat
This fix is really only required for Moodle 4.1 and up, that will
be the one supporting php81, but we always apply composer changes
to all branches (supported and security), so we keep them running
the same stuff.

Note this comes with a bunch of other small updates, all them
pretty minor and should not be problematic. Better we get them
than keeping them apart.
2022-11-25 16:27:39 +01:00
Ilya Tregubov 959721b58a weekly release 3.9.18+ 2022-11-25 15:38:36 +03:00
Jun Pataleta 746fa817c1 Merge branch 'MDL-76340-39' of https://github.com/stevandoMoodle/moodle into MOODLE_39_STABLE 2022-11-25 08:21:32 +08:00
Stevani Andolo cfce223e9b MDL-76340 VideoJS: Fix video controls not showing
- Fixed the menu item not being displayed as expected
2022-11-24 22:57:30 +08:00
Paul Holden 375d8ffb56 MDL-76398 behat: broader action menu partial matching by element.
For action menu elements whose trigger element isn't plain text
(e.g. a pix icon), we should be able to match via the title of
that element.
2022-11-21 16:59:31 +00:00
Jun Pataleta f89a47eff8 Moodle release 3.9.18 2022-11-12 12:55:12 +08:00
Sara Arjona 6a16596f78 weekly release 3.9.17+ 2022-11-11 15:02:06 +01:00
Mathew May 7e22b75c28 MDL-71920 libraries: Migrate LTI lib away from pure curl 2022-11-11 12:55:19 +08:00
Mathew May 7d547f726f MDL-71920 core: update filelib opt name definition 2022-11-11 12:55:19 +08:00
Paul Holden 75c9e608ce MDL-75862 backup: omit sesskey for continue buttons using get method.
It's automatically added by the rendered single_button instance when
using post method, so no need to add it unconditionally.
2022-11-10 10:17:50 +08:00
Jun Pataleta fa8591ea3e Merge branch 'MDL-76054_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-11-09 20:08:49 +08:00
David Woloszyn ae8c5e16e9 MDL-76091 lib: Add additional check to local URLs params 2022-11-09 19:24:56 +08:00
Simey Lameze 4fe95b0e61 MDL-76058 behat: send message using data generator 2022-11-09 09:52:22 +08:00
Eloy Lafuente (stronk7) 5425233b37 MDL-76054 environment: Remove the php-xmlrpc extension check
For Moodle 4.1 and up, the php-xmlrpc is not needed anymore:
- All the MNet stuff has been moved to use php library (MDL-76055).
- The webservice/xmlrpc has been moved from core to contrib (MDL-76052).

So we just remove the check here. Starting with 4.1, it's not
needed for any core functionality.

No lang string changes in this branch, only in master (4.1dev).
2022-11-08 16:47:53 +01:00
Stevani Andolo dcc561762b MDL-75278 VideoJS: Update VideoJS to use validation helper 2022-11-08 13:57:20 +00:00
Víctor Déniz 6307f8dd89 weekly release 3.9.17+ 2022-11-08 13:44:57 +00:00
Jun Pataleta 1a3e679835 Merge branch 'MDL-76207-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-11-08 10:25:12 +08:00
Andrew Nicols 6cfdd1bbae Merge branch 'MDL-75880_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-11-07 21:57:45 +08:00
Andrew Nicols 56a368facf MDL-76207 contentbank: Switch to opened window 2022-11-06 21:00:33 +08:00
Eloy Lafuente (stronk7) 4842ae967c MDL-75880 phpunit: fix all @coversDefaultClass missing @covers
Because @coversDefaultClass doesn't indicate any coverage (it's
just an alias to avoid having to write the class name in @covers),
this commit fixes all the files that were using that annotation
and missing any @covers.

Basically, replacing one by the other and done.
2022-11-04 16:51:36 +01:00
Sara Arjona 6f62e05a96 weekly release 3.9.17+ 2022-11-04 14:52:11 +01:00
Jun Pataleta 6f23e028dd Merge branch 'MDL-76103-39' of https://github.com/junpataleta/moodle into MOODLE_39_STABLE 2022-11-04 11:34:02 +08:00
Marina Glancy ff013438d6 MDL-76103 search: skip solr behat tests if solr is not installed 2022-11-04 11:22:27 +08:00
Jun Pataleta 3e0941fb5b Merge branch 'MDL-76072-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2022-11-04 10:37:19 +08:00
Simey Lameze e667c191f8 MDL-76072 tool_lp: only init inlineGrader module if user can grade 2022-11-04 08:04:30 +08:00
Sara Arjona 4566a44f14 Merge branch 'MDL-76169-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-11-03 17:06:28 +01:00
Andrew Nicols 8b2c0d969d MDL-76169 behat: Normalise exception message in should (not) steps
These steps have accepted a NodeElement instance as an argument for some
time, but were trying to cast it to string when formulating exception
messages, making it harder to debug and, in the case of the 'should see'
step, not work at all.

This patch introduces a new function to produce a consistent naming for
them.
2022-11-03 13:28:51 +08:00
Andrew Nicols 32d337a934 MDL-76169 behat: Add improved steps for using action menus
This commit adds new steps related to action menus to support:
* Choosing an item in a named action menu
* Choosing an item in a named action menu within a container
* Confirming that an action menu item does or does not exist in a named
  action menu
* Confirming that an action menu item does or does not exist in a named
  action menu within a container

The existing action menu steps were insufficient as they assume that
there is only one action menu within he container, which is not
necessarily the case.

The existing action menu steps are not non-JS friendly and will error if
JS is disabled, without providing any fallback when one is easily
available.

Unfortunately these steps cannot be used to replace the existing steps
without manual intervention.
2022-11-03 13:28:51 +08:00
Sara Arjona 4e1d36c8bc weekly release 3.9.17+ 2022-10-28 14:09:25 +02:00
Víctor Déniz 87c2aae85c Merge branch 'MDL-75969-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-27 15:45:39 +01:00
Jun Pataleta 8c6831f0fe weekly release 3.9.17+ 2022-10-25 17:17:19 +08:00
Andrew Nicols 5dbc672825 Merge branch 'MDL-76049_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2022-10-25 11:50:46 +08:00
Ilya Tregubov b97d313c11 weekly release 3.9.17+ 2022-10-21 15:33:55 +03:00
Tim Hunt ee0b0b4fc8 MDL-76049 quiz generator: update calendar events for new overrides 2022-10-20 23:44:54 +01:00
Andrew Nicols 5b707aa422 MDL-75985 behat: Return newline character for \n
Somehow part of this commit was lost during the push and/or squash.
2022-10-19 22:02:55 +08:00
Sara Arjona 519ba9e103 Merge branch 'MDL-76010_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-10-19 12:56:39 +02:00
Jun Pataleta c3a318e16a Merge branch 'MDL-75985-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-19 10:55:28 +08:00
Eloy Lafuente (stronk7) faf63d076d MDL-76010 behat: New scenario to verify that manual attempts work
This is basically the manual background that was removed in the
previous commit, with 4 attempts here. Note it includes the 2
waits that are REQUIRED to make it pass in too-quick environments.

If they are removed, they begin to fail because it seems that
the attempts need a minimum of separation between them.
2022-10-18 14:28:14 +02:00
Eloy Lafuente (stronk7) b1fe51cf0d MDL-76010 behat: Move feature to use attempts generator
This moves away from manual attempts and uses the activity
attempts generator instead. Quicker and not exposed to the
problems with clicks, refreshes and missing attempts.

Note that there is a small change in the attempt generator
so, now, when a new attempt is created, if the activity has
tracking enabled, the final result / grades are recalculated.

That's the real behaviour when the activity settings are
changes in the edition form and it's natural to get them
recalculated without having to visit the form. Specifically,
this allows the 1st scenario to pass, because in that scenario
no changes to the form are being performed.

Also, little detail, amend a dupe scenario name.
2022-10-18 14:28:14 +02:00
Sara Arjona 651a97efc0 weekly release 3.9.17+ 2022-10-18 13:10:01 +02:00
Víctor Déniz cd8af2d23a Merge branch 'MDL-75983_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-10-18 01:09:35 +01:00
Sara Arjona 8b75bb1772 Merge branch 'MDL-72836-39' of https://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2022-10-17 16:40:07 +02:00
Andrew Nicols b672263e04 MDL-75969 behat: Allow the editor field to request a save
Some editors do not immediately store their content to the textarea they
represent and only do so when the form is submitted or they are
requested to.

This change adds to the existing API to allow an (optional)
`store_current_value` function to be defined for the editor type so that
it can use the JavaScript API to persist any current content to the
editor.
2022-10-14 23:46:25 +08:00
Andrew Nicols 1b506c9639 MDL-75985 behat: Standardise HTML output when comparing editor content
This commit adds a standardise_html function and updates the matches
function to compare normalised content.

This allows for a wider variety of valid editor output to be handled
using the standard value matching steps in Behat, thus supporting
editors other than Atto better.
2022-10-14 23:44:11 +08:00
Eloy Lafuente (stronk7) c463d72821 MDL-75983 gha: Update used actions to be node16 compatible
Node12 is being deprecated in github for actions:

https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/

So we need to ensure we are using node16 actions.
2022-10-14 13:28:33 +02:00
Sara Arjona 162053448e weekly release 3.9.17+ 2022-10-14 12:49:26 +02:00
Sara Arjona 2034d440af Merge branch 'MDL-75959-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-13 16:03:50 +02:00
Jun Pataleta 70f7efe0fe Merge branch 'MDL-75887-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-12 09:22:17 +08:00
Simey Lameze f1447db751 MDL-75887 behat: Add ability to set value regardless of the editor
Prior to this commit, the behat_form_editor integration was hard-coded
to use Atto.

This change allows other editors to be used to set editor values, and
breaks that hard bond. Following this change, any editor is able to
define a behat_editor_[name].php file defining a function which meets
the following signature:

  set_editor_value(string $editorid, string $value): void

Each editor is responsible for checking whether its own API is available
and calling any relevant functions to force the editor to set the
content.

Please note: Behat is unable to determine the current editor in use on
the page automatically.
2022-10-12 06:44:30 +08:00
Andrew Nicols 7fc01a94e2 MDL-75959 customfield: Correct inappropriate class import
I suspect this was an incorrect tab completion import by an IDE which
was missed.
2022-10-12 06:40:26 +08:00
Jun Pataleta 568e72e7dc weekly release 3.9.17+ 2022-10-11 23:16:45 +08:00
Jun Pataleta 5d4db3dce3 Merge branch 'MDL-75909-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-10 18:07:58 +08:00
Jun Pataleta e5c7b50d85 Merge branch 'MDL-75922-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-10 14:54:04 +08:00
Jun Pataleta 9fda41582c Merge branch 'MDL-75910-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-10 11:06:49 +08:00
Simey Lameze bddacfd5d7 MDL-75922 behat: Apply @editor_atto tag to tests requiring Atto
These steps are currently using Atto-specific UI features and must
therefore make use of the @editor_atto tag to ensure that they continue
to run using Atto.

A new issue will be raised to migrate each of these to be
editor-agnostic.
2022-10-09 20:28:07 +08:00
Michael Hawkins f3d9759375 MDL-72836 core: Updated security.txt expiry and policy URL 2022-10-07 14:12:23 +08:00
Andrew Nicols 1d776476b6 weekly release 3.9.17+ 2022-10-07 13:04:06 +08:00
Simey Lameze fca9778023 MDL-75910 core_form: Allow editor field to set a hidden label
When an editor is used in a form as part of a group, it is missing its
label element.

This happens because there is no inline template for the editor, and
therefore it reverts to using the old `toHtml` function. The legacy
function does not cater to the editor being in a group, and therefore
does not add the hidden label.

In addition, the hiddenLabel attribute was missing from the editor
element. This is a semi-standard element but must be added to each
supporting element.

Both the missing inline template for the editor, and the hidden label
attribute must be present:
- If the hidden label attribute is not present, then the standard inline
  template will add a visible label within the group.
- If the inline editor template is missing, then the label is not shown
  at all.
2022-10-06 22:54:20 +08:00
Andrew Nicols 482de4e370 MDL-75909 mod_data: Make template editor use html editor
When the template editor is configured to use the HTML Editor, it should
indicate this to Behat by setting the `data-fieldtype` to "editor".

This indicates to the behat field manager that the editor is in use,
which ensures that the correct value setting can take place.

This is important in the context of MDL-75887.
2022-10-06 21:49:08 +08:00
Shamim Rezaie 91f43dd47f Merge branch 'MDL-75886-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-10-06 12:25:07 +11:00
Andrew Nicols fa9ba48533 MDL-75886 atto: Always use Atto for @atto tests
This change, which should be easy to mimic for other editors.

This will ensure that the correct editor is used for tests relating to
that editor, or its subplugins.
2022-10-05 09:57:54 +08:00
Jake Dallimore 141657a483 weekly release 3.9.17+ 2022-09-30 10:17:43 +08:00
Jun Pataleta c8be5a9ab3 Merge branch 'MDL-75559-39' of https://github.com/andrewnicols/moodle into MOODLE_39_STABLE 2022-09-29 10:53:14 +08:00
Jun Pataleta 507f737266 Merge branch 'MDL-75726_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-09-28 08:12:26 +08:00
Jun Pataleta 6d75761b94 Merge branch 'MDL-75776_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-09-28 08:06:32 +08:00
Eloy Lafuente (stronk7) 52a9113c6d MDL-75726 ci: Bump GHA to Ubuntu 22.04
Have tried to also bump Travis to 22.04 (jammy) but it
was not working ok, with problems trying to find both
PHP and PostgreSQL versions.

Surely that's because 22.04 support is really new (Sep 9, 2022):

https://blog.travis-ci.com/22-9-9-ubuntujammy

So we'll have to wait a little more before being able to, also,
bump Travis to use 22.04
2022-09-22 17:45:23 +02:00
Eloy Lafuente (stronk7) 94f703e1d1 MDL-75776 composer: minor updates
In stables, just minors updates to components.

Generated using the instructions @ https://docs.moodle.org/dev/Composer
and using PHP 7.2 (always the min version supported) to generate the
lock file.
2022-09-22 17:44:51 +02:00
Eloy Lafuente (stronk7) d9ceef45de weekly release 3.9.17+ 2022-09-22 17:05:56 +02:00
Jun Pataleta 1ad332bbde Merge branch 'MDL-75757_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-09-19 13:01:43 +08:00
Eloy Lafuente (stronk7) d23efa1ff2 MDL-75757 phpunit: Add some tolerance to a few failing assertions
Recently, PHPUnit (all versions) did some changes about how the
comparators worked and this has caused some float comparisons
to stop working.

We need to move them to assertEqualsWithDelta(), allowing a small
tolerance to workaround the floats comparison problem.

0.00001 has been decided. And applied to all the similar assertions
within the unittest function, so if more cases are added to them
better be copied with the agreed tolerance.
2022-09-18 16:02:18 +02:00
Andrew Nicols bf1ebf3b44 MDL-75559 behat: Sort behat_hooks to top of context list 2022-09-12 12:33:46 +08:00
Eloy Lafuente (stronk7) 33e9b8c394 Moodle release 3.9.17 2022-09-10 12:15:47 +02:00
Jun Pataleta 5bb0f00c0e weekly release 3.9.16+ 2022-09-09 08:36:54 +08:00
Paul Holden 670b636c47 MDL-72012 mod_h5pactivity: respect user access when getting report. 2022-09-08 21:17:57 +08:00
Paul Holden e48460c8cc MDL-75695 mod_h5pactivity: add group filter to attempts report.
This is a backport from MDL-71662.
2022-09-08 17:14:00 +04:00
Michael Hawkins ad5bc5b5ca MDL-68066 output: Apply disable lambda rendering to Mustache renderer 2022-09-07 23:57:05 +08:00
Lars Bonczek 013cb2fb64 MDL-68066 output: Mustache - Add option to disable lambda rendering
This commit is based on an outstanding pull request to the Mustache repo
2022-09-07 23:57:05 +08:00
stevando c4df60bb8d MDL-75283 admin: Update admin user fetching to use sort helper 2022-09-07 13:18:55 +08:00
Paul Holden 786a4956dd MDL-75405 block_html: safer unserialize during old block conversion. 2022-09-06 17:57:15 +02:00
Jun Pataleta 323e272c85 Merge branch 'MDL-75231-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2022-09-06 23:49:01 +08:00
Sara Arjona 6e769797fd Merge branch 'MDL-75550-39' of https://github.com/mickhawkins/moodle into MOODLE_39_STABLE 2022-09-05 08:57:43 +02:00
Jun Pataleta 0a48ddad8f Merge branch 'MDL-75641_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-09-05 14:37:02 +08:00
Eloy Lafuente (stronk7) c939cd4b6d MDL-75641 core_lang: Add string for new Europe/Kyiv timezone
With IANA TZDB (timezone database) release 2022b, Europe/Kiev
has been renamed to Europe/Kyiv. So we need to add this string
to our list to keep tests passing.

Note that the old Europe/Kiev continues working (is an alias) and,
also, there are places in core where we are using it. Just we cannot
remove/replace those uses in core until we ensure that everybody is
using PHP 8.0.23 (TZDB 2022b) or more recent versions. Hence,
not changing those uses now.
2022-09-04 10:06:39 +02:00
Ilya Tregubov fd27acfcb1 weekly release 3.9.16+ 2022-09-02 08:49:23 +04:00
Jun Pataleta 9ae0e4a58b Merge branch 'MDL-75019-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-08-31 20:24:37 +08:00
Ilya Tregubov 874472a85d Merge branch 'MDL-74861-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-08-31 11:51:54 +04:00
Michael Hawkins 5f893f890f MDL-75550 lib: Update Mustache const to reflect correct version
Mustache version 2.14.1 is already included, but the VERSION const
incorrectly listed 2.14.0 in the tagged Mustache release. A later
upstream commit corrected this in the library, which this now matches.
2022-08-31 15:29:59 +08:00
Simey Lameze 69e03eacba MDL-75231 files: make bucket calculations more precise
This commit changes changes the unit test calculations to
keep track of the time the bucket starts/finishes bursting
and use milliseconds instead of seconds to have a precise
time to sleep.
2022-08-22 14:24:09 +08:00
Sara Arjona d369112db4 Moodle release 3.9.16 2022-08-19 09:50:36 +02:00
Sara Arjona 62d603a054 weekly release 3.9.15+ 2022-08-18 14:54:24 +02:00
Laurent David 4cb39164fa MDL-75210 mod_quiz: fix sequential quiz access
* As a student I should only be able to access the next question or the current question
* The API should not show more than the current question
* Once the quiz is previewed we can see the question in any order (existing behaviour)
* Related to ticket MDL-71728

Co-authored-by: Rajneel Totaram <rjnlfj@yahoo.com>
Co-authored-by: Tim Hunt <t.j.hunt@open.ac.uk>
2022-08-18 08:08:50 +04:00
Sara Arjona d5e8561011 Merge branch 'MDL-72178-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-08-16 16:58:50 +02:00
Mark Johnson 944455bcce MDL-75388 lib: Update mustache to 2.14.1
MDL-67114 local change removed as it is now available upstream.
2022-08-12 04:17:17 +02:00
Petr Skoda ee888615ea MDL-75237 core: improve PARAM_SAFEPATH docs 2022-08-12 04:17:17 +02:00
Petr Skoda 3f58d35337 MDL-75237 qformat_blackboard_six: sanitise blackboard import file paths 2022-08-12 04:17:17 +02:00
Petr Skoda 6983a17fc0 MDL-75237 core: Revert MDL-72029
This reverts commit 9f270d956e.
2022-08-12 04:17:17 +02:00
Petr Skoda ce2d88a951 MDL-75237 qformat_blackboard_six: Revert MDL-72029
This reverts commit 47c211ba0e.
2022-08-12 04:17:17 +02:00
Shamim Rezaie 5a4f73d144 weekly release 3.9.15+ 2022-08-12 11:53:00 +10:00
Noel De Martin 1c8396e2b5 MDL-72178 feedback: Implement behat generators
Based on Andrew's WIP from https://github.com/andrewnicols/moodle/commit/b3d40cb20d1f0edf0bf21077c8f94bce5dec56db

Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
2022-08-11 10:59:09 +02:00
Jun Pataleta 5668055015 Merge branch 'MDL-74636_39' of https://github.com/timhunt/moodle into MOODLE_39_STABLE 2022-08-09 11:01:00 +08:00
Angelia Dela Cruz 1dfd13841a MDL-74861 behat: H5P behat generators use UI
Replace steps that manually add H5Pactivity instances via the UI
and use Behat generators. This improves the speed of the Behat test
runs.

Co-authored-by: Simey Lameze <simey@moodle.com>
2022-08-08 12:54:02 +08:00
Jun Pataleta 405cd4fb35 Merge branch 'MDL-74211-39' of https://github.com/lameze/moodle into MOODLE_39_STABLE 2022-08-08 11:15:15 +08:00
Ilya Tregubov 2f4b6bd2d7 Merge branch 'MDL-74475-39' of https://github.com/aanabit/moodle into MOODLE_39_STABLE 2022-08-05 13:21:21 +04:00
Ilya Tregubov acf70635c6 weekly release 3.9.15+ 2022-08-05 13:06:07 +04:00
Angelia Dela Cruz 5d15e96a98 MDL-75019 behat: Folder behat generators use UI
Replace steps that manually add Folder instances via the UI and
use Behat generators. This improves the speed of the Behat test
runs.
2022-08-05 15:53:57 +08:00
Marina Glancy e3b1e103bd MDL-74502 behat: when setting a field value it may not be visible
for example in case of editor field, the textarea element is hidden by wysiwyg widget but we still need to be able to set it
2022-08-04 11:10:43 +08:00
Andrew Nicols 8d1867cdcc Merge branch 'MDL-75080-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-08-04 10:45:25 +08:00
Simey Lameze 2cfa9817b1 MDL-74211 behat: convert few more steps to use new data generators 2022-08-04 10:43:36 +08:00
Andrew Nicols 641b8c31ee Merge branch 'MDL-74655-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-08-04 10:09:22 +08:00
Noel De Martin 6ce1d39f4e MDL-74655 competency: Implement behat generators 2022-08-03 10:49:41 +02:00
Amaia Anabitarte 9d4fb0a3ad MDL-74475 core_badges: Behat test using new step 2022-08-03 10:30:53 +02:00
Amaia Anabitarte 4110054b51 MDL-74475 behat: Option to jump to course edit page 2022-08-03 10:30:53 +02:00
Tim Hunt dd4d110c9b MDL-74636 behat: step to skip this scenario if a plugin isn't installed 2022-07-29 09:50:56 +01:00
Simey Lameze 017f8ff6bf MDL-74211 behat: replace steps to use new categories page type 2022-07-29 13:24:44 +08:00
Simey Lameze 1ff7beef8f MDL-74211 behat: add course question categories page type 2022-07-29 13:24:35 +08:00
Simey Lameze 35783784b3 MDL-74211 quiz: make use of question data generators 2022-07-29 13:13:46 +08:00
Angelia Dela Cruz 194ca4970a MDL-75080 behat: Chat behat generators use UI
Replace steps that manually add Chat instances via the UI and use
Behat generators. This improves the speed of the Behat test runs.
2022-07-29 11:51:46 +08:00
Jun Pataleta d4f3852dd2 weekly release 3.9.15+ 2022-07-29 10:56:51 +08:00
Andrew Nicols 3fbbc7a86b Merge branch 'MDL-73788-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-07-26 11:39:02 +08:00
Jun Pataleta 7cff4e8bc1 Merge branch 'MDL-74057-39-fix' of https://github.com/junpataleta/moodle into MOODLE_39_STABLE 2022-07-26 11:11:23 +08:00
Jun Pataleta 827803ea3d MDL-74057 mod_scorm: Fix unnecessary whitespaces at the end of the file 2022-07-26 11:09:00 +08:00
Jun Pataleta ccb639002f Merge branch 'MDL-74057-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-07-26 11:01:37 +08:00
Angelia Dela Cruz df62f09a4c MDL-74057 behat: SCORM behat generators use UI
Replace steps that manually add SCORM instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-07-25 18:01:00 +08:00
Angelia Dela Cruz 7c0a982958 MDL-73788 behat: URL behat generators use UI
Replace steps that manually add URL instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-07-19 09:18:53 +08:00
Víctor Déniz 940e4da0fa weekly release 3.9.15+ 2022-07-14 12:06:16 +01:00
Jun Pataleta ae531ae852 Merge branch 'MDL-71747_39' of https://github.com/stronk7/moodle into MOODLE_39_STABLE 2022-07-12 10:51:13 +08:00
Jake Dallimore 84d3ae1b08 Moodle release 3.9.15 2022-07-08 11:28:28 +08:00
Eloy Lafuente (stronk7) d51f307ffa MDL-71747 environment: Ensure that check_xmlrpc_usage is in >=39
This is a partial backport of MDL-73270 to ensure that the
check_xmlrpc_usage custom check is present in all the supported
branches and it's applied to all branches able to run php80:

- MOODLE_311_STABLE
- MOODLE_400_STABLE
- master (aka, 4.1 and up)

Note that the whole patch has not been backported, only the
environmental check (xml file and check implementation).
2022-07-07 23:44:36 +02:00
Eloy Lafuente (stronk7) a4018fbcdd MDL-71747 environment: Apply agreed changes
- PHP 7.4 required.
- Moodle 3.9 required.
- MariaDB 10.4 required.
- PostgreSQL 12 required.
- Oracle 19c required.
2022-07-07 19:19:57 +02:00
Eloy Lafuente (stronk7) 2dd34c5ae4 MDL-71747 environment: 4.1 base information
This is a direct copy of the 4.0 information, to
have the changes under control in the next commit.
2022-07-07 19:19:57 +02:00
Jun Pataleta 71f83af13c weekly release 3.9.14+ 2022-07-07 21:33:14 +08:00
Víctor Déniz d587d8b242 Merge branch 'MDL-74835-M39_update-nodejs-version-in-travis-integration-to-lts-gallium' of https://github.com/ziegenberg/moodle into MOODLE_39_STABLE 2022-07-06 12:13:40 +01:00
stevando f1b1570b02 MDL-72171 tool_mobile: Ensure auto login URL is always local 2022-07-06 14:29:10 +08:00
Mihail Geshoski f9ca67a78d MDL-71921 scorm: Sanitize element names before outputting track details 2022-07-01 12:47:18 +02:00
Alex Morris c8f9140e70 MDL-75044 assignfeedback_editpdf: Add SAFER option to GS command
Adds the SAFER option to the Ghostscript command to limit interaction
with IO and OS commands
2022-07-01 12:47:18 +02:00
Huong Nguyen 47c211ba0e MDL-72029 Lesson: Prevent arbitrary file read when importing lesson questions in blackboard format 2022-07-01 12:47:18 +02:00
Huong Nguyen 9f270d956e MDL-72029 lib: Prevent path traversal for clean_param with PARAM_SAFEPATH 2022-07-01 12:47:18 +02:00
Laurent David 32ee8e3d34 MDL-74473 core_analytics: Upgrade ML Backend to 2.6.6 2022-07-01 12:47:18 +02:00
Jake Dallimore 77a1413fa0 MDL-72299 mod_lti: fix html escaping when reposting cross site posts 2022-07-01 12:47:18 +02:00
Víctor Déniz 14760d9787 weekly release 3.9.14+ 2022-07-01 11:28:53 +01:00
Jun Pataleta 03b6b93589 Merge branch 'MDL-74613-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 20:23:48 +08:00
Noel De Martin 47402416fd MDL-74613 grade: Fix undefined behat step 2022-06-30 11:32:35 +02:00
Andrew Nicols 0087cede97 Merge branch 'MDL-75084-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:14:09 +08:00
Andrew Nicols 264c405192 Merge branch 'MDL-74613-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:05:38 +08:00
Andrew Nicols 1742e0c27c Merge branch 'MDL-74220-39' of https://github.com/NoelDeMartin/moodle into MOODLE_39_STABLE 2022-06-30 11:00:59 +08:00
Andrew Nicols 7371cb4838 Merge branch 'MDL-74744-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-06-30 10:56:19 +08:00
Andrew Nicols c1512e8d89 Merge branch 'MDL-74841-39' of https://github.com/andelacruz/moodle into MOODLE_39_STABLE 2022-06-30 10:45:12 +08:00
Jake Dallimore e5aaeed609 Merge branch 'MDL-74674-39' of https://github.com/alfonso-salces/moodle into MOODLE_39_STABLE 2022-06-29 16:45:23 +08:00
Alfonso Salces a950ed04a7 MDL-74674 core: create notification generators 2022-06-29 10:29:33 +02:00
Noel De Martin 964c98c8d9 MDL-75084 blog: Implement behat generators 2022-06-29 09:38:55 +02:00
Jake Dallimore 635389b235 Merge branch 'MDL-74864-39' of https://github.com/dpalou/moodle into MOODLE_39_STABLE 2022-06-29 13:41:31 +08:00
Dani Palou 1385e3bc09 MDL-74864 forum: Allow specifying group in discussions generator 2022-06-28 07:00:18 +02:00
Jun Pataleta 2dc581f717 weekly release 3.9.14+ 2022-06-17 15:30:38 +08:00
Víctor Déniz 4f8369c3f1 Merge branch 'MDL-74242-39-randomize_update_check' of https://github.com/mudrd8mz/moodle into MOODLE_39_STABLE 2022-06-14 09:48:51 +01:00
Jun Pataleta 730b405d68 Merge branch 'MDL-74816-39' of https://github.com/dpalou/moodle into MOODLE_39_STABLE 2022-06-14 13:58:29 +08:00
Angelia Dela Cruz 87c04f1e0b MDL-74841 behat: Label behat generators use UI
Replace steps that manually add Label instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-06-10 13:58:46 +08:00
Andrew Nicols f4df13fb6c weekly release 3.9.14+ 2022-06-03 11:06:38 +08:00
Paul Holden 4a8abf77ac MDL-71276 message_email: include alternate email in privacy export. 2022-06-01 18:48:11 +02:00
Noel De Martin 7e48ec1820 MDL-74613 grade: Add missing generators 2022-05-31 18:15:23 +02:00
Jake Dallimore 05087afd40 weekly release 3.9.14+ 2022-05-27 10:02:16 +08:00
Noel De Martin 56afed9678 MDL-74220 data: Implement behat generators 2022-05-26 10:39:38 +02:00
Paul Holden af8c168f78 MDL-73801 backup: set predictably ordered backup next start time.
Prior to this change, the testcase would assert ordering based on
identical fields which could lead to random failures. Set distinct
next start time of course backup, and also remove random ordering
by sorting on defined course order (all other fields being equal).
2022-05-26 12:10:49 +08:00
Dani Palou 4c52746b41 MDL-74816 mod_resource: Allow specify default file name in generator 2022-05-25 10:41:43 +02:00
Angelia Dela Cruz 7768a35366 MDL-74744 behat: Quiz behat generators use UI
Replace steps that manually add Quiz instances via the UI and use
Behat generators. This improves the speed of Behat test runs.
2022-05-24 11:23:21 +08:00
Daniel Ziegenberg 05847affc1 MDL-74835 ci: Update nodejs version in travis integration to lts/gallium
In MDL-73915 the nodejs version was switched to lts/gallium but the
travis integration was not updated.

Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
2022-05-22 23:55:08 +02:00
David Mudrák f652a2b613 MDL-74242 task: Fix calculation of random minute in the task schedule
The random minute was incorrectly set to a random value from the range
0 - 23 instead of 0 - 59 due to this copy & paste mistake.

This is a backport of MDL-73765 already present in 3.11.
2022-03-20 17:06:51 +01:00
David Mudrák 04d4cbde78 MDL-74242 admin: Check for available updates daily on random time
It's been a mistake to make every Moodle site out there to check for
available update every two hours, on the hour. We are experiencing
server load peaks that are harder and harder to deal with.

The patch addresses this by (1) checking for available updates just once
a day and (2) distributing the checking times randomly around the clock.

This is a backport of MDL-73748 already present in 3.11.
2022-03-20 17:06:51 +01:00
352 changed files with 7691 additions and 3021 deletions
+10 -8
View File
@@ -13,14 +13,14 @@ env:
jobs:
Grunt:
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- name: Checking out code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Configuring node & npm
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
@@ -54,17 +54,17 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-22.04
php: 7.2
db: mysqli
- os: ubuntu-18.04
- os: ubuntu-22.04
php: 7.4
db: pgsql
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: johanmeiring/mysql-action@tmpfs-patch
uses: moodlehq/mysql-action@v1
with:
collation server: utf8mb4_bin
mysql version: 5.7
@@ -72,6 +72,8 @@ jobs:
mysql user: test
mysql password: test
use tmpfs: true
tmpfs size: '1024M'
extra conf: --skip-log-bin
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
@@ -83,7 +85,7 @@ jobs:
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v3.x
uses: rlespinasse/github-slug-action@v4
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
@@ -92,7 +94,7 @@ jobs:
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setting up PHPUnit
env:
+5 -3
View File
@@ -36,7 +36,7 @@ jobs:
- php: 7.2
env: DB=none TASK=CITEST
- php: 7.2
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
env: DB=none TASK=GRUNT NVM_VERSION='lts/gallium'
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.2
@@ -52,7 +52,7 @@ jobs:
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 7.4
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
env: DB=none TASK=GRUNT NVM_VERSION='lts/gallium'
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 7.4
@@ -81,7 +81,8 @@ install:
sudo service mysql stop
sudo mv /var/lib/mysql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/mysql /var/lib/mysql
sudo service mysql restart
echo -e "[mysqld]\nskip-log-bin" | sudo tee -a /etc/mysql/my.cnf
sudo service mysql start
fi
- >
if [ "$DB" = 'pgsql' ];
@@ -92,6 +93,7 @@ install:
sudo mv /var/lib/postgresql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
sudo service postgresql start 9.6
sh -c 'until pg_isready -p 5432; do echo "Waiting for the DB to be up..."; sleep 2; done'
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
+1 -1
View File
@@ -142,7 +142,7 @@ module.exports = function(grunt) {
const path = require('path');
const tasks = {};
const async = require('async');
const DOMParser = require('xmldom').DOMParser;
const DOMParser = require('@xmldom/xmldom').DOMParser;
const xpath = require('xpath');
const semver = require('semver');
const watchman = require('fb-watchman');
+53 -35
View File
@@ -1,48 +1,66 @@
MOODLE TRADEMARKS POLICY
========================
The word "Moodle" is trademarked in many countries around the world. The word
was originally coined as an acronym: Modular Object-Oriented Dynamic Learning
Environment. The trademark is owned by Martin Dougiamas, Founder and Director
of Moodle.
The Moodle Trademark
--------------------
The law obligates trademark owners to police their marks and prevent the use of
confusingly similar names by third parties. Through this policy wed like to
make it clear how Moodle-related projects, organisations, and people can use
the Moodle trademark. Wed also like to be clear about how use of the word is
restricted when used to promote commercial Moodle services. We do this to
protect the very business model that allows us to continue developing Moodle
for you.
The brand and word "Moodle" has trade mark protection in many countries around
the world. Various Moodle™ trade marks are owned by either Moodle Pty Ltd or
one of its associated entities. The law obligates trade mark owners to police
their trade marks and prevent the use of confusingly similar names by
third parties.
Allowed uses
------------
We have created a more concise and thorough set of Trademark Guidelines
(https://moodle.com/wp-content/uploads/2023/02/Moodle-Trademark-Guidelines-2023-4.pdf)
to help you understand how to comply with Moodle's trade mark requirements.
The Trademark Guidelines will also assist our Moodle Certified Partners and the
community to understand some of the principles that inform Moodle's stance
whenever potential infringement has been detected by us or our community.
The following uses dont require any permission at all:
We need to be clear about use of the word "Moodle" and how we restrict its use
when promoting commercial Moodle™ branded services. The proper use of
trade marks reliably assures consumers about the quality of the associated
products or services and where they have been derived from. Because the
Moodle LMS is made available under the open source GNU General Public License'
that permits you to modify the copyrighted software, the distribution of such
modified software in combination with Moodle trade marks can potentially
mislead others in the community. To be clear, the GNU GPL does not include an
implied right or licence to use Moodle's trade marks.
* Referring to the software or the Moodle project.
* Describing your own Moodle implementation (including within corporate
settings).
We do all this to protect the very business model that allows us to continue
developing various Moodle software solutions for you.
Allowed uses of "Moodle"
------------------------
The following uses don't require any permission at all:
* Referring to the software or the Moodle project as the "Moodle™ software"
or the "Moodle™ project"
* Describing your own implementation of the Moodle™ software platform
(including within corporate settings).
* Describing a Moodle-based community hub.
* Describing some software youve made that integrates with Moodle
(eg a Moodle integration feature on another system).
* Describing certain software you've made that integrates with Moodle
branded software (e.g. a Moodle integration feature on another system).
Restricted uses
---------------
Restricted uses of "Moodle"
---------------------------
The following uses are generally prohibited without explicit and direct
permission being granted to you by Moodle Pty Ltd. We do this to protect the
Moodle project from software and sites which could confuse people. Please
contact us to ask for permission in writing.
Moodle project from software and sites which could confuse people. If in
doubt, reach out for clarification at <trademarks@moodle.com>
* You cant use "Moodle" in the name of your software (including Mobile apps)
* You cant use "Moodle" in your company name
* You cant use "Moodle" in your domain name
* You cant use "Moodle" in advertising-related keywords (such as Adsense)
* You cant use "Moodle" to describe services around Moodle (such as hosting,
training, support, consulting, course creation services, theme development,
customisation, installation, integration and certification). This applies
even if you do not charge for the services. Note that usually only Moodle
Partners have this permission.
For information about the Moodle Partner Certification Mark as well as for how
to contact us, please see <https://moodle.com/trademarks/>.
* You can't use the word "Moodle" or any Moodle logos for commercial purposes
without prior written permission from Moodle HQ.
* You can't use "Moodle" in the name of your software (including Mobile apps).
* You can't use "Moodle" in your company name.
* You can't use "Moodle" in your domain name.
* You can't use "Moodle" in advertising-related keywords (such as Adsense).
* You can't use "Moodle" to describe services around Moodle
(such as hosting, training, support, consulting, course creation services,
theme development, customisation, installation, integration, analytics
and certification) that cause consumers to be confused that you are
associated with Moodle HQ if you are not.
This applies even if you do not charge for the services.
Note that usually only Moodle Partners have this permission.
+382
View File
@@ -3371,6 +3371,7 @@
<VENDOR name="oracle" version="11.2" />
</DATABASE>
<PHP version="7.3.0" level="required">
<RESTRICT function="restrict_php_version_81" message="unsupportedphpversion81" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
@@ -3539,6 +3540,8 @@
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.0" requires="3.6">
@@ -3555,6 +3558,7 @@
<VENDOR name="oracle" version="11.2" />
</DATABASE>
<PHP version="7.3.0" level="required">
<RESTRICT function="restrict_php_version_81" message="unsupportedphpversion81" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
@@ -3729,6 +3733,384 @@
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.1" requires="3.9">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="10.4" />
<VENDOR name="mysql" version="5.7" />
<VENDOR name="postgres" version="12" />
<VENDOR name="mssql" version="14.0" />
<VENDOR name="oracle" version="19" />
</DATABASE>
<PHP version="7.4.0" level="required">
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
<ON_CHECK message="pcreunicodewarning" />
</FEEDBACK>
</PCREUNICODE>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_ERROR message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="required">
<FEEDBACK>
<ON_ERROR message="mbstringrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_ERROR message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="required">
<FEEDBACK>
<ON_ERROR message="opensslrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zlib" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="required">
<FEEDBACK>
<ON_ERROR message="gdrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_ERROR message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_ERROR message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlreader" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="required">
<FEEDBACK>
<ON_ERROR message="intlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
<PHP_EXTENSION name="fileinfo" level="required"/>
<PHP_EXTENSION name="sodium" level="optional"/>
<PHP_EXTENSION name="exif" level="optional"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="96M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="opcache.enable" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="opcacherecommended" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
<CUSTOM_CHECKS>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbstorageengine" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
<FEEDBACK>
<ON_ERROR message="quizattemptsupgradedmessage" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
<FEEDBACK>
<ON_CHECK message="slashargumentswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
<FEEDBACK>
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
<FEEDBACK>
<ON_CHECK message="unoconvwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
<FEEDBACK>
<ON_CHECK message="ishttpswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
<FEEDBACK>
<ON_CHECK message="incompleteunicodesupport" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
<FEEDBACK>
<ON_CHECK message="sixtyfourbitswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
<FEEDBACK>
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="4.2" requires="3.11.8">
<UNICODE level="required">
<FEEDBACK>
<ON_ERROR message="unicoderequired" />
</FEEDBACK>
</UNICODE>
<DATABASE level="required">
<VENDOR name="mariadb" version="10.6.7" />
<VENDOR name="mysql" version="8.0" />
<VENDOR name="postgres" version="13" />
<VENDOR name="mssql" version="14.0" />
<VENDOR name="oracle" version="19" />
</DATABASE>
<PHP version="8.0.0" level="required">
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
<ON_CHECK message="pcreunicodewarning" />
</FEEDBACK>
</PCREUNICODE>
<PHP_EXTENSIONS>
<PHP_EXTENSION name="iconv" level="required">
<FEEDBACK>
<ON_ERROR message="iconvrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="mbstring" level="required">
<FEEDBACK>
<ON_ERROR message="mbstringrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="curl" level="required">
<FEEDBACK>
<ON_ERROR message="curlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="openssl" level="required">
<FEEDBACK>
<ON_ERROR message="opensslrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="tokenizer" level="optional">
<FEEDBACK>
<ON_CHECK message="tokenizerrecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="soap" level="optional">
<FEEDBACK>
<ON_CHECK message="soaprecommended" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="ctype" level="required">
<FEEDBACK>
<ON_ERROR message="ctyperequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zip" level="required">
<FEEDBACK>
<ON_ERROR message="ziprequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="zlib" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="gd" level="required">
<FEEDBACK>
<ON_ERROR message="gdrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="simplexml" level="required">
<FEEDBACK>
<ON_ERROR message="simplexmlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="spl" level="required">
<FEEDBACK>
<ON_ERROR message="splrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="pcre" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="dom" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xml" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="xmlreader" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="intl" level="required">
<FEEDBACK>
<ON_ERROR message="intlrequired" />
</FEEDBACK>
</PHP_EXTENSION>
<PHP_EXTENSION name="json" level="required">
</PHP_EXTENSION>
<PHP_EXTENSION name="hash" level="required"/>
<PHP_EXTENSION name="fileinfo" level="required"/>
<PHP_EXTENSION name="sodium" level="required"/>
<PHP_EXTENSION name="exif" level="optional"/>
</PHP_EXTENSIONS>
<PHP_SETTINGS>
<PHP_SETTING name="memory_limit" value="96M" level="required">
<FEEDBACK>
<ON_ERROR message="settingmemorylimit" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="file_uploads" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="settingfileuploads" />
</FEEDBACK>
</PHP_SETTING>
<PHP_SETTING name="opcache.enable" value="1" level="optional">
<FEEDBACK>
<ON_CHECK message="opcacherecommended" />
</FEEDBACK>
</PHP_SETTING>
</PHP_SETTINGS>
<CUSTOM_CHECKS>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbstorageengine" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
<FEEDBACK>
<ON_ERROR message="quizattemptsupgradedmessage" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
<FEEDBACK>
<ON_CHECK message="slashargumentswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
<FEEDBACK>
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
<FEEDBACK>
<ON_CHECK message="unoconvwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfileformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddbfilepertable" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
<FEEDBACK>
<ON_ERROR message="unsupporteddblargeprefix" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
<FEEDBACK>
<ON_CHECK message="ishttpswarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
<FEEDBACK>
<ON_CHECK message="incompleteunicodesupport" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="required">
<FEEDBACK>
<ON_ERROR message="sixtyfourbitsrequired" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_max_input_vars" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_admin_dir_usage" level="optional">
<FEEDBACK>
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mod_assignment" level="required">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
+12
View File
@@ -0,0 +1,12 @@
define("tool_behat/steps",["exports","core/ajax","core/templates","core/pending"],(function(_exports,_ajax,_templates,_pending){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_templates=_interopRequireDefault(_templates),_pending=_interopRequireDefault(_pending);
/**
* Enhancements for the step definitions page.
*
* @module tool_behat/steps
* @copyright 2022 Catalyst IT EU
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
var getRequiredFieldsContent=function(entityData){var _entityData$required;return null!==(_entityData$required=entityData.required)&&void 0!==_entityData$required&&_entityData$required.length?_templates.default.renderForPromise("tool_behat/steprequiredfields",{fields:entityData.required}):Promise.resolve({html:"",js:""})};_exports.init=function(){var fn,_ref;document.addEventListener("change",(fn=regeneratorRuntime.mark((function _callee(e){var entityElement,stepElement,pendingPromise,entityData,_yield$getRequiredFie,html,js,stepRequiredFields;return regeneratorRuntime.wrap((function(_context){for(;;)switch(_context.prev=_context.next){case 0:if(entityElement=e.target.closest(".entities"),stepElement=e.target.closest(".stepcontent"),entityElement&&stepElement){_context.next=4;break}return _context.abrupt("return");case 4:return pendingPromise=new _pending.default("tool_behat/steps:change"),_context.next=7,entityType=e.target.value,_ajax.default.call([{methodname:"tool_behat_get_entity_generator",args:{entitytype:entityType}}])[0];case 7:return entityData=_context.sent,_context.next=10,getRequiredFieldsContent(entityData);case 10:if(_yield$getRequiredFie=_context.sent,html=_yield$getRequiredFie.html,js=_yield$getRequiredFie.js,!(stepRequiredFields=stepElement.querySelector(".steprequiredfields"))){_context.next=19;break}return _context.next=17,_templates.default.replaceNode(stepRequiredFields,html,js);case 17:_context.next=21;break;case 19:return _context.next=21,_templates.default.appendNodeContents(stepElement,html,js);case 21:pendingPromise.resolve();case 22:case"end":return _context.stop()}var entityType}),_callee)})),_ref=function(){var self=this,args=arguments;return new Promise((function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(void 0)}))},function(_x){return _ref.apply(this,arguments)}))}}));
//# sourceMappingURL=steps.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"steps.min.js","sources":["../src/steps.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\nimport Ajax from 'core/ajax';\nimport Templates from 'core/templates';\nimport PendingJS from 'core/pending';\n\n/**\n * Enhancements for the step definitions page.\n *\n * @module tool_behat/steps\n * @copyright 2022 Catalyst IT EU\n * @author Mark Johnson <mark.johnson@catalyst-eu.net>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Call the get_entity_generator web service function\n *\n * Takes the name of an entity generator and returns an object containing a list of the required fields.\n *\n * @param {String} entityType\n * @returns {Promise}\n */\nconst getGeneratorEntities = (entityType) => Ajax.call([{\n methodname: 'tool_behat_get_entity_generator',\n args: {entitytype: entityType}\n}])[0];\n\n/**\n * Render HTML for required fields\n *\n * Takes the entity data returned from getGeneratorEntities and renders the HTML to display the required fields.\n *\n * @param {String} entityData\n * @return {Promise}\n */\nconst getRequiredFieldsContent = (entityData) => {\n if (!entityData.required?.length) {\n return Promise.resolve({\n html: '',\n js: ''\n });\n }\n return Templates.renderForPromise('tool_behat/steprequiredfields', {fields: entityData.required});\n};\n\nexport const init = () => {\n // When an entity is selected in the \"the following exist\" step, fetch and display the required fields.\n document.addEventListener('change', async(e) => {\n const entityElement = e.target.closest('.entities');\n const stepElement = e.target.closest('.stepcontent');\n if (!entityElement || !stepElement) {\n return;\n }\n\n const pendingPromise = new PendingJS('tool_behat/steps:change');\n\n const entityData = await getGeneratorEntities(e.target.value);\n const {html, js} = await getRequiredFieldsContent(entityData);\n\n const stepRequiredFields = stepElement.querySelector('.steprequiredfields');\n if (stepRequiredFields) {\n await Templates.replaceNode(stepRequiredFields, html, js);\n } else {\n await Templates.appendNodeContents(stepElement, html, js);\n }\n pendingPromise.resolve();\n });\n};\n"],"names":["getRequiredFieldsContent","entityData","required","_entityData$required","length","Templates","renderForPromise","fields","Promise","resolve","html","js","document","addEventListener","e","entityElement","target","closest","stepElement","pendingPromise","PendingJS","entityType","value","Ajax","call","methodname","args","entitytype","stepRequiredFields","querySelector","replaceNode","appendNodeContents"],"mappings":";;;;;;;;;IAiDMA,yBAA2B,SAACC,yEACzBA,WAAWC,0CAAXC,qBAAqBC,OAMnBC,mBAAUC,iBAAiB,gCAAiC,CAACC,OAAQN,WAAWC,WAL5EM,QAAQC,QAAQ,CACnBC,KAAM,GACNC,GAAI,oBAMI,uBAEhBC,SAASC,iBAAiB,sCAAU,iBAAMC,oNAChCC,cAAgBD,EAAEE,OAAOC,QAAQ,aACjCC,YAAcJ,EAAEE,OAAOC,QAAQ,gBAChCF,eAAkBG,kFAIjBC,eAAiB,IAAIC,iBAAU,2CAhCfC,WAkCwBP,EAAEE,OAAOM,MAlClBC,cAAKC,KAAK,CAAC,CACpDC,WAAY,kCACZC,KAAM,CAACC,WAAYN,eACnB,iBA+BUpB,0CACmBD,yBAAyBC,2DAA3CS,2BAAAA,KAAMC,yBAAAA,KAEPiB,mBAAqBV,YAAYW,cAAc,wEAE3CxB,mBAAUyB,YAAYF,mBAAoBlB,KAAMC,mEAEhDN,mBAAU0B,mBAAmBb,YAAaR,KAAMC,YAE1DQ,eAAeV,mDA3CM,IAACY"}
+82
View File
@@ -0,0 +1,82 @@
// 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/>.
import Ajax from 'core/ajax';
import Templates from 'core/templates';
import PendingJS from 'core/pending';
/**
* Enhancements for the step definitions page.
*
* @module tool_behat/steps
* @copyright 2022 Catalyst IT EU
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Call the get_entity_generator web service function
*
* Takes the name of an entity generator and returns an object containing a list of the required fields.
*
* @param {String} entityType
* @returns {Promise}
*/
const getGeneratorEntities = (entityType) => Ajax.call([{
methodname: 'tool_behat_get_entity_generator',
args: {entitytype: entityType}
}])[0];
/**
* Render HTML for required fields
*
* Takes the entity data returned from getGeneratorEntities and renders the HTML to display the required fields.
*
* @param {String} entityData
* @return {Promise}
*/
const getRequiredFieldsContent = (entityData) => {
if (!entityData.required?.length) {
return Promise.resolve({
html: '',
js: ''
});
}
return Templates.renderForPromise('tool_behat/steprequiredfields', {fields: entityData.required});
};
export const init = () => {
// When an entity is selected in the "the following exist" step, fetch and display the required fields.
document.addEventListener('change', async(e) => {
const entityElement = e.target.closest('.entities');
const stepElement = e.target.closest('.stepcontent');
if (!entityElement || !stepElement) {
return;
}
const pendingPromise = new PendingJS('tool_behat/steps:change');
const entityData = await getGeneratorEntities(e.target.value);
const {html, js} = await getRequiredFieldsContent(entityData);
const stepRequiredFields = stepElement.querySelector('.steprequiredfields');
if (stepRequiredFields) {
await Templates.replaceNode(stepRequiredFields, html, js);
} else {
await Templates.appendNodeContents(stepElement, html, js);
}
pendingPromise.resolve();
});
};
@@ -0,0 +1,92 @@
<?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/>.
/**
* Return data about an entity generator.
*
* @package tool_behat
* @copyright 2022 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_behat\external;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/externallib.php');
/**
* External function for getting properties of entity generators.
*/
class get_entity_generator extends \external_api {
/**
* Define parameters for external function.
*
* The parameter is either in the format 'entity' or 'component_name > entity'. There is no appropriate param type for a
* string like this containing angle brackets, so we will do PARAM_RAW. The value will be parsed by
* behat_data_generators::parse_entity_type, which validates the format of the parameter and throws an exception if it is not
* correct.
*
* @return \external_function_parameters
*/
public static function execute_parameters(): \external_function_parameters {
return new \external_function_parameters([
'entitytype' => new \external_value(PARAM_RAW, 'Entity type that can be created by a generator.'),
]);
}
/**
* Return a list of the required fields for a given entity type.
*
* @param string $entitytype
* @return array
*/
public static function execute(string $entitytype): array {
global $CFG;
// Ensure we can load Behat and Facebook namespaces in behat libraries.
require_once("{$CFG->dirroot}/vendor/autoload.php");
require_once("{$CFG->libdir}/tests/behat/behat_data_generators.php");
$params = self::validate_parameters(self::execute_parameters(), ['entitytype' => $entitytype]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
$generators = new \behat_data_generators();
$entity = $generators->get_entity($params['entitytype']);
return ['required' => $entity['required']];
}
/**
* Define return values.
*
* Return required fields
*
* @return \external_single_structure
*/
public static function execute_returns(): \external_single_structure {
return new \external_single_structure([
'required' => new \external_multiple_structure(
new \external_value(PARAM_TEXT, 'Required field'),
'Required fields',
VALUE_OPTIONAL
),
]);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?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/>.
/**
* Define web service functions for tool_behat
*
* @package tool_behat
* @copyright 2022 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = [
'tool_behat_get_entity_generator' => [
'classname' => 'tool_behat\\external\\get_entity_generator',
'methodname' => 'execute',
'description' => 'Get the generator details for an entity',
'type' => 'read',
'ajax' => true,
'capabilities' => 'moodle/site:config'
]
];
+1
View File
@@ -56,6 +56,7 @@ if ($components) {
$form = new steps_definitions_form(null, array('components' => $componentswithsteps));
// Output contents.
$PAGE->requires->js_call_amd('tool_behat/steps', 'init');
$renderer = $PAGE->get_renderer('tool_behat');
echo $renderer->render_stepsdefinitions($steps, $form);
+28
View File
@@ -24,6 +24,8 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/behat/classes/behat_generator_base.php');
/**
* Renderer for behat tool web features
*
@@ -106,6 +108,32 @@ class tool_behat_renderer extends plugin_renderer_base {
},
$stepsdefinitions
);
$elementstrings = [];
$count = 1;
$stepsdefinitions = preg_replace_callback('/(the following ")ELEMENT\d?_STRING(" exist:)/',
function($matches) use (&$elementstrings, &$count) {
// Replace element type arguments with a user-friendly select.
if (empty($elementstrings)) {
$behatgenerators = new behat_data_generators();
$componententities = $behatgenerators->get_all_entities();
ksort($componententities);
$elementstrings = [];
foreach ($componententities as $component => $entities) {
asort($entities);
foreach ($entities as $entity) {
$string = ($component === 'core') ? $entity : $component . ' > ' . $entity;
$elementstrings[$string] = $string;
}
}
}
$select = html_writer::select($elementstrings, 'entities' . $count, '', ['' => 'choosedots'],
['class' => 'entities']);
$count++;
return $matches[1] . $select . $matches[2];
},
$stepsdefinitions
);
}
// Steps definitions.
+6
View File
@@ -29,3 +29,9 @@
#page-admin-tool-behat-index .steps-definitions .stepregex {
color: #060;
}
#page-admin-tool-behat-index .steprequiredfields {
font-weight: bold;
font-size: 1em;
margin-top: 1em;
}
@@ -0,0 +1,33 @@
{{!
This file is part of Moodle - https://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/>.
}}
{{!
@template tool_behat/steprequiredfields
Display a Gherkin-style table row showing required columns for a step.
Example context (json):
{
"fields": [
"user",
"role",
"context"
]
}
}}
<pre class="steprequiredfields">
|{{#fields}} {{{.}}} |{{/fields}}
</pre>
@@ -30,10 +30,9 @@ Feature: Verify that all form fields values can be get and set
| student2 | G2 |
| student3 | G2 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | firstpagetitle | wikimode | visible |
| wiki | C1 | wiki1 | Test this one | Test this one | Test this one | collaborative | 0 |
And I log in as "admin"
And I am on "Course 1" course homepage
| activity | course | idnumber | name | firstpagetitle | wikimode | visible |
| wiki | C1 | wiki1 | Test this one | Test this one | collaborative | 0 |
And I am on the "Course 1" course page logged in as admin
And I navigate to "Reset" in current page administration
# Select (multi-select) - Checking "the select box should contain".
And I expand all fieldsets
@@ -61,16 +60,14 @@ Feature: Verify that all form fields values can be get and set
# Checkbox - Checking "I set the field" and "The field matches value" ticked.
And I set the field "Force format" to "1"
And I press "Save and return to course"
And I am on the "Test this one" "wiki activity" page
And I navigate to "Edit settings" in current page administration
And I am on the "Test this one" "wiki activity editing" page
And I expand all fieldsets
And the field "Force format" matches value "1"
And the field "Force format" does not match value ""
# Checkbox - Checking "I set the field" and "The field matches value" unticked.
And I set the field "Force format" to ""
And I press "Save and return to course"
And I am on the "Test this one" "wiki activity" page
And I navigate to "Edit settings" in current page administration
And I am on the "Test this one" "wiki activity editing" page
And I expand all fieldsets
And the field "Force format" matches value ""
And the field "Force format" does not match value "1"
@@ -78,8 +75,7 @@ Feature: Verify that all form fields values can be get and set
And I set the following fields to these values:
| Force format | 1 |
And I press "Save and return to course"
And I am on the "Test this one" "wiki activity" page
And I navigate to "Edit settings" in current page administration
And I am on the "Test this one" "wiki activity editing" page
And I expand all fieldsets
And the following fields match these values:
| Force format | 1 |
@@ -89,8 +85,7 @@ Feature: Verify that all form fields values can be get and set
And I set the following fields to these values:
| Force format | |
And I press "Save and return to course"
And I am on the "Test this one" "wiki activity" page
And I navigate to "Edit settings" in current page administration
And I am on the "Test this one" "wiki activity editing" page
And I expand all fieldsets
And the following fields match these values:
| Force format | |
@@ -136,12 +131,13 @@ Feature: Verify that all form fields values can be get and set
And I navigate to "Edit settings" in current page administration
And the field "Course ID number" matches value "Course id number"
Scenario: with JS disabled all form fields getters and setters works as expected
@javascript
Scenario: with JS enabled all form fields getters and setters works as expected
Then I am on "Course 1" course homepage
And I navigate to "Users > Groups" in current page administration
Given the following "activities" exist:
| activity | course | name |
| lesson | C1 | Test lesson |
When I am on "Course 1" course homepage
Then I navigate to "Users > Groups" in current page administration
# Select (multi-select & AJAX) - Checking "I set the field" and "select box should contain".
And I set the field "groups" to "Group 2"
And the "members" select box should contain "Student 2 (s2@example.com)"
@@ -152,11 +148,8 @@ Feature: Verify that all form fields values can be get and set
And the "members" select box should contain "Student 2 (s2@example.com)"
And the "members" select box should not contain "Student 3 (s3@example.com)"
# Checkbox (AJAX) - Checking "I set the field" and "I set the following fields to these values".
And I am on "Course 1" course homepage
And I add a "Lesson" to section "1"
And I am on the "Test lesson" "lesson activity editing" page
And I set the following fields to these values:
| Name | Test lesson |
| Description | Test lesson description |
| available[enabled] | 1 |
And I set the field "deadline[enabled]" to "1"
# Checkbox (AJAX) - Checking "the field matches value" before saving.
@@ -7,8 +7,8 @@ Feature: Behat steps for interacting with form work
@javascript
Scenario: Test fields in containers
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
| fullname | shortname | summary | summaryformat |
| Course 1 | C1 | Red | 1 |
When I log in as "admin"
And I am on "Course 1" course homepage
# Just get to any form.
@@ -17,11 +17,15 @@ Feature: Behat steps for interacting with form work
And I set the following fields in the "Appearance" "fieldset" to these values:
| Show activity reports | Yes |
| Number of announcements | 1 |
And I set the following fields in the "Description" "fieldset" to these values:
| Course summary | Green |
Then the field "Show activity reports" in the "Appearance" "fieldset" matches value "Yes"
And the field "Show activity reports" in the "Appearance" "fieldset" does not match value "No"
And the following fields in the "region-main" "region" match these values:
| Course full name | Frog |
| Number of announcements | 1 |
| Course summary | Green |
And the following fields in the "region-main" "region" do not match these values:
| Course full name | Course 1 |
| Number of announcements | 5 |
| Course summary | Red |
@@ -13,6 +13,10 @@ Feature: List the system steps definitions
Scenario: Accessing the list
Then I should see "Step definitions"
And I should not see "There aren't steps definitions matching this filter"
And I should not see "the following \"ELEMENT_STRING\" exist:"
And "entities1" "select" should exist
And the "entities1" select box should contain "users"
And the "entities1" select box should contain "mod_assign > submissions"
@javascript
Scenario: Filtering by type
@@ -34,3 +38,11 @@ Feature: List the system steps definitions
Then I should not see "There aren't steps definitions matching this filter"
And I should see "Checks the provided element and selector type exists in the current page."
And I should see "Checks that an element and selector type exists in another element and selector type on the current page."
@javascript
Scenario: Get required fields
Given I set the field "entities1" to "users"
And I should see "| username |"
When I set the field "entities1" to "mod_quiz > user overrides"
Then I should not see "| username |"
And I should see "| quiz | user |"
@@ -20,9 +20,10 @@ Feature: Forms manipulation
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1"
And the following "activities" exist:
| activity | course | section | name |
| quiz | C1 | 1 | Quiz 1 |
And I am on the "Quiz 1" "quiz activity editing" page logged in as admin
When I expand all fieldsets
Then I should see "Close the quiz"
And I should see "Group mode"
@@ -0,0 +1,104 @@
<?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 tests for get_entity_generator web service
*
* @package tool_behat
* @copyright 2022 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_behat\external;
/**
* Tests for get_entity_generator web service
*
* @covers \tool_behat\external\get_entity_generator
*/
class get_entity_generator_test extends \advanced_testcase {
/**
* Log in as admin
*
* @return void
*/
public function setUp(): void {
$this->resetAfterTest();
$this->setAdminUser();
}
/**
* Get the generator for a core entity.
*
* @return void
*/
public function test_execute_core_entity(): void {
$generator = get_entity_generator::execute('users');
$this->assertEquals(['required' => ['username']], $generator);
}
/**
* Get the generator for the plugin entity.
*
* @return void
*/
public function test_execute_plugin_entity(): void {
$generator = get_entity_generator::execute('mod_book > chapters');
$this->assertEquals(['required' => ['book', 'title', 'content']], $generator);
}
/**
* Get the generator for an entity with no required fields.
*
* @return void
*/
public function test_execute_no_requried(): void {
$generator = get_entity_generator::execute('mod_forum > posts');
$this->assertEquals(['required' => []], $generator);
}
/**
* Attempt to get the generator for a core entity that does not exist.
*
* @return void
*/
public function test_execute_invalid_entity(): void {
$this->expectException('coding_exception');
get_entity_generator::execute('foo');
}
/**
* Attempt to get a generator form a plugin that does not exist.
*
* @return void
*/
public function test_execute_invalid_plugin(): void {
$this->expectException('coding_exception');
get_entity_generator::execute('foo > bar');
}
/**
* Attempt to get a generator for an entity that does not exist, from a plugin that does.
*
* @return void
*/
public function test_execute_invalid_plugin_entity(): void {
$this->expectException('coding_exception');
get_entity_generator::execute('mod_book > bar');
}
}
+1 -1
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2020061500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->version = 2020061501; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2020060900; // Requires this Moodle version
$plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
+14 -1
View File
@@ -79,6 +79,19 @@ class locale {
* @return string|false Returns the new current locale, or FALSE on error.
*/
protected function set_locale(int $category = LC_ALL, string $locale = '0') {
return setlocale($category, $locale);
if (strlen($locale) <= 255 || PHP_OS_FAMILY === 'BSD' || PHP_OS_FAMILY === 'Darwin') {
// We can set the whole locale all together.
return setlocale($category, $locale);
}
// Too long locale with linux or windows, let's split it into known and supported categories.
$split = explode(';', $locale);
foreach ($split as $element) {
[$category, $value] = explode('=', $element);
if (defined($category)) { // Only if the category exists, there are OS differences.
setlocale(constant($category), $value);
}
}
return setlocale(LC_ALL, 0); // Finally, return the complete configured locale.
}
}
@@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die();
/**
* Tests for \tool_langimport\locale class.
*
* @coversDefaultClass \tool_langimport\locale
* @copyright 2018 Université Rennes 2 {@link https://www.univ-rennes2.fr}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -34,6 +35,7 @@ class locale_testcase extends \advanced_testcase {
/**
* Test that \tool_langimport\locale::check_locale_availability() works as expected.
*
* @covers ::check_locale_availability
* @return void
*/
public function test_check_locale_availability() {
@@ -68,4 +70,100 @@ class locale_testcase extends \advanced_testcase {
$this->expectException(coding_exception::class);
$locale->check_locale_availability('');
}
/**
* Test \tool_langimport\locale::set_locale() own logic.
*
* We have to explicitly test set_locale() own logic and results,
* that effectively sets the current locale, so we need to restore
* the original locale after every test (ugly, from a purist unit test
* point of view, but needed).
*
* @dataProvider set_locale_provider
* @covers ::set_locale
*
* @param string $set locale string to be set.
* @param string $ret expected results returned after setting the locale.
*/
public function test_set_locale(string $set, string $ret) {
// Make set_locale() public.
$loc = new \tool_langimport\locale();
$rc = new \ReflectionClass(\tool_langimport\locale::class);
$rm = $rc->getMethod('set_locale');
$rm->setAccessible(true);
// Capture current locale for later restore (funnily, using the set_locale() method itself.
$originallocale = $rm->invokeArgs($loc, [LC_ALL, 0]);
// Assert we get the locale defined as expected.
$this->assertEquals($ret, $rm->invokeArgs($loc, [LC_ALL, $set]));
// We have finished, restore the original locale, so this doesn't affect other tests at distance.
// (again, funnily, using the very same set_locale() method).
$rm->invokeArgs($loc, [LC_ALL, $originallocale]);
}
/**
* Data provider for test_set_locale().
*
* Provides a locale to be set (as 'set') and a expected return value (as 'ret'). Note that
* some of the locales are OS dependent, so only the ones matching the OS will be provided.
*
* We make extensive use of the en_AU.UTF-8/English_Australia.1252 locale that is mandatory to
* be installed in any system running PHPUnit tests.
*/
public function set_locale_provider(): array {
// Let's list the allowed categories by OS.
$bsdallowed = ['LC_COLLATE', 'LC_CTYPE', 'LC_MESSAGES', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME'];
$winallowed = ['LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME'];
$linuxallowed = [
'LC_COLLATE', 'LC_CTYPE', 'LC_MESSAGES', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME',
'LC_PAPER', 'LC_NAME', 'LC_ADDRESS', 'LC_TELEPHONE', 'LC_MEASUREMENT', 'LC_IDENTIFICATION'
];
// The base locale name is also OS dependent.
$baselocale = get_string('locale', 'langconfig');
if (PHP_OS_FAMILY === 'Windows') {
$baselocale = get_string('localewin', 'langconfig');
}
// Here we'll go accumulating cases to be provided.
$cases = [];
// First, the simplest case, just pass a locale name, without categories.
$cases['rawlocale'] = [
'set' => $baselocale,
'ret' => $baselocale,
];
// Now, let's fill ALL LC categories, we should get back the locale name if all them are set with same value.
// Note that this case is the one that, under Linux only, covers the changes performed to the set_locale() method.
// Pick the correct categories depending on the OS.
$oscategories = $bsdallowed; // Default to BSD/Dawrwin ones because they are the standard 6 supported by PHP.
if (PHP_OS_FAMILY === 'Windows') {
$oscategories = $winallowed;
} else if (PHP_OS_FAMILY === 'Linux') {
$oscategories = $linuxallowed;
}
$localestr = '';
foreach ($oscategories as $category) {
// Format is different by OS too, so let build the string conditionally.
if (PHP_OS_FAMILY === 'BSD' || PHP_OS_FAMILY === 'Darwin') {
// BSD uses slashes (/) separated list of the 6 values in exact order.
$localestr .= '/' . $baselocale;
} else {
// Linux/Windows use semicolon (;) separated list of category=value pairs.
$localestr .= ';' . $category . '=' . $baselocale;
}
}
$cases['allcategories'] = [
'set' => trim($localestr, ';/'),
'ret' => $baselocale,
];
// Return all the built cases.
return $cases;
}
}
@@ -33,3 +33,27 @@ Feature: Licence manager
And "This is the site default licence" "icon" should exist in the "cc" "table_row"
And "Enable licence" "icon" should not exist in the "cc" "table_row"
And "This is the site default licence" "icon" should not exist in the "public" "table_row"
@javascript @_file_upload
Scenario Outline: User licence preference is remembered depending of setting value
Given the following config values are set as admin:
| sitedefaultlicense | cc |
| rememberuserlicensepref | <rememberuserlicensepref> |
And I log in as "admin"
And I follow "Manage private files..."
And I follow "Add..."
And I follow "Upload a file"
And the field with xpath "//select[@name='license']" matches value "Creative Commons"
And I click on "Close" "button" in the "File picker" "dialogue"
When I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager as:
| Save as | empty_copy.txt |
| license | Public domain |
And I press "Save changes"
And I follow "Manage private files..."
And I follow "Add..."
Then the field with xpath "//select[@name='license']" matches value "<expectedlicence>"
Examples:
| rememberuserlicensepref | expectedlicence |
| 0 | Creative Commons |
| 1 | Public domain |
@@ -32,8 +32,7 @@ class logstore_database_store_testcase extends advanced_testcase {
* Tests log writing.
*
* @param bool $jsonformat True to test with JSON format
* @dataProvider test_log_writing_provider
* @throws moodle_exception
* @dataProvider log_writing_provider
*/
public function test_log_writing(bool $jsonformat) {
global $DB, $CFG;
@@ -251,9 +250,9 @@ class logstore_database_store_testcase extends advanced_testcase {
* Returns different JSON format settings so the test can be run with JSON format either on or
* off.
*
* @return [bool] Array of true/false
* @return bool[] Array of true/false
*/
public static function test_log_writing_provider(): array {
public static function log_writing_provider(): array {
return [
[false],
[true]
@@ -310,17 +309,16 @@ class logstore_database_store_testcase extends advanced_testcase {
$logmanager = get_log_manager();
$allreports = \core_component::get_plugin_list('report');
$supportedreports = array(
'report_log' => '/report/log',
'report_loglive' => '/report/loglive'
);
// Make sure all supported reports are installed.
$expectedreports = array_keys(array_intersect_key($allreports, $supportedreports));
$reports = $logmanager->get_supported_reports('logstore_database');
$reports = array_keys($reports);
$expectedreports = array_intersect_key([
'log' => 'report_log',
'loglive' => 'report_loglive',
], $allreports);
$supportedreports = $logmanager->get_supported_reports('logstore_database');
foreach ($expectedreports as $expectedreport) {
$this->assertContains($expectedreport, $reports);
$this->assertArrayHasKey($expectedreport, $supportedreports);
}
}
}
@@ -257,20 +257,19 @@ class logstore_legacy_store_testcase extends advanced_testcase {
$logmanager = get_log_manager();
$allreports = \core_component::get_plugin_list('report');
$supportedreports = array(
'report_log' => '/report/log',
'report_loglive' => '/report/loglive',
'report_outline' => '/report/outline',
'report_participation' => '/report/participation',
'report_stats' => '/report/stats'
);
// Make sure all supported reports are installed.
$expectedreports = array_keys(array_intersect_key($allreports, $supportedreports));
$reports = $logmanager->get_supported_reports('logstore_legacy');
$reports = array_keys($reports);
$expectedreports = array_intersect_key([
'log' => 'report_log',
'loglive' => 'report_loglive',
'outline' => 'report_outline',
'participation' => 'report_participation',
'stats' => 'report_stats'
], $allreports);
$supportedreports = $logmanager->get_supported_reports('logstore_legacy');
foreach ($expectedreports as $expectedreport) {
$this->assertContains($expectedreport, $reports);
$this->assertArrayHasKey($expectedreport, $supportedreports);
}
}
@@ -37,8 +37,7 @@ class logstore_standard_store_testcase extends advanced_testcase {
* Tests log writing.
*
* @param bool $jsonformat True to test with JSON format
* @dataProvider test_log_writing_provider
* @throws moodle_exception
* @dataProvider log_writing_provider
*/
public function test_log_writing(bool $jsonformat) {
global $DB;
@@ -222,9 +221,9 @@ class logstore_standard_store_testcase extends advanced_testcase {
* Returns different JSON format settings so the test can be run with JSON format either on or
* off.
*
* @return [bool] Array of true/false
* @return bool[] Array of true/false
*/
public static function test_log_writing_provider(): array {
public static function log_writing_provider(): array {
return [
[false],
[true]
@@ -238,20 +237,19 @@ class logstore_standard_store_testcase extends advanced_testcase {
$logmanager = get_log_manager();
$allreports = \core_component::get_plugin_list('report');
$supportedreports = array(
'report_log' => '/report/log',
'report_loglive' => '/report/loglive',
'report_outline' => '/report/outline',
'report_participation' => '/report/participation',
'report_stats' => '/report/stats'
);
// Make sure all supported reports are installed.
$expectedreports = array_keys(array_intersect_key($allreports, $supportedreports));
$reports = $logmanager->get_supported_reports('logstore_standard');
$reports = array_keys($reports);
$expectedreports = array_intersect_key([
'log' => 'report_log',
'loglive' => 'report_loglive',
'outline' => 'report_outline',
'participation' => 'report_participation',
'stats' => 'report_stats'
], $allreports);
$supportedreports = $logmanager->get_supported_reports('logstore_standard');
foreach ($expectedreports as $expectedreport) {
$this->assertContains($expectedreport, $reports);
$this->assertArrayHasKey($expectedreport, $supportedreports);
}
}
@@ -367,7 +365,7 @@ class logstore_standard_store_testcase extends advanced_testcase {
* Tests the decode_other function can cope with both JSON and PHP serialized format.
*
* @param mixed $value Value to encode and decode
* @dataProvider test_decode_other_provider
* @dataProvider decode_other_provider
*/
public function test_decode_other($value) {
$this->assertEquals($value, \logstore_standard\log\store::decode_other(serialize($value)));
@@ -386,7 +384,7 @@ class logstore_standard_store_testcase extends advanced_testcase {
*
* @return array Array of parameters
*/
public function test_decode_other_provider(): array {
public function decode_other_provider(): array {
return [
[['info' => 'd2819896', 'logurl' => 'discuss.php?d=2819896']],
[null],
@@ -399,8 +397,7 @@ class logstore_standard_store_testcase extends advanced_testcase {
* Checks that backup and restore of log data works correctly.
*
* @param bool $jsonformat True to test with JSON format
* @dataProvider test_log_writing_provider
* @throws moodle_exception
* @dataProvider log_writing_provider
*/
public function test_backup_restore(bool $jsonformat) {
global $DB;
@@ -77,9 +77,10 @@
ucw.registerEvents('[data-region="user-competency-status"]');
ucw.on('status-changed', infoReloader.reload.bind(infoReloader));
ucw.on('error-occured', infoReloader.reload.bind(infoReloader));
var inlineGrader = new mod('#rate_{{uniqid}}', '{{competency.scaleid}}', '{{competency.competency.id}}', '{{user.id}}', '{{plan.id}}', '', '{{#str}}chooserating, tool_lp{{/str}}');
inlineGrader.on('competencyupdated', infoReloader.reload.bind(infoReloader));
{{#cangrade}}
var inlineGrader = new mod('#rate_{{uniqid}}', '{{competency.scaleid}}', '{{competency.competency.id}}', '{{user.id}}', '{{plan.id}}', '', '{{#str}}chooserating, tool_lp{{/str}}');
inlineGrader.on('competencyupdated', infoReloader.reload.bind(infoReloader));
{{/cangrade}}
});
{{/js}}
{{/usercompetency}}
@@ -95,13 +95,14 @@
{{#js}}
require(['jquery', 'tool_lp/grade_user_competency_inline', 'tool_lp/user_competency_info'], function($, mod, info) {
var inlineGrader = new mod('#rate_{{uniqid}}', '{{competency.scaleid}}', '{{competency.competency.id}}', '{{user.id}}', '', '{{course.id}}', '{{#str}}chooserating, tool_lp{{/str}}');
var competencyElement = $('[data-region-id="{{uniqid}}"]');
var displayuser = ('{{displayuser}}' == 'true') ? true : false;
var infoReloader = new info(competencyElement, '{{competency.competency.id}}', '{{user.id}}', '', '{{course.id}}', displayuser);
inlineGrader.on('competencyupdated', infoReloader.reload.bind(infoReloader));
{{#cangrade}}
var inlineGrader = new mod('#rate_{{uniqid}}', '{{competency.scaleid}}', '{{competency.competency.id}}', '{{user.id}}', '', '{{course.id}}', '{{#str}}chooserating, tool_lp{{/str}}');
inlineGrader.on('competencyupdated', infoReloader.reload.bind(infoReloader));
{{/cangrade}}
});
{{/js}}
@@ -63,4 +63,67 @@ class behat_tool_lp extends behat_base {
$this->execute('behat_general::i_click_on', [$xpathtarget, 'xpath_element']);
}
/**
* Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'.
*
* Recognised page names are:
* | pagetype | name meaning | description |
* | Course competencies | Course name | The course competencies page |
*
* @param string $page identifies which type of page this is, e.g. 'Course competencies'.
* @param string $identifier identifies the particular page, e.g. 'C1'.
* @return moodle_url the corresponding URL.
* @throws Exception with a meaningful error message if the specified page cannot be found.
*/
protected function resolve_page_instance_url(string $page, string $identifier): moodle_url {
switch (strtolower($page)) {
case 'course competencies':
$courseid = $this->get_course_id($identifier);
return new moodle_url('/admin/tool/lp/coursecompetencies.php', [
'courseid' => $courseid,
]);
default:
throw new Exception("Unrecognised page type '{$page}'");
}
}
/**
* Return a list of the exact named selectors for the component.
*
* @return behat_component_named_selector[]
*/
public static function get_exact_named_selectors(): array {
return [
new behat_component_named_selector('competency', [
"//*[@data-region='coursecompetencies']//table[contains(@class,'managecompetencies')]".
"//tr[contains(., //a[@title='View details'][contains(., %locator%)])]",
]),
new behat_component_named_selector('learning plan', [
"//*[@data-region='plan-competencies']//table[contains(@class,'managecompetencies')]".
"//tr[@data-node='user-competency'][contains(., //a[@data-usercompetency='true'][contains(., %locator%)])]",
]),
new behat_component_named_selector('competency description', [
"//td/p[contains(., %locator%)]",
]),
new behat_component_named_selector('competency grade', [
"//span[contains(concat(' ', normalize-space(@class), ' '), ' badge ')][contains(., %locator%)]",
]),
new behat_component_named_selector('learning plan rating', [
"//td[position()=2][contains(., %locator%)]",
]),
new behat_component_named_selector('learning plan proficiency', [
"//td[position()=3][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page proficiency', [
"//dt[contains(., 'Proficient')]/following-sibling::dd[1][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page rating', [
"//dt[contains(., 'Rating')]/following-sibling::dd[1][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page related competency', [
"//*[@data-region='relatedcompetencies']//a[contains(., %locator%)]",
]),
];
}
}
@@ -144,9 +144,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -163,9 +161,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -185,9 +181,7 @@ Feature: Manage plan workflow
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | complete | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | complete | manager1 |
And I log in as "manager1"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
And I follow "Learning plans"
@@ -0,0 +1,187 @@
@tool @tool_lp @javascript
Feature: View competencies
In order to access competency information
As a user
I need to view user competencies
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | Student | first |
| teacher1 | Teacher | first |
And the following "system role assigns" exist:
| user | role | contextlevel |
| teacher1 | editingteacher | System |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/competency:planview | Allow | editingteacher | System | |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "scales" exist:
| name | scale |
| Test Scale | Bad, Good, Great |
And the following "core_competency > frameworks" exist:
| shortname | idnumber | scale |
| Cookery | cookery | Test Scale |
| Literacy | literacy | Test Scale |
And the following "core_competency > competencies" exist:
| shortname | idnumber | description | competencyframework |
| Salads | salads | Salads are important | cookery |
| Desserts | desserts | Desserts are important | cookery |
| Cakes | cakes | Cakes are important | cookery |
| Reading | reading | Reading is important | literacy |
| Writing | writing | Writing is important | literacy |
And the following "core_competency > related_competencies" exist:
| competency | relatedcompetency |
| desserts | cakes |
And the following "core_competency > plans" exist:
| name | description | competencies | user |
| Cookery | Cookery is important | salads, desserts, cakes | student1 |
| Literacy | Literacy is important | reading, writing | student1 |
And the following "core_competency > course_competencies" exist:
| course | competency |
| C1 | salads |
| C1 | desserts |
| C1 | cakes |
| C1 | reading |
| C1 | writing |
And the following "core_competency > user_competency" exist:
| competency | user | grade |
| salads | student1 | Good |
| desserts | student1 | Great |
| cakes | student1 | Great |
And the following "core_competency > user_competency_courses" exist:
| course | competency | user | grade |
| C1 | salads | student1 | Good |
| C1 | desserts | student1 | Great |
| C1 | cakes | student1 | Great |
Scenario: Student view
# Course competencies
Given I am on the "C1" "tool_lp > course competencies" page logged in as "student1"
Then I should see "You are proficient in 3 out of 5 competencies in this course"
And "Salads are important" "tool_lp > competency description" should exist in the "Salads" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should exist in the "Salads" "tool_lp > competency"
And "Desserts are important" "tool_lp > competency description" should exist in the "Desserts" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should exist in the "Desserts" "tool_lp > competency"
And "Cakes are important" "tool_lp > competency description" should exist in the "Cakes" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should exist in the "Cakes" "tool_lp > competency"
And "Reading is important" "tool_lp > competency description" should exist in the "Reading" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Bad" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Writing is important" "tool_lp > competency description" should exist in the "Writing" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
And "Bad" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
# Course competencies details
And I click on "Desserts" "link" in the "Desserts" "tool_lp > competency"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Course competencies summary
And I click on "Cakes" "link"
And I should see "Cakes are important"
# Learning plans
And I click on "Close" "button" in the "Cakes" "dialogue"
And I follow "Profile" in the user menu
And I click on "Learning plans" "link"
And I should see "Cookery"
And I should see "Literacy"
# Learning plans details
And I click on "Cookery" "link"
And I should see "Cookery is important"
And I should see "3 out of 3 competencies are proficient"
And "Good" "tool_lp > learning plan rating" should exist in the "Salads" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Salads" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Desserts" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Desserts" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Cakes" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Cakes" "tool_lp > learning plan"
And I should not see "Literacy"
And I should not see "Reading"
And I should not see "Writing"
# Learning plans competency details
And I click on "Desserts" "link" in the "Desserts" "tool_lp > learning plan"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Learning plans competency summary
And I click on "Cakes cakes" "link"
And I should see "Cakes are important"
Scenario: Teacher view
# Participant competencies
Given I am on the "C1" "report_competency > breakdown" page logged in as "teacher1"
Then I should see "Student first"
And "Good" "report_competency > breakdown rating" should exist in the "Salads" "report_competency > breakdown"
And "Great" "report_competency > breakdown rating" should exist in the "Desserts" "report_competency > breakdown"
And "Great" "report_competency > breakdown rating" should exist in the "Cakes" "report_competency > breakdown"
And "Not rated" "report_competency > breakdown rating" should exist in the "Reading" "report_competency > breakdown"
And "Not rated" "report_competency > breakdown rating" should exist in the "Writing" "report_competency > breakdown"
# Participant competencies details
And I click on "Great" "report_competency > breakdown rating" in the "Desserts" "report_competency > breakdown"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Participant competencies summary
And I click on "Cakes" "tool_lp > competency page related competency"
And I should see "Cakes are important"
# Participant learning plans
And I click on "Close" "button" in the "Cakes" "dialogue"
And I click on "Close" "button" in the "User competency summary" "dialogue"
And I navigate to course participants
And I click on "Student first" "link"
And I click on "Learning plans" "link"
And I should see "Cookery"
And I should see "Literacy"
# Participant learning plans details
And I click on "Cookery" "link"
And I should see "Cookery is important"
And I should see "3 out of 3 competencies are proficient"
And "Good" "tool_lp > learning plan rating" should exist in the "Salads" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Salads" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Desserts" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Desserts" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Cakes" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Cakes" "tool_lp > learning plan"
And I should not see "Literacy"
And I should not see "Reading"
And I should not see "Writing"
# Learning plans competency details
And I click on "Desserts" "link"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Learning plans competency summary
And I click on "Cakes" "tool_lp > competency page related competency"
And I should see "Cakes are important"
+2 -1
View File
@@ -27,7 +27,8 @@ require_once($CFG->libdir . '/externallib.php');
$userid = required_param('userid', PARAM_INT); // The user id the key belongs to (for double-checking).
$key = required_param('key', PARAM_ALPHANUMEXT); // The key generated by the tool_mobile_external::get_autologin_key() external function.
$urltogo = optional_param('urltogo', $CFG->wwwroot, PARAM_URL); // URL to redirect.
$urltogo = optional_param('urltogo', $CFG->wwwroot, PARAM_LOCALURL); // URL to redirect.
$urltogo = $urltogo ?: $CFG->wwwroot;
$context = context_system::instance();
$PAGE->set_context($context);
+12 -6
View File
@@ -69,22 +69,28 @@ class tool_mobile_api_testcase extends externallib_advanced_testcase {
*/
public function test_get_potential_config_issues() {
global $CFG;
require_once($CFG->dirroot . '/message/lib.php');
$this->resetAfterTest(true);
$this->setAdminUser();
// Set non-SSL wwwroot, to avoid spurious certificate checking.
$CFG->wwwroot = 'http://www.example.com';
$CFG->userquota = '73289234723498234723423489273423497234234';
$CFG->debugdisplay = 1;
set_config('debugauthdb', 1, 'auth_db');
set_config('debugdb', 1, 'enrol_database');
$expectedissues = array('nohttpsformobilewarning', 'invaliduserquotawarning', 'adodbdebugwarning', 'displayerrorswarning');
// Get potential issues, obtain their keys for comparison.
$issues = api::get_potential_config_issues();
$this->assertCount(count($expectedissues), $issues);
foreach ($issues as $issue) {
$this->assertTrue(in_array($issue[0], $expectedissues));
}
$issuekeys = array_column($issues, 0);
$this->assertEqualsCanonicalizing([
'nohttpsformobilewarning',
'invaliduserquotawarning',
'adodbdebugwarning',
'displayerrorswarning',
], $issuekeys);
}
/**
@@ -241,9 +241,7 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
And I set the field "I agree to the This site policy" to "1"
And I press "Next"
And I log out
And I log in as "admin"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "Manager"
And I am on the "manager" "user > profile" page logged in as "admin"
And I follow "Log in as"
And I press "Continue"
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
@@ -562,9 +562,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
And the following "users" exist:
| username | firstname | lastname | email |
| user1 | User | 1 | user1@example.com |
When I log in as "admin"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
When I am on the "user1" "user > profile" page logged in as "admin"
And I follow "Log in as"
Then I should see "You are logged in as User 1"
And I press "Continue"
@@ -603,8 +601,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
And I set the field "I agree to the This site policy" to "1"
And I set the field "I agree to the This privacy policy" to "1"
And I press "Next"
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I follow "User 1"
And I am on the "user1" "user > profile" page
And I follow "Log in as"
Then I should see "You are logged in as User 1"
And I press "Continue"
@@ -19,14 +19,13 @@ Feature: Backup user data
And the following config values are set as admin:
| coursebinenable | 1 | tool_recyclebin |
| autohide | 0 | tool_recyclebin |
And the following "activities" exist:
| activity | course | section | name | intro |
| quiz | C1 | 1 | Quiz 1 | Test quiz description |
@javascript
Scenario: Delete and restore a quiz with user data
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Quiz" to section "1" and I fill the form with:
| Name | Quiz 1 |
| Description | Test quiz description |
Given I am on the "Quiz 1" "quiz activity" page logged in as teacher1
And I add a "True/False" question to the "Quiz 1" quiz with:
| Question name | TF1 |
| Question text | First question |
@@ -41,6 +40,8 @@ Feature: Backup user data
| Correct answer | False |
| Feedback for the response 'True'. | So you think it is true |
| Feedback for the response 'False'. | So you think it is false |
And I set the field "maxgrade" to "10.0"
And I press "savechanges"
And I log out
When I am on the "Quiz 1" "quiz activity" page logged in as student1
And I press "Attempt quiz now"
@@ -386,7 +386,7 @@ class availability_completion_condition_testcase extends advanced_testcase {
/**
* Tests the is_available and get_description functions for previous activity option.
*
* @dataProvider test_previous_activity_data
* @dataProvider previous_activity_data
* @param int $grade the current assign grade (0 for none)
* @param int $condition true for complete, false for incomplete
* @param string $mark activity to mark as complete
@@ -475,7 +475,7 @@ class availability_completion_condition_testcase extends advanced_testcase {
$this->assertRegExp($description, $information);
}
public function test_previous_activity_data(): array {
public function previous_activity_data(): array {
// Assign grade, condition, activity to complete, activity to test, result, resultnot, description.
return [
'Missing previous activity complete' => [
@@ -567,7 +567,7 @@ class availability_completion_condition_testcase extends advanced_testcase {
* Tests the is_available and get_description functions for
* previous activity option in course sections.
*
* @dataProvider test_section_previous_activity_data
* @dataProvider section_previous_activity_data
* @param int $condition condition value
* @param bool $mark if Page 1 must be mark as completed
* @param string $section section to add the availability
@@ -640,7 +640,7 @@ class availability_completion_condition_testcase extends advanced_testcase {
}
public function test_section_previous_activity_data(): array {
public function section_previous_activity_data(): array {
return [
// Condition, Activity completion, section to test, result, resultnot, description.
'Completion complete Section with no previous activity' => [
@@ -197,7 +197,12 @@ class condition extends \core_availability\condition {
$this->customfield);
}
} else {
$translatedfieldname = get_user_field_name($this->standardfield);
$standardfields = self::get_standard_profile_fields();
if (array_key_exists($this->standardfield, $standardfields)) {
$translatedfieldname = $standardfields[$this->standardfield];
} else {
$translatedfieldname = get_string('missing', 'availability_profile', $this->standardfield);
}
}
$context = \context_course::instance($course->id);
$a = new \stdClass();
@@ -321,6 +326,33 @@ class condition extends \core_availability\condition {
return $fieldconditionmet;
}
/**
* Return list of standard user profile fields used by the condition
*
* @return string[]
*/
public static function get_standard_profile_fields(): array {
return [
'firstname' => get_user_field_name('firstname'),
'lastname' => get_user_field_name('lastname'),
'email' => get_user_field_name('email'),
'city' => get_user_field_name('city'),
'country' => get_user_field_name('country'),
'url' => get_user_field_name('url'),
'icq' => get_user_field_name('icq'),
'skype' => get_user_field_name('skype'),
'aim' => get_user_field_name('aim'),
'yahoo' => get_user_field_name('yahoo'),
'msn' => get_user_field_name('msn'),
'idnumber' => get_user_field_name('idnumber'),
'institution' => get_user_field_name('institution'),
'department' => get_user_field_name('department'),
'phone1' => get_user_field_name('phone1'),
'phone2' => get_user_field_name('phone2'),
'address' => get_user_field_name('address')
];
}
/**
* Gets data about custom profile fields. Cached statically in current
* request.
@@ -472,6 +504,11 @@ class condition extends \core_availability\condition {
$valuefield = 'data';
$default = $customfield->defaultdata;
} else {
$standardfields = self::get_standard_profile_fields();
if (!array_key_exists($this->standardfield, $standardfields)) {
// If the field isn't found, nobody matches.
return [];
}
$values = $DB->get_records_select('user', 'id ' . $sql, $params,
'', 'id, '. $this->standardfield);
$valuefield = $this->standardfield;
@@ -595,6 +632,11 @@ class condition extends \core_availability\condition {
$where = "(ud.data IS NOT NULL AND $condition)";
}
} else {
$standardfields = self::get_standard_profile_fields();
if (!array_key_exists($this->standardfield, $standardfields)) {
// If the field isn't found, nobody matches.
return ['SELECT id FROM {user} WHERE 0 = 1', []];
}
$tablesql = "JOIN {user} u ON u.id = userids.id";
list ($where, $mainparams) = $this->get_condition_sql(
'u.' . $this->standardfield);
@@ -42,26 +42,9 @@ class frontend extends \core_availability\frontend {
protected function get_javascript_init_params($course, \cm_info $cm = null,
\section_info $section = null) {
// Standard user fields.
$standardfields = array(
'firstname' => get_user_field_name('firstname'),
'lastname' => get_user_field_name('lastname'),
'email' => get_user_field_name('email'),
'city' => get_user_field_name('city'),
'country' => get_user_field_name('country'),
'url' => get_user_field_name('url'),
'icq' => get_user_field_name('icq'),
'skype' => get_user_field_name('skype'),
'aim' => get_user_field_name('aim'),
'yahoo' => get_user_field_name('yahoo'),
'msn' => get_user_field_name('msn'),
'idnumber' => get_user_field_name('idnumber'),
'institution' => get_user_field_name('institution'),
'department' => get_user_field_name('department'),
'phone1' => get_user_field_name('phone1'),
'phone2' => get_user_field_name('phone2'),
'address' => get_user_field_name('address')
);
$standardfields = condition::get_standard_profile_fields();
\core_collator::asort($standardfields);
// Custom fields.
@@ -39,7 +39,7 @@ $string['requires_notendswith'] = 'Your <strong>{$a->field}</strong> does not en
$string['requires_notisequalto'] = 'Your <strong>{$a->field}</strong> is not <strong>{$a->value}</strong>';
$string['requires_notstartswith'] = 'Your <strong>{$a->field}</strong> does not start with <strong>{$a->value}</strong>';
$string['requires_startswith'] = 'Your <strong>{$a->field}</strong> starts with <strong>{$a->value}</strong>';
$string['missing'] = '(Missing custom field: {$a})';
$string['missing'] = '(Missing field: {$a})';
$string['title'] = 'User profile';
$string['op_contains'] = 'contains';
$string['op_doesnotcontain'] = 'doesn\'t contain';
+1 -1
View File
@@ -48,7 +48,7 @@ class backup_files_edit_form extends moodleform {
$mform->setType('component', PARAM_COMPONENT);
$mform->addElement('hidden', 'returnurl', $this->_customdata['returnurl']);
$mform->setType('returnurl', PARAM_URL);
$mform->setType('returnurl', PARAM_LOCALURL);
$this->add_action_buttons(true, get_string('savechanges'));
$this->set_data($this->_customdata['data']);
@@ -77,6 +77,7 @@ abstract class backup_cron_automated_helper {
* First backup courses that do not have an entry in backup_courses first,
* as they are likely new and never been backed up. Do the oldest modified courses first.
* Then backup courses that have previously been backed up starting with the oldest next start time.
* Finally, all else being equal, defer to the sortorder of the courses.
*
* @param null|int $now timestamp to use in course selection.
* @return moodle_recordset The recordset of matching courses.
@@ -93,7 +94,8 @@ abstract class backup_cron_automated_helper {
LEFT JOIN {backup_courses} bc ON bc.courseid = c.id
WHERE bc.nextstarttime IS NULL OR bc.nextstarttime < ?
ORDER BY nextstarttime ASC,
c.timemodified DESC';
c.timemodified DESC,
c.sortorder';
$params = array(
$now, // Only get courses where the backup start time is in the past.
+1 -1
View File
@@ -383,7 +383,7 @@ class backup_cron_helper_testcase extends advanced_testcase {
$backupcourse3 = new stdClass;
$backupcourse3->courseid = $course3->id;
$backupcourse3->laststatus = testable_backup_cron_automated_helper::BACKUP_STATUS_OK;
$backupcourse3->nextstarttime = 1554858160;
$backupcourse3->nextstarttime = 1554822160;
$DB->insert_record('backup_courses', $backupcourse3);
$backupcourse4 = new stdClass;
+1 -1
View File
@@ -643,7 +643,7 @@ class backup_ui_stage_complete extends backup_ui_stage_final {
}
$output .= $renderer->get_samesite_notification();
$output .= $renderer->notification(get_string('executionsuccess', 'backup'), 'notifysuccess');
$output .= $renderer->continue_button($restorerul);
$output .= $renderer->continue_button($restorerul, 'get');
$output .= $renderer->box_end();
return $output;
+2 -2
View File
@@ -553,7 +553,8 @@ class core_backup_renderer extends plugin_renderer_base {
}
/**
* Displays a continue button
* Displays a continue button, overriding core renderer method of the same in order
* to override submission method of the button form
*
* @param string|moodle_url $url
* @param string $method
@@ -566,7 +567,6 @@ class core_backup_renderer extends plugin_renderer_base {
if ($method != 'post') {
$method = 'get';
}
$url->param('sesskey', sesskey());
$button = new single_button($url, get_string('continue'), $method, true);
$button->class = 'continuebutton';
return $this->render($button);
+4 -2
View File
@@ -1161,8 +1161,10 @@ class restore_ui_stage_complete extends restore_ui_stage_process {
$html .= $renderer->notification(get_string('restorefileweremissing', 'backup'), 'notifyproblem');
}
$html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');
$html .= $renderer->continue_button(new moodle_url('/course/view.php', array(
'id' => $this->get_ui()->get_controller()->get_courseid())), 'get');
$courseurl = course_get_url($this->get_ui()->get_controller()->get_courseid());
$html .= $renderer->continue_button($courseurl, 'get');
$html .= $renderer->box_end();
return $html;
@@ -12,9 +12,10 @@ Feature: Restore Moodle 2 course backups
| Course 3 | C3 | 0 | topics | 2 | 0 |
| Course 4 | C4 | 0 | topics | 20 | 0 |
And the following "activities" exist:
| activity | course | idnumber | name | intro | section |
| assign | C3 | assign1 | Test assign name | Assign description | 1 |
| data | C3 | data1 | Test database name | Database description | 2 |
| activity | course | idnumber | name | intro | section | externalurl |
| assign | C3 | assign1 | Test assign name | Assign description | 1 | |
| data | C3 | data1 | Test database name | Database description | 2 | |
| url | C1 | url1 | Test URL name | Test URL description | 3 | http://www.moodle.org |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Forum" to section "1" and I fill the form with:
@@ -108,11 +109,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup in an existing course retaining the backup course settings
Given I add a "URL" to section "3" and I fill the form with:
| Name | Test URL name |
| Description | Test URL description |
| id_externalurl | http://www.moodle.org |
And I hide section "3"
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
@@ -134,11 +131,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup in an existing course keeping the target course settings
Given I add a "URL" to section "3" and I fill the form with:
| Name | Test URL name |
| Description | Test URL description |
| id_externalurl | http://www.moodle.org |
And I hide section "3"
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Confirmation | Filename | test_backup.mbz |
@@ -160,11 +153,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup in an existing course deleting contents and retaining the backup course settings
Given I add a "URL" to section "3" and I fill the form with:
| Name | Test URL name |
| Description | Test URL description |
| id_externalurl | http://www.moodle.org |
And I hide section "3"
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
@@ -189,11 +178,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup in an existing course deleting contents and keeping the current course settings
Given I add a "URL" to section "3" and I fill the form with:
| Name | Test URL name |
| Description | Test URL description |
| id_externalurl | http://www.moodle.org |
And I hide section "3"
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
@@ -218,11 +203,7 @@ Feature: Restore Moodle 2 course backups
@javascript
Scenario: Restore a backup in an existing course deleting contents decreasing the number of sections
Given I add a "URL" to section "3" and I fill the form with:
| Name | Test URL name |
| Description | Test URL description |
| id_externalurl | http://www.moodle.org |
And I hide section "3"
Given I hide section "3"
And I hide section "7"
When I backup "Course 1" course using this options:
| Initial | Include enrolled users | 0 |
@@ -30,9 +30,7 @@ Feature: Award badges with separate groups
| teacher1 | CB |
| student2 | CA |
| teacher2 | CA |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Edit settings" in current page administration
And I am on the "Course 1" "course editing" page logged in as "teacher1"
And I expand all fieldsets
And I set the field "Group mode" to "Separate groups"
And I press "Save and display"
+2 -2
View File
@@ -36,7 +36,7 @@ class moodle1_block_html_handler extends moodle1_block_handler {
$contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);
$decodeddata = base64_decode($olddata['configdata']);
list($updated, $configdata) = upgrade_fix_serialized_objects($decodeddata);
$configdata = unserialize($configdata);
$configdata = unserialize_object($configdata);
// get a fresh new file manager for this instance
$this->fileman = $this->converter->get_file_manager($contextid, 'block_html');
@@ -44,7 +44,7 @@ class moodle1_block_html_handler extends moodle1_block_handler {
// convert course files embedded in the block content
$this->fileman->filearea = 'content';
$this->fileman->itemid = 0;
$configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);
$configdata->text = moodle1_converter::migrate_referenced_files($configdata->text ?? '', $this->fileman);
$configdata->format = FORMAT_HTML;
return base64_encode(serialize($configdata));
@@ -146,6 +146,7 @@ Feature: My overview block pagination
| student1 | C12 | student |
| student1 | C13 | student |
When I log in as "student1"
And I wait until ".block_myoverview [data-control='next']" "css_element" exists
And I click on "[data-control='next']" "css_element" in the "Course overview" "block"
Then the "class" attribute of ".block_myoverview [data-control='next']" "css_element" should contain "disabled"
And I log out
@@ -10,10 +10,18 @@ Feature: Add URL to main menu block
And I am on site homepage
And I navigate to "Turn editing on" in current page administration
And I add the "Main menu" block
When I add a "URL" to section "0" and I fill the form with:
| Name | google |
| Description | gooooooooogle |
| External URL | http://www.google.com |
And the following "activity" exists:
| activity | url |
| course | Acceptance test site |
| name | google |
| intro | gooooooooogle |
| externalurl | http://www.google.com |
| section | 0 |
When I am on the "google" "url activity editing" page
And I expand all fieldsets
And I set the following fields to these values:
| id_display | In pop-up |
And I press "Save and return to course"
Then "google" "link" should exist in the "Main menu" "block"
And "Add an activity" "button" should exist in the "Main menu" "block"
And "Add an activity or resource" "button" should exist in the "Main menu" "block"
+10 -17
View File
@@ -14,23 +14,16 @@ Feature: Block appearances
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Survey" to section "1" and I fill the form with:
| Name | Test survey name |
| Survey type | ATTLS (20 item version) |
| Description | Test survey description |
And I add a "Book" to section "1" and I fill the form with:
| Name | Test book name |
| Description | Test book description |
And I follow "Test book name"
And I set the following fields to these values:
| Chapter title | Book title |
| Content | Book content test test |
And I press "Save changes"
And I log out
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And the following "activities" exist:
| activity | course | name | element |
| survey | C1 | Test survey name | 4 |
| book | C1 | Test book name | |
And the following "mod_book > chapter" exists:
| book | Test book name |
| title | Book title |
| content | Book content test test |
And I am on the "Course 1" course page logged in as teacher1
And I turn editing mode on
And I add the "Comments" block
And I configure the "Comments" block
And I set the following fields to these values:
+8 -15
View File
@@ -14,21 +14,14 @@ Feature: Block region moving
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "Survey" to section "1" and I fill the form with:
| Name | Test survey name |
| Survey type | ATTLS (20 item version) |
| Description | Test survey description |
And I add a "Book" to section "1" and I fill the form with:
| Name | Test book name |
| Description | Test book description |
And I follow "Test book name"
And I set the following fields to these values:
| Chapter title | Book title |
| Content | Book content test test |
And I press "Save changes"
And I log out
And the following "activities" exist:
| activity | name | course | template |
| survey | Test survey name | C1 | 4 |
| book | Test book name | C1 | |
And the following "mod_book > chapter" exists:
| book | Test book name |
| title | Book title |
| content | Book content test test |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add the "Comments" block
+1 -1
View File
@@ -64,7 +64,7 @@ class blog_edit_external_form extends moodleform {
$mform->setDefault('id', 0);
$mform->addElement('hidden', 'returnurl');
$mform->setType('returnurl', PARAM_URL);
$mform->setType('returnurl', PARAM_LOCALURL);
$mform->setDefault('returnurl', 0);
}
+3 -9
View File
@@ -9,6 +9,9 @@ Feature: Comment on a blog entry
| username | firstname | lastname | email |
| testuser | Test | User | moodle@example.com |
| testuser2 | Test2 | User2 | moodle2@example.com |
And the following "core_blog > entries" exist:
| subject | body | user |
| Blog post from user 1 | User 1 blog post content | testuser |
And I log in as "admin"
And I am on site homepage
And I turn editing mode on
@@ -19,15 +22,6 @@ Feature: Comment on a blog entry
| Page contexts | Display throughout the entire site |
And I press "Save changes"
And I log out
And I log in as "testuser"
And I click on "Site pages" "list_item" in the "Navigation" "block"
And I click on "Site blogs" "link" in the "Navigation" "block"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post from user 1 |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I log out
@javascript
Scenario: Commenting on my own blog entry
+4 -11
View File
@@ -8,6 +8,10 @@ Feature: Delete a blog entry
Given the following "users" exist:
| username | firstname | lastname | email |
| testuser | Test | User | moodle@example.com |
And the following "core_blog > entries" exist:
| subject | body | user |
| Blog post one | User 1 blog post content | testuser |
| Blog post two | User 1 blog post content | testuser |
And I log in as "admin"
And I am on site homepage
And I turn editing mode on
@@ -19,17 +23,6 @@ Feature: Delete a blog entry
And I press "Save changes"
And I log out
And I log in as "testuser"
And I click on "Site blogs" "link" in the "Navigation" "block"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post one |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | Blog post two |
| Blog entry body | User 1 blog post content |
And I press "Save changes"
And I am on site homepage
And I click on "Site blogs" "link" in the "Navigation" "block"
@@ -0,0 +1,51 @@
<?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/>.
/**
* Behat data generator for core_blog.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Behat data generator for core_blog.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_core_blog_generator extends behat_generator_base {
/**
* Get a list of the entities that can be created.
*
* @return array entity name => information about how to generate.
*/
protected function get_creatable_entities(): array {
return [
'entries' => [
'singular' => 'entry',
'datagenerator' => 'entry',
'required' => ['subject', 'body'],
'switchids' => ['user' => 'userid'],
],
];
}
}
+55
View File
@@ -0,0 +1,55 @@
<?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/>.
/**
* Generator for blog area.
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/blog/locallib.php');
/**
* Blog module test data generator class
*
* @package core_blog
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_blog_generator extends component_generator_base {
/**
* Create a blog entry
*
* @param array $data Entry data.
* @return blog_entry Entry instance.
*/
public function create_entry(array $data = []): blog_entry {
$data['publishstate'] = $data['publishstate'] ?? 'site';
$data['summary'] = $data['summary'] ?? $data['body'];
$entry = new blog_entry(null, $data);
$entry->add();
return $entry;
}
}
+5 -5
View File
@@ -2628,7 +2628,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
*
* @return array
*/
public function test_get_calendar_event_by_id_prevent_read_other_users_events_data_provider(): array {
public function get_calendar_event_by_id_prevent_read_other_users_events_data_provider(): array {
$syscontext = context_system::instance();
$managerrole = 'manager';
return [
@@ -2643,7 +2643,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
* Prevent user from reading other user's event.
*
* @covers \core_calendar_external::get_calendar_event_by_id
* @dataProvider test_get_calendar_event_by_id_prevent_read_other_users_events_data_provider
* @dataProvider get_calendar_event_by_id_prevent_read_other_users_events_data_provider
*
* @param bool $isadminevent Is admin's event
* @param bool $isadmin Is current user admin user
@@ -2699,7 +2699,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
*
* @return array
*/
public function test_edit_or_delete_other_users_events_data_provider(): array {
public function edit_or_delete_other_users_events_data_provider(): array {
$syscontext = context_system::instance();
$managerrole = 'manager';
return [
@@ -2713,7 +2713,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
/**
* Test the behavior of deleting other users' user events.
*
* @dataProvider test_edit_or_delete_other_users_events_data_provider
* @dataProvider edit_or_delete_other_users_events_data_provider
* @covers \core_calendar_external::delete_calendar_events
* @param bool $isadmin Whether the current user is admin.
* @param bool $isadminevent Whether it's an admin event or not.
@@ -2760,7 +2760,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
/**
* Test the behavior of editing other users' user events
*
* @dataProvider test_edit_or_delete_other_users_events_data_provider
* @dataProvider edit_or_delete_other_users_events_data_provider
* @covers \core_calendar_external::submit_create_update_form
* @param bool $isadmin Whether the current user is admin.
* @param bool $isadminevent Whether it's an admin event or not.
+6 -6
View File
@@ -56,7 +56,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test proxying.
*
* @dataProvider test_proxy_testcases()
* @dataProvider proxy_testcases
* @param int $id Object ID.
* @param string $member Object member to retrieve.
* @param mixed $expected Expected value of member.
@@ -72,7 +72,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test setting values with a base class.
*
* @dataProvider test_proxy_testcases()
* @dataProvider proxy_testcases
* @param int $id Object ID.
* @param string $member Object member to retrieve.
* @param mixed $storedvalue Value as would be stored externally.
@@ -93,7 +93,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test getting a non existant member.
*
* @dataProvider test_get_set_testcases()
* @dataProvider get_set_testcases
* @param int $id ID of the object being proxied.
*/
public function test_get_invalid_member($id) {
@@ -108,7 +108,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test get proxied instance.
*
* @dataProvider test_get_set_testcases()
* @dataProvider get_set_testcases
* @param int $id Object ID.
*/
public function test_get_proxied_instance($id) {
@@ -122,7 +122,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test cases for proxying test.
*/
public function test_proxy_testcases() {
public function proxy_testcases() {
return [
'Object 1 member 1' => [
1,
@@ -160,7 +160,7 @@ class core_calendar_std_proxy_testcase extends advanced_testcase {
/**
* Test cases for getting and setting tests.
*/
public function test_get_set_testcases() {
public function get_set_testcases() {
return [
'Object 1' => [1],
'Object 2' => [5]
@@ -0,0 +1,261 @@
<?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/>.
use core_competency\competency;
use core_competency\competency_framework;
use core_competency\plan;
/**
* Behat data generator for core_competency.
*
* @package core_competency
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_core_competency_generator extends behat_generator_base {
/**
* Get a list of the entities that Behat can create using the generator step.
*
* @return array
*/
protected function get_creatable_entities(): array {
return [
'competencies' => [
'singular' => 'competency',
'datagenerator' => 'competency',
'required' => ['shortname', 'competencyframework'],
'switchids' => ['competencyframework' => 'competencyframeworkid'],
],
'course_competencies' => [
'singular' => 'course_competency',
'datagenerator' => 'course_competency',
'required' => ['course', 'competency'],
'switchids' => ['course' => 'courseid', 'competency' => 'competencyid'],
],
'frameworks' => [
'singular' => 'framework',
'datagenerator' => 'framework',
'required' => ['shortname'],
'switchids' => ['scale' => 'scaleid'],
],
'plans' => [
'singular' => 'plan',
'datagenerator' => 'plan',
'required' => ['name'],
'switchids' => ['user' => 'userid'],
],
'related_competencies' => [
'singular' => 'related_competency',
'datagenerator' => 'related_competency',
'required' => ['competency', 'relatedcompetency'],
'switchids' => ['competency' => 'competencyid', 'relatedcompetency' => 'relatedcompetencyid'],
],
'user_competency' => [
'singular' => 'user_competency',
'datagenerator' => 'user_competency',
'required' => ['competency', 'user'],
'switchids' => ['competency' => 'competencyid', 'user' => 'userid'],
],
'user_competency_courses' => [
'singular' => 'user_competency_course',
'datagenerator' => 'user_competency_course',
'required' => ['course', 'competency', 'user'],
'switchids' => ['course' => 'courseid', 'competency' => 'competencyid', 'user' => 'userid'],
],
'user_competency_plans' => [
'singular' => 'user_competency_plan',
'datagenerator' => 'user_competency_plan',
'required' => ['plan', 'competency', 'user'],
'switchids' => ['plan' => 'planid', 'competency' => 'competencyid', 'user' => 'userid'],
],
];
}
/**
* Get the competecy framework id using an idnumber.
*
* @param string $idnumber
* @return int The competecy framework id
*/
protected function get_competencyframework_id(string $idnumber): int {
global $DB;
if (!$id = $DB->get_field('competency_framework', 'id', ['idnumber' => $idnumber])) {
throw new Exception('The specified competency framework with idnumber "' . $idnumber . '" could not be found.');
}
return $id;
}
/**
* Get the competecy id using an idnumber.
*
* @param string $idnumber
* @return int The competecy id
*/
protected function get_competency_id(string $idnumber): int {
global $DB;
if (!$id = $DB->get_field('competency', 'id', ['idnumber' => $idnumber])) {
throw new Exception('The specified competency with idnumber "' . $idnumber . '" could not be found.');
}
return $id;
}
/**
* Get the learning plan id using a name.
*
* @param string $name
* @return int The learning plan id
*/
protected function get_plan_id(string $name): int {
global $DB;
if (!$id = $DB->get_field('competency_plan', 'id', ['name' => $name])) {
throw new Exception('The specified learning plan with name "' . $name . '" could not be found.');
}
return $id;
}
/**
* Get the related competecy id using an idnumber.
*
* @param string $idnumber
* @return int The related competecy id
*/
protected function get_relatedcompetency_id(string $idnumber): int {
return $this->get_competency_id($idnumber);
}
/**
* Add a plan.
*
* @param array $data Plan data.
*/
public function process_plan(array $data): void {
$generator = $this->get_data_generator();
$competencyids = $data['competencyids'] ?? [];
unset($data['competencyids']);
$plan = $generator->create_plan($data);
foreach ($competencyids as $competencyid) {
$generator->create_plan_competency([
'planid' => $plan->get('id'),
'competencyid' => $competencyid,
]);
}
}
/**
* Preprocess user competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess user course competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency_course(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess user learning plan competency data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_user_competency_plan(array $data): array {
$this->prepare_grading($data);
return $data;
}
/**
* Preprocess plan data.
*
* @param array $data Raw data.
* @return array Processed data.
*/
protected function preprocess_plan(array $data): array {
if (isset($data['competencies'])) {
$competencies = array_map('trim', str_getcsv($data['competencies']));
$data['competencyids'] = array_map([$this, 'get_competency_id'], $competencies);
unset($data['competencies']);
}
global $USER;
return $data + [
'userid' => $USER->id,
'status' => plan::STATUS_ACTIVE,
];
}
/**
* Prepare grading attributes for record data.
*
* @param array $data Record data.
*/
protected function prepare_grading(array &$data): void {
if (!isset($data['grade'])) {
return;
}
global $DB;
$competency = competency::get_record(['id' => $data['competencyid']]);
$competencyframework = competency_framework::get_record(['id' => $competency->get('competencyframeworkid')]);
$scale = $DB->get_field('scale', 'scale', ['id' => $competencyframework->get('scaleid')]);
$grades = array_map('trim', explode(',', $scale));
$grade = array_search($data['grade'], $grades);
if ($grade === false) {
throw new Exception('The grade "'.$data['grade'].'" was not found in the "'.
$competencyframework->get('shortname').'" competency framework.');
}
$data['proficiency'] = true;
$data['grade'] = $grade + 1;
}
/**
* Get the module data generator.
*
* @return core_competency_generator Competency data generator.
*/
protected function get_data_generator(): core_competency_generator {
return $this->componentdatagenerator;
}
}
+5 -2
View File
@@ -136,7 +136,11 @@ class core_competency_generator extends component_generator_base {
* @return competency_framework
*/
public function create_framework($record = null) {
$generator = phpunit_util::get_data_generator();
if (defined('BEHAT_TEST') && BEHAT_TEST) {
$generator = behat_util::get_data_generator();
} else {
$generator = phpunit_util::get_data_generator();
}
$this->frameworkcount++;
$i = $this->frameworkcount;
$record = (object) $record;
@@ -584,4 +588,3 @@ class core_competency_generator extends component_generator_base {
}
}
@@ -34,9 +34,9 @@ Feature: Restrict sections availability through completion or grade conditions
And I set the following fields to these values:
| Enable completion tracking | Yes |
And I press "Save and display"
And I add a "Label" to section "1" and I fill the form with:
| Label text | Test label |
| Completion tracking | Students can manually mark the activity as completed |
And the following "activities" exist:
| activity | course | section | intro | completion | idnumber |
| label | C1 | 1 | Test label | 1 | 1 |
And I add a "Page" to section "2" and I fill the form with:
| Name | Test page name |
| Description | Test page description |
+5 -5
View File
@@ -7,13 +7,13 @@
"require-dev": {
"phpunit/phpunit": "7.5.*",
"phpunit/dbunit": "4.0.*",
"mikey179/vfsstream": "^1.6",
"behat/mink": "~1.8",
"mikey179/vfsstream": "1.6.*",
"behat/mink": "^1.10.0",
"behat/mink-extension": "~2.3",
"behat/mink-goutte-driver": "~1.2",
"behat/mink-goutte-driver": "^1.3",
"symfony/process": "^4.0 || ^5.0",
"behat/behat": "3.10.*",
"oleg-andreyev/mink-phpwebdriver": "^1.0"
"behat/behat": "3.11.*",
"oleg-andreyev/mink-phpwebdriver": "^1.2.1"
},
"autoload-dev": {
"psr-0": {
Generated
+385 -338
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -70,6 +70,10 @@ $CFG->dboptions = array(
// can be removed for MySQL (by default it will
// use 'utf8mb4_unicode_ci'. This option should
// be removed for all other databases.
// 'extrainfo' => [], // Extra information for the DB driver, e.g. SQL Server,
// has additional configuration according to its environment,
// which the administrator can specify to alter and
// override any connection options.
// 'fetchbuffersize' => 100000, // On PostgreSQL, this option sets a limit
// on the number of rows that are fetched into
// memory when doing a large recordset query
@@ -14,7 +14,7 @@ Feature: Sections can be edited and deleted in topics format
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| assign | Test assignment name | Test assignment description | C1 | assign1 | 0 |
| book | Test book name | Test book description | C1 | book1 | 1 |
| book | Test book name | | C1 | book1 | 1 |
| chat | Test chat name | Test chat description | C1 | chat1 | 4 |
| choice | Test choice name | Test choice description | C1 | choice1 | 5 |
And the following "course enrolments" exist:
@@ -14,7 +14,7 @@ Feature: Sections can be edited and deleted in weeks format
And the following "activities" exist:
| activity | name | intro | course | idnumber | section |
| assign | Test assignment name | Test assignment description | C1 | assign1 | 0 |
| book | Test book name | Test book description | C1 | book1 | 1 |
| book | Test book name | | C1 | book1 | 1 |
| chat | Test chat name | Test chat description | C1 | chat1 | 4 |
| choice | Test choice name | Test choice description | C1 | choice1 | 5 |
And the following "course enrolments" exist:
+2 -2
View File
@@ -34,7 +34,7 @@ require_once($CFG->dirroot.'/course/lib.php');
$id = required_param('id', PARAM_INT);
$switchrole = optional_param('switchrole', -1, PARAM_INT);
$returnurl = optional_param('returnurl', '', PARAM_RAW);
$returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
if (strpos($returnurl, '?') === false) {
// Looks like somebody did not set proper page url, better go to course page.
@@ -43,7 +43,7 @@ if (strpos($returnurl, '?') === false) {
if (strpos($returnurl, $CFG->wwwroot) !== 0) {
$returnurl = $CFG->wwwroot.$returnurl;
}
$returnurl = clean_param($returnurl, PARAM_URL);
$returnurl = clean_param($returnurl, PARAM_LOCALURL);
}
$PAGE->set_url('/course/switchrole.php', array('id'=>$id, 'switchrole'=>$switchrole));
+80
View File
@@ -0,0 +1,80 @@
@core @core_course
Feature: Teacher can change the course format
In order to change course format
As a teacher
I should be able to edit a course
@javascript
Scenario: Teacher can change the course format
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
# Course format is initially set to Topics format
And the following "courses" exist:
| fullname | shortname | format | startdate |
| Course 1 | C1 | topics | ## 1 day ago ## |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
# Confirm that course format is Topics
When I am on the "Course 1" course page logged in as teacher1
Then I should see "Topic 1"
And I am on the "Course 1" "course editing" page
And I expand all fieldsets
# Fields that appear for Topics format exist
# Also confirm contents of Hidden sections and Course layout select box
And I should see "Hidden sections"
And the "Hidden sections" select box should contain "Hidden sections are shown in collapsed form"
And the "Hidden sections" select box should contain "Hidden sections are completely invisible"
# Hidden sections default value is 0 (Hidden sections are shown in collapsed form)
And the field "Hidden sections" matches value "0"
And I should see "Course layout"
And the "Course layout" select box should contain "Show all sections on one page"
And the "Course layout" select box should contain "Show one section per page"
# Course layout default value is 0 (Show all sections on one page)
And the field "Course layout" matches value "0"
# Set course format to Single activity format
And I set the field "Format" to "Single activity format"
And I expand all fieldsets
# Confirm that fields that appear for Single activity format appears
And I should see "Type of activity"
And I set the field "Type of activity" to "Glossary"
And I press "Save and display"
And I set the field "Name" to "Glossary 1"
And I press "Save and display"
# Confirm that course page displays single activity of type Glossary
And I should see "Browse the glossary using this index"
And I should not see "Topic 1"
And I am on the "Course 1" "course editing" page
And I expand all fieldsets
# Set course format to Weekly format
And I set the field "Format" to "Weekly format"
And I expand all fieldsets
# Confirm that fields that appear for Weekly format appears
# Also confirm contents of Hidden sections and Course layout select box
And I should see "Hidden sections"
And the "Hidden sections" select box should contain "Hidden sections are shown in collapsed form"
And the "Hidden sections" select box should contain "Hidden sections are completely invisible"
# Hidden sections default value is 0 (Hidden sections are shown in collapsed form)
And the field "Hidden sections" matches value "0"
And I should see "Course layout"
And the "Course layout" select box should contain "Show all sections on one page"
And the "Course layout" select box should contain "Show one section per page"
# Course layout default value is 0 (Show all sections on one page)
And the field "Course layout" matches value "0"
And I press "Save and display"
# Confirm that course page displays weekly sections
And I should see "This week"
And I should not see "Browse the glossary using this index"
And I am on the "Course 1" "course editing" page
And I expand all fieldsets
# Set course format to Social format
And I set the field "Format" to "Social format"
# Confirm that fields that appear for Social format appears
And I expand all fieldsets
And I should see "Number of discussions"
And the field "Number of discussions" matches value "10"
And I press "Save and display"
# Confirm that course page displays a forum
And I should see "There are no discussion topics yet in this forum"
And I should not see "This week"
+3 -3
View File
@@ -14,11 +14,11 @@ Feature: Force group mode in a course
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | course | name |
| chat | C1 | Chat room |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Chat" to section "1" and I fill the form with:
| Name of this chat room | Chat room |
| Description | Chat description |
And I navigate to "Edit settings" in current page administration
@javascript
@@ -43,15 +43,15 @@ Feature: Course paged mode
Given the following "courses" exist:
| fullname | shortname | category | format | coursedisplay | numsections | startdate |
| Course 1 | C1 | 0 | <courseformat> | 1 | 3 | 0 |
And I log in as "admin"
And the following "activities" exist:
| activity | course | name |
| chat | C1 | Chat room |
When I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I click on <section1> "link" in the <section1> "section"
And I should see <section1> in the "div.single-section" "css_element"
And I should see <section2> in the ".single-section span.mdl-right" "css_element"
And I should not see <prevunexistingsection> in the ".single-section" "css_element"
When I add a "Chat" to section "1" and I fill the form with:
| Name of this chat room | Chat room |
| Description | Chat description |
Then I should see <section1> in the "div.single-section" "css_element"
And I should see <section2> in the ".single-section span.mdl-right" "css_element"
And I should not see <prevunexistingsection> in the ".single-section" "css_element"
@@ -14,6 +14,9 @@ Feature: Restrict activities availability
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | course | name |
| chat | C1 | Test chat name |
@javascript
Scenario: Activities can be added with the default permissions
@@ -22,9 +25,6 @@ Feature: Restrict activities availability
When I add a "Glossary" to section "1" and I fill the form with:
| Name | Test glossary name |
| Description | Test glossary description |
And I add a "Chat" to section "1" and I fill the form with:
| Name of this chat room | Test chat name |
| Description | Test chat description |
Then I should see "Test glossary name"
And I should see "Test chat name"
@@ -14,13 +14,10 @@ Feature: View subfolders in a course in-line
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add a "Folder" to section "3" and I fill the form with:
| Name | Test folder |
| Display folder contents | On a separate page |
| Show subfolders expanded | |
And I am on the "Test folder" "folder activity" page
And the following "activities" exist:
| activity | course | name | display | showexpanded |
| folder | C1 | Test folder | 0 | 0 |
And I am on the "Test folder" "folder activity" page logged in as "teacher1"
And I press "Edit"
And I press "Create folder"
And I set the field "New folder name" to "Test subfolder 1"
+1 -2
View File
@@ -33,7 +33,6 @@ use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\writer;
use core_privacy\manager;
use Horde\Socket\Client\Exception;
/**
* Class provider
@@ -196,7 +195,7 @@ class provider implements
$field = array_key_exists($record->fieldid, $fields) ? $fields[$record->fieldid] : null;
$data = data_controller::create(0, $record, $field);
self::export_customfield_data($data, array_merge($subcontext, [$record->id]));
} catch (Exception $e) {
} catch (\Exception $e) {
// We store some data that we can not initialise controller for. We still need to export it.
self::export_customfield_data_unknown($record, $field, array_merge($subcontext, [$record->id]));
}
@@ -1,4 +1,5 @@
@customfield @customfield_textarea @javascript @_file_upload
# This feature has Atto-specific steps. See MDL-75913 for further details.
@customfield @customfield_textarea @javascript @_file_upload @editor_atto
Feature: Default value for the textarea custom field can contain images
In order to see images on custom fields
As a manager
@@ -0,0 +1,81 @@
@enrol @enrol_cohort
Feature: Cohort enrolment management
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher001 | Teacher | 001 | teacher001@example.com |
| s1 | Sandra | Cole | s1@example.com |
| s2 | John | Smith | s2@example.com |
| s4 | Jane | Doe | s4@example.com |
| s3 | Bianca | McAfee | s3@example.com |
| s5 | Abigail | Wyatt | s5@example.com |
And the following "cohorts" exist:
| name | idnumber | visible | Context |
| Alpha1 | A1 | 1 | 3 |
| Beta2 | B1 | 1 | 3 |
And the following "courses" exist:
| fullname | shortname | format | startdate |
| Course 001 | C001 | weeks | ##1 month ago## |
And the following "course enrolments" exist:
| user | course | role | timestart |
| teacher001 | C001 | editingteacher | ##1 month ago## |
And the following "cohort members" exist:
| user | cohort |
| s1 | A1 |
| s2 | A1 |
| s3 | B1 |
| s5 | B1 |
And I am on the "Course 001" course page logged in as teacher001
@javascript
Scenario: Add groups in the course cohort enrolment
When I add "Cohort sync" enrolment method with:
| Cohort | A1 |
| customint2 | -1 |
Then I should see "Cohort sync (Alpha1 - Student)"
And I am on "Course 001" course homepage
And I navigate to "Users > Groups" in current page administration
# Confirm that group was created and corresponding group members are present
And I set the field "groups[]" to "Alpha1 cohort (2)"
And the "members" select box should contain "Sandra Cole (s1@example.com)"
And the "members" select box should contain "John Smith (s2@example.com)"
And I log in as "admin"
And I navigate to "Users > Accounts > Cohorts" in site administration
And I click on "Assign" "link" in the "Alpha1" "table_row"
And I should see "Cohort 'Alpha1' members"
And I should see "Removing users from a cohort may result in unenrolling of users from multiple courses which includes deleting of user settings, grades, group membership and other user information from affected courses."
# Remove user s4 from cohort
And I set the field "removeselect[]" to "John Smith (s2@example.com)"
And I click on "Remove" "button"
# Add user s4 to the cohort.
And I set the field "addselect_searchtext" to "s4"
And I set the field "addselect[]" to "Jane Doe (s4@example.com)"
And I click on "Add" "button"
And the "removeselect[]" select box should contain "Sandra Cole (s1@example.com)"
And the "removeselect[]" select box should contain "Jane Doe (s4@example.com)"
And the "removeselect[]" select box should not contain "John Smith (s2@example.com)"
And I trigger cron
And I am on "Course 001" course homepage
And I navigate to course participants
# Verifies students 1 and 4 are in the cohort and student 2 is not any more.
And the following should exist in the "participants" table:
| First name / Last name | Email address | Roles | Groups |
| Sandra Cole | s1@example.com | Student | Alpha1 cohort |
| Jane Doe | s4@example.com | Student | Alpha1 cohort |
And the following should not exist in the "participants" table:
| First name / Last name | Email address | Roles | Groups |
| John Smith | s2@example.com | Student | Alpha1 cohort |
@javascript
Scenario: Course cohort enrolment creates a new group
When I add "Cohort sync" enrolment method with:
| Cohort | B1 |
And I click on "Edit" "link" in the "Beta2" "table_row"
And I set the field "Add to group" to "Create new group"
And I click on "Save changes" "button"
And I am on "Course 001" course homepage
And I navigate to "Users > Groups" in current page administration
And I set the field "groups[]" to "Beta2 cohort (2)"
Then the "members" select box should contain "Bianca McAfee (s3@example.com)"
And the "members" select box should contain "Abigail Wyatt (s5@example.com)"
+1 -2
View File
@@ -28,9 +28,8 @@ Feature: Users can be added to multiple groups at once
And I am on "Course 1" course homepage
And I follow "Participants"
And I click on "Edit groups for \"Student 1\"" "link" in the "student1" "table_row"
And I click on ".form-autocomplete-downarrow" "css_element" in the "student1" "table_row"
And I open the autocomplete suggestions list in the "student1" "table_row"
And I click on "Group 1" item in the autocomplete list
And I click on ".form-autocomplete-downarrow" "css_element" in the "student1" "table_row"
And I click on "Group 2" item in the autocomplete list
And I press the escape key
And I click on "Save changes" "link" in the "student1" "table_row"
@@ -26,9 +26,8 @@ Feature: Add a new custom file type
| Custom description | Moodle rules |
And I press "Save changes"
And I should see "application/x-moodle-rules"
And I log out
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I am on the "Course 1" course page logged in as teacher1
And I turn editing mode on
When I add a "File" to section "1" and I fill the form with:
| Name | Test file |
| Select files | files/tests/fixtures/custom_filetype.mdlr |
+1 -1
View File
@@ -237,7 +237,7 @@ class filter_algebra extends moodle_text_filter {
$DB->insert_record("cache_filters", $texcache, false);
$text = str_replace( $matches[0][$i], filter_algebra_image($filename, $texexp, '', '', $align), $text);
} else {
$text = str_replace( $matches[0][$i],"<b>Undetermined error:</b> ",$text);
$text = str_replace( $matches[0][$i],"<b>Undetermined error:</b> " . $matches[0][$i], $text);
}
} else {
$text = str_replace( $matches[0][$i], filter_algebra_image($filename, $texcache->rawtext), $text);
+1 -1
View File
@@ -123,7 +123,7 @@ class filter_data extends moodle_text_filter {
usort($contents, 'filter_data::sort_entries_by_length');
foreach ($contents as $content) {
$href_tag_begin = '<a class="data autolink dataid'.$content->dataid.'" title="'.$content->content.'" '.
$href_tag_begin = '<a class="data autolink dataid'.$content->dataid.'" title="'.s($content->content).'" '.
'href="'.$CFG->wwwroot.'/mod/data/view.php?d='.$content->dataid.
'&amp;rid='.$content->recordid.'">';
$contentlist[] = new filterobject($content->content, $href_tag_begin, '</a>', false, true);
@@ -49,7 +49,8 @@ Feature: Render H5P content using filters
And I wait until the page is ready
Then ".h5p-iframe" "css_element" should not exist
@javascript
# This scenario has Atto-specific steps. See MDL-75913 for further details.
@javascript @editor_atto
Scenario: Render a local H5P file as admin
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
@@ -83,7 +84,8 @@ Feature: Render H5P content using filters
And I should not see "you don't have access"
And I should see "Lorum ipsum"
@javascript
# This scenario has Atto-specific steps. See MDL-75913 for further details.
@javascript @editor_atto
Scenario: Render a local H5P file as teacher
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
@@ -107,7 +109,8 @@ Feature: Render H5P content using filters
Then I should see "Note that the libraries may exist in the file you uploaded, but you're not allowed to upload new libraries."
And I should see "missing-required-library"
@javascript
# This scenario has Atto-specific steps. See MDL-75913 for further details.
@javascript @editor_atto
Scenario: Render a local H5P file with existing libraries
Given I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
+4 -11
View File
@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Provides the {@link filter_mathjaxloader_filter_testcase} class.
*
* @package filter_mathjaxloader
* @category test
* @copyright 2017 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
@@ -31,6 +22,8 @@ require_once($CFG->dirroot.'/filter/mathjaxloader/filter.php');
/**
* Unit tests for the MathJax loader filter.
*
* @package filter_mathjaxloader
* @category test
* @copyright 2017 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -42,7 +35,7 @@ class filter_mathjaxloader_filter_testcase extends advanced_testcase {
* @param string $moodlelangcode the user's current language
* @param string $mathjaxlangcode the mathjax language to be used for the moodle language
*
* @dataProvider test_map_language_code_expected_mappings
* @dataProvider map_language_code_expected_mappings
*/
public function test_map_language_code($moodlelangcode, $mathjaxlangcode) {
@@ -55,7 +48,7 @@ class filter_mathjaxloader_filter_testcase extends advanced_testcase {
*
* @return array of [moodlelangcode, mathjaxcode] tuples
*/
public function test_map_language_code_expected_mappings() {
public function map_language_code_expected_mappings() {
return [
['cz', 'cs'], // Explicit mapping.
@@ -38,7 +38,7 @@ class filter_mathjaxloader_filtermath_testcase extends advanced_testcase {
* @param string $inputtext The text given by the user.
* @param string $expected The expected output after filtering.
*
* @dataProvider test_math_filtering_inputs
* @dataProvider math_filtering_inputs
*/
public function test_math_filtering($inputtext, $expected) {
$filter = new filter_mathjaxloader(context_system::instance(), []);
@@ -50,7 +50,7 @@ class filter_mathjaxloader_filtermath_testcase extends advanced_testcase {
*
* @return array of [inputtext, expectedoutput] tuples.
*/
public function test_math_filtering_inputs() {
public function math_filtering_inputs() {
return [
// One inline formula.
['Some inline math \\( y = x^2 \\).',
@@ -12,7 +12,7 @@ Feature: We can change what we are viewing on the grader report
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 1 | student2@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
@@ -26,19 +26,15 @@ Feature: We can change what we are viewing on the grader report
| assign | user | onlinetext |
| Test assignment name 1 | student1 | This is a submission for assignment 1 |
| Test assignment name 2 | student1 | This is a submission for assignment 2 |
And I am on the "Test assignment name 1" "assign activity" page logged in as student1
Then I should see "Submitted for grading"
And I am on the "Test assignment name 2" "assign activity" page
Then I should see "Submitted for grading"
And I log out
And the following "grade items" exist:
| itemname | grademin | grademax | course |
| Manual grade | 20 | 40 | C1 |
And the following "grade grades" exist:
| gradeitem | user | grade |
| Test assignment name 1 | student1 | 80 |
| Test assignment name 2 | student1 | 90 |
| Manual grade | student1 | 30 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I turn editing mode on
And I give the grade "80.00" to the user "Student 1" for the grade item "Test assignment name 1"
And I give the grade "90.00" to the user "Student 1" for the grade item "Test assignment name 2"
And I press "Save changes"
And I turn editing mode off
@javascript
Scenario: View and minimise the grader report containing hidden activities
@@ -47,29 +43,32 @@ Feature: We can change what we are viewing on the grader report
And I click on "Hide" "link" in the "Test assignment name 2" activity
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | 90 | 170 |
| -1- | -4- | -5- | -6- | -7- |
| Student 1 | 80 | 90 | 30 | 170 |
And I click on "Change to aggregates only" "link"
And I should not see "Test assignment name 1"
And I should not see "Test assignment name 2"
And I should not see "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- |
| Student 1 | 170 |
And I click on "Change to grades only" "link"
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- |
| Student 1 | 80 | 90 |
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | 90 | 30 |
@javascript @skip_chrome_zerosize
Scenario: View and minimise the grader report containing hidden activities without the 'moodle/grade:viewhidden' capability
Scenario: Minimise the grader report containing hidden activities without the 'moodle/grade:viewhidden' capability
When I am on "Course 1" course homepage with editing mode on
And I open "Test assignment name 2" actions menu
And I click on "Hide" "link" in the "Test assignment name 2" activity
@@ -82,23 +81,26 @@ Feature: We can change what we are viewing on the grader report
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "View > Grader report" in the course gradebook
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | - | 80 |
| -1- | -4- | -5- | -6- | -7- |
| Student 1 | 80 | - | 30 | 105.71 |
And I click on "Change to aggregates only" "link"
And I should not see "Test assignment name 1"
And I should not see "Test assignment name 2"
And I should not see "Test assignment name 1" in the "user-grades" "table"
And I should not see "Test assignment name 2" in the "user-grades" "table"
And I should not see "Manual grade"
And I should see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- |
| Student 1 | 80 |
| Student 1 | 105.71 |
And I click on "Change to grades only" "link"
And I should see "Test assignment name 1"
And I should see "Test assignment name 2"
And I should see "Test assignment name 1" in the "user-grades" "table"
And I should see "Test assignment name 2" in the "user-grades" "table"
And I should see "Manual grade"
And I should not see "Course total"
And the following should exist in the "user-grades" table:
| -1- | -4- | -5- |
| Student 1 | 80 | - |
| -1- | -4- | -5- | -6- |
| Student 1 | 80 | - | 30 |
@@ -27,6 +27,7 @@ namespace gradereport_history\output;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/tablelib.php');
require_once($CFG->dirroot . '/user/lib.php');
/**
* Renderable class for gradehistory report.
@@ -53,6 +54,11 @@ class tablelog extends \table_sql implements \renderable {
*/
protected $filters;
/**
* @var \stdClass[] List of users included in the report (if userids are specified as filters)
*/
protected $users = [];
/**
* @var array A list of grade items present in the course.
*/
@@ -99,7 +105,6 @@ class tablelog extends \table_sql implements \renderable {
$this->courseid = $this->context->instanceid;
$this->pagesize = $perpage;
$this->page = $page;
$this->filters = (object)$filters;
$this->gradeitems = \grade_item::fetch_all(array('courseid' => $this->courseid));
$this->cms = get_fast_modinfo($this->courseid);
$this->useridfield = 'userid';
@@ -108,6 +113,9 @@ class tablelog extends \table_sql implements \renderable {
// Define columns in the table.
$this->define_table_columns();
// Define filters.
$this->define_table_filters((object) $filters);
// Define configs.
$this->define_table_configs($url);
@@ -136,6 +144,36 @@ class tablelog extends \table_sql implements \renderable {
$this->no_sorting('grader');
}
/**
* Define table filters
*
* @param \stdClass $filters
*/
protected function define_table_filters(\stdClass $filters): void {
global $DB;
$this->filters = $filters;
if (!empty($this->filters->userids)) {
$course = get_course($this->courseid);
// Retrieve userids that are part of the filters object, and ensure user can access each of them.
[$userselect, $userparams] = $DB->get_in_or_equal(explode(',', $this->filters->userids), SQL_PARAMS_NAMED);
[$usersort] = users_order_by_sql();
$this->users = array_filter(
$DB->get_records_select('user', "id {$userselect}", $userparams, $usersort),
static function(\stdClass $user) use ($course): bool {
return user_can_view_profile($user, $course);
}
);
// Reset userids to the filtered array of users.
$this->filters->userids = implode(',', array_keys($this->users));
}
}
/**
* Setup the headers for the html table.
*/
@@ -507,19 +545,9 @@ class tablelog extends \table_sql implements \renderable {
/**
* Returns a list of selected users.
*
* @return array returns an array in the format $userid => $userid
* @return \stdClass[] List of user objects
*/
public function get_selected_users() {
global $DB;
$idlist = array();
if (!empty($this->filters->userids)) {
$idlist = explode(',', $this->filters->userids);
list($where, $params) = $DB->get_in_or_equal($idlist);
return $DB->get_records_select('user', "id $where", $params);
}
return $idlist;
public function get_selected_users(): array {
return $this->users;
}
}
+14 -4
View File
@@ -60,6 +60,9 @@ class gradereport_history_report_testcase extends advanced_testcase {
self::getDataGenerator()->enrol_user($u4->id, $c1->id, 'student');
self::getDataGenerator()->enrol_user($u5->id, $c1->id, 'student');
self::getDataGenerator()->enrol_user($grader1->id, $c2->id, 'teacher');
self::getDataGenerator()->enrol_user($u5->id, $c2->id, 'student');
// Modules.
$c1m1 = $this->getDataGenerator()->create_module('assign', array('course' => $c1));
$c1m2 = $this->getDataGenerator()->create_module('assign', array('course' => $c1));
@@ -132,11 +135,18 @@ class gradereport_history_report_testcase extends advanced_testcase {
$this->assertEquals(8, $this->get_tablelog_results($c1ctx, array(), true));
$this->assertEquals(13, $this->get_tablelog_results($c2ctx, array(), true));
// Filtering on 1 user.
$this->assertEquals(3, $this->get_tablelog_results($c1ctx, array('userids' => $u1->id), true));
// Filtering on 1 user the current user cannot access should return all records.
$this->assertEquals(8, $this->get_tablelog_results($c1ctx, array('userids' => $u1->id), true));
// Filtering on more users.
$this->assertEquals(4, $this->get_tablelog_results($c1ctx, array('userids' => "$u1->id,$u3->id"), true));
// Filtering on 2 users, only one of whom the current user can access.
$this->assertEquals(1, $this->get_tablelog_results($c1ctx, ['userids' => "$u1->id,$u3->id"], true));
$results = $this->get_tablelog_results($c1ctx, ['userids' => "$u1->id,$u3->id"]);
$this->assertGradeHistoryIds([$grades['c1m1u3']->id], $results);
// Filtering on 2 users, both of whom the current user can access.
$this->assertEquals(3, $this->get_tablelog_results($c1ctx, ['userids' => "$u2->id,$u3->id"], true));
$results = $this->get_tablelog_results($c1ctx, ['userids' => "$u2->id,$u3->id"]);
$this->assertGradeHistoryIds([$grades['c1m1u2']->id, $grades['c1m1u3']->id, $grades['c1m2u2']->id], $results);
// Filtering based on one grade item.
$gi = grade_item::fetch($giparams + array('iteminstance' => $c1m1->id));
@@ -421,6 +421,8 @@ Feature: We can use calculated grade totals
| Extra credit | 0 |
| Maximum grade | 200 |
| Rescale existing grades | No |
# Change window size to ultra-wide to avoid 'out-of-bounds' random failures.
And I change window size to "5120x2160"
And I give the grade "21.00" to the user "Student 1" for the grade item "Manual item 2"
And I press "Save changes"
And I give the grade "20.00" to the user "Student 1" for the grade item "Manual item 2"
@@ -432,6 +434,8 @@ Feature: We can use calculated grade totals
| Extra credit | 0 |
| Maximum grade | 100 |
| Rescale existing grades | No |
# Change window size to ultra-wide to avoid 'out-of-bounds' random failures.
And I change window size to "5120x2160"
And I give the grade "21.00" to the user "Student 1" for the grade item "Manual item 2"
And I press "Save changes"
And I give the grade "20.00" to the user "Student 1" for the grade item "Manual item 2"
+12 -26
View File
@@ -21,13 +21,10 @@ Feature: We can set the grade to pass value
And the following "activity" exists:
| activity | assign |
| course | C1 |
| section | 1 |
| idnumber | assign1 |
| name | Test Assignment 1 |
| intro | Submit your online text |
| assignsubmission_onlinetext_enabled | 1 |
And I log in as "teacher1"
And I am on "Course 1" course homepage
And I am on the "Course 1" course page logged in as teacher1
@javascript
Scenario: Validate that switching the type of grading used correctly disables grade to pass
@@ -115,11 +112,10 @@ Feature: We can set the grade to pass value
Scenario: Set a valid grade to pass for workshop activity
Given the following "activities" exist:
| activity | name | intro | course | section | idnumber |
| workshop | Test Workshop 1 | Test workshop | C1 | 1 | workshop1 |
| activity | name | course | idnumber |
| workshop | Test Workshop 1 | C1 | workshop1 |
And I am on "Course 1" course homepage with editing mode on
And I follow "Test Workshop 1"
And I navigate to "Edit settings" in current page administration
And I am on the "Test Workshop 1" "workshop activity editing" page
And I set the following fields to these values:
| grade | 80 |
| Submission grade to pass | 40 |
@@ -138,19 +134,16 @@ Feature: We can set the grade to pass value
And the field "Grade to pass" matches value "10"
And I set the field "Grade to pass" to "15"
And I press "Save changes"
And I am on "Course 1" course homepage
And I follow "Test Workshop 1"
And I follow "Edit settings"
And I am on the "Test Workshop 1" "workshop activity editing" page
And the field "Submission grade to pass" matches value "45"
And the field "Assessment grade to pass" matches value "15"
Scenario: Set an invalid grade to pass for workshop activity
Given the following "activities" exist:
| activity | name | intro | course | section | idnumber |
| workshop | Test Workshop 1 | Test workshop | C1 | 1 | workshop1 |
| activity | name | course | idnumber |
| workshop | Test Workshop 1 | C1 | workshop1 |
And I am on "Course 1" course homepage with editing mode on
And I follow "Test Workshop 1"
And I navigate to "Edit settings" in current page administration
And I am on the "Test Workshop 1" "workshop activity editing" page
And I set the following fields to these values:
| grade | 80 |
| Submission grade to pass | 90 |
@@ -184,14 +177,9 @@ Feature: We can set the grade to pass value
Scenario: Set a valid grade to pass for lesson activity
Given the following "activities" exist:
| activity | name | intro | course | section | idnumber |
| lesson | Test Lesson 1 | Test | C1 | 1 | lesson1 |
And I am on "Course 1" course homepage with editing mode on
And I follow "Test Lesson 1"
And I navigate to "Edit settings" in current page administration
And I set the following fields to these values:
| Grade to pass | 90 |
And I press "Save and return to course"
| activity | name | course | idnumber | gradepass |
| lesson | Test Lesson 1 | C1 | lesson1 | 90 |
And I am on the "Test Lesson 1" "lesson activity" page
And I navigate to "View > Grader report" in the course gradebook
And I turn editing mode on
And I click on "Edit lesson Test Lesson 1" "link"
@@ -199,9 +187,7 @@ Feature: We can set the grade to pass value
Then the field "Grade to pass" matches value "90"
And I set the field "Grade to pass" to "80"
And I press "Save changes"
And I am on "Course 1" course homepage
And I follow "Test Lesson 1"
And I follow "Edit settings"
And I am on the "Test Lesson 1" "lesson activity editing" page
And the field "Grade to pass" matches value "80"
Scenario: Set a valid grade to pass for database activity
@@ -1,8 +1,8 @@
@core @core_group
Feature: The description of a group can be viewed by students and teachers
In order to view the description of a group
Feature: The description and picture of a group can be viewed by students and teachers
In order to view the description and picture of a group
As a teacher
I need to create groups and add descriptions to them.
I need to create groups and add descriptions and picture to them.
Background:
Given the following "courses" exist:
@@ -19,11 +19,9 @@ Feature: The description of a group can be viewed by students and teachers
| student1 | C1 | student |
| student2 | C1 | student |
@javascript
Scenario: A student can see the group description when visible groups are set. Teachers can see group details.
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Edit settings" in current page administration
@javascript @_file_upload
Scenario: A student can see the group description and picture when visible groups are set. Teachers can see group details.
Given I am on the "Course 1" "course editing" page logged in as "teacher1"
And I set the following fields to these values:
| Group mode | Visible groups |
And I press "Save and display"
@@ -32,6 +30,8 @@ Feature: The description of a group can be viewed by students and teachers
And I set the following fields to these values:
| Group name | Group A |
| Group description | Description for Group A |
# Upload group picture
And I upload "lib/tests/fixtures/gd-logo.png" file to "New picture" filemanager
And I press "Save changes"
And I press "Create group"
And I set the following fields to these values:
@@ -39,11 +39,12 @@ Feature: The description of a group can be viewed by students and teachers
And I press "Save changes"
And I add "Student 1 (student1@example.com)" user to "Group A" group members
And I add "Student 2 (student2@example.com)" user to "Group B" group members
And I am on "Course 1" course homepage
And I navigate to course participants
And I click on "Student 1" "link" in the "participants" "table"
And I click on "Group A" "link"
And I should see "Description for Group A"
# As teacher, confirm that group picture is displayed
And "//img[@class='grouppicture']" "xpath_element" should exist
And ".groupinfobox" "css_element" should exist
And I set the field "type" in the "Filter 1" "fieldset" to "Groups"
And I set the field "Type or select..." in the "Filter 1" "fieldset" to "Group B"
@@ -52,27 +53,23 @@ Feature: The description of a group can be viewed by students and teachers
And I click on "Group B" "link"
And I should see "Student 2" in the "participants" "table"
And ".groupinfobox" "css_element" should not exist
And I log out
When I log in as "student1"
And I am on "Course 1" course homepage
When I am on the "Course 1" course page logged in as student1
And I navigate to course participants
And I click on "Student 1" "link" in the "participants" "table"
And I click on "Group A" "link"
# As student, confirm that group description and picture is displayed
Then I should see "Description for Group A"
And I log out
And I log in as "student2"
And I am on "Course 1" course homepage
And "//img[@class='grouppicture']" "xpath_element" should exist
And I am on the "Course 1" course page logged in as student2
And I navigate to course participants
And I click on "Student 2" "link" in the "participants" "table"
And I click on "Group B" "link"
And I should see "Student 2" in the "participants" "table"
And ".groupinfobox" "css_element" should not exist
@javascript
Scenario: A student can not see the group description when separate groups are set. Teachers can see group details.
Given I log in as "teacher1"
And I am on "Course 1" course homepage
And I navigate to "Edit settings" in current page administration
@javascript @_file_upload
Scenario: A student can not see the group description and picture when separate groups are set. Teachers can see group details.
Given I am on the "Course 1" "course editing" page logged in as "teacher1"
And I set the following fields to these values:
| Group mode | Separate groups |
And I press "Save and display"
@@ -81,6 +78,8 @@ Feature: The description of a group can be viewed by students and teachers
And I set the following fields to these values:
| Group name | Group A |
| Group description | Description for Group A |
# Upload group picture
And I upload "lib/tests/fixtures/gd-logo.png" file to "New picture" filemanager
And I press "Save changes"
And I press "Create group"
And I set the following fields to these values:
@@ -88,11 +87,12 @@ Feature: The description of a group can be viewed by students and teachers
And I press "Save changes"
And I add "Student 1 (student1@example.com)" user to "Group A" group members
And I add "Student 2 (student2@example.com)" user to "Group B" group members
And I am on "Course 1" course homepage
And I navigate to course participants
And I click on "Student 1" "link" in the "participants" "table"
And I click on "Group A" "link"
And I should see "Description for Group A"
# As teacher, confirm that group picture is displayed
And "//img[@class='grouppicture']" "xpath_element" should exist
And ".groupinfobox" "css_element" should exist
And I set the field "type" in the "Filter 1" "fieldset" to "Groups"
And I set the field "Type or select..." in the "Filter 1" "fieldset" to "Group B"
@@ -100,18 +100,16 @@ Feature: The description of a group can be viewed by students and teachers
And I click on "Student 2" "link" in the "participants" "table"
And I click on "Group B" "link"
And ".groupinfobox" "css_element" should not exist
And I log out
When I log in as "student1"
And I am on "Course 1" course homepage
When I am on the "Course 1" course page logged in as student1
And I navigate to course participants
And I click on "Student 1" "link" in the "participants" "table"
And I click on "Group A" "link"
And I should see "Student 1" in the "participants" "table"
And I should not see "Description for Group A"
# As student, confirm that group description and picture are not displayed
Then I should not see "Description for Group A"
And "//img[@class='grouppicture']" "xpath_element" should not exist
And ".groupinfobox" "css_element" should not exist
And I log out
And I log in as "student2"
And I am on "Course 1" course homepage
When I am on the "Course 1" course page logged in as student2
And I navigate to course participants
And I click on "Student 2" "link" in the "participants" "table"
And I click on "Group B" "link"
+7 -15
View File
@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Testing the H5PFrameworkInterface interface implementation.
*
* @package core_h5p
* @category test
* @copyright 2019 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_h5p;
use core_collator;
@@ -32,6 +23,7 @@ use core_collator;
* Test class covering the H5PFrameworkInterface interface implementation.
*
* @package core_h5p
* @category test
* @copyright 2019 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @runTestsInSeparateProcesses
@@ -587,7 +579,7 @@ class framework_testcase extends \advanced_testcase {
/**
* Test the behaviour of isPatchedLibrary().
*
* @dataProvider test_isPatchedLibrary_provider
* @dataProvider isPatchedLibrary_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param bool $expected The expectation whether the library is patched or not
@@ -609,7 +601,7 @@ class framework_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_isPatchedLibrary_provider(): array {
public function isPatchedLibrary_provider(): array {
return [
'Unpatched library. No different versioning' => [
[
@@ -1365,7 +1357,7 @@ class framework_testcase extends \advanced_testcase {
/**
* Test the behaviour of loadLibrarySemantics().
*
* @dataProvider test_loadLibrarySemantics_provider
* @dataProvider loadLibrarySemantics_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param string $expected The expected semantics value
@@ -1388,7 +1380,7 @@ class framework_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_loadLibrarySemantics_provider(): array {
public function loadLibrarySemantics_provider(): array {
$semantics = json_encode(
[
@@ -2157,7 +2149,7 @@ class framework_testcase extends \advanced_testcase {
/**
* Test the behaviour of test_libraryHasUpgrade().
*
* @dataProvider test_libraryHasUpgrade_provider
* @dataProvider libraryHasUpgrade_provider
* @param array $libraryrecords Array containing data for the library creation
* @param array $testlibrary Array containing the test library data
* @param bool $expected The expectation whether the library is patched or not
@@ -2179,7 +2171,7 @@ class framework_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_libraryHasUpgrade_provider(): array {
public function libraryHasUpgrade_provider(): array {
return [
'Lower major version; Identical lower version' => [
[
+11 -22
View File
@@ -14,23 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Test class covering the h5p data generator class.
*
* @package core_h5p
* @category test
* @copyright 2019 Mihail Geshoski <mihail@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_h5p;
use core_h5p\local\library\autoloader;
defined('MOODLE_INTERNAL') || die();
/**
* Generator testcase for the core_grading generator.
* Test class covering the h5p data generator class.
*
* @package core_h5p
* @category test
@@ -165,7 +154,7 @@ class generator_testcase extends \advanced_testcase {
* Test the behaviour of generate_h5p_data(). Test whether library files are created or not
* on filesystem depending what the method defines.
*
* @dataProvider test_generate_h5p_data_files_creation_provider
* @dataProvider generate_h5p_data_files_creation_provider
* @param bool $createlibraryfiles Whether to create library files on the filesystem
* @param bool $expected The expectation whether the files have been created or not
**/
@@ -205,7 +194,7 @@ class generator_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_generate_h5p_data_files_creation_provider(): array {
public function generate_h5p_data_files_creation_provider(): array {
return [
'Do not create library related files on the filesystem' => [
false,
@@ -256,7 +245,7 @@ class generator_testcase extends \advanced_testcase {
* Test the behaviour of create_h5p_record(). Test whather the h5p content data is
* properly saved in the database.
*
* @dataProvider test_create_h5p_record_provider
* @dataProvider create_h5p_record_provider
* @param array $h5pdata The h5p content data
* @param \stdClass $expected The expected saved data
**/
@@ -282,7 +271,7 @@ class generator_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_create_h5p_record_provider(): array {
public function create_h5p_record_provider(): array {
$createdjsoncontent = json_encode(
array(
'text' => '<p>Created dummy text<\/p>\n',
@@ -379,7 +368,7 @@ class generator_testcase extends \advanced_testcase {
* Test the behaviour of create_contents_libraries_record(). Test whether the contents libraries
* are properly saved in the database.
*
* @dataProvider test_create_contents_libraries_record_provider
* @dataProvider create_contents_libraries_record_provider
* @param array $contentslibrariestdata The h5p contents libraries data.
* @param \stdClass $expected The expected saved data.
**/
@@ -403,7 +392,7 @@ class generator_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_create_contents_libraries_record_provider(): array {
public function create_contents_libraries_record_provider(): array {
return [
'Create h5p content library with set dependency type' => [
[
@@ -439,7 +428,7 @@ class generator_testcase extends \advanced_testcase {
* Test the behaviour of create_library_dependency_record(). Test whether the contents libraries
* are properly saved in the database.
*
* @dataProvider test_create_library_dependency_record_provider
* @dataProvider create_library_dependency_record_provider
* @param array $librarydependencydata The library dependency data.
* @param \stdClass $expected The expected saved data.
**/
@@ -463,7 +452,7 @@ class generator_testcase extends \advanced_testcase {
*
* @return array
*/
public function test_create_library_dependency_record_provider(): array {
public function create_library_dependency_record_provider(): array {
return [
'Create h5p library dependency with set dependency type' => [
[
@@ -494,7 +483,7 @@ class generator_testcase extends \advanced_testcase {
/**
* Test the behaviour of create_content_file(). Test whether a file belonging to a content is created.
*
* @dataProvider test_create_content_file_provider
* @dataProvider create_content_file_provider
* @param array $filedata Data from the file to be created.
* @param array $expecteddata Data expected.Data from the file to be created.
*/
@@ -529,7 +518,7 @@ class generator_testcase extends \advanced_testcase {
*
* @return array
**/
public function test_create_content_file_provider(): array {
public function create_content_file_provider(): array {
return [
'Create file in content with id 4' => [
[
+30 -20
View File
@@ -31,39 +31,49 @@ defined('MOODLE_INTERNAL') || die();
*/
class core_iplookup_geoplugin_testcase extends advanced_testcase {
public function setUp() {
/**
* Load required test libraries
*/
public static function setUpBeforeClass(): void {
global $CFG;
require_once("$CFG->libdir/filelib.php");
require_once("$CFG->dirroot/iplookup/lib.php");
require_once("{$CFG->dirroot}/iplookup/lib.php");
}
/**
* In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
*/
public function setUp() {
if (!PHPUNIT_LONGTEST) {
// we do not want to DDOS their server, right?
$this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
}
$this->resetAfterTest();
$CFG->geoipfile = '';
}
public function test_ipv4() {
/**
* Test IPv4 address
*
* @covers ::iplookup_find_location
*/
public function test_ipv4(): void {
$result = iplookup_find_location('50.0.184.0');
$this->assertEquals('array', gettype($result));
$this->assertEquals('San Francisco', $result['city']);
$this->assertEquals(-122.3933, $result['longitude'], 'Coordinates are out of accepted tolerance', 0.1);
$this->assertEquals(37.7697, $result['latitude'], 'Coordinates are out of accepted tolerance', 0.1);
$this->assertInternalType('array', $result);
$this->assertInternalType('float', $result['latitude']);
$this->assertInternalType('float', $result['longitude']);
$this->assertInternalType('string', $result['city']);
$this->assertInternalType('string', $result['country']);
$this->assertInternalType('array', $result['title']);
$this->assertInternalType('string', $result['title'][0]);
$this->assertInternalType('string', $result['title'][1]);
$this->assertNull($result['error']);
$this->assertEquals('array', gettype($result['title']));
$this->assertEquals('San Francisco', $result['title'][0]);
$this->assertEquals('United States', $result['title'][1]);
}
public function test_geoip_ipv6() {
/**
* Test IPv6 address (unsupported by Geoplugin)
*
* @covers ::iplookup_find_location
*/
public function test_ipv6(): void {
$result = iplookup_find_location('2a01:8900:2:3:8c6c:c0db:3d33:9ce6');
$this->assertNotNull($result['error']);
$this->assertEquals($result['error'], get_string('invalidipformat', 'error'));
}
}
+13 -7
View File
@@ -1180,6 +1180,7 @@ $string['sitepolicyhandlerplugin'] = '{$a->name} ({$a->component})';
$string['sitepolicyguest'] = 'Site policy URL for guests';
$string['sitepolicyguest_help'] = 'The URL of the site policy that all guests must see and agree to before accessing the site. Note that this setting will only have an effect if the site policy handler is set to default (core).';
$string['sitesectionhelp'] = 'If selected, a topic section will be displayed on the site\'s front page.';
$string['sixtyfourbitsrequired'] = 'It has been detected that your site is not using a 64-bit PHP version. You are required to upgrade your system (operating system, PHP...) before installing this Moodle version.';
$string['sixtyfourbitswarning'] = 'It has been detected that your site is not using a 64-bit PHP version. It is recommended that you upgrade your site to ensure future compatibility.';
$string['slasharguments'] = 'Use slash arguments';
$string['slashargumentswarning'] = 'It is recommended that the use of slash arguments is enabled. In future it will be required. For more details, see the documentation <a href="https://docs.moodle.org/en/admin/environment/slasharguments">Using slash arguments</a>.';
@@ -1346,12 +1347,13 @@ $string['unsupporteddbfilepertable'] = 'For full support of UTF-8 both MySQL and
$string['unsupporteddblargeprefix'] = 'For full support of UTF-8 both MySQL and MariaDB require you to change your MySQL setting \'innodb_large_prefix\' to \'ON\'. See the documentation for further details.';
$string['unsupporteddbstorageengine'] = 'The database storage engine being used is no longer supported.';
$string['unsupporteddbtablerowformat'] = 'Your database has tables using Antelope as the file format. You are recommended to convert the tables to the Barracuda file format. See the documentation <a href="https://docs.moodle.org/en/cli">Administration via command line</a> for details of a tool for converting InnoDB tables to Barracuda.';
$string['unsupportedphpversion7'] = 'PHP version 7 is not supported.';
$string['unsupportedphpversion71'] = 'PHP version 7.1 is not supported.';
$string['unsupportedphpversion72'] = 'PHP version 7.2 is not supported.';
$string['unsupportedphpversion73'] = 'PHP version 7.3 is not supported.';
$string['unsupportedphpversion74'] = 'PHP version 7.4 is not supported.';
$string['unsupportedphpversion80'] = 'PHP version 8.0 is not supported.';
$string['unsupportedphpversion7'] = 'PHP version 7 and higher are not supported.';
$string['unsupportedphpversion71'] = 'PHP version 7.1 and higher are not supported.';
$string['unsupportedphpversion72'] = 'PHP version 7.2 and higher are not supported.';
$string['unsupportedphpversion73'] = 'PHP version 7.3 and higher are not supported.';
$string['unsupportedphpversion74'] = 'PHP version 7.4 and higher are not supported.';
$string['unsupportedphpversion80'] = 'PHP version 8.0 and higher are not supported.';
$string['unsupportedphpversion81'] = 'PHP version 8.1 and higher are not supported.';
$string['unsuspenduser'] = 'Activate user account';
$string['updateaccounts'] = 'Update existing accounts';
$string['updatecomponent'] = 'Update component';
@@ -1453,9 +1455,13 @@ $string['warningiconvbuggy'] = 'Your version of the iconv library does not suppo
$string['webproxy'] = 'Web proxy';
$string['webproxyinfo'] = 'Fill in the following options if your Moodle server cannot access the internet directly. Internet access is required for the download of environment data, language packs, RSS feeds, timezones, etc.<br /><em>The PHP cURL extension is highly recommended.</em>';
$string['xmlrpcrecommended'] = 'The XMLRPC extension is useful for web services and Moodle networking.';
$string['xmlrpcmaharaenabled'] = 'It has been detected that the Mahara ePortfolio is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer maintained by PHP.';
$string['xmlrpcmnetenabled'] = 'It has been detected that the Moodle Networking is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer maintained by PHP.';
$string['xmlrpcwebserviceenabled'] = 'It has been detected that the XML-RPC Web Service protocol is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer maintained by PHP.';
$string['yuicomboloading'] = 'YUI combo loading';
$string['ziprequired'] = 'The Zip PHP extension is now required by Moodle, info-ZIP binaries or PclZip library are not used anymore.';
$string['modassignmentinuse'] = 'Your site is still using the Assignment 2.2 plugin. Before upgrading you must 1) backup any Assignment 2.2 activities that you want to keep and restore them as Assignment activities, and 2) delete all Assignment 2.2 data from the database.';
$string['modassignmentsubpluginsexist'] = 'Assignment 2.2. subplugins may be present. The mod/assignment folder and all of its subplugins need to be removed before upgrading.';
$string['caching'] = 'Caching';
$string['cachesettings'] = 'Cache settings';
+1 -1
View File
@@ -180,5 +180,5 @@ $string['XOF'] = 'CFA Franc BCEAO';
$string['XPF'] = 'CFP Franc';
$string['YER'] = 'Yemeni Rial';
$string['ZAR'] = 'South African Rand';
$string['ZMK'] = 'Zambian Kwacha';
$string['ZMW'] = 'Zambian Kwacha';
$string['ZWL'] = 'Zimbabwe Dollar';
+1
View File
@@ -53,6 +53,7 @@ $string['cutpastemozilla'] = 'Unfortunately, you cannot currently use normal key
$string['delete'] = 'Delete';
$string['editors'] = 'Text editors';
$string['editorsettings'] = 'Manage editors';
$string['editorxformat'] = '{$a} format';
$string['enterurlfirst'] = 'You have to enter an URL first';
$string['filebrowser'] = 'File Browser';
$string['findwhat'] = 'Find';
+2
View File
@@ -112,6 +112,7 @@ $string['america/cayenne'] = 'America/Cayenne';
$string['america/cayman'] = 'America/Cayman';
$string['america/chicago'] = 'America/Chicago';
$string['america/chihuahua'] = 'America/Chihuahua';
$string['america/ciudad_juarez'] = 'America/Ciudad_Juarez';
$string['america/costa_rica'] = 'America/Costa_Rica';
$string['america/creston'] = 'America/Creston';
$string['america/cuiaba'] = 'America/Cuiaba';
@@ -363,6 +364,7 @@ $string['europe/jersey'] = 'Europe/Jersey';
$string['europe/kaliningrad'] = 'Europe/Kaliningrad';
$string['europe/kiev'] = 'Europe/Kiev';
$string['europe/kirov'] = 'Europe/Kirov';
$string['europe/kyiv'] = 'Europe/Kyiv';
$string['europe/lisbon'] = 'Europe/Lisbon';
$string['europe/ljubljana'] = 'Europe/Ljubljana';
$string['europe/london'] = 'Europe/London';
+44 -5
View File
@@ -333,6 +333,34 @@ class behat_config_util {
return $this->get_component_contexts($component);
}
/**
* Sort the list of components contexts.
*
* This ensures that contexts are sorted consistently.
* Core hooks defined in the behat_hooks class _must_ be defined first.
*
* @param array $contexts
* @return array The sorted context list
*/
protected function sort_component_contexts(array $contexts): array {
// Ensure that the lib_tests are first as they include the root of all tests, hooks, and more.
uksort($contexts, function($a, $b): int {
if ($a === 'behat_hooks') {
return -1;
}
if ($b === 'behat_hooks') {
return 1;
}
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
});
return $contexts;
}
/**
* Behat config file specifing the main context class,
* the required Behat extensions and Moodle test wwwroot.
@@ -638,7 +666,7 @@ class behat_config_util {
[
'capabilities' => [
'extra_capabilities' => [
'chromeOptions' => [
'goog:chromeOptions' => [
'args' => [
'unlimited-storage',
'disable-web-security',
@@ -650,6 +678,16 @@ class behat_config_util {
$values
);
// Selenium no longer supports non-w3c browser control.
// Rename chromeOptions to goog:chromeOptions, which is the W3C variant of this.
if (array_key_exists('chromeOptions', $values['capabilities']['extra_capabilities'])) {
$values['capabilities']['extra_capabilities']['goog:chromeOptions'] = array_merge_recursive(
$values['capabilities']['extra_capabilities']['goog:chromeOptions'],
$values['capabilities']['extra_capabilities']['chromeOptions']
);
unset($values['capabilities']['extra_capabilities']['chromeOptions']);
}
// If the mobile app is enabled, check its version and add appropriate tags.
if ($mobiletags = $this->get_mobile_version_tags()) {
if (!empty($values['tags'])) {
@@ -659,13 +697,13 @@ class behat_config_util {
}
}
$values['capabilities']['extra_capabilities']['chromeOptions']['args'] = array_map(function($arg): string {
$values['capabilities']['extra_capabilities']['goog:chromeOptions']['args'] = array_map(function($arg): string {
if (substr($arg, 0, 2) === '--') {
return substr($arg, 2);
}
return $arg;
}, $values['capabilities']['extra_capabilities']['chromeOptions']['args']);
sort($values['capabilities']['extra_capabilities']['chromeOptions']['args']);
}, $values['capabilities']['extra_capabilities']['goog:chromeOptions']['args']);
sort($values['capabilities']['extra_capabilities']['goog:chromeOptions']['args']);
}
// Fill tags information.
@@ -1537,8 +1575,9 @@ class behat_config_util {
}
// Sort the list of contexts.
ksort($contexts);
$contexts = $this->sort_component_contexts($contexts);
// Cache it for subsequent fetches.
$this->themecontexts[$theme] = $contexts;
return $contexts;
@@ -26,6 +26,7 @@
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
use Behat\Testwork\Environment\Environment;
use Behat\Mink\Exception\DriverException;
/**
* Helper to get behat contexts.
@@ -115,6 +116,34 @@ class behat_context_helper {
return null;
}
/**
* Find all Behat contexts which match the specified context class name prefix.
*
* Moodle uses a consistent class naming scheme for all Behat contexts, whereby the context name is in the format:
*
* behat_{component}
*
* This method will return all contexts which match the specified prefix.
*
* For example, to find all editors, you would pass in 'behat_editor', and this might return:
* - behat_editor_atto
* - behat_editor_textarea
*
* @param string $prefix The prefix to search for
* @return \Behat\Behat\Context\Context[]
*/
public static function get_prefixed_contexts(string $prefix): array {
if (!is_a(self::$environment, \Behat\Behat\Context\Environment\InitializedContextEnvironment::class)) {
throw new DriverException(
'Cannot get prefixed contexts - the environment is not an InitializedContextEnvironment'
);
}
return array_filter(self::$environment->getContexts(), function($context) use ($prefix): bool {
return (strpos(get_class($context), $prefix) === 0);
});
}
/**
* Check for any theme override of the specified class name.
*
@@ -150,6 +150,12 @@ class behat_core_generator extends behat_generator_base {
'required' => ['fullname', 'course'],
'switchids' => ['course' => 'courseid', 'gradecategory' => 'parent'],
],
'grade grades' => [
'singular' => 'grade grade',
'datagenerator' => 'grade_grade',
'required' => ['gradeitem'],
'switchids' => ['user' => 'userid', 'gradeitem' => 'itemid'],
],
'grade items' => [
'singular' => 'grade item',
'datagenerator' => 'grade_item',
@@ -275,11 +281,33 @@ class behat_core_generator extends behat_generator_base {
'required' => ['user', 'course', 'lastaccess'],
'switchids' => ['user' => 'userid', 'course' => 'courseid'],
],
'notifications' => [
'singular' => 'notification',
'datagenerator' => 'notification',
'required' => ['subject', 'userfrom', 'userto'],
'switchids' => ['userfrom' => 'userfromid', 'userto' => 'usertoid'],
],
];
return $entities;
}
/**
* Get the grade item id using a name.
*
* @param string $name
* @return int The grade item id
*/
protected function get_gradeitem_id(string $name): int {
global $DB;
if (!$id = $DB->get_field('grade_items', 'id', ['itemname' => $name])) {
throw new Exception('The specified grade item with name "' . $name . '" could not be found.');
}
return $id;
}
/**
* Remove any empty custom fields, to avoid errors when creating the course.
*
@@ -1009,6 +1037,39 @@ class behat_core_generator extends behat_generator_base {
$DB->insert_record('badge_backpack', $backpack);
}
/**
* Creates notifications to specific user.
*
* @param array $data
* @return void
*/
protected function process_notification(array $data) {
global $DB;
$notification = new stdClass();
$notification->useridfrom = $data['userfromid'];
$notification->useridto = $data['usertoid'];
$notification->subject = $data['subject'];
$notification->fullmessage = $data['subject'] . ' description';
$notification->smallmessage = $data['subject'] . ' description';
$notification->fullmessagehtml = $data['subject'] . ' description';
if ($data['timecreated'] !== 'null') {
$notification->timecreated = $data['timecreated'];
}
if ($data['timeread'] !== 'null') {
$notification->timeread = $data['timeread'];
}
if (!empty($data)) {
$popupnotification = new stdClass();
$popupnotification->notificationid = $DB->insert_record('notifications', $notification);
$DB->insert_record('message_popup_notifications', $popupnotification);
}
}
/**
* Creates user last access data within given courses.
*

Some files were not shown because too many files have changed in this diff Show More