Drupal 8 Functional Test returns an unexpected 403
I recently had a very simple route and controller I wanted to test but for reasons unknown, when I ran the test I kept getting a 403 Forbidden HTTP status code instead of what I was expecting…
Here’s the outline of what I had:
// Route
my_module.action:
path: ‘/proxy’
defaults:
_controller: ‘\Drupal\my_module\Controller\MyModuleProxyController::proxy’
_title: ‘Proxy callback’
requirements:
_permission: ‘access content’
methods: [‘GET’]// Controller (just the method)
public function proxy(Request $request) {
$uri = $request->query->get(‘url’); if ($uri === NULL) {
$response = new Response();
$response->setStatusCode(400);
return $response;
} // Just a touch more code...
}// Test
class MyModuleProxyHandlerResolverTest extends BrowserTestBase {
public static $modules = [‘mymodule_proxy’];
public function testMyModuleProxyHandlerResolverRespondsWithoutUrl() {
$this->drupalGet(‘/proxy’);
$this->assertSession()->statusCodeEquals(400);
}
}
But when I ran the test the result was unexpected (to me at least):
There was 1 error:1) Drupal\Tests\mymodule_proxy\Functional\MyModuleProxyHandlerResolverTest::testMyModuleProxyHandlerResolverRespondsWithoutUrl
Behat\Mink\Exception\ExpectationException: Current response status code is 403, but 400 expected.
What was ever so slightly confusing to me was in the browser, I got the expected 400 Bad request HTTP status code…
After tinkering around (and time spent fruitlessly Googling), I found that if I replaced the _permissions: route requirement with _access: ‘TRUE’ the test passed but I didn’t really want _access: ‘TRUE’.
The solution was to add node to the list of modules to install before the test run…
// Before
public static $modules = [‘mymodule_proxy’];// After
public static $modules = [‘node’, ‘mymodule_proxy’];
It’s obvious, of course, when you think about it: the node module defines the access content permission…
And with that, all is merry and green!