diff options
author | shaver@mozilla.com <shaver@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5> | 2007-02-10 10:48:29 (GMT) |
---|---|---|
committer | shaver@mozilla.com <shaver@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5> | 2007-02-10 10:48:29 (GMT) |
commit | dee24ff5e52e8125b8bab051bc8865382af07072 (patch) | |
tree | c6257bd8576a73033f0b5e42c0b8ad642e5c2812 | |
parent | bd2366fc453b756c3cf13b3f2e35c0eb1c9e5f6a (diff) |
Add app name to the URL, with a simple test for it.
Adapt existing tests and helpers for presence of APP_SHORTNAME.
Only install routes for the active LANG and APP_SHORTNAME, since we know
them at ->connect time.
git-svn-id: http://svn.mozilla.org/addons/trunk@1917 4eb1ac78-321c-0410-a911-ec516a8615a5
-rw-r--r-- | site/app/config/bootstrap.php | 54 | ||||
-rw-r--r-- | site/app/config/routes.php | 57 | ||||
-rw-r--r-- | site/app/controllers/components/image.php | 2 | ||||
-rw-r--r-- | site/app/tests/languageConfig.test.php | 24 | ||||
-rw-r--r-- | site/app/tests/multiapp.test.php | 46 | ||||
-rw-r--r-- | site/app/tests/test_helper_web.php | 2 | ||||
-rw-r--r-- | site/app/tests/views/helpers/addons_html.test.php | 4 | ||||
-rw-r--r-- | site/app/views/helpers/addons_html.php | 10 |
8 files changed, 132 insertions, 67 deletions
diff --git a/site/app/config/bootstrap.php b/site/app/config/bootstrap.php index 699fc77..dd38b8a 100644 --- a/site/app/config/bootstrap.php +++ b/site/app/config/bootstrap.php @@ -99,37 +99,47 @@ function redirectWithNewLocaleAndExit($pathParts) { exit;
}
+// If it is not set, we are at the root
+if (!array_key_exists('url', $_GET) || empty($_GET['url'])) {
+ redirectWithNewLocaleAndExit(array($lang, ''));
+}
+
// If someone goes to a URL without a language, we need to redirect them to one with
// a language, so caching works correctly. If url is set, replace current locale
// with new locale and send the user along.
-if (array_key_exists('url', $_GET) && !empty($_GET['url'])) {
- // Parse our url var so we can get the locale and app, if they're present.
- $buf = explode('/', $_GET['url']);
-
- if ($_GET['url'] === 'favicon.ico') {
- // Ahh, adding another layer of complexity. Cake has a special case for
- // favicon.ico, and we're piggybacking on it in our /discussions/ URLs, so
- // we'll have a special case too. Yay.
- } else {
- // If we already have a set locale, overwrite it.
- if (array_key_exists($buf[0],$valid_languages)) {
- // Only redirect if we're going to a different language
- if ($buf[0] != $lang) {
- $buf[0] = $lang;
- redirectWithNewLocaleAndExit($buf);
- }
- } else {
- // If no locale was currently set, add the detected one.
- array_unshift($buf, $lang);
+
+// Parse our url var so we can get the locale and app, if they're present.
+$buf = explode('/', $_GET['url']);
+
+// Ahh, adding another layer of complexity. Cake has a special case for
+// favicon.ico, and we're piggybacking on it in our /discussions/ URLs, so
+// we'll have a special case too. Yay.
+if ($_GET['url'] !== 'favicon.ico') {
+ // If we already have a set locale, overwrite it.
+ if (array_key_exists($buf[0],$valid_languages)) {
+ // Only redirect if we're going to a different language
+ if ($buf[0] != $lang) {
+ $buf[0] = $lang;
redirectWithNewLocaleAndExit($buf);
}
+ } else {
+ // If no locale was currently set, add the detected one.
+ array_unshift($buf, $lang);
+ redirectWithNewLocaleAndExit($buf);
}
+}
-// If it is not set, we are at the root
-} else {
- redirectWithNewLocaleAndExit(array($lang, ''));
+// Now make sure that there's a known app in the second position.
+if (count($buf) < 2 || !array_key_exists($buf[1], $app_shortnames)) {
+ // No app or unknown app, so we stick firefox in the place of honour and
+ // redirect.
+ array_splice($buf, 1, 0, "firefox");
+ redirectWithNewLocaleAndExit($buf);
}
+// For other functions/classes
+define('APP_SHORTNAME', $buf[1]);
+
// Sets up all the gettext functions for our language
$language_config->setCurrentLanguage(array($lang));
diff --git a/site/app/config/routes.php b/site/app/config/routes.php index 5fb69cc..320dd9a 100644 --- a/site/app/config/routes.php +++ b/site/app/config/routes.php @@ -35,56 +35,53 @@ * to use (in this case, /app/views/pages/home.thtml)... */ - $Route->connect('/', array('controller' => 'addons', 'action' => 'home')); + $Route->connect('/', array('controller' => 'addons', 'action' => 'home')); /** * ...and connect the rest of 'Pages' controller's urls. */ - $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); + $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display')); /** * Then we connect url '/test' to our test controller. This is helpful in * developement. */ - $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index')); + $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index')); - // Declared in the bootstrap - this will connect all our valid languages - global $valid_languages; + // Connect the routes for app and lang. The order of these are important! + // The first one that matches is what it will use. - // Connect each language's routes. The order of these are important! The first - // one that matches is what it will use. - foreach ($valid_languages as $language => $mapping) { + $prefix = LANG . '/' . APP_SHORTNAME; - // If they just go to /$lang/ - $Route->connect("/{$language}", array('controller' => 'addons', 'action' => 'home')); + // If they just go to /$lang/$app/ + $Route->connect("/{$prefix}", array('controller' => 'addons', 'action' => 'home')); - // connect localized, static pages - $Route->connect("/{$language}/pages/*", array('controller' => 'pages', 'action' => 'display')); + // connect localized, static pages + $Route->connect("/{$prefix}/pages/*", array('controller' => 'pages', 'action' => 'display')); - // Setup old URL handlers. These all are in the $lang's section because they - // get redirected here in bootstrap.php. Original redirects can be seen at: - // http://lxr.mozilla.org/mozilla/source/webtools/addons/public/htaccess.dist + // Setup old URL handlers. These all are in the $lang's section because they + // get redirected here in bootstrap.php. Original redirects can be seen at: + // http://lxr.mozilla.org/mozilla/source/webtools/addons/public/htaccess.dist - // v2: Author IDs (eg. /firefox/219/author/) - $Route->connect("/{$language}/firefox/*/author", array('controller' => 'legacy_url', 'action' => 'authorId')); + // v2: Author IDs (eg. /firefox/219/author/) + $Route->connect("/{$prefix}/firefox/*/author", array('controller' => 'legacy_url', 'action' => 'authorId')); - // v2: Addon IDs (eg. /firefox/220) - $Route->connect("/{$language}/firefox/*", array('controller' => 'legacy_url', 'action' => 'addonId')); + // v2: Addon IDs (eg. /firefox/220) + $Route->connect("/{$prefix}/firefox/*", array('controller' => 'legacy_url', 'action' => 'addonId')); - // v2: extensions (eg. /extensions/) - $Route->connect("/{$language}/extensions/", array('controller' => 'addons', 'action' => 'browse', 'type:1')); + // v2: extensions (eg. /extensions/) + $Route->connect("/{$prefix}/extensions/", array('controller' => 'addons', 'action' => 'browse', 'type:1')); - // v2: themes (eg. /themes/) - $Route->connect("/{$language}/themes/", array('controller' => 'addons', 'action' => 'browse', 'type:2')); + // v2: themes (eg. /themes/) + $Route->connect("/{$prefix}/themes/", array('controller' => 'addons', 'action' => 'browse', 'type:2')); - // v2: dictionaries (eg. /search-engines/) - $Route->connect("/{$language}/search-engines/", array('controller' => 'addons', 'action' => 'browse', 'type:4')); + // v2: dictionaries (eg. /search-engines/) + $Route->connect("/{$prefix}/search-engines/", array('controller' => 'addons', 'action' => 'browse', 'type:4')); - // v2: dictionaries (eg. /dictionaries/) - $Route->connect("/{$language}/dictionaries/", array('controller' => 'addons', 'action' => 'browse', 'type:3')); + // v2: dictionaries (eg. /dictionaries/) + $Route->connect("/{$prefix}/dictionaries/", array('controller' => 'addons', 'action' => 'browse', 'type:3')); - // Magical undocumented routing syntax - if nothing has matched up till now, it'll hit this - $Route->connect("/{$language}/:controller/:action/*", array('controller' => 'pages', 'action' => 'index')); + // Magical undocumented routing syntax - if nothing has matched up till now, it'll hit this + $Route->connect("/{$prefix}/:controller/:action/*", array('controller' => 'pages', 'action' => 'index')); - } ?> diff --git a/site/app/controllers/components/image.php b/site/app/controllers/components/image.php index 2d2ce27..7659a9c 100644 --- a/site/app/controllers/components/image.php +++ b/site/app/controllers/components/image.php @@ -58,7 +58,7 @@ class ImageComponent extends Object { * Get URL for an addon preview's thumbnail
*/
function urlForAddonPreview($addon, $previewNum = 1) {
- return $this->base . '/' . LANG . "/images/addon_preview/{$addon}/{$previewNum}";
+ return $this->base . '/' . LANG . '/' . APP_SHORTNAME . "/images/addon_preview/{$addon}/{$previewNum}";
}
/**
diff --git a/site/app/tests/languageConfig.test.php b/site/app/tests/languageConfig.test.php index 72b6110..ce1bd10 100644 --- a/site/app/tests/languageConfig.test.php +++ b/site/app/tests/languageConfig.test.php @@ -173,7 +173,7 @@ class LanguageConfigTest extends WebTestHelper { $this->WebTestCase("Testing that bootstrap allows users to choose a language."); foreach ($valid_languages as $lang => $mapping) { - // Bootstrap should only do one redirect. + // Bootstrap will do one redirect to switch lang. $this->setMaximumRedirects(1); // Check that $_GET overrides the rest of the URL @@ -184,13 +184,25 @@ class LanguageConfigTest extends WebTestHelper { // and should also have the correct URL. $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}."); - // Take the dirname because actionPath() doesn't strip the $lang + // Bootstrap will do two redirects for app and lang if neither are present. + $this->setMaximumRedirects(2); + $path = $this->rawPath("/?lang={$lang}"); $this->getPath($path); // If we pass a valid language, our page should redirect us. // and should also have the correct URL. $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}."); + + // Bootstrap should only do one redirect if there's an app present, but no lang + $this->setMaximumRedirects(1); + + $path = $this->rawPath("/firefox/?lang={$lang}"); + $this->getPath($path); + // If we pass a valid language, our page should redirect us. + // and should also have the correct URL. + $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}."); + } // If we pass an unknown language, there should be a redirect to a detected lang @@ -199,7 +211,7 @@ class LanguageConfigTest extends WebTestHelper { $this->assertResponse('200','Redirect to detected language for bogus language'); // Naughty XSS -- naughty! - $this->setMaximumRedirects(1); + $this->setMaximumRedirects(2); $this->getPath($this->actionPath("")."/?lang=en-US&url=%0ALocation:%20javascript:%0AContent-type:%20text/html%0A%0A%3Cscript%3Ealert(%22XSS%22)%3C/script%3E"); $this->assertResponse('200','Page still displays properly in right locale after attempted XSS attack (?lang=en-US&url=%%0ALocation:%%20javascript:%%0AContent-type:%%20text/html%%0A%%0A%%3Cscript%%3Ealert(%%22XSS%%22)%%3C/script%%3E).'); $this->assertPattern('/lang="en-US"/', "Language was set by bootstrap after attempted XSS attack."); @@ -211,7 +223,7 @@ class LanguageConfigTest extends WebTestHelper { */ function testRegularAcceptHeader() { $this->addHeader('Accept-Language: en-us;q=0.7, de'); - $this->getPath(dirname($this->actionPath(''))); + $this->getPath($this->rawPath('/firefox')); $pattern = '#Alle Rechte vorbehalten#'; $this->assertPattern($pattern, 'Accept-language handler picks right locale according to score'); } @@ -221,7 +233,7 @@ class LanguageConfigTest extends WebTestHelper { */ function testURLLocaleIgnoresALHeader() { $this->addHeader('Accept-Language: de'); - $this->getPath(dirname($this->actionPath('')).'/en-US/'); + $this->getPath($this->rawPath('/en-US/firefox/')); $pattern = '#All rights reserved#'; $this->assertPattern($pattern, 'Accept-language is ignored when URL contains locale'); } @@ -231,7 +243,7 @@ class LanguageConfigTest extends WebTestHelper { */ function testALUnsharpMatching() { $this->addHeader('Accept-Language: de-de, en-us;q=0.3'); - $this->getPath(dirname($this->actionPath(''))); + $this->getPath($this->rawPath('')); $pattern = '#Alle Rechte vorbehalten#'; $this->assertPattern($pattern, 'Accept-language handler resolves de-de to de'); } diff --git a/site/app/tests/multiapp.test.php b/site/app/tests/multiapp.test.php new file mode 100644 index 0000000..4423511 --- /dev/null +++ b/site/app/tests/multiapp.test.php @@ -0,0 +1,46 @@ +<?php +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is addons.mozilla.org site. + * + * The Initial Developer of the Original Code is + * Mozilla Corporation (shaver@mozilla.com). + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +class MultiAppTest extends WebTestHelper { + function testRedirectWhenNoAppProvided() { + $this->setMaximumRedirects(0); + $this->get($this->rawURI('/' . LANG . '/')); + $this->assertResponse('302', 'redirected to include app: %s'); + $this->assertHeader('Location', $this->actionURI('/')); + } +} +?>
\ No newline at end of file diff --git a/site/app/tests/test_helper_web.php b/site/app/tests/test_helper_web.php index a4d2c30..2194946 100644 --- a/site/app/tests/test_helper_web.php +++ b/site/app/tests/test_helper_web.php @@ -32,7 +32,7 @@ class WebTestHelper extends WebTestCase { /* As above, but just the local path and not a complete URI. */ function rawPath($path) { - return preg_replace('/\/' . LANG . '\/tests.*/', $path, setUri()); + return preg_replace('/\/' . LANG . '\/' . APP_SHORTNAME . '\/tests.*/', $path, setUri()); } /* Make a GET for the given action, accounting for us possibly not being at diff --git a/site/app/tests/views/helpers/addons_html.test.php b/site/app/tests/views/helpers/addons_html.test.php index 4c467f2..9c80f4e 100644 --- a/site/app/tests/views/helpers/addons_html.test.php +++ b/site/app/tests/views/helpers/addons_html.test.php @@ -62,7 +62,7 @@ class AddonsHtmlHelperTest extends UnitTestCase { * is link generated with locale? */ function testLinkLocale() { - $expected = '!<a href="http://example.com/mybase/en-US/addons/browse"( )*>foo</a>!'; + $expected = '!<a href="http://example.com/mybase/'.LANG.'/'.APP_SHORTNAME.'/addons/browse"( )*>foo</a>!'; $result = $this->html->link('foo', '/addons/browse'); $this->assertTrue(preg_match($expected, $result), 'link generation with locale'); } @@ -71,7 +71,7 @@ class AddonsHtmlHelperTest extends UnitTestCase { * is link generated without locale? */ function testLinkNoLocale() { - $expected = '!<a href="http://example.com/mybase/addons/browse"( )*>foo</a>!'; + $expected = '!<a href="http://example.com/mybase/'.APP_SHORTNAME.'/addons/browse"( )*>foo</a>!'; $result = $this->html->linkNoLocale('foo', '/addons/browse'); $this->assertTrue(preg_match($expected, $result), 'link generation without locale'); } diff --git a/site/app/views/helpers/addons_html.php b/site/app/views/helpers/addons_html.php index be24a65..eb6ffd8 100644 --- a/site/app/views/helpers/addons_html.php +++ b/site/app/views/helpers/addons_html.php @@ -97,14 +97,14 @@ class AddonsHtmlHelper extends HtmlHelper function url($url = null, $return = false, $addLocale = true) { $oldbase = $this->base; - if ($addLocale && $this->addLocale) { + $newbase = strip_plugin($this->base, $this->plugin); + if ($addLocale && $this->addLocale) // rewrite base address to include locale, if applicable - $newbase = strip_plugin($this->base, $this->plugin); $newbase .= '/'.LANG; + $newbase .= '/'.APP_SHORTNAME; - if ($this->plugin) $newbase .= '/'.$this->plugin; - $this->base = $newbase; - } + if ($this->plugin) $newbase .= '/'.$this->plugin; + $this->base = $newbase; $ret = parent::url($url, $return); |