3 use Wikimedia\TestingAccessWrapper
;
7 * @covers MessageBlobStore
9 class MessageBlobStoreTest
extends PHPUnit_Framework_TestCase
{
11 protected function setUp() {
13 // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE.
14 // Use hash instead so that caching is observed
15 $this->wanCache
= $this->getMockBuilder( 'WANObjectCache' )
16 ->setConstructorArgs( [ [
17 'cache' => new HashBagOStuff(),
19 'relayer' => new EventRelayerNull( [] )
21 ->setMethods( [ 'makePurgeValue' ] )
24 $this->wanCache
->expects( $this->any() )
25 ->method( 'makePurgeValue' )
26 ->will( $this->returnCallback( function ( $timestamp, $holdoff ) {
27 // Disable holdoff as it messes with testing
28 return WANObjectCache
::PURGE_VAL_PREFIX
. (float)$timestamp . ':0';
32 protected function makeBlobStore( $methods = null, $rl = null ) {
33 $blobStore = $this->getMockBuilder( 'MessageBlobStore' )
34 ->setConstructorArgs( [ $rl ] )
35 ->setMethods( $methods )
38 $access = TestingAccessWrapper
::newFromObject( $blobStore );
39 $access->wanCache
= $this->wanCache
;
43 protected function makeModule( array $messages ) {
44 $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
45 $module->setName( 'test.blobstore' );
49 /** @covers MessageBlobStore::setLogger */
50 public function testSetLogger() {
51 $blobStore = $this->makeBlobStore();
52 $this->assertSame( null, $blobStore->setLogger( new Psr\Log\
NullLogger() ) );
55 /** @covers MessageBlobStore::getResourceLoader */
56 public function testGetResourceLoader() {
57 // Call protected method
58 $blobStore = TestingAccessWrapper
::newFromObject( $this->makeBlobStore() );
59 $this->assertInstanceOf(
60 ResourceLoader
::class,
61 $blobStore->getResourceLoader()
65 /** @covers MessageBlobStore::fetchMessage */
66 public function testFetchMessage() {
67 $module = $this->makeModule( [ 'mainpage' ] );
68 $rl = new ResourceLoader();
69 $rl->register( $module->getName(), $module );
71 $blobStore = $this->makeBlobStore( null, $rl );
72 $blob = $blobStore->getBlob( $module, 'en' );
74 $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
77 /** @covers MessageBlobStore::fetchMessage */
78 public function testFetchMessageFail() {
79 $module = $this->makeModule( [ 'i-dont-exist' ] );
80 $rl = new ResourceLoader();
81 $rl->register( $module->getName(), $module );
83 $blobStore = $this->makeBlobStore( null, $rl );
84 $blob = $blobStore->getBlob( $module, 'en' );
86 $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
89 public function testGetBlob() {
90 $module = $this->makeModule( [ 'foo' ] );
91 $rl = new ResourceLoader();
92 $rl->register( $module->getName(), $module );
94 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
95 $blobStore->expects( $this->once() )
96 ->method( 'fetchMessage' )
97 ->will( $this->returnValue( 'Example' ) );
99 $blob = $blobStore->getBlob( $module, 'en' );
101 $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
104 public function testGetBlobCached() {
105 $module = $this->makeModule( [ 'example' ] );
106 $rl = new ResourceLoader();
107 $rl->register( $module->getName(), $module );
109 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
110 $blobStore->expects( $this->once() )
111 ->method( 'fetchMessage' )
112 ->will( $this->returnValue( 'First' ) );
114 $module = $this->makeModule( [ 'example' ] );
115 $blob = $blobStore->getBlob( $module, 'en' );
116 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
118 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
119 $blobStore->expects( $this->never() )
120 ->method( 'fetchMessage' )
121 ->will( $this->returnValue( 'Second' ) );
123 $module = $this->makeModule( [ 'example' ] );
124 $blob = $blobStore->getBlob( $module, 'en' );
125 $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
128 public function testUpdateMessage() {
129 $module = $this->makeModule( [ 'example' ] );
130 $rl = new ResourceLoader();
131 $rl->register( $module->getName(), $module );
132 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
133 $blobStore->expects( $this->once() )
134 ->method( 'fetchMessage' )
135 ->will( $this->returnValue( 'First' ) );
137 $blob = $blobStore->getBlob( $module, 'en' );
138 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
140 $blobStore->updateMessage( 'example' );
142 $module = $this->makeModule( [ 'example' ] );
143 $rl = new ResourceLoader();
144 $rl->register( $module->getName(), $module );
145 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
146 $blobStore->expects( $this->once() )
147 ->method( 'fetchMessage' )
148 ->will( $this->returnValue( 'Second' ) );
150 $blob = $blobStore->getBlob( $module, 'en' );
151 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
154 public function testValidation() {
155 $module = $this->makeModule( [ 'foo' ] );
156 $rl = new ResourceLoader();
157 $rl->register( $module->getName(), $module );
159 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
160 $blobStore->expects( $this->once() )
161 ->method( 'fetchMessage' )
162 ->will( $this->returnValueMap( [
163 [ 'foo', 'en', 'Hello' ],
166 $blob = $blobStore->getBlob( $module, 'en' );
167 $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
169 // Now, imagine a change to the module is deployed. The module now contains
170 // message 'foo' and 'bar'. While updateMessage() was not called (since no
171 // message values were changed) it should detect the change in list of
173 $module = $this->makeModule( [ 'foo', 'bar' ] );
174 $rl = new ResourceLoader();
175 $rl->register( $module->getName(), $module );
177 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
178 $blobStore->expects( $this->exactly( 2 ) )
179 ->method( 'fetchMessage' )
180 ->will( $this->returnValueMap( [
181 [ 'foo', 'en', 'Hello' ],
182 [ 'bar', 'en', 'World' ],
185 $blob = $blobStore->getBlob( $module, 'en' );
186 $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
189 public function testClear() {
190 $module = $this->makeModule( [ 'example' ] );
191 $rl = new ResourceLoader();
192 $rl->register( $module->getName(), $module );
193 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
194 $blobStore->expects( $this->exactly( 2 ) )
195 ->method( 'fetchMessage' )
196 ->will( $this->onConsecutiveCalls( 'First', 'Second' ) );
198 $blob = $blobStore->getBlob( $module, 'en' );
199 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
201 $blob = $blobStore->getBlob( $module, 'en' );
202 $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
206 $blob = $blobStore->getBlob( $module, 'en' );
207 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );