3 use Wikimedia\TestingAccessWrapper
;
7 * @covers MessageBlobStore
9 class MessageBlobStoreTest
extends PHPUnit\Framework\TestCase
{
11 use MediaWikiCoversValidator
;
13 protected function 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(),
21 'relayer' => new EventRelayerNull( [] )
23 ->setMethods( [ 'makePurgeValue' ] )
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';
34 protected function makeBlobStore( $methods = null, $rl = null ) {
35 $blobStore = $this->getMockBuilder( MessageBlobStore
::class )
36 ->setConstructorArgs( [ $rl ] )
37 ->setMethods( $methods )
40 $access = TestingAccessWrapper
::newFromObject( $blobStore );
41 $access->wanCache
= $this->wanCache
;
45 protected function makeModule( array $messages ) {
46 $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
47 $module->setName( 'test.blobstore' );
51 /** @covers MessageBlobStore::setLogger */
52 public function testSetLogger() {
53 $blobStore = $this->makeBlobStore();
54 $this->assertSame( null, $blobStore->setLogger( new Psr\Log\
NullLogger() ) );
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()
67 /** @covers MessageBlobStore::fetchMessage */
68 public function testFetchMessage() {
69 $module = $this->makeModule( [ 'mainpage' ] );
70 $rl = new ResourceLoader();
71 $rl->register( $module->getName(), $module );
73 $blobStore = $this->makeBlobStore( null, $rl );
74 $blob = $blobStore->getBlob( $module, 'en' );
76 $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
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 );
85 $blobStore = $this->makeBlobStore( null, $rl );
86 $blob = $blobStore->getBlob( $module, 'en' );
88 $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
91 public function testGetBlob() {
92 $module = $this->makeModule( [ 'foo' ] );
93 $rl = new ResourceLoader();
94 $rl->register( $module->getName(), $module );
96 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
97 $blobStore->expects( $this->once() )
98 ->method( 'fetchMessage' )
99 ->will( $this->returnValue( 'Example' ) );
101 $blob = $blobStore->getBlob( $module, 'en' );
103 $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
107 * Seems to fail sometimes (T176097).
111 public function testGetBlobCached() {
112 $module = $this->makeModule( [ 'example' ] );
113 $rl = new ResourceLoader();
114 $rl->register( $module->getName(), $module );
116 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
117 $blobStore->expects( $this->once() )
118 ->method( 'fetchMessage' )
119 ->will( $this->returnValue( 'First' ) );
121 $module = $this->makeModule( [ 'example' ] );
122 $blob = $blobStore->getBlob( $module, 'en' );
123 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
125 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
126 $blobStore->expects( $this->never() )
127 ->method( 'fetchMessage' )
128 ->will( $this->returnValue( 'Second' ) );
130 $module = $this->makeModule( [ 'example' ] );
131 $blob = $blobStore->getBlob( $module, 'en' );
132 $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
135 public function testUpdateMessage() {
136 $module = $this->makeModule( [ 'example' ] );
137 $rl = new ResourceLoader();
138 $rl->register( $module->getName(), $module );
139 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
140 $blobStore->expects( $this->once() )
141 ->method( 'fetchMessage' )
142 ->will( $this->returnValue( 'First' ) );
144 $blob = $blobStore->getBlob( $module, 'en' );
145 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
147 $blobStore->updateMessage( 'example' );
149 $module = $this->makeModule( [ 'example' ] );
150 $rl = new ResourceLoader();
151 $rl->register( $module->getName(), $module );
152 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
153 $blobStore->expects( $this->once() )
154 ->method( 'fetchMessage' )
155 ->will( $this->returnValue( 'Second' ) );
157 $blob = $blobStore->getBlob( $module, 'en' );
158 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
161 public function testValidation() {
162 $module = $this->makeModule( [ 'foo' ] );
163 $rl = new ResourceLoader();
164 $rl->register( $module->getName(), $module );
166 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
167 $blobStore->expects( $this->once() )
168 ->method( 'fetchMessage' )
169 ->will( $this->returnValueMap( [
170 [ 'foo', 'en', 'Hello' ],
173 $blob = $blobStore->getBlob( $module, 'en' );
174 $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
176 // Now, imagine a change to the module is deployed. The module now contains
177 // message 'foo' and 'bar'. While updateMessage() was not called (since no
178 // message values were changed) it should detect the change in list of
180 $module = $this->makeModule( [ 'foo', 'bar' ] );
181 $rl = new ResourceLoader();
182 $rl->register( $module->getName(), $module );
184 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
185 $blobStore->expects( $this->exactly( 2 ) )
186 ->method( 'fetchMessage' )
187 ->will( $this->returnValueMap( [
188 [ 'foo', 'en', 'Hello' ],
189 [ 'bar', 'en', 'World' ],
192 $blob = $blobStore->getBlob( $module, 'en' );
193 $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
196 public function testClear() {
197 $module = $this->makeModule( [ 'example' ] );
198 $rl = new ResourceLoader();
199 $rl->register( $module->getName(), $module );
200 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
201 $blobStore->expects( $this->exactly( 2 ) )
202 ->method( 'fetchMessage' )
203 ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
205 $blob = $blobStore->getBlob( $module, 'en' );
206 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
208 $blob = $blobStore->getBlob( $module, 'en' );
209 $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
213 $blob = $blobStore->getBlob( $module, 'en' );
214 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );