diff --git a/README.md b/README.md index a8a4633..0b3a65e 100644 --- a/README.md +++ b/README.md @@ -113,32 +113,8 @@ Inject the detected language here with the following code: ``` -### Disable UriPathStrategy in PHPUNIT -This is necessary (at the moment) if you want to use ``this->dispatch('my/uri');`` in your `AbstractHttpControllerTestCase` unit tests. -Otherwise, if you check for responseCode you will get `302` where it should be `200`. - -Example: -``` -$this->dispatch('/to/my/uri'); -$this->assertResponseStatusCode(200); // this will be 302 instead of 200 - -$this->dispatch('/en/to/my/uri'); -$this->assertResponseStatusCode(200); // this will be 302 instead of 200 -``` - -To fix add the following to your phpunit config. - -phpunit.xml: -``` - - ... - - - - -``` - -Or set ``$_SERVER['DISABLE_URIPATHSTRATEGY'] = true;`` in your bootstrap file of phpunit. +### PHPUNIT configuration (as this module breaks some tests at the moment) +Have a look at [strategies documentation](docs/2.Strategies.md). ### Create a list of available locales diff --git a/docs/2.Strategies.md b/docs/2.Strategies.md index 3ab2be5..d11396b 100644 --- a/docs/2.Strategies.md +++ b/docs/2.Strategies.md @@ -89,4 +89,59 @@ To cope with such problems use AssetStrategy: The `file_extensions` array should contain all file endings you use for your assets. URIs of files which have one of the specified extensions will not be rewritten (the example above excludes `css` and `js` files). -**Important:** Make sure to add AssetStrategy first / have AssetStrategy added with highest priority in your config. Otherwise some other strategies may rewrite the URI of an asset. \ No newline at end of file +**Important:** Make sure to add AssetStrategy first / have AssetStrategy added with highest priority in your config. Otherwise some other strategies may rewrite the URI of an asset. + +### PHPUNIT strategy +This is necessary (at the moment) if you want to use ``this->dispatch('my/uri');`` in your `AbstractHttpControllerTestCase` unit tests. +Otherwise, if you check for responseCode you will get `302` where it should be `200`. +More information at: https://github.com/basz/SlmLocale/issues/26 + +Example: +``` +$this->dispatch('/to/my/uri'); +$this->assertResponseStatusCode(200); // this will be 302 instead of 200 + +$this->dispatch('/en/to/my/uri'); +$this->assertResponseStatusCode(200); // this will be 302 instead of 200 +``` + +To fix add the following to your phpunit config. + +phpunit.xml: +``` + + ... + + + + +``` + +Or set ``$_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = true;`` in your bootstrap file of phpunit. + +Do not forget to enable phpunit strategy in config (example): + +``` +'strategies' => [ + 'phpunit', + [ + 'name' => SlmLocale\Strategy\AssetStrategy::class, + 'options' => [ + 'file_extensions' => [ + 'css', 'js' + ] + ] + ], + 'query', + [ + 'name' => \SlmLocale\Strategy\UriPathStrategy::class, + 'options' => [ + 'redirect_when_found' => true, + 'aliases' => array('de' => 'de_DE', 'en' => 'en_GB'), + ] + ], + 'cookie', + 'acceptlanguage' +], +``` +**Important:** Make sure to add PhpunitStrategy first / have PhpunitStrategy added with highest priority in your config. Otherwise some other strategies may rewrite the URI of an asset. \ No newline at end of file diff --git a/src/SlmLocale/Module.php b/src/SlmLocale/Module.php index 1b7c6d1..44f25c7 100644 --- a/src/SlmLocale/Module.php +++ b/src/SlmLocale/Module.php @@ -58,6 +58,23 @@ public function getConfig() } public function onBootstrap(EventInterface $e) + { + $app = $e->getApplication(); + $sm = $app->getServiceManager(); + $detector = $sm->get(Detector::class); + + $em = $app->getEventManager(); + $em->attach(MvcEvent::EVENT_ROUTE, function ($e) use ($app, $detector) { + $result = $detector->detect($app->getRequest(), $app->getResponse()); + if ($result instanceof ResponseInterface) { + return $result; + } else { + Locale::setDefault($result); + } + }, PHP_INT_MAX); + } + + /*public function onBootstrap(EventInterface $e) { $app = $e->getApplication(); $sm = $app->getServiceManager(); @@ -76,7 +93,7 @@ public function onBootstrap(EventInterface $e) * * The listener is attached at PHP_INT_MAX to return the response as early as * possible. - */ + * $em = $app->getEventManager(); $em->attach(MvcEvent::EVENT_ROUTE, function ($e) use ($result) { return $result; @@ -84,5 +101,5 @@ public function onBootstrap(EventInterface $e) } else { Locale::setDefault($result); } - } + }*/ } diff --git a/src/SlmLocale/Strategy/PhpunitStrategy.php b/src/SlmLocale/Strategy/PhpunitStrategy.php new file mode 100644 index 0000000..11a598b --- /dev/null +++ b/src/SlmLocale/Strategy/PhpunitStrategy.php @@ -0,0 +1,44 @@ +stopPropagationIfPhpunit($event); + } + + public function found(LocaleEvent $event) + { + $this->stopPropagationIfPhpunit($event); + } + + private function stopPropagationIfPhpunit(LocaleEvent $event) + { + if (! $this->isHttpRequest($event->getRequest())) { + return; + } + + $isPhpunit = array_key_exists('SLMLOCALE_DISABLE_STRATEGIES', $_SERVER) && $_SERVER['SLMLOCALE_DISABLE_STRATEGIES']; + + // if the file extension of the uri is found within the configured file_extensions, we do not rewrite and skip further processing + if ($isPhpunit) { + $event->stopPropagation(); + } + } +} diff --git a/src/SlmLocale/Strategy/StrategyPluginManager.php b/src/SlmLocale/Strategy/StrategyPluginManager.php index ae9a005..b12116a 100644 --- a/src/SlmLocale/Strategy/StrategyPluginManager.php +++ b/src/SlmLocale/Strategy/StrategyPluginManager.php @@ -58,6 +58,7 @@ class StrategyPluginManager extends AbstractPluginManager 'query' => QueryStrategy::class, 'uripath' => UriPathStrategy::class, 'asset' => AssetStrategy::class, + 'phpunit' => PhpunitStrategy::class, ]; /** @@ -70,5 +71,6 @@ class StrategyPluginManager extends AbstractPluginManager QueryStrategy::class => InvokableFactory::class, UriPathStrategy::class => UriPathStrategyFactory::class, AssetStrategy::class => InvokableFactory::class, + PhpunitStrategy::class => InvokableFactory::class, ]; } diff --git a/src/SlmLocale/Strategy/UriPathStrategy.php b/src/SlmLocale/Strategy/UriPathStrategy.php index f995314..837729e 100644 --- a/src/SlmLocale/Strategy/UriPathStrategy.php +++ b/src/SlmLocale/Strategy/UriPathStrategy.php @@ -118,10 +118,6 @@ public function detect(LocaleEvent $event) public function found(LocaleEvent $event) { - if (array_key_exists('DISABLE_URIPATHSTRATEGY', $_SERVER) && true === $_SERVER['DISABLE_URIPATHSTRATEGY']) { - return; - } - $request = $event->getRequest(); if (! $this->isHttpRequest($request)) { return; diff --git a/tests/SlmLocaleTest/Strategy/PhpunitStrategyTest.php b/tests/SlmLocaleTest/Strategy/PhpunitStrategyTest.php new file mode 100644 index 0000000..5b559a7 --- /dev/null +++ b/tests/SlmLocaleTest/Strategy/PhpunitStrategyTest.php @@ -0,0 +1,109 @@ +router = new HttpRouter(); + + $this->event = new LocaleEvent(); + $this->event->setSupported(['nl', 'de', 'en']); + + $this->strategy = new PhpunitStrategy(); + } + + public function testPreventStrategiesExecutionIfPhpunit() + { + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = true; + + $uri = 'http://username:password@example.com:8080/some/deep/path/some.file?withsomeparam=true'; + $request = new HttpRequest(); + $request->setUri($uri); + + $this->event->setLocale('en'); + $this->event->setRequest($request); + $this->event->setResponse(new HttpResponse()); + + $this->strategy->found($this->event); + + $statusCode = $this->event->getResponse()->getStatusCode(); + $this->assertEquals(200, $statusCode); + + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = false; + } + + public function testPhpunitStrategyCanPreventOtherStrategiesExecution() + { + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = true; + + $request = new HttpRequest(); + $request->setUri('http://example.com/css/style.css'); + $query = $request->getQuery(); + $query->lang = 'de'; + $request->setQuery($query); + $this->event->setRequest($request); + + $detector = new Detector(); + $detector->setEventManager(new EventManager()); + $detector->setSupported(['nl', 'de', 'en']); + $detector->setDefault('en'); + $detector->addStrategy($this->strategy); + $detector->addStrategy(new \SlmLocale\Strategy\QueryStrategy()); + $response = new HttpResponse(); + + $result = $detector->detect($request, $response); + $this->assertEquals('en', $result); + + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = false; + } + + public function testPhpunitStrategyDoesNotPreventOtherStrategiesExecution() + { + // can also be null / not set + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = false; + + $request = new HttpRequest(); + $request->setUri('http://example.com/css/style.css'); + $query = $request->getQuery(); + $query->lang = 'de'; + $request->setQuery($query); + $this->event->setRequest($request); + + $detector = new Detector(); + $detector->setEventManager(new EventManager()); + $detector->setSupported(['nl', 'de', 'en']); + $detector->setDefault('en'); + $detector->addStrategy($this->strategy); + $detector->addStrategy(new \SlmLocale\Strategy\QueryStrategy()); + $response = new HttpResponse(); + + $result = $detector->detect($request, $response); + $this->assertEquals('de', $result); + + $_SERVER['SLMLOCALE_DISABLE_STRATEGIES'] = false; + } +} diff --git a/tests/SlmLocaleTest/Strategy/UriPathStrategyTest.php b/tests/SlmLocaleTest/Strategy/UriPathStrategyTest.php index 962e866..a49af0f 100644 --- a/tests/SlmLocaleTest/Strategy/UriPathStrategyTest.php +++ b/tests/SlmLocaleTest/Strategy/UriPathStrategyTest.php @@ -348,28 +348,6 @@ public function testAssembleWorksWithAliasesToo() $this->assertEquals($expected, $actual); } - public function testDisableUriPathStrategyPhpunit() - { - $_SERVER['DISABLE_URIPATHSTRATEGY'] = true; - - $uri = 'http://username:password@example.com:8080/some/deep/path/some.file?withsomeparam=true'; - $request = new HttpRequest(); - $request->setUri($uri); - - $this->event->setLocale('en'); - $this->event->setRequest($request); - $this->event->setResponse(new HttpResponse()); - - $this->strategy->found($this->event); - - $statusCode = $this->event->getResponse()->getStatusCode(); - $header = $this->event->getResponse()->getHeaders()->get('Location'); - $expected = 'Location: http://username:password@example.com:8080/en/some/deep/path/some.file?withsomeparam=true'; - $this->assertEquals(200, $statusCode); - - $_SERVER['DISABLE_URIPATHSTRATEGY'] = false; - } - protected function getPluginManager($console = false) { $sl = new ServiceManager();