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