Introducing WPFilesystem module
July 12, 2017
Getting to know wp-browser latest module.
Striking out items
I've laid down a list of the things to come in wp-browser and I'm striking out the items.
Today I'm shipping a new module aimed at making interaction with WordPress file structure easier; extending Codeception Filesystem module here is the WPFilesystem
module.
Some code examples
The module aims at resolving some basic navigation issues in WordPress well know file and folder structure and requires, at a minimum, just one argument:
modules:
enabled:
- WPFilesystem
config:
WPFilesystem:
wpRootFolder: /var/www/html
Relative paths to the uploads, themes, plugins and must-use plugins folders can be specified to cover non-standard WordPress installations.
Once the module has been provided this information moving into the WordPress installation files becomes a one-line work; if I had to test that a plugin or theme is correctly handling the file.txt
file upload to the my-plugin
folder in WordPress uploads folder I could write this:
$I->seeUploadedFileFound('my-plugin/file.txt');
In place of an assertion I might need to put a known file structure in place in the uploads folder as part of the testing fixture:
$source = codecept_data_dir('my-plugin-files');
$I->copyDirToUploads($source, 'my-plugin-files');
This will create a my-plugin-files
folder in the WordPress installation uploads folder.
The module will deal with WordPress default uploads organization system where files are filed in a year/month folder hierarchy; if today was 2017-07-12 then any file uploaded today would end up, by default, in the uploads/2017/07
folder.
Any method provided by the module dealing with uploads supports a date
argument to make sure that structure is respected.
Rewriting the examples above:
$I->seeUploadedFileFound('my-plugin/file.txt', 'today');
and
$I->copyDirToUploads($source, 'my-plugin-files', '-4 months');
In the first case, assuming today is 2017-07-12, the module will make sure an uploads/2017/07/my-plugin/file.txt
file exists; in the second case the source folder will be copied to the uploads/2017/03
folder.
Since I'm lazy the module $date
argument can be a UNIX timestamp, a formatted date or a string in a format supported by the strtotime
function.
This is not nearly the end of it but it's a quick overview.
Themes, plugins and must-use plugin files
The module provides methods similar to those dedicated to uploads for plugins, must-use plugins and themes too.
If I had to make sure my theme preferences could be set using a preferences.json
file placed in the theme root folder I could write this:
$preferences = json_encode(['showAds' => false]);
$I->writeToThemeFile('my-theme/preferences.json', $preferences);
$I->amOnPage('/');
$I->dontSeeElement('.ad');
The same applies to plugins and must-use plugins:
$license = 'luca::' . $this->generateLicenseFor('luca');
$I->writeToPluginFile('my-plugin/license', $license);
Each method provided by the WPFilesytem
module that is creating files or folder will take care of removing those at the end of the test.
Sudo themes and plugins
Baked into the module is another feature I've wanted for a long time: ad-hoc creation of "sudo" test plugins and themes.
As an example I might have developed a plugin that hides plugins in the plugin administration screen for certain users; the list of the plugins that should be hidden is a plugin setting; I now want to make sure that the plugins that should be hidden for the user are, in fact, hidden:
$userId = $I->haveUserInDatabase('user','administrator', ['user_pass' => 'secret']);
$I->haveOptionInDatabase('my-plugin-hide-plugins',[$userId => ['foo','baz']]);
$code = '<?php echo "Hello there!";';
$I->havePlugin('foo/plugin.php', $code);
$I->havePlugin('baz/plugin.php', $code);
$I->havePlugin('bar/plugin.php', $code);
$I->loginAs('user','secret');
$I->amOnPluginsPage();
$I->dontSeeElement('tr[data-slug="foo"]');
$I->dontSeeElement('tr[data-slug="baz"]');
$I->seeElement('tr[data-slug="bar"]');
The module will create the plugin files but will not activate the plugins in the installation; for that dedicated methods like WPBrowser::activatePlugin()
or the activate_plugin
function are available.
On the same note the module allows scaffolding must-use plugins:
$I->haveMuPlugin('mu-plugin-1', $code);
And themes:
$I->haveTheme('test-theme', $indexCode, $functionsCode);
Themes are not activated but just created.
Any theme, plugin and must-use plugin created this way will be removed after the test.
Next
I have a bunch of fixes to put in place on wp-browser; after that I will tackled dedicated attachment support in the WPDb module and work on some ideas I've got for next features.