I am trying to add some validation to my controller but my tests are failing because the request is trying to treat the PUT call as if it was a string. My test looks like this:
PHP Code:
class UserRolesTest extends FeatureTestCase {
/** @test */
public function aUserCanAssignRolesToAnotherUser() {
$this->createAuthenticatedUser(['user_admin']);
$user = $this->createUser();
$response = $this->put('/users/' . $user->id . '/roles', ['bin_approver']);
$response->assertStatus(200);
$response->assertJSONFragment(['bin_approver']);
//asserting database has changed
}
}
My controller looks like this:
PHP Code:
<?php
namespace App\Controllers;
use CodeIgniter\API\ResponseTrait;
use App\Models\UserModel;
/**
* Class Users
* @package App\Controllers
*/
class Users extends BaseController {
use ResponseTrait;
/** @var UserModel */
private $userModel;
/**
* Users constructor.
*/
public function __construct() {
$this->userModel = model(UserModel::class);
}
/**
* The endpoint to update the roles for a user
*
* @param int $userId
* @return \CodeIgniter\HTTP\Response|mixed
*/
public function rolesUpdate($userId) {
if (!$this->request->user->can('edit_users')) {
return $this->failForbidden('User cannot edit users');
}
if ($this->request->user->id == $userId) {
return $this->failForbidden('Users cannot edit their own roles');
}
if (!$this->validate([
'*' => 'alpha_numeric_punct'
])) {
$errors = $this->validator->getErrors();
return $this->failValidationError($errors[0]);
}
//logic to get the user and save the roles
return $this->response->setJSON($user->roles);
}
}
The error that I am getting is:
Code:
ErrorException : parse_str() expects parameter 1 to be string, array given
/var/www/html/vendor/codeigniter4/framework/system/HTTP/IncomingRequest.php:377
/var/www/html/vendor/codeigniter4/framework/system/Validation/Validation.php:339
/var/www/html/vendor/codeigniter4/framework/system/Controller.php:217
/var/www/html/app/Controllers/Users.php:82
/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php:915
/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php:401
/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php:309
/var/www/html/vendor/codeigniter4/framework/system/Test/FeatureTestCase.php:182
/var/www/html/vendor/codeigniter4/framework/system/Test/FeatureTestCase.php:238
/var/www/html/tests/feature/UserRolesTest.php:16
This seems like a bug to me but I wanted to post here first to see if I am missing something.
I also tried doing this with a POST call but that didn't work because when the validation library attaches the request, it tries to grab the data from the $_REQUEST super global and puts that into the request's data property but the request mock is never setting that super global. I would rather use PUT anyway because it is the better action verb for my use case but that is another potential bug that I would like to be able to do at some point.
Any help you can give here would be much appreciated.