summaryrefslogtreecommitdiff
path: root/tests/phpunit/includes/specials
diff options
context:
space:
mode:
Diffstat (limited to 'tests/phpunit/includes/specials')
-rw-r--r--tests/phpunit/includes/specials/SpecialBlankPageTest.php25
-rw-r--r--tests/phpunit/includes/specials/SpecialPageTestBase.php165
-rw-r--r--tests/phpunit/includes/specials/SpecialPreferencesTest.php3
-rw-r--r--tests/phpunit/includes/specials/SpecialSearchTest.php106
4 files changed, 297 insertions, 2 deletions
diff --git a/tests/phpunit/includes/specials/SpecialBlankPageTest.php b/tests/phpunit/includes/specials/SpecialBlankPageTest.php
new file mode 100644
index 00000000..1d4f5e51
--- /dev/null
+++ b/tests/phpunit/includes/specials/SpecialBlankPageTest.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @licence GNU GPL v2+
+ * @author Adam Shorland
+ *
+ * @covers SpecialBlankpage
+ */
+class SpecialBlankPageTest extends SpecialPageTestBase {
+
+ /**
+ * Returns a new instance of the special page under test.
+ *
+ * @return SpecialPage
+ */
+ protected function newSpecialPage() {
+ return new SpecialBlankpage();
+ }
+
+ public function testHasWikiMsg() {
+ list( $html, ) = $this->executeSpecialPage();
+ $this->assertContains( wfMessage( 'intentionallyblankpage' )->text(), $html );
+ }
+
+}
diff --git a/tests/phpunit/includes/specials/SpecialPageTestBase.php b/tests/phpunit/includes/specials/SpecialPageTestBase.php
new file mode 100644
index 00000000..9c7b0f00
--- /dev/null
+++ b/tests/phpunit/includes/specials/SpecialPageTestBase.php
@@ -0,0 +1,165 @@
+<?php
+
+/**
+ * Base class for testing special pages.
+ *
+ * @since 1.26
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Daniel Kinzler
+ * @author Adam Shorland
+ * @author Thiemo Mättig
+ */
+abstract class SpecialPageTestBase extends MediaWikiTestCase {
+
+ private $obLevel;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->obLevel = ob_get_level();
+ }
+
+ protected function tearDown() {
+ $obLevel = ob_get_level();
+
+ while ( ob_get_level() > $this->obLevel ) {
+ ob_end_clean();
+ }
+
+ if ( $obLevel !== $this->obLevel ) {
+ $this->fail(
+ "Test changed output buffer level: was {$this->obLevel} before test, but $obLevel after test."
+ );
+ }
+
+ parent::tearDown();
+ }
+
+ /**
+ * Returns a new instance of the special page under test.
+ *
+ * @return SpecialPage
+ */
+ abstract protected function newSpecialPage();
+
+ /**
+ * @param string $subPage The subpage parameter to call the page with
+ * @param WebRequest|null $request Web request that may contain URL parameters, etc
+ * @param Language|string|null $language The language which should be used in the context
+ * @param User|null $user The user which should be used in the context of this special page
+ *
+ * @throws Exception
+ * @return array( string, WebResponse ) A two-elements array containing the HTML output
+ * generated by the special page as well as the response object.
+ */
+ protected function executeSpecialPage(
+ $subPage = '',
+ WebRequest $request = null,
+ $language = null,
+ User $user = null
+ ) {
+ $context = $this->newContext( $request, $language, $user );
+
+ $output = new OutputPage( $context );
+ $context->setOutput( $output );
+
+ $page = $this->newSpecialPage();
+ $page->setContext( $context );
+ $output->setTitle( $page->getPageTitle() );
+
+ $html = $this->getHTMLFromSpecialPage( $page, $subPage );
+ $response = $context->getRequest()->response();
+
+ if ( $response instanceof FauxResponse ) {
+ $code = $response->getStatusCode();
+
+ if ( $code > 0 ) {
+ $response->header( 'Status: ' . $code . ' ' . HttpStatus::getMessage( $code ) );
+ }
+ }
+
+ return array( $html, $response );
+ }
+
+ /**
+ * @param WebRequest|null $request
+ * @param Language|string|null $language
+ * @param User|null $user
+ *
+ * @return DerivativeContext
+ */
+ private function newContext(
+ WebRequest $request = null,
+ $language = null,
+ User $user = null
+ ) {
+ $context = new DerivativeContext( RequestContext::getMain() );
+
+ $context->setRequest( $request ?: new FauxRequest() );
+
+ if ( $language !== null ) {
+ $context->setLanguage( $language );
+ }
+
+ if ( $user !== null ) {
+ $context->setUser( $user );
+ }
+
+ $this->setEditTokenFromUser( $context );
+
+ return $context;
+ }
+
+ /**
+ * If we are trying to edit and no token is set, supply one.
+ *
+ * @param DerivativeContext $context
+ */
+ private function setEditTokenFromUser( DerivativeContext $context ) {
+ $request = $context->getRequest();
+
+ // Edits via GET are a security issue and should not succeed. On the other hand, not all
+ // POST requests are edits, but should ignore unused parameters.
+ if ( !$request->getCheck( 'wpEditToken' ) && $request->wasPosted() ) {
+ $request->setVal( 'wpEditToken', $context->getUser()->getEditToken() );
+ }
+ }
+
+ /**
+ * @param SpecialPage $page
+ * @param string $subPage
+ *
+ * @throws Exception
+ * @return string HTML
+ */
+ private function getHTMLFromSpecialPage( SpecialPage $page, $subPage ) {
+ ob_start();
+
+ try {
+ $page->execute( $subPage );
+
+ $output = $page->getOutput();
+
+ if ( $output->getRedirect() !== '' ) {
+ $output->output();
+ $html = ob_get_contents();
+ } elseif ( $output->isDisabled() ) {
+ $html = ob_get_contents();
+ } else {
+ $html = $output->getHTML();
+ }
+ } catch ( Exception $ex ) {
+ ob_end_clean();
+
+ // Re-throw exception after "finally" handling because PHP 5.3 doesn't have "finally".
+ throw $ex;
+ }
+
+ ob_end_clean();
+
+ return $html;
+ }
+
+}
diff --git a/tests/phpunit/includes/specials/SpecialPreferencesTest.php b/tests/phpunit/includes/specials/SpecialPreferencesTest.php
index 4f6c4116..1545d7ec 100644
--- a/tests/phpunit/includes/specials/SpecialPreferencesTest.php
+++ b/tests/phpunit/includes/specials/SpecialPreferencesTest.php
@@ -4,10 +4,11 @@
*
* Copyright © 2013, Antoine Musso
* Copyright © 2013, Wikimedia Foundation Inc.
- *
*/
/**
+ * @group Database
+ *
* @covers SpecialPreferences
*/
class SpecialPreferencesTest extends MediaWikiTestCase {
diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php
index 83489c65..13c28381 100644
--- a/tests/phpunit/includes/specials/SpecialSearchTest.php
+++ b/tests/phpunit/includes/specials/SpecialSearchTest.php
@@ -136,9 +136,113 @@ class SpecialSearchTest extends MediaWikiTestCase {
# Compare :-]
$this->assertRegExp(
- '/' . preg_quote( $term ) . '/',
+ '/' . preg_quote( $term, '/' ) . '/',
$pageTitle,
"Search term '{$term}' should not be expanded in Special:Search <title>"
);
}
+
+ public function provideRewriteQueryWithSuggestion() {
+ return array(
+ array(
+ 'With suggestion and no rewritten query shows did you mean',
+ '/Did you mean: <a[^>]+>first suggestion/',
+ new SpecialSearchTestMockResultSet( 'first suggestion', null, array(
+ SearchResult::newFromTitle( Title::newMainPage() ),
+ ) ),
+ ),
+
+ array(
+ 'With rewritten query informs user of change',
+ '/Showing results for <a[^>]+>first suggestion/',
+ new SpecialSearchTestMockResultSet( 'asdf', 'first suggestion', array(
+ SearchResult::newFromTitle( Title::newMainPage() ),
+ ) ),
+ ),
+
+ array(
+ 'When both queries have no results user gets no results',
+ '/There were no results matching the query/',
+ new SpecialSearchTestMockResultSet( 'first suggestion', 'first suggestion', array() ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider provideRewriteQueryWithSuggestion
+ */
+ public function testRewriteQueryWithSuggestion( $message, $expectRegex, $results ) {
+ $mockSearchEngine = $this->mockSearchEngine( $results );
+ $search = $this->getMockBuilder( 'SpecialSearch' )
+ ->setMethods( array( 'getSearchEngine' ) )
+ ->getMock();
+ $search->expects( $this->any() )
+ ->method( 'getSearchEngine' )
+ ->will( $this->returnValue( $mockSearchEngine ) );
+
+ $search->getContext()->setTitle( Title::makeTitle( NS_SPECIAL, 'Search' ) );
+ $search->load();
+ $search->showResults( 'this is a fake search' );
+
+ $html = $search->getContext()->getOutput()->getHTML();
+ foreach ( (array)$expectRegex as $regex ) {
+ $this->assertRegExp( $regex, $html, $message );
+ }
+ }
+
+ protected function mockSearchEngine( $results ) {
+ $mock = $this->getMockBuilder( 'SearchEngine' )
+ ->setMethods( array( 'searchText', 'searchTitle' ) )
+ ->getMock();
+
+ $mock->expects( $this->any() )
+ ->method( 'searchText' )
+ ->will( $this->returnValue( $results ) );
+
+ return $mock;
+ }
+}
+
+class SpecialSearchTestMockResultSet extends SearchResultSet {
+ protected $results;
+ protected $suggestion;
+
+ public function __construct( $suggestion = null, $rewrittenQuery = null, array $results = array(), $containedSyntax = false) {
+ $this->suggestion = $suggestion;
+ $this->rewrittenQuery = $rewrittenQuery;
+ $this->results = $results;
+ $this->containedSyntax = $containedSyntax;
+ }
+
+ public function numRows() {
+ return count( $this->results );
+ }
+
+ public function getTotalHits() {
+ return $this->numRows();
+ }
+
+ public function hasSuggestion() {
+ return $this->suggestion !== null;
+ }
+
+ public function getSuggestionQuery() {
+ return $this->suggestion;
+ }
+
+ public function getSuggestionSnippet() {
+ return $this->suggestion;
+ }
+
+ public function hasRewrittenQuery() {
+ return $this->rewrittenQuery !== null;
+ }
+
+ public function getQueryAfterRewrite() {
+ return $this->rewrittenQuery;
+ }
+
+ public function getQueryAfterRewriteSnippet() {
+ return htmlspecialchars( $this->rewrittenQuery );
+ }
}