<?php
class HtmlTest extends MediaWikiTestCase {
+ private $restoreWarnings;
protected function setUp() {
parent::setUp();
'wgUseMediaWikiUIEverywhere' => false,
] );
- $langObj = Language::factory( 'en' );
+ $contLangObj = Language::factory( 'en' );
// Hardcode namespaces during test runs,
// so that html output based on existing namespaces
// can be properly evaluated.
- $langObj->setNamespaces( [
+ $contLangObj->setNamespaces( [
-2 => 'Media',
-1 => 'Special',
0 => '',
100 => 'Custom',
101 => 'Custom_talk',
] );
- $this->setUserLang( $langObj );
- $this->setContentLang( $langObj );
+ $this->setContentLang( $contLangObj );
+
+ $userLangObj = Language::factory( 'es' );
+ $userLangObj->setNamespaces( [
+ -2 => "Medio",
+ -1 => "Especial",
+ 0 => "",
+ 1 => "Discusión",
+ 2 => "Usuario",
+ 3 => "Usuario discusión",
+ 4 => "Wiki",
+ 5 => "Wiki discusión",
+ 6 => "Archivo",
+ 7 => "Archivo discusión",
+ 8 => "MediaWiki",
+ 9 => "MediaWiki discusión",
+ 10 => "Plantilla",
+ 11 => "Plantilla discusión",
+ 12 => "Ayuda",
+ 13 => "Ayuda discusión",
+ 14 => "Categoría",
+ 15 => "Categoría discusión",
+ 100 => "Personalizado",
+ 101 => "Personalizado discusión",
+ ] );
+ $this->setUserLang( $userLangObj );
+
+ $this->restoreWarnings = false;
+ }
+
+ protected function tearDown() {
+ Language::factory( 'en' )->resetNamespaces();
+
+ if ( $this->restoreWarnings ) {
+ $this->restoreWarnings = false;
+ Wikimedia\restoreWarnings();
+ }
+
+ parent::tearDown();
}
/**
public function testNamespaceSelector() {
$this->assertEquals(
'<select id="namespace" name="namespace">' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
$this->assertEquals(
'<label for="mw-test-namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="mw-test-namespace" name="wpNamespace">' . "\n" .
- '<option value="all">all</option>' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="all">todos</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2" selected="">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
$this->assertEquals(
'<label for="namespace">Select a namespace:</label>' . "\u{00A0}" .
'<select id="namespace" name="namespace">' . "\n" .
- '<option value="0">(Main)</option>' . "\n" .
+ '<option value="0">(Principal)</option>' . "\n" .
'<option value="1">Talk</option>' . "\n" .
'<option value="2">User</option>' . "\n" .
'<option value="3">User talk</option>' . "\n" .
public function testCanDisableANamespaces() {
$this->assertEquals(
'<select id="namespace" name="namespace">' . "\n" .
- '<option disabled="" value="0">(Main)</option>' . "\n" .
+ '<option disabled="" value="0">(Principal)</option>' . "\n" .
'<option disabled="" value="1">Talk</option>' . "\n" .
'<option disabled="" value="2">User</option>' . "\n" .
'<option disabled="" value="3">User talk</option>' . "\n" .
],
'Ampersand' => [
'EXAMPLE.is(a && b);',
- '<script>/*<![CDATA[*/EXAMPLE.is(a && b);/*]]>*/</script>'
+ '<script>EXAMPLE.is(a && b);</script>'
],
'HTML' => [
'EXAMPLE.label("<a>");',
- '<script>/*<![CDATA[*/EXAMPLE.label("<a>");/*]]>*/</script>'
+ '<script>EXAMPLE.label("<a>");</script>'
],
- 'Script closing string' => [
+ 'Script closing string (lower)' => [
'EXAMPLE.label("</script>");',
- // Broken: First </script> ends the script in HTML
- '<script>/*<![CDATA[*/EXAMPLE.label("</script>");/*]]>*/</script>'
+ '<script>/* ERROR: Invalid script */</script>',
+ true,
],
- 'CDATA string' => [
- 'EXAMPLE.label("&> CDATA ]]>");',
- // Broken: Works in HTML, but is invalid XML.
- '<script>/*<![CDATA[*/EXAMPLE.label("&> CDATA ]]>");/*]]>*/</script>'
+ 'Script closing with non-standard attributes (mixed)' => [
+ 'EXAMPLE.label("</SCriPT and STyLE>");',
+ '<script>/* ERROR: Invalid script */</script>',
+ true,
+ ],
+ 'HTML-comment-open and script-open' => [
+ // In HTML, <script> contents aren't just plain CDATA until </script>,
+ // there are levels of escaping modes, and the below sequence puts an
+ // HTML parser in a state where </script> would *not* close the script.
+ // https://html.spec.whatwg.org/multipage/parsing.html#script-data-double-escape-end-state
+ 'var a = "<!--<script>";',
+ '<script>/* ERROR: Invalid script */</script>',
+ true,
],
];
}
* @dataProvider provideInlineScript
* @covers Html::inlineScript
*/
- public function testInlineScript( $code, $expected ) {
+ public function testInlineScript( $code, $expected, $error = false ) {
+ if ( $error ) {
+ Wikimedia\suppressWarnings();
+ $this->restoreWarnings = true;
+ }
$this->assertSame( Html::inlineScript( $code ), $expected );
}
}