Merge "Add ?safemode=1 to disable user JS/CSS"
[lhc/web/wiklou.git] / tests / phpunit / includes / resourceloader / MessageBlobStoreTest.php
1 <?php
2
3 /**
4 * @group Cache
5 * @covers MessageBlobStore
6 */
7 class MessageBlobStoreTest extends PHPUnit_Framework_TestCase {
8
9 protected function setUp() {
10 parent::setUp();
11 // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE.
12 // Use hash instead so that caching is observed
13 $this->wanCache = $this->getMockBuilder( 'WANObjectCache' )
14 ->setConstructorArgs( [ [
15 'cache' => new HashBagOStuff(),
16 'pool' => 'test',
17 'relayer' => new EventRelayerNull( [] )
18 ] ] )
19 ->setMethods( [ 'makePurgeValue' ] )
20 ->getMock();
21
22 $this->wanCache->expects( $this->any() )
23 ->method( 'makePurgeValue' )
24 ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
25 // Disable holdoff as it messes with testing
26 return WANObjectCache::PURGE_VAL_PREFIX . (float)$timestamp . ':0';
27 } ) );
28 }
29
30 protected function makeBlobStore( $methods = null, $rl = null ) {
31 $blobStore = $this->getMockBuilder( 'MessageBlobStore' )
32 ->setConstructorArgs( [ $rl ] )
33 ->setMethods( $methods )
34 ->getMock();
35
36 $access = TestingAccessWrapper::newFromObject( $blobStore );
37 $access->wanCache = $this->wanCache;
38 return $blobStore;
39 }
40
41 protected function makeModule( array $messages ) {
42 $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
43 $module->setName( 'test.blobstore' );
44 return $module;
45 }
46
47 /** @covers MessageBlobStore::setLogger */
48 public function testSetLogger() {
49 $blobStore = $this->makeBlobStore();
50 $this->assertSame( null, $blobStore->setLogger( new Psr\Log\NullLogger() ) );
51 }
52
53 /** @covers MessageBlobStore::getResourceLoader */
54 public function testGetResourceLoader() {
55 // Call protected method
56 $blobStore = TestingAccessWrapper::newFromObject( $this->makeBlobStore() );
57 $this->assertInstanceOf(
58 ResourceLoader::class,
59 $blobStore->getResourceLoader()
60 );
61 }
62
63 /** @covers MessageBlobStore::fetchMessage */
64 public function testFetchMessage() {
65 $module = $this->makeModule( [ 'mainpage' ] );
66 $rl = new ResourceLoader();
67 $rl->register( $module->getName(), $module );
68
69 $blobStore = $this->makeBlobStore( null, $rl );
70 $blob = $blobStore->getBlob( $module, 'en' );
71
72 $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
73 }
74
75 /** @covers MessageBlobStore::fetchMessage */
76 public function testFetchMessageFail() {
77 $module = $this->makeModule( [ 'i-dont-exist' ] );
78 $rl = new ResourceLoader();
79 $rl->register( $module->getName(), $module );
80
81 $blobStore = $this->makeBlobStore( null, $rl );
82 $blob = $blobStore->getBlob( $module, 'en' );
83
84 $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
85 }
86
87 public function testGetBlob() {
88 $module = $this->makeModule( [ 'foo' ] );
89 $rl = new ResourceLoader();
90 $rl->register( $module->getName(), $module );
91
92 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
93 $blobStore->expects( $this->once() )
94 ->method( 'fetchMessage' )
95 ->will( $this->returnValue( 'Example' ) );
96
97 $blob = $blobStore->getBlob( $module, 'en' );
98
99 $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
100 }
101
102 public function testGetBlobCached() {
103 $module = $this->makeModule( [ 'example' ] );
104 $rl = new ResourceLoader();
105 $rl->register( $module->getName(), $module );
106
107 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
108 $blobStore->expects( $this->once() )
109 ->method( 'fetchMessage' )
110 ->will( $this->returnValue( 'First' ) );
111
112 $module = $this->makeModule( [ 'example' ] );
113 $blob = $blobStore->getBlob( $module, 'en' );
114 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
115
116 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
117 $blobStore->expects( $this->never() )
118 ->method( 'fetchMessage' )
119 ->will( $this->returnValue( 'Second' ) );
120
121 $module = $this->makeModule( [ 'example' ] );
122 $blob = $blobStore->getBlob( $module, 'en' );
123 $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
124 }
125
126 public function testUpdateMessage() {
127 $module = $this->makeModule( [ 'example' ] );
128 $rl = new ResourceLoader();
129 $rl->register( $module->getName(), $module );
130 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
131 $blobStore->expects( $this->once() )
132 ->method( 'fetchMessage' )
133 ->will( $this->returnValue( 'First' ) );
134
135 $blob = $blobStore->getBlob( $module, 'en' );
136 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
137
138 $blobStore->updateMessage( 'example' );
139
140 $module = $this->makeModule( [ 'example' ] );
141 $rl = new ResourceLoader();
142 $rl->register( $module->getName(), $module );
143 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
144 $blobStore->expects( $this->once() )
145 ->method( 'fetchMessage' )
146 ->will( $this->returnValue( 'Second' ) );
147
148 $blob = $blobStore->getBlob( $module, 'en' );
149 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
150 }
151
152 public function testValidation() {
153 $module = $this->makeModule( [ 'foo' ] );
154 $rl = new ResourceLoader();
155 $rl->register( $module->getName(), $module );
156
157 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
158 $blobStore->expects( $this->once() )
159 ->method( 'fetchMessage' )
160 ->will( $this->returnValueMap( [
161 [ 'foo', 'en', 'Hello' ],
162 ] ) );
163
164 $blob = $blobStore->getBlob( $module, 'en' );
165 $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
166
167 // Now, imagine a change to the module is deployed. The module now contains
168 // message 'foo' and 'bar'. While updateMessage() was not called (since no
169 // message values were changed) it should detect the change in list of
170 // message keys.
171 $module = $this->makeModule( [ 'foo', 'bar' ] );
172 $rl = new ResourceLoader();
173 $rl->register( $module->getName(), $module );
174
175 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
176 $blobStore->expects( $this->exactly( 2 ) )
177 ->method( 'fetchMessage' )
178 ->will( $this->returnValueMap( [
179 [ 'foo', 'en', 'Hello' ],
180 [ 'bar', 'en', 'World' ],
181 ] ) );
182
183 $blob = $blobStore->getBlob( $module, 'en' );
184 $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
185 }
186
187 public function testClear() {
188 $module = $this->makeModule( [ 'example' ] );
189 $rl = new ResourceLoader();
190 $rl->register( $module->getName(), $module );
191 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
192 $blobStore->expects( $this->exactly( 2 ) )
193 ->method( 'fetchMessage' )
194 ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
195
196 $blob = $blobStore->getBlob( $module, 'en' );
197 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
198
199 $blob = $blobStore->getBlob( $module, 'en' );
200 $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
201
202 $blobStore->clear();
203
204 $blob = $blobStore->getBlob( $module, 'en' );
205 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
206 }
207 }