tests/App/TextParser.php
<?php
/**
* TextParser test file.
*
* @package Tests
*
* @copyright YetiForce S.A.
* @license YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
* @author Sławomir Kłos <s.klos@yetiforce.com>
* @author Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
*/
namespace Tests\App;
/**
* TextParser test class.
*/
class TextParser extends \Tests\Base
{
/**
* Test record instance.
*
* @var \App\TextParser
*/
private static $parserRecord;
/**
* Test clean instance.
*
* @var \App\TextParser
*/
private static $parserClean;
/**
* Test clean instance with module.
*
* @var \App\TextParser
*/
private static $parserCleanModule;
/** @var \Vtiger_Record_Model Temporary Leads record object. */
protected static $recordLeads;
/** @var \Vtiger_Record_Model Temporary Products record object. */
private static $product;
/**
* Testing instances creation.
*/
public function testInstancesCreation()
{
self::$parserClean = \App\TextParser::getInstance();
$this->assertInstanceOf('\App\TextParser', self::$parserClean, 'Expected clean instance without module of \App\TextParser');
self::$parserCleanModule = \App\TextParser::getInstance('Leads');
$this->assertInstanceOf('\App\TextParser', self::$parserCleanModule, 'Expected clean instance with module Leads of \App\TextParser');
self::$recordLeads = $recordModel = \Tests\Base\C_RecordActions::createLeadRecord(false);
$this->assertInstanceOf('\App\TextParser', \App\TextParser::getInstanceById($recordModel->getId(), 'Leads'), 'Expected instance from lead id and module string of \App\TextParser');
self::$parserRecord = \App\TextParser::getInstanceByModel($recordModel);
$this->assertInstanceOf('\App\TextParser', self::$parserRecord, 'Expected instance from record model of \App\TextParser');
}
/**
* Tests empty content condition.
*/
public function testEmptyContent()
{
$this->assertSame('', self::$parserClean
->setContent('')
->parse()
->getContent(), 'Clean instance: empty content should return empty result');
}
/**
* Tests base variables list.
*/
public function testGetBaseListVariable()
{
$arr = self::$parserClean->getBaseListVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any related list data');
foreach ($arr as $option) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($option['key']), 'Option: ' . $option['label'] . ', value: ' . $option['key'] . ' should be parseable');
}
}
/**
* Tests related module variables list.
*/
public function testGetRelatedListVariable()
{
$arr = self::$parserCleanModule->getRelatedListVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any related list data');
foreach ($arr as $option) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($option['key']), 'Option: ' . $option['label'] . ', value: ' . $option['key'] . ' should be parseable');
}
}
/**
* Tests static methods.
*/
public function testStaticMethods()
{
$this->assertSame(1, \App\TextParser::isVaribleToParse('$(TestGroup : TestVar)$'), 'string should be parseable');
$this->assertSame(0, \App\TextParser::isVaribleToParse('$X(TestGroup : TestVar)$'), 'string should be not parseable');
}
/**
* Tests empty content condition.
*/
public function testUnregisteredFunction()
{
$this->assertSame('+ +', self::$parserClean
->setContent('+ $(notExist : CurrentTime)$ +')
->parse()
->getContent(), 'Clean instance: unregistered function placeholder should return empty string');
}
/**
* Tests general placeholders replacement.
*/
public function testGeneral()
{
$this->assertSame('+ ' . (new \DateTimeField(null))->getDisplayDate() . ' +', self::$parserClean
->setContent('+ $(general : CurrentDate)$ +')
->parse()
->getContent(), 'Clean instance: $(general : CurrentDate)$ should return current date');
$this->assertSame('+ ' . \Vtiger_Util_Helper::convertTimeIntoUsersDisplayFormat(date('H:i:s')) . ' +', self::$parserClean
->setContent('+ $(general : CurrentTime)$ +')
->parse()
->getContent(), 'Clean instance: $(general : CurrentTime)$ should return current time');
$this->assertSame(
'+ ' . (empty($defaultTimeZone = date_default_timezone_get()) ? \App\Config::main('default_timezone') : $defaultTimeZone) . ' +',
self::$parserClean->setContent('+ $(general : BaseTimeZone)$ +')->parse()->getContent(),
'Clean instance: $(general : BaseTimeZone)$ should return system timezone');
$user = \App\User::getCurrentUserModel();
$this->assertSame(
'+ ' . ($user->getDetail('time_zone') ?: \App\Config::main('default_timezone')) . ' +',
self::$parserClean->setContent('+ $(general : UserTimeZone)$ +')->parse()->getContent(),
'Clean instance: $(general : UserTimeZone)$ should return user timezone'
);
$this->assertSame('+ ' . \App\Config::main('site_URL') . ' +', self::$parserClean
->setContent('+ $(general : SiteUrl)$ +')
->parse()
->getContent(), 'Clean instance: $(general : SiteUrl)$ should return site url');
$this->assertSame('+ ' . \App\Config::main('PORTAL_URL') . ' +', self::$parserClean
->setContent('+ $(general : PortalUrl)$ +')
->parse()
->getContent(), 'Clean instance: $(general : PortalUrl)$ should return portal url');
$this->assertSame('+ PlaceholderNotExist +', self::$parserClean
->setContent('+ $(general : PlaceholderNotExist)$ +')
->parse()
->getContent(), 'Clean instance: $(general : PlaceholderNotExist)$ should return placeholder var name');
}
/**
* Tests date placeholders replacement.
*/
public function testDate()
{
$this->assertSame('+ ' . \date('Y-m-d') . ' +', self::$parserClean
->setContent('+ $(date : now)$ +')
->parse()
->getContent(), 'Clean instance: $(date : now)$ should return current date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('+1 day')) . ' +', self::$parserClean
->setContent('+ $(date : tomorrow)$ +')
->parse()
->getContent(), 'Clean instance: $(date : tomorrow)$ should return tommorow date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('-1 day')) . ' +', self::$parserClean
->setContent('+ $(date : yesterday)$ +')
->parse()
->getContent(), 'Clean instance: $(date : yesterday)$ should return yesterday date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('monday this week')) . ' +', self::$parserClean
->setContent('+ $(date : monday this week)$ +')
->parse()
->getContent(), 'Clean instance: $(date : monday this week)$ should return this week monday date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('monday next week')) . ' +', self::$parserClean
->setContent('+ $(date : monday next week)$ +')
->parse()
->getContent(), 'Clean instance: $(date : monday next week)$ should return next week monday date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('first day of this month')) . ' +', self::$parserClean
->setContent('+ $(date : first day of this month)$ +')
->parse()
->getContent(), 'Clean instance: $(date : first day of this month)$ should return this month first day date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('last day of this month')) . ' +', self::$parserClean
->setContent('+ $(date : last day of this month)$ +')
->parse()
->getContent(), 'Clean instance: $(date : last day of this month)$ should return this month last day date');
$this->assertSame('+ ' . \date('Y-m-d', \strtotime('first day of next month')) . ' +', self::$parserClean
->setContent('+ $(date : first day of next month)$ +')
->parse()
->getContent(), 'Clean instance: $(date : first day of next month)$ should return next month first day date');
}
/**
* Testing params functions.
*/
public function testParams()
{
self::$parserClean->setParams(['test_var' => 'test']);
$text = '+ $(params : test_var)$ +';
$this->assertSame('+ test +', self::$parserClean
->setContent($text)
->parse()
->getContent(), 'Clean instance: Test params placeholder should return value test');
$text = '+ $(params : test_var_not_exist)$ +';
$this->assertSame('+ +', self::$parserClean
->setContent($text)
->parse()
->getContent(), 'Clean instance: Test param not exist, placeholder should return empty value');
$this->assertSame('test', self::$parserClean->getParam('test_var'), 'Clean instance: getParam should return value test');
$this->assertNull(self::$parserClean->getParam('test_var_not_exist'), 'Clean instance: key not exist, getParam should return false');
}
/**
* Testing basic field placeholder replacement.
*/
public function testBasicField()
{
$tmpUser = \App\User::getCurrentUserId();
\App\User::setCurrentUserId((new \App\Db\Query())->select(['id'])->from('vtiger_users')->where(['status' => 'Active'])->andWhere(['not in', 'id', (new \App\Db\Query())->select(['smownerid'])->from('vtiger_crmentity')->where(['deleted' => 0, 'setype' => 'OSSEmployees'])
->column(), ])
->scalar());
$text = '+ $(employee : last_name)$ +';
$this->assertSame('+ +', self::$parserClean
->setContent($text)
->parse()
->getContent(), 'Clean instance: By default employee last name should be empty');
$this->assertSame('+ +', self::$parserClean
->setContent($text)
->parse()
->getContent(), 'Clean instance: By default employee last name should be empty(cached)');
$this->assertSame('+ +', self::$parserRecord
->setContent($text)
->parse()
->getContent(), 'Record instance: By default employee last name should be empty');
\App\User::setCurrentUserId($tmpUser);
\App\Cache::clear();
}
/**
* Testing Employee placeholders.
*/
public function testEmployee()
{
$currentUser = \App\User::getCurrentUserId();
$userName = 'Employee';
$userExistsId = (new \App\Db\Query())->select(['id'])->from('vtiger_users')->where(['user_name' => $userName])
->scalar();
$employeeUser = $userExistsId ? \Vtiger_Record_Model::getInstanceById($userExistsId, 'Users') : \Vtiger_Record_Model::getCleanInstance('Users');
$employeeUser->set('user_name', $userName);
$employeeUser->set('email1', $userName . '@yetiforce.com');
$employeeUser->set('first_name', $userName);
$employeeUser->set('last_name', 'YetiForce');
$employeeUser->set('user_password', \Tests\Base\A_User::$defaultPassrowd);
$employeeUser->set('confirm_password', \Tests\Base\A_User::$defaultPassrowd);
$employeeUser->set('roleid', 'H2');
$employeeUser->set('is_admin', 'on');
$employeeUser->save();
$this->assertNotEmpty($employeeUser->getId(), 'New user id should be not empty');
\App\User::setCurrentUserId($employeeUser->getId());
$employeeExistsId = (new \App\Db\Query())
->select(['crmid'])
->from('vtiger_crmentity')->where(['deleted' => 0, 'setype' => 'OSSEmployees', 'smownerid' => $employeeUser->getId()])
->limit(1)
->scalar();
$employeeModel = $employeeExistsId ? \Vtiger_Record_Model::getInstanceById($employeeExistsId, 'OSSEmployees') : \Vtiger_Record_Model::getCleanInstance('OSSEmployees');
$employeeModel->set('assigned_user_id', $employeeUser->getId());
$employeeModel->set('name', 'Test employee');
$employeeModel->save();
\App\Cache::clear();
$text = '+ $(employee : name)$ +';
$this->assertSame(
'+ ' . \Vtiger_Record_Model::getInstanceById($employeeModel->getId(), 'OSSEmployees')->get('name') . ' +',
\App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(),
'Clean instance: Employee name should be same as in db'
);
$this->assertSame(
'+ ' . \Vtiger_Record_Model::getInstanceById($employeeModel->getId(), 'OSSEmployees')->get('name') . ' +',
\App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(),
'Clean instance: Employee name should be same as in db(cached)'
);
\App\User::setCurrentUserId($currentUser);
}
/**
* Testing records list placeholders replacement.
*/
public function testRecordsListPlaceholders()
{
$text = '$(recordsList : Leads|lead_no,company,email,description|[[["company","a","Test"]]]|All|5)$';
$result = \App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent();
$this->assertNotEmpty($result, 'recordsList should return not empty string');
$this->assertNotFalse(strpos($result, 'records-list'), 'Record list should contain html class recordsList');
$this->assertSame(4, \substr_count($result, '<th '), 'Columns count should be equal to provided list');
$text = '$(recordsList : Leads|lead_no,lastname,phone,description|[[["company","a","Test"]]]|NotExist|5)$';
$result = \App\TextParser::getInstance()->withoutTranslations(true)
->setContent($text)
->parse()
->getContent();
$this->assertNotEmpty($result, 'recordsList should return not empty string(CustomView not exists)');
}
/**
* Testing related records list placeholders replacement.
*/
public function testRelatedRecordsList()
{
$text = '$(relatedRecordsList : Accounts|lead_no,lastname,phone,description|[[["company","a","Test"]]]|All|5)$';
$result = \App\TextParser::getInstanceByModel(self::$recordLeads)
->setContent($text)
->parse()
->getContent();
$this->assertEmpty($result, 'relatedRecordsList should return empty string if no related records found');
$text = '$(relatedRecordsList : Leads|lead_no,lastname,phone,description|[[["company","a","Test"]]]|NotExist|5)$';
$result = \App\TextParser::getInstanceByModel(self::$recordLeads)->withoutTranslations(true)
->setContent($text)
->parse()
->getContent();
$this->assertEmpty($result, 'relatedRecordsList should return empty string if no related records found(CustomView not exists)');
$accountModel = \Tests\Base\C_RecordActions::createAccountRecord();
$contactModel = \Tests\Base\C_RecordActions::createContactRecord();
$contactModel->set('parent_id', $accountModel->getId());
$contactModel->save();
$text = '$(relatedRecordsList : Contacts|firstname,decision_maker,createdtime,contactstatus,verification|[[["firstname","a","Test"]]]|All|5)$';
$result = \App\TextParser::getInstanceByModel($accountModel)->withoutTranslations(true)
->setContent($text)
->parse()
->getContent();
$this->assertNotEmpty($result, 'relatedRecordsList should return not empty string if related records found');
$this->assertNotFalse(\strpos($result, $contactModel->get('firstname')), 'relatedRecordsList should contain test record row');
$text = '$(relatedRecordsList : Contacts|firstname,decision_maker,createdtime,contactstatus,verification|[[["firstname","a","Test"]]]|NotExists|5)$';
$result = \App\TextParser::getInstanceByModel(\Tests\Base\C_RecordActions::createAccountRecord())->withoutTranslations(true)
->setContent($text)
->parse()
->getContent();
$this->assertNotEmpty($result, 'relatedRecordsList should return not empty string if related records found');
$this->assertNotFalse(\strpos($result, $contactModel->get('firstname')), 'relatedRecordsList should contain test record row');
}
/**
* Testing custom placeholders.
*/
public function testCustomPlaceholders()
{
$text = '+ $(custom : NotExists)$ +';
$this->assertSame('+ +', \App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(), 'custom function with not existent parser should return empty string');
$text = '+ $(custom : NotExists|NotExists)$ +';
$this->assertSame('+ +', \App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(), 'custom function with not existent parser should return empty string');
$text = '+ $(custom : TableTaxSummary)$ +';
$this->assertSame('+ +', \App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(), 'custom function with TableTaxSummary parser should return empty string');
$text = '+ $(custom : NotExists|Leads)$ +';
$this->assertSame('+ +', \App\TextParser::getInstance()
->setContent($text)
->parse()
->getContent(), 'custom function with not existent Leads module parser should return empty string');
}
/**
* Testing record vars placeholders replacement.
*/
public function testRecord()
{
$text = '+ $(record : NotExists)$ +';
$this->assertSame('+ +', self::$parserClean->setContent($text)->parse()->getContent(), 'Expected empty string');
$text = '+ $(record : CrmDetailViewURL)$ +';
$this->assertSame('+ ' . \App\Config::main('site_URL') . 'index.php?module=Leads&view=Detail&record=' . self::$recordLeads->getId() . ' +',
self::$parserRecord->setContent($text)->parse()->getContent(), 'Expected url is different');
$text = '+ $(record : PortalDetailViewURL)$ +';
$this->assertSame('+ ' . \App\Config::main('PORTAL_URL') . '/index.php?module=Leads&action=index&id=' . self::$recordLeads->getId() . ' +',
self::$parserRecord->setContent($text)->parse()->getContent(), 'Expected url is different');
$text = '+ $(record : ModuleName)$ +';
$this->assertSame('+ Leads +', self::$parserRecord->setContent($text)->parse()->getContent(), 'Expected module name is different');
$text = '+ $(record : RecordId)$ +';
$this->assertSame('+ ' . self::$recordLeads->getId() . ' +', self::$parserRecord->setContent($text)->parse()->getContent(), 'Expected record id is different');
$text = '+ $(record : RecordLabel)$ +';
$this->assertSame('+ ' . self::$recordLeads->getName() . ' +', self::$parserRecord->setContent($text)->parse()->getContent(), 'Expected record label is different');
$text = '+ $(record : ChangesListChanges)$ +';
$this->assertSame('+ +', self::$parserRecord->setContent($text)->parse()->getContent());
self::$parserRecord->withoutTranslations(true);
$text = '+ $(record : ChangesListChanges)$ +';
$this->assertSame('+ +', self::$parserRecord->setContent($text)->parse()->getContent());
self::$parserRecord->withoutTranslations(false);
self::$parserRecord->recordModel->set('email', 'test3@yetiforce.com')->save();
$text = '$(record : ChangesListValues)$';
$this->assertSame('Mail podstawowy: test3@yetiforce.com<br>', self::$parserRecord->setContent($text)->parse()->getContent());
self::$parserRecord->withoutTranslations(true);
$text = '+ $(record : ChangesListValues)$ +';
$this->assertSame('+ $(translate : Leads|Email)$: test3@yetiforce.com<br> +', self::$parserRecord->setContent($text)->parse()->getContent());
self::$parserRecord->withoutTranslations(false);
self::$recordLeads->set('vat_id', 'test');
self::$recordLeads->save();
self::$recordLeads->set('vat_id', 'testing');
self::$recordLeads->save();
$text = '+ $(record : ChangesListChanges)$ +';
$this->assertStringContainsString('test', self::$parserRecord->setContent($text)->parse()->getContent(), 'Test record changes list should should contain vat_id info');
self::$parserRecord->withoutTranslations(true);
$text = '+ $(record : ChangesListChanges)$ +';
$this->assertStringContainsString('test', self::$parserRecord->setContent($text)->parse()->getContent(), 'Test record changes list should should contain vat_id info');
self::$parserRecord->withoutTranslations(false);
$text = '+ $(record : ChangesListValues)$ +';
$this->assertStringContainsString('testing', self::$parserRecord->setContent($text)->parse()->getContent(), 'Test record changes list values should be not empty');
$text = '+ $(record : company)$ +';
$this->assertSame('+ ' . self::$recordLeads->get('company') . ' +', self::$parserRecord->setContent($text)->parse()->getContent(), 'Test record company should be same as in db');
$text = '+ $(record : Comments 5|true)$ +';
$comment = \Vtiger_Record_Model::getCleanInstance('ModComments');
$comment->set('commentcontent', 'TestComment');
$comment->set('related_to', self::$recordLeads->getId());
$comment->save();
$this->assertSame('+ TestComment +', self::$parserRecord->setContent($text)
->parse()
->getContent(), 'Test record comments list should be empty');
$text = '+ $(record : FieldNotExists)$ +';
$this->assertSame('+ +', self::$parserRecord->setContent($text)
->parse()
->getContent(), 'Test function record when field not exists should return empty string');
}
/**
* Testing basic translate function.
*/
public function testTranslate()
{
$this->assertSame(
'+$(general : CurrentDate)$ | ' . \App\Language::translate('LBL_SECONDS') . '==' . \App\Language::translate('LBL_COPY_BILLING_ADDRESS', 'Accounts') . '+',
self::$parserClean->setContent('+$(general : CurrentDate)$ | $(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parseTranslations()->getContent(),
'Clean instance: Only translations should be replaced');
$this->assertSame(
'+$(general : CurrentDate)$ | ' . \App\Language::translate('LBL_SECONDS') . '==' . \App\Language::translate('LBL_COPY_BILLING_ADDRESS', 'Accounts') . '+',
self::$parserClean->setLanguage('pl-PL')->setContent('+$(general : CurrentDate)$ | $(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parseTranslations()->getContent(),
'Clean instance: Only translations should be replaced(setLanguage)');
$this->assertSame(
'+' . \App\Language::translate('LBL_SECONDS') . '==' . \App\Language::translate('LBL_COPY_BILLING_ADDRESS', 'Accounts') . '+',
self::$parserClean->setContent('+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parse()->getContent(),
'Clean instance: Translations should be equal');
self::$parserClean->withoutTranslations(true);
$this->assertSame(
'+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+',
self::$parserClean->setContent('+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parse()->getContent(),
'Clean instance: Translations should be equal');
self::$parserClean->withoutTranslations(false);
$this->assertSame(
'+' . \App\Language::translate('LBL_SECONDS') . '==' . \App\Language::translate('LBL_COPY_BILLING_ADDRESS', 'Accounts') . '+',
self::$parserRecord->setContent('+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parse()->getContent(),
'Record instance: Translations should be equal');
self::$parserRecord->withoutTranslations(true);
$this->assertSame(
'+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+',
self::$parserRecord->setContent('+$(translate : LBL_SECONDS)$==$(translate : Accounts|LBL_COPY_BILLING_ADDRESS)$+')->parse()->getContent(),
'Record instance: Translations should be equal');
self::$parserRecord->withoutTranslations(false);
}
/**
* Tests record variables array.
*/
public function testGetRecordVariable()
{
$arr = self::$parserCleanModule->getRecordVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any related variables data');
foreach ($arr as $group => $data) {
$this->assertIsArray($data, 'Expected array type');
$this->assertNotEmpty($data, 'Expected any related variables data');
foreach ($data as $key => $element) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_value']), 'Option: ' . $element['label'] . ', value: ' . $element['var_value'] . ' should be parseable in group: ' . $group);
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_label']), 'Option: ' . $element['label'] . ', value: ' . $element['var_label'] . ' should be parseable in group: ' . $group);
}
}
$arr = self::$parserCleanModule->getRecordVariable();
$this->assertIsArray($arr, 'Expected (cached) array type');
$this->assertNotEmpty($arr, 'Expected any (cached) related variables data');
}
/**
* Tests source variables array.
*/
public function testGetSourceVariable()
{
$this->assertFalse(\App\TextParser::getInstance('Leads')->setSourceRecord(self::$recordLeads->getId())->getSourceVariable(), 'TextParser::getSourceVariable() should return false for Leads module');
$arr = \App\TextParser::getInstance('Campaigns')->setSourceRecord(self::$recordLeads->getId())->getSourceVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any related variables data');
foreach ($arr as $key => $content) {
$this->assertIsArray($content, 'Expected array type');
$this->assertNotEmpty($content, 'Expected any related variables data');
foreach ($content as $group => $data) {
$this->assertIsArray($data, 'Expected array type');
$this->assertNotEmpty($data, 'Expected any related variables data');
if (isset($data['var_value'])) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($data['var_value']), 'Option: ' . $data['label'] . ', value: ' . $data['var_value'] . ' should be parseable in group: ' . $group);
$this->assertSame(1, \App\TextParser::isVaribleToParse($data['var_label']), 'Option: ' . $data['label'] . ', value: ' . $data['var_label'] . ' should be parseable in group: ' . $group);
} else {
foreach ($data as $element) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_value']), 'Option: ' . $element['label'] . ', value: ' . $element['var_value'] . ' should be parseable in group: ' . $group);
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_label']), 'Option: ' . $element['label'] . ', value: ' . $element['var_label'] . ' should be parseable in group: ' . $group);
}
}
}
}
}
/**
* Tests related variables array.
*/
public function testGetRelatedVariable()
{
$arr = self::$parserCleanModule->getRelatedVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any related variables data');
foreach ($arr as $key => $content) {
$this->assertIsArray($content, 'Expected array type');
$this->assertNotEmpty($content, 'Expected any related variables data');
foreach ($content as $group => $data) {
$this->assertIsArray($data, 'Expected array type');
$this->assertNotEmpty($data, 'Expected any related variables data');
foreach ($data as $element) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_value']), 'Option: ' . $element['label'] . ', value: ' . $element['var_value'] . ' should be parseable in group: ' . $group);
$this->assertSame(1, \App\TextParser::isVaribleToParse($element['var_label']), 'Option: ' . $element['label'] . ', value: ' . $element['var_label'] . ' should be parseable in group: ' . $group);
}
}
}
$arr = self::$parserCleanModule->getRelatedVariable();
$this->assertIsArray($arr, 'Expected (cached) array type');
$this->assertNotEmpty($arr, 'Expected any (cached) related variables data');
}
/**
* Tests general variables array.
*/
public function testGetGeneralVariable()
{
$arr = \App\TextParser::getInstance('IStorages')->getGeneralVariable();
$this->assertIsArray($arr, 'Expected array type');
$this->assertNotEmpty($arr, 'Expected any general variables data');
foreach ($arr as $groupName => $group) {
$this->assertIsArray($group, 'Expected array type from group: ' . $groupName);
$this->assertNotEmpty($group, 'Expected any data in group: ' . $groupName);
if (!empty($group)) {
foreach ($group as $placeholder => $translation) {
if (!\strpos($placeholder, ', ')) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($placeholder), 'Option: ' . $translation . ', value: ' . $placeholder . ' should be parseable in group: ' . $groupName);
} else {
$placeholders = \explode(', ', $placeholder);
$this->assertIsArray($placeholders, 'Expected array type in group: ' . $groupName);
$this->assertNotEmpty($placeholders, 'Expected any group data in group: ' . $groupName);
foreach ($placeholders as $item) {
$this->assertSame(1, \App\TextParser::isVaribleToParse($item), 'Option: ' . $translation . ', value: ' . $item . ' should be parseable in group: ' . $groupName);
}
}
}
}
}
}
/**
* Testing basic source record related functions.
*/
public function testBasicSrcRecord()
{
$this->assertSame(
'+ +', self::$parserClean->setContent('+ $(sourceRecord : description)$ +')->parse()->getContent(),
'Clean instance: returned string should be empty if no source record provided');
$this->assertSame(
'+autogenerated test lead for \App\TextParser tests+', self::$parserClean->setContent('+$(sourceRecord : description)$+')->setSourceRecord(\Tests\Base\C_RecordActions::createLeadRecord()->getId())->parse()->getContent(),
'Clean instance: Translations should be equal');
$this->assertSame(
'+autogenerated test lead for \App\TextParser tests+',
self::$parserRecord->setContent('+$(sourceRecord : description)$+')->setSourceRecord(\Tests\Base\C_RecordActions::createLeadRecord()->getId())->parse()->getContent(),
'Record instance: Translations should be equal');
}
/**
* Testing related record placeholders.
*/
public function testRelatedRecord()
{
$this->assertNotSame('+ +', '+ ' . \App\TextParser::getInstanceByModel(\Tests\Base\C_RecordActions::createContactRecord())->setContent('+$(relatedRecord : parent_id|accountname|Accounts)$+')->parse()->getContent() . ' +', 'Account name should be not empty');
$this->assertNotSame('+ +', '+ ' . \App\TextParser::getInstanceByModel(\Tests\Base\C_RecordActions::createContactRecord())->setContent('+$(relatedRecord : parent_id|accountname)$+')->parse()->getContent() . ' +', 'Account name should be not empty(without module)');
$this->assertNotSame('+ +', '+ ' . self::$parserRecord->setContent('+$(relatedRecord : assigned_user_id|user_name|Users)$+')->parse()->getContent() . ' +', 'Lead creator user_name should be not empty');
$comment = \Vtiger_Record_Model::getCleanInstance('ModComments');
$comment->set('commentcontent', 'TestComment');
$comment->set('related_to', \Tests\Base\C_RecordActions::createLeadRecord()->getId());
$comment->save();
$this->assertNotSame('+ +', '+ ' . \App\TextParser::getInstanceById($comment->getId(), 'ModComments')->setContent('+ $(relatedRecord : related_to|company)$ +')->parse()->getContent() . ' +', 'Lead creator email should be not empty');
}
/**
* test Amount to Return.
*
* @return void
*/
public function testAmountToReturn(): void
{
$invoiceModel = \Vtiger_Record_Model::getCleanInstance('FInvoice');
$invoiceModel->set('assigned_user_id', \App\User::getCurrentUserId());
$subject = 'FV' . date('Y/m/d');
$invoiceModel->set('subject', $subject);
$this->createProduct();
$inventory = $this->createInventory();
$invoiceModel->initInventoryData([$inventory]);
$invoiceModel->saveInventoryData();
$invoiceModel->save();
$inventory['price'] = 110;
$inventory['discount'] = 26.4;
$correctingInvoiceModel = \Vtiger_Record_Model::getCleanInstance('FCorectingInvoice');
$correctingInvoiceModel->set('assigned_user_id', \App\User::getCurrentUserId());
$correctingInvoiceModel->set('subject', $subject);
$correctingInvoiceModel->set('finvoiceid', $invoiceModel->getId());
$correctingInvoiceModel->initInventoryData([$inventory]);
$correctingInvoiceModel->save();
$this->assertSame('-14.29 zł', \App\TextParser::getInstanceByModel($correctingInvoiceModel)->setContent('$(custom : AmountToReturn)$')->parse()->getContent());
$invoiceModel->delete();
$correctingInvoiceModel->delete();
}
/**
* Create Inventory for Amount to return test.
*
* @return array
*/
private function createInventory(): array
{
$inventory = [];
$inventory['currency'] = \Vtiger_Util_Helper::getBaseCurrency()['id'];
$inventory['discountmode'] = 1;
$inventory['discountparam'] = json_encode([
'aggregationType' => 'individual',
'individualDiscount' => 24,
'individualDiscountType' => 'percentage',
]);
$inventory['taxmode'] = 0;
$inventory['name'] = self::$product->getId();
$inventory['unit'] = 'Hours';
$inventory['qty'] = 1;
$inventory['price'] = 100;
$inventory['discount'] = 24;
$inventory['taxparam'] = json_encode([
'aggregationType' => 'individual',
'individualTax' => 88,
'globalTax' => 0,
]);
$inventory['comment1'] = 'test';
return $inventory;
}
/**
* Crete Products record.
*
* @return void
*/
private function createProduct(): void
{
self::$product = \Vtiger_Record_Model::getCleanInstance('Products');
self::$product->set('productname', 'Test');
self::$product->save();
}
/**
* Cleaning after tests.
*
* @return void
*/
public static function tearDownAfterClass(): void
{
self::$product->delete();
}
}