I work with Drupal 8 and need to check if customers (Product Owners) have the correct rights to create, update, and delete content types.
At first I did this by writing a separate Acceptance Cest for every single content type I needed to test. However, this became very tedious very fast.
This is why I decided to write an Acceptance Cest that retrieves predefined content types from a JSON file, then checks which right should be in place for that content type and then, following those rights, tests if the content manager user is indeed able to preform that action (or unable in the case that they shouldn't be able to preform an action). It does this for all content types defined in the JSON file.
It works beautifully and I'm very happy that this was possible by making use of the @dataProvider annotation.
There is, however, one thing I am unhappy with and that is the fact that Codeception seems to print the values of the content type it's looping over in the command line.
The weird thing though, is that it overwrites what is already visible in the command line with the text from my $I->wantTo();
method call.
Is there any way to prevent Codeception from printing the values of the content type in the command line? If not, why does it do this because I don't really understand what's causing this to happen.
I've provided code of the method that loops over the content types and tests them, code of the method that retrieves the data from the JSON file, and the JSON file itself. There will also be a GIF of what happens in the command line when I run a test for visualization.
I hope that with this I have provided sufficient information. If there is need for more I will be happy to provide.
//This method checks if the rights to create a content type are in place correctly
/**
* @param AcceptanceTester $I
* @dataProvider typeProvider
*/
public function CmUserCreateRight(AcceptanceTester $I, \Codeception\Example $contentType)
{
$objective = sprintf("see that the CM user " . ($contentType['rights']['create'] ? 'can' : 'cannot') . " create a %s", $contentType['realname']);
$I->wantTo($objective);
$I->amOnPage('/node/add');
$I->seeResponseCodeIs(200);
//The rights are defined as either true or false, this checks which is defined and tests accordingly.
if ($contentType['rights']['create']) {
$I->seeLink(sprintf('%s', $contentType['realname']), sprintf('/node/add/%s', $contentType['urlname']));
} else {
$I->dontSeeLink(sprintf('%s', $contentType['realname']), sprintf('/node/add/%s', $contentType['urlname']));
}
}
As you can see "TypeProvider" is being used as a dataProvider. This method is in the same class as the method above.
/**
* @return array
*/
protected function typeProvider()
{
$TH = new TypeHelper();
return $TH->getTypes();
}
The TypeProvider method makes a call to the class "ContentTypes" (I used it as "TypeHelper" here), which retrieves the JSON data.
class ContentTypes {
private $contentTypes = [];
public function __construct()
{
$this->contentTypes = $this->getConfig();
}
private function getConfig() {
$json = file_get_contents('tests/_data/contenttypes.json');
return json_decode($json, true);
}
public function getTypes() {
return $this->contentTypes;
}
}
Finally, this class retrieves the JSON data and returns it to the original method as a \Codeception\Example
to be used in the Cest.
JSON file:
[
{
"urlname": "configuratie_pagina",
"realname": "Configuratie pagina",
"rights": {
"create": false,
"update": true,
"delete": false
}
},
{
"urlname": "content",
"realname": "Contentpagina",
"rights": {
"create": true,
"update": true,
"delete": true
}
}
]