Add session_write_close() calls to SessionManager tests
[lhc/web/wiklou.git] / tests / phpunit / includes / resourceloader / ResourceLoaderModuleTest.php
1 <?php
2
3 class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
4
5 /**
6 * @covers ResourceLoaderModule::getVersionHash
7 * @covers ResourceLoaderModule::getModifiedTime
8 * @covers ResourceLoaderModule::getModifiedHash
9 */
10 public function testGetVersionHash() {
11 $context = $this->getResourceLoaderContext();
12
13 $baseParams = [
14 'scripts' => [ 'foo.js', 'bar.js' ],
15 'dependencies' => [ 'jquery', 'mediawiki' ],
16 'messages' => [ 'hello', 'world' ],
17 ];
18
19 $module = new ResourceLoaderFileModule( $baseParams );
20 $version = json_encode( $module->getVersionHash( $context ) );
21
22 // Exactly the same
23 $module = new ResourceLoaderFileModule( $baseParams );
24 $this->assertEquals(
25 $version,
26 json_encode( $module->getVersionHash( $context ) ),
27 'Instance is insignificant'
28 );
29
30 // Re-order dependencies
31 $module = new ResourceLoaderFileModule( [
32 'dependencies' => [ 'mediawiki', 'jquery' ],
33 ] + $baseParams );
34 $this->assertEquals(
35 $version,
36 json_encode( $module->getVersionHash( $context ) ),
37 'Order of dependencies is insignificant'
38 );
39
40 // Re-order messages
41 $module = new ResourceLoaderFileModule( [
42 'messages' => [ 'world', 'hello' ],
43 ] + $baseParams );
44 $this->assertEquals(
45 $version,
46 json_encode( $module->getVersionHash( $context ) ),
47 'Order of messages is insignificant'
48 );
49
50 // Re-order scripts
51 $module = new ResourceLoaderFileModule( [
52 'scripts' => [ 'bar.js', 'foo.js' ],
53 ] + $baseParams );
54 $this->assertNotEquals(
55 $version,
56 json_encode( $module->getVersionHash( $context ) ),
57 'Order of scripts is significant'
58 );
59
60 // Subclass
61 $module = new ResourceLoaderFileModuleTestModule( $baseParams );
62 $this->assertNotEquals(
63 $version,
64 json_encode( $module->getVersionHash( $context ) ),
65 'Class is significant'
66 );
67 }
68
69 /**
70 * @covers ResourceLoaderModule::validateScriptFile
71 */
72 public function testValidateScriptFile() {
73 $this->setMwGlobals( 'wgResourceLoaderValidateJS', true );
74
75 $context = $this->getResourceLoaderContext();
76
77 $module = new ResourceLoaderTestModule( [
78 'script' => "var a = 'this is';\n {\ninvalid"
79 ] );
80 $this->assertEquals(
81 'mw.log.error(' .
82 '"JavaScript parse error: Parse error: Unexpected token; ' .
83 'token } expected in file \'input\' on line 3"' .
84 ');',
85 $module->getScript( $context ),
86 'Replace invalid syntax with error logging'
87 );
88
89 $module = new ResourceLoaderTestModule( [
90 'script' => "\n'valid';"
91 ] );
92 $this->assertEquals(
93 "\n'valid';",
94 $module->getScript( $context ),
95 'Leave valid scripts as-is'
96 );
97 }
98
99 public static function provideBuildContentScripts() {
100 return [
101 [
102 "mw.foo()",
103 "mw.foo()\n",
104 ],
105 [
106 "mw.foo();",
107 "mw.foo();\n",
108 ],
109 [
110 "mw.foo();\n",
111 "mw.foo();\n",
112 ],
113 [
114 "mw.foo()\n",
115 "mw.foo()\n",
116 ],
117 [
118 "mw.foo()\n// mw.bar();",
119 "mw.foo()\n// mw.bar();\n",
120 ],
121 [
122 "mw.foo()\n// mw.bar()",
123 "mw.foo()\n// mw.bar()\n",
124 ],
125 [
126 "mw.foo()// mw.bar();",
127 "mw.foo()// mw.bar();\n",
128 ],
129 ];
130 }
131
132 /**
133 * @dataProvider provideBuildContentScripts
134 * @covers ResourceLoaderModule::buildContent
135 */
136 public function testBuildContentScripts( $raw, $build, $message = null ) {
137 $context = $this->getResourceLoaderContext();
138 $module = new ResourceLoaderTestModule( [
139 'script' => $raw
140 ] );
141 $this->assertEquals( $raw, $module->getScript( $context ), 'Raw script' );
142 $this->assertEquals(
143 [ 'scripts' => $build ],
144 $module->getModuleContent( $context ),
145 $message
146 );
147 }
148
149 /**
150 * @covers ResourceLoaderModule::getRelativePaths
151 * @covers ResourceLoaderModule::expandRelativePaths
152 */
153 public function testPlaceholderize() {
154 $getRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'getRelativePaths' );
155 $getRelativePaths->setAccessible( true );
156 $expandRelativePaths = new ReflectionMethod( ResourceLoaderModule::class, 'expandRelativePaths' );
157 $expandRelativePaths->setAccessible( true );
158
159 $this->setMwGlobals( [
160 'IP' => '/srv/example/mediawiki/core',
161 ] );
162 $raw = [
163 '/srv/example/mediawiki/core/resources/foo.js',
164 '/srv/example/mediawiki/core/extensions/Example/modules/bar.js',
165 '/srv/example/mediawiki/skins/Example/baz.css',
166 '/srv/example/mediawiki/skins/Example/images/quux.png',
167 ];
168 $canonical = [
169 'resources/foo.js',
170 'extensions/Example/modules/bar.js',
171 '../skins/Example/baz.css',
172 '../skins/Example/images/quux.png',
173 ];
174 $this->assertEquals(
175 $canonical,
176 $getRelativePaths->invoke( null, $raw ),
177 'Insert placeholders'
178 );
179 $this->assertEquals(
180 $raw,
181 $expandRelativePaths->invoke( null, $canonical ),
182 'Substitute placeholders'
183 );
184 }
185
186 /**
187 * @covers ResourceLoaderModule::getHeaders
188 * @covers ResourceLoaderModule::getPreloadLinks
189 */
190 public function testGetHeaders() {
191 $context = $this->getResourceLoaderContext();
192
193 $module = new ResourceLoaderTestModule();
194 $this->assertSame( [], $module->getHeaders( $context ), 'Default' );
195
196 $module = $this->getMockBuilder( ResourceLoaderTestModule::class )
197 ->setMethods( [ 'getPreloadLinks' ] )->getMock();
198 $module->method( 'getPreloadLinks' )->willReturn( [
199 'https://example.org/script.js' => [ 'as' => 'script' ],
200 ] );
201 $this->assertSame(
202 [
203 'Link: <https://example.org/script.js>;rel=preload;as=script'
204 ],
205 $module->getHeaders( $context ),
206 'Preload one resource'
207 );
208
209 $module = $this->getMockBuilder( ResourceLoaderTestModule::class )
210 ->setMethods( [ 'getPreloadLinks' ] )->getMock();
211 $module->method( 'getPreloadLinks' )->willReturn( [
212 'https://example.org/script.js' => [ 'as' => 'script' ],
213 '/example.png' => [ 'as' => 'image' ],
214 ] );
215 $this->assertSame(
216 [
217 'Link: <https://example.org/script.js>;rel=preload;as=script,' .
218 '</example.png>;rel=preload;as=image'
219 ],
220 $module->getHeaders( $context ),
221 'Preload two resources'
222 );
223 }
224 }