Skip to content

Easy way to set HTTP_HOST for functional tests with symfony missing. #4260

@c33s

Description

@c33s

What are you trying to achieve?

i am trying to functional test a symfony application where the routes only listen to specific domains, lets say example.com. i simply want to run $I->amOnPage('/'); and get the

symfony2 routing.yml

mybundle:
    resource: "@MyBundle/Resources/config/routing.yml"
    host: example.com

What do you get instead?

so a $I->amOnPage('/'); leads to a 404 because it is accessed with http://localhost.

What i found out

as workaround i can change all urls to also listen to localhost.

mybundle:
    resource: "@MyBundle/Resources/config/routing.yml"
    host:     "{hostname}"
    defaults: { hostname: example.com }
    requirements:
        hostname:     example.com|localhost

which is a little bit overkill to do this for all routes and maybe also have negative sideeffects.

the correct solution for the symfony browser would be setting the HTTP_HOST:

https://stackoverflow.com/a/10677520

class AgencyControllerTest extends WebTestCase
{
    public function testShowFoo()
    {
        $client = static::createClient();

        $crawler = $client->request('GET', '/', array(), array(), array(
            'HTTP_HOST'       => 'foo.domain.dev',
            'HTTP_USER_AGENT' => 'Symfony/2.0',
        ));

        $this->assertGreaterThan(0, $crawler->filter('html:contains("Text of foo domain")')->count());
    }
}

searching this repo i found that the yii framework had a similar issue, which was fixed:

https://github.com/Codeception/Codeception/pull/2350/files

     public function _createClient()
     {
         $this->client = new Yii1Connector();
+        $this->client->setServerParameter("HTTP_HOST", parse_url($this->config['url'], PHP_URL_HOST));
         $this->client->appPath = $this->config['appPath'];
         $this->client->url = $this->config['url'];
         $this->client->appSettings = [

so it looks like this is done somewhere here for symfony as the SymfonyConnector extends \Symfony\Component\HttpKernel\Client:
https://github.com/Codeception/Codeception/blob/2.3/src/Codeception/Module/Symfony.php#L185

    /**
     * Initialize new client instance before each test
     */
    public function _before(\Codeception\TestInterface $test)
    {
        $this->persistentServices = array_merge($this->persistentServices, $this->permanentServices);
        $this->client = new SymfonyConnector($this->kernel, $this->persistentServices, $this->config['rebootable_client']);
    }

for now i havn't found/verified the exact location where same client as in the WebTestCase is created.

if i set the url in functional.suite.yml under Symfony2 i would assume it sets the HTTP_HOST but it does nothing.

actor: FunctionalTester
modules:
    enabled:
        - Symfony2:
#            url: 'http://example.com/'

also tried

        - PhpBrowser:
            url: 'http://example.com'

but this only leads in accessing the real webserver or the local webserver if i use a domain which points to localhost.

what helps is using a similar helper descibed in #2717 (comment)

Functional.php

<?php
namespace Helper;

class Functional extends \Codeception\Module
{
    public function setHost($host)
    {
        $this->getModule('Symfony2')->client->setServerParameter('HTTP_HOST', $host);
    }
<?php

/**
 * @group frontpage
 */

class BasicCest
{
    public function _before(FunctionalTester $I)
    {
        $I->setHost('example.com');
    }

but doing this for each cest is not that what i am looking for, i would like to set it globaly.

adding it to the frontpage group _before also doesn't work, because the client is not initialized yet:

<?php
namespace Group;

use \Codeception\Event\TestEvent;

class Frontpage extends \Codeception\Platform\Group
{
    public static $group = 'frontpage';

    public function _before(TestEvent $e)
    {
        $this->getModule('Symfony2')->client->setServerParameter('HTTP_HOST', 'example.com');
    }
}

as i said i would wish to simply set the url setting for my symfony module so it correctly sets the HTTP_HOST for the client.

if i missed something in the docs, please point me the way, it this is currently not possible, i would be happy to see this feature soon in codeception

Details

  • Codeception version: 2.3.1
  • PHP Version: 7.1.4
  • Operating System: Windows
  • Installation type: Phar

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions