// /** * Created by PhpStorm. * User: Eric * Date: 30/10/2017 * Time: 13:43 */ namespace Combodo\iTop\Test\UnitTest\Core; use Combodo\iTop\Test\UnitTest\ItopTestCase; use Dict; class dictApcuTest extends ItopTestCase { private $sEnvName; private $oApcService; private $sDictionaryFolder; protected function setUp(): void { parent::setUp(); $this->RequireOnceItopFile('core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php'); // This id will be used as path to the dictionary files // It must be unique enough for the magic of Dict to operate (due to the use of require_once to load dictionaries) $this->sEnvName = uniqid(); $_SESSION['itop_env'] = $this->sEnvName; // Preserve the dictionary for test that will be executed later on static::BackupStaticProperties('Dict'); // Reset and prepare the dictionary static::SetNonPublicStaticProperty('Dict', 'm_aData', []); $this->oApcService = $this->createMock(\ApcService::class); Dict::SetApcService($this->oApcService); Dict::EnableCache('toto'); Dict::SetLanguagesList(['FR FR' => 'fr', 'EN US' => 'en', 'DE DE' => 'de', 'RU RU' => 'de']); $this->InitDictionnaries(); } private function InitDictionnaries() { clearstatcache(); $this->sDictionaryFolder = APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries"; @mkdir($this->sDictionaryFolder, 0777, true); $sLabels = << 'fr1', STR; $this->InitDictionnary($this->sDictionaryFolder, 'FR FR', 'fr-fr', $sLabels); $sLabels = << 'ru1', 'label2' => 'ru2', STR; $this->InitDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru', $sLabels); $sLabels = << 'en1', 'label2' => 'en2', 'label3' => 'en3', STR; $this->InitDictionnary($this->sDictionaryFolder, 'EN US', 'en-us', $sLabels); clearstatcache(); } private function InitDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename, $sLabels) { $sContent = <<sEnvName".DIRECTORY_SEPARATOR."dictionaries".DIRECTORY_SEPARATOR."*") as $sFile) { unlink($sFile); } rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries"); rmdir(APPROOT."env-$this->sEnvName"); static::RestoreStaticProperties('Dict'); parent::tearDown(); } public function InitLangIfNeeded_NoApcProvider() { return [ 'apcu mocked' => [ 'bApcuMocked' => true ], 'integration test - apcu service like in production - install php-apcu before' => [ 'bApcuMocked' => false ], ]; } /** * @dataProvider InitLangIfNeeded_NoApcProvider */ public function testInitLangIfNeeded_NoApc($bApcuMocked) { if ($bApcuMocked) { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(false); $this->oApcService->expects($this->never()) ->method('apc_fetch'); $this->oApcService->expects($this->never()) ->method('apc_store'); } else { Dict::SetApcService(null); } //EN US default language $this->assertEquals('en1', Dict::S('label1')); $this->assertEquals('en2', Dict::S('label2')); $this->assertEquals('en3', Dict::S('label3')); $this->assertEquals('not_defined_label', Dict::S('not_defined_label')); //default language set to RU RU Dict::SetDefaultLanguage('RU RU'); $this->assertEquals('ru1', Dict::S('label1')); $this->assertEquals('ru2', Dict::S('label2')); $this->assertEquals('en3', Dict::S('label3')); $this->assertEquals('not_defined_label', Dict::S('not_defined_label')); //user language set to FR FR Dict::SetUserLanguage('FR FR'); $this->assertEquals('fr1', Dict::S('label1')); $this->assertEquals('ru2', Dict::S('label2')); $this->assertEquals('en3', Dict::S('label3')); $this->assertEquals('not_defined_label', Dict::S('not_defined_label')); } public function testInitLangIfNeeded_Apc_LanguageMismatchDictionnary() { //language mismatch!! $sLabels = << 'de1', STR; $this->InitDictionnary($this->sDictionaryFolder, 'RU RU', 'de-de', $sLabels); clearstatcache(); $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(false); $this->oApcService->expects($this->exactly(0)) ->method('apc_fetch'); $this->oApcService->expects($this->never()) ->method('apc_store'); Dict::SetUserLanguage('DE DE'); $this->assertEquals('label1', Dict::S('label1')); } public function testInitLangIfNeeded_Apc_BrokenUserDictionnary() { $this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de'); $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(false); $this->oApcService->expects($this->exactly(0)) ->method('apc_fetch'); $this->oApcService->expects($this->never()) ->method('apc_store'); Dict::SetUserLanguage('DE DE'); $this->assertEquals('en1', Dict::S('label1')); Dict::SetDefaultLanguage('RU RU'); $this->assertEquals('ru1', Dict::S('label1')); } public function testInitLangIfNeeded_Apc_BrokenDictionnary_UserAndDefault() { $this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de'); $this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru'); $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(false); $this->oApcService->expects($this->exactly(0)) ->method('apc_fetch'); $this->oApcService->expects($this->never()) ->method('apc_store'); Dict::SetUserLanguage('DE DE'); Dict::SetDefaultLanguage('RU RU'); $this->assertEquals('en1', Dict::S('label1')); } public function testInitLangIfNeeded_Apc_BrokenDictionnary_ALL() { $this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de'); $this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru'); $this->InitBrokenDictionnary($this->sDictionaryFolder, 'EN US', 'en-us'); $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(false); $this->oApcService->expects($this->exactly(0)) ->method('apc_fetch'); $this->oApcService->expects($this->never()) ->method('apc_store'); Dict::SetUserLanguage('DE DE'); Dict::SetDefaultLanguage('RU RU'); $this->assertEquals('label1', Dict::S('label1')); } public function testInitLangIfNeeded_ApcFromCache_PropertyInUserDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(1)) ->method('apc_fetch') ->with('toto-dict-FR FR') ->willReturn(['label1' => 'fr1']); $this->oApcService->expects($this->exactly(0)) ->method('apc_store'); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('fr1', Dict::S('label1')); } public function testInitLangIfNeeded_ApcStore_PropertyInUserDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(1)) ->method('apc_fetch') ->with('toto-dict-FR FR') ->willReturn(false); $this->oApcService->expects($this->exactly(1)) ->method('apc_store') ->with('toto-dict-FR FR', ['label1' => 'fr1']); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('fr1', Dict::S('label1')); } //corrupted data not fixed //we will return label from another dictionary (defaut one => russian here) public function testInitLangIfNeeded_Apc_CorruptedCache_PropertyInUserDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(2)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU']) ->willReturnOnConsecutiveCalls('corrupteddata', ['label1' => 'ru1']); $this->oApcService->expects($this->exactly(0)) ->method('apc_store'); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('ru1', Dict::S('label1')); } public function testInitLangIfNeeded_Apc_PropertyInDefaultLanguageDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(2)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU']) ->willReturnOnConsecutiveCalls([], false); $this->oApcService->expects($this->exactly(1)) ->method('apc_store') ->withConsecutive( ['toto-dict-RU RU', ['label1' => 'ru1', 'label2' => 'ru2']] ); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('ru2', Dict::S('label2')); } //corrupted data not fixed //we will return label from default language dictionary (EN here) public function testInitLangIfNeeded_ApcCorrupted_PropertyInDefaultLanguageDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(3)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US']) ->willReturnOnConsecutiveCalls([], 'corrupteddata', ['label1' => 'en1', 'label2' => 'en2', 'label3' => 'en3']); $this->oApcService->expects($this->exactly(0)) ->method('apc_store'); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('en2', Dict::S('label2')); } public function testInitLangIfNeeded_Apc_PropertyInDictDefaultLanguageDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(3)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US']) ->willReturnOnConsecutiveCalls([], [], false); $this->oApcService->expects($this->exactly(1)) ->method('apc_store') ->withConsecutive( ['toto-dict-EN US', ['label1' => 'en1', 'label2' => 'en2', 'label3' => 'en3']] ); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('en3', Dict::S('label3')); } public function testInitLangIfNeeded_ApcCorrupted_PropertyInDictDefaultLanguageDictionnary() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(3)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US']) ->willReturnOnConsecutiveCalls([], [], 'corrupteddata'); $this->oApcService->expects($this->exactly(0)) ->method('apc_store'); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('label3', Dict::S('label3')); } public function testInitLangIfNeeded_Apc_PropertyNotFound() { $this->oApcService->expects($this->any()) ->method('function_exists') ->willReturn(true); $this->oApcService->expects($this->exactly(3)) ->method('apc_fetch') ->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US']) ->willReturnOnConsecutiveCalls([], [], []); $this->oApcService->expects($this->exactly(0)) ->method('apc_store'); Dict::SetDefaultLanguage('RU RU'); Dict::SetUserLanguage('FR FR'); $this->assertEquals('undefined_label', Dict::S('undefined_label')); } }