Merge "Don't check namespace in SpecialWantedtemplates"
[lhc/web/wiklou.git] / tests / phpunit / includes / specials / SpecialPageTestBase.php
1 <?php
2
3 /**
4 * Base class for testing special pages.
5 *
6 * @since 1.26
7 *
8 * @licence GNU GPL v2+
9 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
10 * @author Daniel Kinzler
11 * @author Adam Shorland
12 * @author Thiemo Mättig
13 */
14 abstract class SpecialPageTestBase extends MediaWikiTestCase {
15
16 private $obLevel;
17
18 protected function setUp() {
19 parent::setUp();
20
21 $this->obLevel = ob_get_level();
22 }
23
24 protected function tearDown() {
25 $obLevel = ob_get_level();
26
27 while ( ob_get_level() > $this->obLevel ) {
28 ob_end_clean();
29 }
30
31 if ( $obLevel !== $this->obLevel ) {
32 $this->fail(
33 "Test changed output buffer level: was {$this->obLevel} before test, but $obLevel after test."
34 );
35 }
36
37 parent::tearDown();
38 }
39
40 /**
41 * Returns a new instance of the special page under test.
42 *
43 * @return SpecialPage
44 */
45 abstract protected function newSpecialPage();
46
47 /**
48 * @param string $subPage The subpage parameter to call the page with
49 * @param WebRequest|null $request Web request that may contain URL parameters, etc
50 * @param Language|string|null $language The language which should be used in the context
51 * @param User|null $user The user which should be used in the context of this special page
52 *
53 * @throws Exception
54 * @return array( string, WebResponse ) A two-elements array containing the HTML output
55 * generated by the special page as well as the response object.
56 */
57 protected function executeSpecialPage(
58 $subPage = '',
59 WebRequest $request = null,
60 $language = null,
61 User $user = null
62 ) {
63 $context = $this->newContext( $request, $language, $user );
64
65 $output = new OutputPage( $context );
66 $context->setOutput( $output );
67
68 $page = $this->newSpecialPage();
69 $page->setContext( $context );
70 $output->setTitle( $page->getPageTitle() );
71
72 $html = $this->getHTMLFromSpecialPage( $page, $subPage );
73 $response = $context->getRequest()->response();
74
75 if ( $response instanceof FauxResponse ) {
76 $code = $response->getStatusCode();
77
78 if ( $code > 0 ) {
79 $response->header( 'Status: ' . $code . ' ' . HttpStatus::getMessage( $code ) );
80 }
81 }
82
83 return array( $html, $response );
84 }
85
86 /**
87 * @param WebRequest|null $request
88 * @param Language|string|null $language
89 * @param User|null $user
90 *
91 * @return DerivativeContext
92 */
93 private function newContext(
94 WebRequest $request = null,
95 $language = null,
96 User $user = null
97 ) {
98 $context = new DerivativeContext( RequestContext::getMain() );
99
100 $context->setRequest( $request ?: new FauxRequest() );
101
102 if ( $language !== null ) {
103 $context->setLanguage( $language );
104 }
105
106 if ( $user !== null ) {
107 $context->setUser( $user );
108 }
109
110 $this->setEditTokenFromUser( $context );
111
112 return $context;
113 }
114
115 /**
116 * If we are trying to edit and no token is set, supply one.
117 *
118 * @param DerivativeContext $context
119 */
120 private function setEditTokenFromUser( DerivativeContext $context ) {
121 $request = $context->getRequest();
122
123 // Edits via GET are a security issue and should not succeed. On the other hand, not all
124 // POST requests are edits, but should ignore unused parameters.
125 if ( !$request->getCheck( 'wpEditToken' ) && $request->wasPosted() ) {
126 $request->setVal( 'wpEditToken', $context->getUser()->getEditToken() );
127 }
128 }
129
130 /**
131 * @param SpecialPage $page
132 * @param string $subPage
133 *
134 * @throws Exception
135 * @return string HTML
136 */
137 private function getHTMLFromSpecialPage( SpecialPage $page, $subPage ) {
138 ob_start();
139
140 try {
141 $page->execute( $subPage );
142
143 $output = $page->getOutput();
144
145 if ( $output->getRedirect() !== '' ) {
146 $output->output();
147 $html = ob_get_contents();
148 } elseif ( $output->isDisabled() ) {
149 $html = ob_get_contents();
150 } else {
151 $html = $output->getHTML();
152 }
153 } catch ( Exception $ex ) {
154 ob_end_clean();
155
156 // Re-throw exception after "finally" handling because PHP 5.3 doesn't have "finally".
157 throw $ex;
158 }
159
160 ob_end_clean();
161
162 return $html;
163 }
164
165 }