Warning: The magic method SFML_Singleton::__wakeup() must have public visibility in /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php on line 72

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642

Warning: Cannot modify header information - headers already sent by (output started at /home/public/wp-content/plugins/sf-move-login/inc/classes/class-sfml-singleton.php:72) in /home/public/wp-includes/rest-api/class-wp-rest-server.php on line 1642
{"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":"

I recently added the\u00a0Laravel-Localization package<\/a>\u00a0(with Laravel 5.2) to a project I’m working on. Initial setup went smoothly, and I was impressed with how well things worked essentially out of the box.<\/p>\n

Then I tried to test my routes.<\/p>\n

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

There was 1 failure:\r\n\r\n1) AllRoutesOkTest::testGetRoutes\r\nA request to [http:\/\/localhost\/en] failed. Received status code [404].<\/pre>\n

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’s default locale set to ‘en’, and every indication was that it worked perfectly everywhere except in the tests. I pared the test right down:<\/p>\n

public function testMinimalExample()\r\n{\r\n    $this->visit('\/')\r\n         ->assertResponseOk();\r\n}<\/pre>\n

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’m using\u00a0the LaravelLocalizationRedirectFilter middleware and expect there to be a redirect. But why would the route simply disappear?<\/p>\n

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,\u00a0the testing framework tries to follow redirects within the routes available to the same initial request object<\/em>.<\/p>\n

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(‘\/’, …)` 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,\u00a0which means `setLocale()` is called again, this time returning `’en’`<\/em>. So `Route::get(‘\/’, …)` is now prefixed by `’en’`, \u00a0the requested route is matched, and everything works correctly.<\/p>\n

In the test however, there is only ever a single request object, in which the prefix defined by `setLocale()` is simply `”`. 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 `”`, any route prefixed by `’en’` won’t exist.<\/p>\n


\n

So, how do we solve this? I’ve found two interim solutions so far, though I plan to keep looking another day.<\/p>\n

Option 1 is to disable the\u00a0LaravelLocalizationRedirectFilter middleware. This means that requests to un-locale-prefixed routes will work just fine, but won’t be redirected to their prefixed versions, resulting in two different URLs for each resource in the default language.<\/p>\n

Option 2 is to set `’hideDefaultLocaleInURL’ => 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’s browser will now be ignored.<\/p>\n

Likely some other options exist that involve changing the requested routes in the test cases instead.<\/p>\n","protected":false},"excerpt":{"rendered":"

I recently added the\u00a0Laravel-Localization package\u00a0(with Laravel 5.2) to a project I’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 … [Read more…]<\/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}]}}