wiki.techinc.nl/tests/phpunit/integration/includes/TemplateParserIntegrationTest.php
Sam Smith d4be8b9c08 TemplateParser: Include template dir in cache key
Template names aren't expected to be globally unique. Template paths are
by construction.

Include the template directory in the cache key in order to avoid the
cache keys of ambiguosly-named templates - e.g. index.mustache -
overriding one another.

Bug: T113095
Bug: T248010
Change-Id: I3196967ec2a7a5cec409a0c7ce4471a7d8773978
2020-03-18 21:57:34 +00:00

133 lines
3.1 KiB
PHP

<?php
use LightnCandy\LightnCandy;
use Wikimedia\TestingAccessWrapper;
/**
* @group Templates
* @coversDefaultClass TemplateParser
*/
class TemplateParserIntegrationTest extends MediaWikiIntegrationTestCase {
private const TEMPLATE_NAME = 'foobar';
private $secretKey;
private $cache;
private $templateDir;
private $templateParser;
private function makeKey() : string {
return $this->cache->makeKey(
'lightncandy-compiled',
// See TemplateParser::$cacheVersion
'2.2.0',
// See TemplateParser::__construct and TemplateParser::$compileFlags
LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy::FLAG_MUSTACHELOOKUP,
$this->templateDir,
self::TEMPLATE_NAME
);
}
private function getTemplate() {
//
// NOTE: Deliberately destroy the per-instance cache every time we render a template in
// order to test interactions with the server-local cache.
$templateParser = TestingAccessWrapper::newFromObject(
new TemplateParser( $this->templateDir )
);
return $templateParser->getTemplate( self::TEMPLATE_NAME );
}
// Tests
// =====
protected function setUp() : void {
parent::setUp();
// Data
$this->secretKey = 'foo';
$this->setMwGlobals( [
'wgSecretKey' => $this->secretKey,
] );
$this->templateDir = __DIR__ . '/../../data/templates';
// Stubs
$this->cache = ObjectCache::getLocalServerInstance( CACHE_ANYTHING );
}
/**
* @covers ::getTemplate
*/
public function testGetTemplateCachesCompilationResult() {
$this->getTemplate();
$value = $this->cache->get( $this->makeKey() );
$this->assertIsArray( $value );
$this->assertArrayHasKey( 'phpCode', $value );
$this->assertArrayHasKey( 'files', $value );
$this->assertArrayHasKey( 'filesHash', $value );
// ---
$this->assertEquals(
hash_hmac( 'sha256', $value['phpCode'], $this->secretKey ),
$value['integrityHash'],
'::getTemplate adds an integrity hash to the compiled template before caching it.'
);
}
/**
* @covers ::getTemplate
*/
public function testGetTemplateInvalidatesCacheWhenFilesHashIsInvalid() {
$key = $this->makeKey();
$this->cache->set( $key, [
'phpCode' => 'foo',
'files' => [ 'bar' ],
'filesHash' => 'baz',
] );
$this->getTemplate();
$expectedFiles = [ $this->templateDir . '/' . self::TEMPLATE_NAME . '.mustache' ];
$expectedFilesHash = FileContentsHasher::getFileContentsHash( $expectedFiles );
$value = $this->cache->get( $this->makeKey() );
$this->assertNotEquals( 'foo', $value['phpCode'] );
$this->assertEquals( $expectedFiles, $value['files'] );
$this->assertEquals(
$expectedFilesHash,
$value['filesHash'],
'The cached compiled template was invalidated.'
);
}
/**
* @covers ::getTemplate
*/
public function testGetTemplateInvalidatesCacheWhenIntegrityHashIsInvalid() {
$this->getTemplate();
$key = $this->makeKey();
$value = $this->cache->get( $key );
$value['integrityHash'] = 'foo';
$this->cache->set( $key, $value );
$this->getTemplate();
$newValue = $this->cache->get( $key );
$this->assertNotEquals(
$newValue['integrityHash'],
$value['integrityHash'],
'The cached compiled template was invalidated.'
);
}
}