<br />
<b>Warning</b>:  The magic method SFML_Singleton::__wakeup() must have public visibility in <b>/home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php</b> on line <b>72</b><br />
{"id":79,"date":"2016-03-16T18:55:10","date_gmt":"2016-03-17T00:55:10","guid":{"rendered":"http:\/\/www.munderwood.ca\/?p=79"},"modified":"2016-03-16T18:55:10","modified_gmt":"2016-03-17T00:55:10","slug":"testing-routes-with-laravel-localization","status":"publish","type":"post","link":"https:\/\/www.munderwood.ca\/index.php\/2016\/03\/16\/testing-routes-with-laravel-localization\/","title":{"rendered":"Testing routes with Laravel-Localization"},"content":{"rendered":"<p>I recently added the\u00a0<a href=\"https:\/\/github.com\/mcamara\/laravel-localization\">Laravel-Localization package<\/a>\u00a0(with Laravel 5.2) to a project I&#8217;m working on. Initial setup went smoothly, and I was impressed with how well things worked essentially out of the box.<\/p>\n<p>Then I tried to test my routes.<\/p>\n<p>I had previously made a test case that ran through all of my public routes and asserted that each one returned HTTP status code 200 OK. Suddenly this was failing on every route I tried, saying that 404 Not Found was being returned instead.<\/p>\n<pre class=\"lang:default highlight:0 decode:true\" title=\"PHPUnit results\">There was 1 failure:\r\n\r\n1) AllRoutesOkTest::testGetRoutes\r\nA request to [http:\/\/localhost\/en] failed. Received status code [404].<\/pre>\n<p>The route worked in the browser. It returned the correct result using `curl` on the vagrant box. But it refused to work in the test. I had the application&#8217;s default locale set to &#8216;en&#8217;, and every indication was that it worked perfectly everywhere except in the tests. I pared the test right down:<\/p>\n<pre class=\"lang:php decode:true \" title=\"Minimal test\">public function testMinimalExample()\r\n{\r\n    $this-&gt;visit('\/')\r\n         -&gt;assertResponseOk();\r\n}<\/pre>\n<p>The error was the same. The request was correctly updated from `\/` to `\/en` based on the default locale, but apparently Laravel insisted on returning 404 to the test. I would have understood if the status code were 301 or 302, since I&#8217;m using\u00a0the LaravelLocalizationRedirectFilter middleware and expect there to be a redirect. But why would the route simply disappear?<\/p>\n<p>To make a long debugging session short, it turns out that while LaravelLocalizationRedirectFilter middleware correctly leads any browser to make a second request for the new URL,\u00a0<em>the testing framework tries to follow redirects within the routes available to the same initial request object<\/em>.<\/p>\n<p>Standard operation of Laravel-Localization is to set up a route group with a prefix value of `LaravelLocalization::setLocale()`. When the browser visits the homepage initially, this function returns null so `Route::get(&#8216;\/&#8217;, &#8230;)` is matched, the middleware is invoked, and the browser is redirected to `\/en`.\u00a0The browser then invokes a second request, this time to `\/en` as directed,\u00a0<em>which means `setLocale()` is called again, this time returning `&#8217;en&#8217;`<\/em>. So `Route::get(&#8216;\/&#8217;, &#8230;)` is now prefixed by `&#8217;en&#8217;`, \u00a0the requested route is matched, and everything works correctly.<\/p>\n<p>In the test however, there is only ever a single request object, in which the prefix defined by `setLocale()` is simply `&#8221;`. This matches the first time, the server runs the middleware and sends a redirect, but instead of making a second request, the testing framework tries to follow the redirect by resolving the new route against the `RouteCollection` in the original `Request` object. Since it was created with a prefix of `&#8221;`, any route prefixed by `&#8217;en&#8217;` won&#8217;t exist.<\/p>\n<hr \/>\n<p>So, how do we solve this? I&#8217;ve found two interim solutions so far, though I plan to keep looking another day.<\/p>\n<p>Option 1 is to disable the\u00a0LaravelLocalizationRedirectFilter middleware. This means that requests to un-locale-prefixed routes will work just fine, but won&#8217;t be redirected to their prefixed versions, resulting in two different URLs for each resource in the default language.<\/p>\n<p>Option 2 is to set `&#8217;hideDefaultLocaleInURL&#8217; =&gt; true` in the `laravellocalization.php` config file. This results in the redirection of all URLs prefixed with the default locale to unprefixed ones\u2014`\/en` becomes `\/`, `\/en\/users` becomes `\/users`, and so on. This is perhaps preferable to Option 1 from an SEO standpoint, but comes with the caveat that the\u00a0Accept-Language header of any user&#8217;s browser will now be ignored.<\/p>\n<p>Likely some other options exist that involve changing the requested routes in the test cases instead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently added the\u00a0Laravel-Localization package\u00a0(with Laravel 5.2) to a project I&#8217;m working on. Initial setup went smoothly, and I was impressed with how well things worked essentially out of the box. Then I tried to test my routes. I had previously made a test case that ran through all of my public routes and asserted &#8230; <span class=\"more\"><a class=\"more-link\" href=\"https:\/\/www.munderwood.ca\/index.php\/2016\/03\/16\/testing-routes-with-laravel-localization\/\">[Read more&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[4],"_links":{"self":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/79"}],"collection":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/comments?post=79"}],"version-history":[{"count":5,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/79\/revisions"}],"predecessor-version":[{"id":84,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/posts\/79\/revisions\/84"}],"wp:attachment":[{"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/media?parent=79"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/categories?post=79"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.munderwood.ca\/index.php\/wp-json\/wp\/v2\/tags?post=79"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}