5 * @covers MessageBlobStore
7 class MessageBlobStoreTest
extends PHPUnit_Framework_TestCase
{
9 protected function 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(),
17 'relayer' => new EventRelayerNull( [] )
19 ->setMethods( [ 'makePurgeValue' ] )
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';
30 protected function makeBlobStore( $methods = null, $rl = null ) {
31 $blobStore = $this->getMockBuilder( 'MessageBlobStore' )
32 ->setConstructorArgs( [ $rl ] )
33 ->setMethods( $methods )
36 $access = TestingAccessWrapper
::newFromObject( $blobStore );
37 $access->wanCache
= $this->wanCache
;
41 protected function makeModule( array $messages ) {
42 $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] );
43 $module->setName( 'test.blobstore' );
47 /** @covers MessageBlobStore::setLogger */
48 public function testSetLogger() {
49 $blobStore = $this->makeBlobStore();
50 $this->assertSame( null, $blobStore->setLogger( new Psr\Log\
NullLogger() ) );
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()
63 /** @covers MessageBlobStore::fetchMessage */
64 public function testFetchMessage() {
65 $module = $this->makeModule( [ 'mainpage' ] );
66 $rl = new ResourceLoader();
67 $rl->register( $module->getName(), $module );
69 $blobStore = $this->makeBlobStore( null, $rl );
70 $blob = $blobStore->getBlob( $module, 'en' );
72 $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' );
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 );
81 $blobStore = $this->makeBlobStore( null, $rl );
82 $blob = $blobStore->getBlob( $module, 'en' );
84 $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' );
87 public function testGetBlob() {
88 $module = $this->makeModule( [ 'foo' ] );
89 $rl = new ResourceLoader();
90 $rl->register( $module->getName(), $module );
92 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
93 $blobStore->expects( $this->once() )
94 ->method( 'fetchMessage' )
95 ->will( $this->returnValue( 'Example' ) );
97 $blob = $blobStore->getBlob( $module, 'en' );
99 $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' );
102 public function testGetBlobCached() {
103 $module = $this->makeModule( [ 'example' ] );
104 $rl = new ResourceLoader();
105 $rl->register( $module->getName(), $module );
107 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
108 $blobStore->expects( $this->once() )
109 ->method( 'fetchMessage' )
110 ->will( $this->returnValue( 'First' ) );
112 $module = $this->makeModule( [ 'example' ] );
113 $blob = $blobStore->getBlob( $module, 'en' );
114 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
116 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
117 $blobStore->expects( $this->never() )
118 ->method( 'fetchMessage' )
119 ->will( $this->returnValue( 'Second' ) );
121 $module = $this->makeModule( [ 'example' ] );
122 $blob = $blobStore->getBlob( $module, 'en' );
123 $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' );
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' ) );
135 $blob = $blobStore->getBlob( $module, 'en' );
136 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
138 $blobStore->updateMessage( 'example' );
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' ) );
148 $blob = $blobStore->getBlob( $module, 'en' );
149 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );
152 public function testValidation() {
153 $module = $this->makeModule( [ 'foo' ] );
154 $rl = new ResourceLoader();
155 $rl->register( $module->getName(), $module );
157 $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl );
158 $blobStore->expects( $this->once() )
159 ->method( 'fetchMessage' )
160 ->will( $this->returnValueMap( [
161 [ 'foo', 'en', 'Hello' ],
164 $blob = $blobStore->getBlob( $module, 'en' );
165 $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' );
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
171 $module = $this->makeModule( [ 'foo', 'bar' ] );
172 $rl = new ResourceLoader();
173 $rl->register( $module->getName(), $module );
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' ],
183 $blob = $blobStore->getBlob( $module, 'en' );
184 $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' );
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' ) );
196 $blob = $blobStore->getBlob( $module, 'en' );
197 $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' );
199 $blob = $blobStore->getBlob( $module, 'en' );
200 $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' );
204 $blob = $blobStore->getBlob( $module, 'en' );
205 $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' );