2014-03-11 23:39:26 +01:00
< ? php
/* Copyright ( C ) 2013 Laurent Destailleur < eldy @ users . sourceforge . net >
2023-05-07 14:31:35 +02:00
* Copyright ( C ) 2023 Alexandre Janniaux < alexandre . janniaux @ gmail . com >
2025-01-30 17:53:56 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2024-11-14 00:16:43 +01:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2014-03-11 23:39:26 +01:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2014-03-11 23:39:26 +01:00
*/
/**
* \file test / phpunit / LangTest . php
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI : phpunit filename . php
*/
2025-01-28 13:55:25 +01:00
global $conf , $user , $langs , $db ;
2014-03-11 23:39:26 +01:00
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
2014-05-01 19:57:53 +02:00
//require_once 'PHPUnit/Autoload.php';
2014-03-11 23:39:26 +01:00
require_once dirname ( __FILE__ ) . '/../../htdocs/master.inc.php' ;
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security.lib.php' ;
require_once dirname ( __FILE__ ) . '/../../htdocs/core/lib/security2.lib.php' ;
2024-02-16 23:26:32 +01:00
require_once dirname ( __FILE__ ) . '/CommonClassTest.class.php' ;
2014-03-11 23:39:26 +01:00
2021-01-14 15:09:08 +01:00
if ( ! defined ( 'NOREQUIREUSER' )) {
define ( 'NOREQUIREUSER' , '1' );
}
if ( ! defined ( 'NOREQUIREDB' )) {
define ( 'NOREQUIREDB' , '1' );
}
if ( ! defined ( 'NOREQUIRESOC' )) {
define ( 'NOREQUIRESOC' , '1' );
}
if ( ! defined ( 'NOREQUIRETRAN' )) {
define ( 'NOREQUIRETRAN' , '1' );
}
if ( ! defined ( 'NOCSRFCHECK' )) {
define ( 'NOCSRFCHECK' , '1' );
}
if ( ! defined ( 'NOTOKENRENEWAL' )) {
define ( 'NOTOKENRENEWAL' , '1' );
}
if ( ! defined ( 'NOREQUIREMENU' )) {
define ( 'NOREQUIREMENU' , '1' ); // If there is no menu to show
}
if ( ! defined ( 'NOREQUIREHTML' )) {
define ( 'NOREQUIREHTML' , '1' ); // If we don't need to load the html.form.class.php
}
if ( ! defined ( 'NOREQUIREAJAX' )) {
define ( 'NOREQUIREAJAX' , '1' );
}
if ( ! defined ( " NOLOGIN " )) {
define ( " NOLOGIN " , '1' ); // If this page is public (can be called outside logged session)
}
if ( empty ( $user -> id )) {
2024-03-27 21:51:21 +01:00
print " Load permissions for admin user nb 1 " . PHP_EOL ;
2021-01-14 15:09:08 +01:00
$user -> fetch ( 1 );
2024-11-14 00:16:43 +01:00
$user -> loadRights ();
2014-03-11 23:39:26 +01:00
}
2024-02-19 15:28:21 +01:00
$conf -> global -> MAIN_DISABLE_ALL_MAILS = 1 ;
2014-03-11 23:39:26 +01:00
/**
* Class for PHPUnit tests
*
* @ backupGlobals disabled
* @ backupStaticAttributes enabled
* @ remarks backupGlobals must be disabled to have db , conf , user and lang not erased .
*/
2024-02-16 23:26:32 +01:00
class LangTest extends CommonClassTest
2014-03-11 23:39:26 +01:00
{
2024-03-27 21:51:21 +01:00
/**
* Data provider for testLang
*
* @ return array < string , array { 0 : string } >
*/
public function langDataProvider () : array
{
$langCodes = [];
$filesarray = scandir ( DOL_DOCUMENT_ROOT . '/langs' );
foreach ( $filesarray as $key => $code ) {
if ( ! preg_match ( '/^[a-z]+_[A-Z]+$/' , $code )) {
continue ;
}
2024-07-16 09:51:50 +02:00
if ( in_array ( $code , array ( 'mk_MK' ))) { // We exclude some language not yet ready
continue ;
}
2024-03-27 21:51:21 +01:00
$langCodes [ $code ] = [ $code ];
}
return $langCodes ;
}
2025-01-12 22:33:20 +01:00
/**
2025-01-28 13:55:25 +01:00
* testTransWithHTMLInParam
2025-01-12 22:33:20 +01:00
*
* @ return void
*/
public function testTransWithHTMLInParam () : void
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
include_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php' ;
$newlang = new Translate ( '' , $conf );
$newlang -> setDefaultLang ( 'fr_FR' );
$newlang -> load ( " admin " );
// ErrorModuleRequirePHPVersion is a string than contains accent é and <b>
// The ->transnoentities() does not escape nothing into entities.
$result = $newlang -> transnoentities ( " ModuleMustBeEnabled " , '<b>é</b><span class="red">aaa</span>' );
print " result= " . $result . PHP_EOL ;
$this -> assertEquals ( 'Le module <b><b>é</b><span class="red">aaa</span></b> doit être activé' , $result , 'Translation transnoentities ko' );
// ErrorModuleRequirePHPVersion is a string than contains accent é and <b>
// The ->trans() escapes content into ModuleMustBeEnabled except b, strong, a, i, br and span tags,
// but content of parameters are escaped
$result = $newlang -> trans ( " ModuleMustBeEnabled " , '<b>é</b><span class="red">aaa</span>' );
print " result= " . $result . PHP_EOL ;
$this -> assertEquals ( 'Le module <b><b>é</b><span class="red">aaa</span></b> doit être activé' , $result , 'Translation trans ko' );
return ;
}
2024-03-27 21:51:21 +01:00
2025-01-28 13:55:25 +01:00
/**
* testTransWithPercent
*
* @ return void
*/
public function testTransWithPercent () : void
{
global $conf , $user , $langs , $db ;
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
include_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php' ;
$newlang = new Translate ( '' , $conf );
$newlang -> setDefaultLang ( 'fr_FR' );
$newlang -> load ( " main " );
$result = $newlang -> trans ( " DatabaseConnection " );
print " result= " . $result . PHP_EOL ;
$this -> assertEquals ( 'Connexion à la base' , $result );
$result = $newlang -> transnoentities ( " FormatDateHourSecShort " );
print " result= " . $result . PHP_EOL ;
$this -> assertEquals ( '%d/%m/%Y %H:%M:%S' , $result );
$newlang = new Translate ( '' , $conf );
$newlang -> setDefaultLang ( 'en_US' );
$newlang -> load ( " main " );
$result = $newlang -> transnoentities ( " FormatDateHourText " );
print " result= " . $result . PHP_EOL ;
$this -> assertEquals ( '%B %d, %Y, %I:%M %p' , $result );
return ;
}
2024-03-27 21:51:21 +01:00
2021-01-14 15:09:08 +01:00
/**
* testLang
2024-03-27 21:51:21 +01:00
* @ dataProvider langDataProvider
2021-01-14 15:09:08 +01:00
*
2024-07-22 16:39:26 +02:00
* @ param string $code Language code for which to verify translations
* @ return void
2025-01-12 22:33:20 +01:00
* @ depends testTransWithHTMLInParam
2021-01-14 15:09:08 +01:00
*/
2024-03-27 21:51:21 +01:00
public function testLang ( $code ) : void
2021-01-14 15:09:08 +01:00
{
global $conf , $user , $langs , $db ;
2024-02-19 15:28:21 +01:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2014-03-11 23:39:26 +01:00
2021-01-14 15:09:08 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/class/translate.class.php' ;
2014-03-11 23:39:26 +01:00
2024-03-27 21:51:21 +01:00
$prefix = __METHOD__ . " ( $code ) " ;
$tmplangs = new Translate ( '' , $conf );
$langcode = $code ;
$tmplangs -> setDefaultLang ( $langcode );
$tmplangs -> load ( " main " );
2014-03-11 23:39:26 +01:00
2025-01-30 17:53:56 +01:00
print PHP_EOL . $prefix . " Check language files " . PHP_EOL ;
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> transnoentitiesnoconv ( " FONTFORPDF " );
print $prefix . " FONTFORPDF= " . $result . PHP_EOL ;
$this -> assertTrue ( in_array ( $result , array ( 'msungstdlight' , 'stsongstdlight' , 'helvetica' , 'DejaVuSans' , 'cid0jp' , 'cid0kr' , 'freemono' , 'freeserif' )), 'Error bad value ' . $result . ' for FONTFORPDF in main.lang file ' . $code );
2021-09-28 16:47:09 +02:00
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> transnoentitiesnoconv ( " DIRECTION " );
print $prefix . " DIRECTION= " . $result . PHP_EOL ;
$this -> assertTrue ( in_array ( $result , array ( 'rtl' , 'ltr' )), 'Error bad value for DIRECTION in main.lang file ' . $code );
2021-05-03 15:24:19 +02:00
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> transnoentitiesnoconv ( " SeparatorDecimal " );
print $prefix . " SeparatorDecimal= " . $result . PHP_EOL ;
$this -> assertTrue ( in_array ( $result , array ( '.' , ',' , '/' , '。' , ' ' , '' , 'None' )), 'Error on decimal separator for lang code ' . $code ); // Note that ، that is coma for RTL languages is not supported
2014-03-11 23:39:26 +01:00
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> transnoentitiesnoconv ( " SeparatorThousand " );
print $prefix . " SeparatorThousand= " . $result . PHP_EOL ;
$this -> assertTrue ( in_array ( $result , array ( '.' , ',' , '/' , ' ' , '' , '\'' , 'None' , 'Space' )), 'Error on thousand separator for lang code ' . $code ); // Note that ، that is coma for RTL languages is not supported
2014-03-11 23:39:26 +01:00
2024-03-27 21:51:21 +01:00
// Test java string contains only d,M,y,/,-,. and not m,...
$result = $tmplangs -> transnoentitiesnoconv ( " FormatDateShortJava " );
print $prefix . " FormatDateShortJava= " . $result . PHP_EOL ;
$tmpvar = preg_match ( '/^[dMy\/\-\.]+$/' , $result );
$this -> assertEquals ( 1 , $tmpvar , 'FormatDateShortJava KO for lang code ' . $code . '. Does not match /[dMy\/\-\.]+/' );
2024-02-20 14:58:46 +01:00
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> trans ( " FormatDateShortJavaInput " );
print $prefix . " FormatDateShortJavaInput= " . $result . PHP_EOL ;
$tmpvar = preg_match ( '/^[dMy\/\-\.]+$/' , $result );
$this -> assertEquals ( 1 , $tmpvar , 'FormatDateShortJavaInput KO for lang code ' . $code . '. Does not match /^[dMy\/\-\.]+$/' );
2014-03-11 23:39:26 +01:00
2024-03-27 21:51:21 +01:00
unset ( $tmplangs );
2020-05-23 22:01:17 +02:00
2025-01-30 17:53:56 +01:00
print $prefix . " Check syntax rules in the language files " . PHP_EOL ;
2024-03-27 21:51:21 +01:00
$filesarray2 = scandir ( DOL_DOCUMENT_ROOT . '/langs/' . $code );
foreach ( $filesarray2 as $key => $file ) {
if ( ! preg_match ( '/\.lang$/' , $file )) {
continue ;
}
2020-05-23 22:01:17 +02:00
2025-01-30 17:53:56 +01:00
//print $prefix.'Check lang file '.$file.PHP_EOL;
2024-03-27 21:51:21 +01:00
$filecontent = file_get_contents ( DOL_DOCUMENT_ROOT . '/langs/' . $code . '/' . $file );
2020-05-23 22:01:17 +02:00
2024-03-27 21:51:21 +01:00
$result = preg_match ( '/=--$/m' , $filecontent ); // A special % char we don't want. We want the common one.
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
$this -> assertTrue ( $result == 0 , 'Found a translation KEY=-- in file ' . $code . '/' . $file . '. We probably want Key=- instead.' );
2020-11-19 14:57:36 +01:00
2024-03-27 21:51:21 +01:00
$result = strpos ( $filecontent , '% ' ); // A special % char we don't want. We want the common one.
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
$this -> assertTrue ( $result === false , 'Found a bad percent char % instead of % in file ' . $code . '/' . $file );
2022-07-29 17:35:31 +02:00
2024-03-27 21:51:21 +01:00
$result = preg_match ( '/%n/m' , $filecontent ); // A sequence of char we don't want
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
$this -> assertTrue ( $result == 0 , 'Found a sequence %n in the translation file ' . $code . '/' . $file . '. We probably want %s' );
2022-07-29 18:16:29 +02:00
2024-03-27 21:51:21 +01:00
$result = preg_match ( '/<<<<</m' , $filecontent ); // A sequence of char we don't want
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
$this -> assertTrue ( $result == 0 , 'Found a sequence <<<<< in the translation file ' . $code . '/' . $file . '. Probably a bad merge of code were done.' );
2024-02-20 22:53:59 +01:00
2024-03-27 21:51:21 +01:00
$reg = array ();
$result = preg_match ( '/(.*)\'notranslate\'/im' , $filecontent , $reg ); // A sequence of char we don't want
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
2025-01-30 17:53:56 +01:00
$this -> assertTrue ( $result == 0 , 'Found a sequence tag \'notranslate\' in the translation file ' . $code . '/' . $file . ' in line ' . ( empty ( $reg [ 1 ]) ? '' : $reg [ 1 ]));
2024-03-27 21:51:21 +01:00
if ( ! in_array ( $code , array ( 'ar_SA' ))) {
2024-02-21 12:13:04 +01:00
$reg = array ();
2024-03-27 21:51:21 +01:00
$result = preg_match ( '/(.*)<([^a-z\/\s,=\(]1)/im' , $filecontent , $reg ); // A sequence of char we don't want
//print $prefix."Result for checking we don't have bad percent char = ".$result.PHP_EOL;
2024-09-09 16:51:26 +02:00
//$this->assertTrue($result == 0, 'Found a sequence tag <'.(empty($reg[2]) ? '' : $reg[2]).' in the translation file '.$code.'/'.$file.' in line '.empty($reg[1]) ? '' : $reg[1]);
2020-05-23 22:01:17 +02:00
}
2014-03-11 23:39:26 +01:00
}
2024-03-27 21:51:21 +01:00
}
2014-03-11 23:39:26 +01:00
2024-03-27 21:51:21 +01:00
/**
* Data provider for testTrans
*
* @ return array < string , string [] >
*/
public function transDataProvider () : array
{
return [
'en_US-1' => [
'Result of lang->trans must have original translation string with its original HTML tag, but inserted values must be fully encoded.' , // Description
" en_US " , // Langcode
" main " , // Dict
" Search criteria '<b><input autofocus onfocus='alert(1337)' <--!</b>' into fields " , // Expected
" FilterOnInto " , " <input autofocus onfocus='alert(1337)' <--! " ],
'fr-FR-1' => [
'Result of lang->trans must have original translation string with its original HTML tag, but inserted values must be fully encoded.' , // Description
" fr_FR " , // Langcode
" main " , // Dict
" Rechercher le critère '<b><input autofocus onfocus='alert(1337)' <--!</b>' dans les champs " , // Expected
" FilterOnInto " , " <input autofocus onfocus='alert(1337)' <--! " ],
];
2021-01-14 15:09:08 +01:00
}
2024-03-27 21:51:21 +01:00
2021-01-14 15:09:08 +01:00
/**
* testTrans
2024-03-27 21:51:21 +01:00
* @ dataProvider transDataProvider
*
* @ param string $description Test description
* @ param string $langcode Language code for translation
* @ param string $dict Dictionary file for translation
* @ param string $expected Expected translation result
* @ param string $key Key for translation
* @ param ? string $param1 Parameter 1 for translation
* @ param ? string $param2 Parameter 2 for translation
2021-01-14 15:09:08 +01:00
* @ return string
*/
2024-03-27 21:51:21 +01:00
public function testTrans ( $description , $langcode , $dict , $expected , $key , $param1 = null , $param2 = null )
2021-01-14 15:09:08 +01:00
{
global $conf , $user , $langs , $db ;
2024-02-19 15:28:21 +01:00
$conf = $this -> savconf ;
$user = $this -> savuser ;
$langs = $this -> savlangs ;
$db = $this -> savdb ;
2021-01-14 15:09:08 +01:00
2024-02-19 15:28:21 +01:00
$tmplangs = new Translate ( '' , $conf );
2021-01-14 15:09:08 +01:00
$tmplangs -> setDefaultLang ( $langcode );
2024-03-27 21:51:21 +01:00
$tmplangs -> load ( $dict );
2021-01-14 15:09:08 +01:00
2024-03-27 21:51:21 +01:00
$result = $tmplangs -> trans ( $key , $param1 , $param2 );
$prefix = __METHOD__ . " ( { $this -> dataName () } ) " ;
print $prefix . " result trans $key = " . $result . PHP_EOL ;
$this -> assertEquals ( $expected , $result , $description );
2021-01-14 15:09:08 +01:00
}
2014-03-11 23:39:26 +01:00
}