diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php |
first commit
Diffstat (limited to 'www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php')
-rw-r--r-- | www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php b/www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php new file mode 100644 index 00000000..7eb09441 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/resourceloader/MessageBlobStoreTest.php @@ -0,0 +1,224 @@ +<?php + +use Wikimedia\TestingAccessWrapper; + +/** + * @group Cache + * @covers MessageBlobStore + */ +class MessageBlobStoreTest extends PHPUnit\Framework\TestCase { + + use MediaWikiCoversValidator; + + protected function setUp() { + parent::setUp(); + // MediaWiki tests defaults $wgMainWANCache to CACHE_NONE. + // Use hash instead so that caching is observed + $this->wanCache = $this->getMockBuilder( WANObjectCache::class ) + ->setConstructorArgs( [ [ + 'cache' => new HashBagOStuff(), + 'pool' => 'test', + 'relayer' => new EventRelayerNull( [] ) + ] ] ) + ->setMethods( [ 'makePurgeValue' ] ) + ->getMock(); + + $this->wanCache->expects( $this->any() ) + ->method( 'makePurgeValue' ) + ->will( $this->returnCallback( function ( $timestamp, $holdoff ) { + // Disable holdoff as it messes with testing. Aside from a 0-second holdoff, + // make sure that "time" passes between getMulti() check init and the set() + // in recacheMessageBlob(). This especially matters for Windows clocks. + $ts = (float)$timestamp - 0.0001; + + return WANObjectCache::PURGE_VAL_PREFIX . $ts . ':0'; + } ) ); + } + + protected function makeBlobStore( $methods = null, $rl = null ) { + $blobStore = $this->getMockBuilder( MessageBlobStore::class ) + ->setConstructorArgs( [ $rl ] ) + ->setMethods( $methods ) + ->getMock(); + + $access = TestingAccessWrapper::newFromObject( $blobStore ); + $access->wanCache = $this->wanCache; + return $blobStore; + } + + protected function makeModule( array $messages ) { + $module = new ResourceLoaderTestModule( [ 'messages' => $messages ] ); + $module->setName( 'test.blobstore' ); + return $module; + } + + /** @covers MessageBlobStore::setLogger */ + public function testSetLogger() { + $blobStore = $this->makeBlobStore(); + $this->assertSame( null, $blobStore->setLogger( new Psr\Log\NullLogger() ) ); + } + + /** @covers MessageBlobStore::getResourceLoader */ + public function testGetResourceLoader() { + // Call protected method + $blobStore = TestingAccessWrapper::newFromObject( $this->makeBlobStore() ); + $this->assertInstanceOf( + ResourceLoader::class, + $blobStore->getResourceLoader() + ); + } + + /** @covers MessageBlobStore::fetchMessage */ + public function testFetchMessage() { + $module = $this->makeModule( [ 'mainpage' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( null, $rl ); + $blob = $blobStore->getBlob( $module, 'en' ); + + $this->assertEquals( '{"mainpage":"Main Page"}', $blob, 'Generated blob' ); + } + + /** @covers MessageBlobStore::fetchMessage */ + public function testFetchMessageFail() { + $module = $this->makeModule( [ 'i-dont-exist' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( null, $rl ); + $blob = $blobStore->getBlob( $module, 'en' ); + + $this->assertEquals( '{"i-dont-exist":"\u29fci-dont-exist\u29fd"}', $blob, 'Generated blob' ); + } + + public function testGetBlob() { + $module = $this->makeModule( [ 'foo' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->once() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValue( 'Example' ) ); + + $blob = $blobStore->getBlob( $module, 'en' ); + + $this->assertEquals( '{"foo":"Example"}', $blob, 'Generated blob' ); + } + + /** + * Seems to fail sometimes (T176097). + * + * @group Broken + */ + public function testGetBlobCached() { + $module = $this->makeModule( [ 'example' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->once() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValue( 'First' ) ); + + $module = $this->makeModule( [ 'example' ] ); + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' ); + + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->never() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValue( 'Second' ) ); + + $module = $this->makeModule( [ 'example' ] ); + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"First"}', $blob, 'Cache hit' ); + } + + public function testUpdateMessage() { + $module = $this->makeModule( [ 'example' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->once() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValue( 'First' ) ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' ); + + $blobStore->updateMessage( 'example' ); + + $module = $this->makeModule( [ 'example' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->once() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValue( 'Second' ) ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' ); + } + + public function testValidation() { + $module = $this->makeModule( [ 'foo' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->once() ) + ->method( 'fetchMessage' ) + ->will( $this->returnValueMap( [ + [ 'foo', 'en', 'Hello' ], + ] ) ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"foo":"Hello"}', $blob, 'Generated blob' ); + + // Now, imagine a change to the module is deployed. The module now contains + // message 'foo' and 'bar'. While updateMessage() was not called (since no + // message values were changed) it should detect the change in list of + // message keys. + $module = $this->makeModule( [ 'foo', 'bar' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->exactly( 2 ) ) + ->method( 'fetchMessage' ) + ->will( $this->returnValueMap( [ + [ 'foo', 'en', 'Hello' ], + [ 'bar', 'en', 'World' ], + ] ) ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"foo":"Hello","bar":"World"}', $blob, 'Updated blob' ); + } + + public function testClear() { + $module = $this->makeModule( [ 'example' ] ); + $rl = new ResourceLoader(); + $rl->register( $module->getName(), $module ); + $blobStore = $this->makeBlobStore( [ 'fetchMessage' ], $rl ); + $blobStore->expects( $this->exactly( 2 ) ) + ->method( 'fetchMessage' ) + ->will( $this->onConsecutiveCalls( 'First', 'Second' ) ); + + $now = microtime( true ); + $this->wanCache->setMockTime( $now ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"First"}', $blob, 'Generated blob' ); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"First"}', $blob, 'Cache-hit' ); + + $now += 1; + $blobStore->clear(); + + $blob = $blobStore->getBlob( $module, 'en' ); + $this->assertEquals( '{"example":"Second"}', $blob, 'Updated blob' ); + } +} |