snapshot of https://github.com/espocrm/espocrm.git (master, 2026-09-18; blobs > 131072B omitted)
Some checks failed
Test / Test on PHP 8.3 (push) Failing after 5s
Test / Test on PHP 8.4 (push) Failing after 4s
Test / Test on PHP 8.5 (push) Failing after 3s
TypeScript static analysis / TypeScript check (push) Failing after 14s
Test Integration on MySQL / Test on PHP 8.3 (push) Failing after 2s
Test Integration on MySQL / Test on PHP 8.5 (push) Failing after 0s
Test Integration on PostgreSQL / Test on PHP 8.4 fix (push) Failing after 1s
Test Integration on PostgreSQL / Test on PHP 8.4 master (push) Failing after 1s
Some checks failed
Test / Test on PHP 8.3 (push) Failing after 5s
Test / Test on PHP 8.4 (push) Failing after 4s
Test / Test on PHP 8.5 (push) Failing after 3s
TypeScript static analysis / TypeScript check (push) Failing after 14s
Test Integration on MySQL / Test on PHP 8.3 (push) Failing after 2s
Test Integration on MySQL / Test on PHP 8.5 (push) Failing after 0s
Test Integration on PostgreSQL / Test on PHP 8.4 fix (push) Failing after 1s
Test Integration on PostgreSQL / Test on PHP 8.4 master (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Classes\FieldSanitizers;
|
||||
|
||||
use Espo\Classes\FieldSanitizers\ArrayStringTrim;
|
||||
use Espo\Core\FieldSanitize\Sanitizer\Data;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ArrayStringTrimTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param string[] $expected
|
||||
* @param string[] $input
|
||||
* @return void
|
||||
*/
|
||||
#[DataProvider('provider')]
|
||||
public function testTrim(array $expected, array $input): void
|
||||
{
|
||||
$data = new Data((object) ['test' => $input]);
|
||||
|
||||
(new ArrayStringTrim())->sanitize($data, 'test');
|
||||
|
||||
$this->assertEquals($expected, $data->get('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{string[], string[]}[]
|
||||
*/
|
||||
public static function provider(): array
|
||||
{
|
||||
return [
|
||||
[['test'], [' test ']],
|
||||
];
|
||||
}
|
||||
}
|
||||
55
tests/unit/Espo/Classes/FieldSanitizers/StringTrimTest.php
Normal file
55
tests/unit/Espo/Classes/FieldSanitizers/StringTrimTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Classes\FieldSanitizers;
|
||||
|
||||
use Espo\Classes\FieldSanitizers\StringTrim;
|
||||
use Espo\Core\FieldSanitize\Sanitizer\Data;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StringTrimTest extends TestCase
|
||||
{
|
||||
#[DataProvider('provider')]
|
||||
public function testTrim(string $expected, string $input): void
|
||||
{
|
||||
$data = new Data((object) ['test' => $input]);
|
||||
|
||||
(new StringTrim())->sanitize($data, 'test');
|
||||
|
||||
$this->assertEquals($expected, $data->get('test'));
|
||||
}
|
||||
|
||||
public static function provider(): array
|
||||
{
|
||||
return [
|
||||
['test', ' test '],
|
||||
];
|
||||
}
|
||||
}
|
||||
495
tests/unit/Espo/Commands/ConfigTest.php
Normal file
495
tests/unit/Espo/Commands/ConfigTest.php
Normal file
@@ -0,0 +1,495 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Commands;
|
||||
|
||||
use Closure;
|
||||
use Espo\Classes\ConsoleCommands\GetConfigParam;
|
||||
use Espo\Classes\ConsoleCommands\SetConfigParam;
|
||||
use Espo\Core\Console\Command\Params;
|
||||
use Espo\Core\Console\IO;
|
||||
use Espo\Core\Utils\Config;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConfigTest extends TestCase
|
||||
{
|
||||
public function testGetParamNoParam(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: [],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$this->expectIoError($io);
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamNonExistingParam(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(false);
|
||||
|
||||
$this->expectIoError($io);
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamExisting(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$config
|
||||
->method('get')
|
||||
->with('test')
|
||||
->willReturn('hello');
|
||||
|
||||
$this->expectIoNoError($io);
|
||||
$this->expectWriteLine($io, 'hello');
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamJson(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: ['json'],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$config
|
||||
->method('get')
|
||||
->with('test')
|
||||
->willReturn('hello');
|
||||
|
||||
$this->expectIoNoError($io);
|
||||
$this->expectWriteLine($io, '"hello"');
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamTrue(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$config
|
||||
->method('get')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$this->expectIoNoError($io);
|
||||
$this->expectWriteLine($io, 'true');
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamFalse(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$config
|
||||
->method('get')
|
||||
->with('test')
|
||||
->willReturn(false);
|
||||
|
||||
$this->expectIoNoError($io);
|
||||
$this->expectWriteLine($io, 'false');
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testGetParamNull(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config
|
||||
->method('has')
|
||||
->with('test')
|
||||
->willReturn(true);
|
||||
|
||||
$config
|
||||
->method('get')
|
||||
->with('test')
|
||||
->willReturn(null);
|
||||
|
||||
$this->expectIoNoError($io);
|
||||
$this->expectWriteLine($io, 'null');
|
||||
|
||||
(new GetConfigParam($config))->run($params, $io);
|
||||
}
|
||||
|
||||
private function expectIoError(IO & MockObject $io): void
|
||||
{
|
||||
$io->expects($this->once())
|
||||
->method('setExitStatus')
|
||||
->with(1);
|
||||
}
|
||||
|
||||
private function expectIoNoError(IO & MockObject $io): void
|
||||
{
|
||||
$io->expects($this->never())
|
||||
->method('setExitStatus');
|
||||
}
|
||||
|
||||
private function expectWriteLine(IO & MockObject $io, string $value): void
|
||||
{
|
||||
$io->expects($this->once())
|
||||
->method('writeLine')
|
||||
->with($value);
|
||||
}
|
||||
|
||||
public function testSetConfigNoParam(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: [],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
$configWriter = $this->createMock(Config\ConfigWriter::class);
|
||||
|
||||
$this->expectIoError($io);
|
||||
|
||||
(new SetConfigParam($config, $configWriter))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testSetConfigNoValue(): void
|
||||
{
|
||||
$params = new Params(
|
||||
options: [],
|
||||
flagList: [],
|
||||
argumentList: ['test'],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
$configWriter = $this->createMock(Config\ConfigWriter::class);
|
||||
|
||||
$this->expectIoError($io);
|
||||
|
||||
(new SetConfigParam($config, $configWriter))->run($params, $io);
|
||||
}
|
||||
|
||||
public function testSetConfigValueString1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: null,
|
||||
paramName: 'test',
|
||||
value: 'hello',
|
||||
valueExpected: 'hello',
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueString2(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'string',
|
||||
paramName: 'test',
|
||||
value: 'hello',
|
||||
valueExpected: 'hello',
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueBool1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'bool',
|
||||
paramName: 'test',
|
||||
value: '1',
|
||||
valueExpected: true,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueBool2(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'bool',
|
||||
paramName: 'test',
|
||||
value: '0',
|
||||
valueExpected: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueBool3(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'bool',
|
||||
paramName: 'test',
|
||||
value: 'true',
|
||||
valueExpected: true,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueBool4(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'bool',
|
||||
paramName: 'test',
|
||||
value: 'false',
|
||||
valueExpected: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueBoolBad(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'bool',
|
||||
paramName: 'test',
|
||||
value: 'yes',
|
||||
error: true,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueJson(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'json',
|
||||
paramName: 'test',
|
||||
value: '"true"',
|
||||
valueExpected: "true",
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueObject1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: null,
|
||||
paramName: 'database.host',
|
||||
value: 'hello',
|
||||
valueExpected: ['host' => 'hello', 'port' => 0],
|
||||
hook: function (Config & MockObject $config) {
|
||||
$config
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('database')
|
||||
->willReturn(['host' => 'localhost', 'port' => 0]);
|
||||
},
|
||||
setParamNameExpected: 'database',
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoTrue1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'true',
|
||||
valueExpected: true,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoTrue2(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'TRUE',
|
||||
valueExpected: true,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoFalse1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'false',
|
||||
valueExpected: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoNull1(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'null',
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoNull2(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'NULL',
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoInt(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: '2',
|
||||
valueExpected: 2,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoFloat(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: '2.0',
|
||||
valueExpected: 2.0,
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetConfigValueAutoString(): void
|
||||
{
|
||||
$this->internalTestSet(
|
||||
type: 'auto',
|
||||
paramName: 'test',
|
||||
value: 'value',
|
||||
valueExpected: 'value',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param (Closure(Config & MockObject): void)|null $hook
|
||||
*/
|
||||
private function internalTestSet(
|
||||
?string $type,
|
||||
string $paramName,
|
||||
string $value,
|
||||
mixed $valueExpected = null,
|
||||
bool $error = false,
|
||||
?Closure $hook = null,
|
||||
?string $setParamNameExpected = null,
|
||||
): void {
|
||||
|
||||
$options = [];
|
||||
|
||||
if ($type !== null) {
|
||||
$options = ['type' => $type];
|
||||
}
|
||||
|
||||
$params = new Params(
|
||||
options: $options,
|
||||
flagList: [],
|
||||
argumentList: [$paramName, $value],
|
||||
);
|
||||
|
||||
$io = $this->createMock(IO::class);
|
||||
$config = $this->createMock(Config::class);
|
||||
$configWriter = $this->createMock(Config\ConfigWriter::class);
|
||||
|
||||
if ($hook) {
|
||||
$hook($config);
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->expectIoNoError($io);
|
||||
|
||||
$configWriter
|
||||
->expects($this->once())
|
||||
->method('save');
|
||||
|
||||
$configWriter
|
||||
->expects($this->once())
|
||||
->method('set')
|
||||
->with($setParamNameExpected ?? $paramName, $valueExpected);
|
||||
} else {
|
||||
$this->expectIoError($io);
|
||||
}
|
||||
|
||||
(new SetConfigParam($config, $configWriter))->run($params, $io);
|
||||
}
|
||||
}
|
||||
79
tests/unit/Espo/Core/Acl/FieldDataTest.php
Normal file
79
tests/unit/Espo/Core/Acl/FieldDataTest.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\FieldData,
|
||||
Acl\Table,
|
||||
};
|
||||
|
||||
class FieldDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testGet1(): void
|
||||
{
|
||||
$raw = (object) [
|
||||
Table::ACTION_EDIT => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
];
|
||||
|
||||
$data = FieldData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getRead());
|
||||
$this->assertEquals(Table::LEVEL_YES, $data->getEdit());
|
||||
}
|
||||
|
||||
public function testGet2(): void
|
||||
{
|
||||
$raw = (object) [
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
Table::ACTION_READ => Table::LEVEL_YES,
|
||||
];
|
||||
|
||||
$data = FieldData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_YES, $data->getRead());
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getEdit());
|
||||
}
|
||||
|
||||
public function testGetEmpty(): void
|
||||
{
|
||||
$raw = (object) [
|
||||
];
|
||||
|
||||
$data = FieldData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getRead());
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getEdit());
|
||||
}
|
||||
}
|
||||
65
tests/unit/Espo/Core/Acl/Map/DefaultCacheKeyProviderTest.php
Normal file
65
tests/unit/Espo/Core/Acl/Map/DefaultCacheKeyProviderTest.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl\Map;
|
||||
|
||||
use Espo\Core\Acl\Map\DefaultCacheKeyProvider;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DefaultCacheKeyProviderTest extends TestCase
|
||||
{
|
||||
#[DataProvider('provider')]
|
||||
public function testKey(string $expected, string $userId, ?array $scopes = null): void
|
||||
{
|
||||
$user = $this->createMock(User::class);
|
||||
|
||||
$user->expects(self::any())
|
||||
->method('getId')
|
||||
->willReturn($userId);
|
||||
|
||||
$user->expects(self::any())
|
||||
->method('getScopes')
|
||||
->willReturn($scopes);
|
||||
|
||||
$provider = new DefaultCacheKeyProvider($user);
|
||||
|
||||
$this->assertEquals($expected, $provider->get());
|
||||
}
|
||||
|
||||
public static function provider(): array
|
||||
{
|
||||
return [
|
||||
['aclMap/01', '01', null],
|
||||
['aclMap/01/37f6e5e382faedc68e0769892e78d8d3', '01', ['Admin', 'Global']],
|
||||
['aclMap/01/99aa06d3014798d86001c324468d497f', '01', []],
|
||||
];
|
||||
}
|
||||
}
|
||||
427
tests/unit/Espo/Core/Acl/Map/MapTest.php
Normal file
427
tests/unit/Espo/Core/Acl/Map/MapTest.php
Normal file
@@ -0,0 +1,427 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl\Map;
|
||||
|
||||
use Espo\Core\Acl\FieldData;
|
||||
use Espo\Core\Acl\Map\CacheKeyProvider;
|
||||
use Espo\Core\Acl\Map\DataBuilder;
|
||||
use Espo\Core\Acl\Map\Map;
|
||||
use Espo\Core\Acl\Map\MetadataProvider;
|
||||
use Espo\Core\Acl\ScopeData;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Utils\Cache\DataCacheAccess;
|
||||
use Espo\Core\Utils\Config\SystemConfig;
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Core\Utils\FieldUtil;
|
||||
|
||||
use Espo\Core\Utils\Log;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use stdClass;
|
||||
|
||||
class MapTest extends TestCase
|
||||
{
|
||||
private $fieldUtil;
|
||||
private $table;
|
||||
private $metadataProvider;
|
||||
private $cacheKeyProvider;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->fieldUtil = $this->createMock(FieldUtil::class);
|
||||
$this->table = $this->createMock(Table::class);
|
||||
$this->metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
$this->cacheKeyProvider = $this->createMock(CacheKeyProvider::class);
|
||||
|
||||
}
|
||||
|
||||
private function mockTableData(array $scopeData, array $fieldData, array $permissionData): void
|
||||
{
|
||||
$returnMap1 = [];
|
||||
|
||||
foreach ($scopeData as $scope => $item) {
|
||||
$returnMap1[] = [$scope, ScopeData::fromRaw($item)];
|
||||
}
|
||||
|
||||
$this->table
|
||||
->expects($this->any())
|
||||
->method('getScopeData')
|
||||
->willReturnMap($returnMap1);
|
||||
|
||||
$returnMap2 = [];
|
||||
|
||||
foreach ($fieldData as $scope => $item1) {
|
||||
foreach ($item1 as $field => $item2) {
|
||||
$returnMap2[] = [$scope, $field, FieldData::fromRaw($item2)];
|
||||
}
|
||||
}
|
||||
|
||||
$this->table
|
||||
->expects($this->any())
|
||||
->method('getFieldData')
|
||||
->willReturnMap($returnMap2);
|
||||
|
||||
$returnMap3 = [];
|
||||
|
||||
foreach ($permissionData as $permission => $level) {
|
||||
$returnMap3[] = [$permission, $level];
|
||||
}
|
||||
|
||||
$this->table
|
||||
->expects($this->any())
|
||||
->method('getPermissionLevel')
|
||||
->willReturnMap($returnMap3);
|
||||
}
|
||||
|
||||
public function testMap1(): void
|
||||
{
|
||||
$dataBuilder = new DataBuilder($this->metadataProvider, $this->fieldUtil);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getScopeList')
|
||||
->willReturn(['Test1', 'Test2', 'Test3', 'Test4', 'Test5']);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getPermissionList')
|
||||
->willReturn(['assignment', 'portal']);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('isScopeEntity')
|
||||
->willReturnMap([
|
||||
['Test1', true],
|
||||
['Test2', true],
|
||||
['Test3', true],
|
||||
['Test4', true],
|
||||
['Test5', false],
|
||||
]);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getScopeFieldList')
|
||||
->willReturnMap([
|
||||
['Test1', ['field1', 'field2', 'field3', 'field4']],
|
||||
['Test2', ['field1']],
|
||||
['Test3', []],
|
||||
['Test4', []],
|
||||
['Test5', []],
|
||||
]);
|
||||
|
||||
$this->fieldUtil
|
||||
->expects($this->any())
|
||||
->method('getAttributeList')
|
||||
->willReturnMap([
|
||||
['Test1', 'field1', ['attr1a', 'attr1b']],
|
||||
['Test1', 'field2', ['field2']],
|
||||
['Test1', 'field3', ['field3']],
|
||||
['Test1', 'field4', ['field4']],
|
||||
['Test2', 'field1', ['field1']],
|
||||
]);
|
||||
|
||||
$this->mockTableData(
|
||||
[
|
||||
'Test1' => (object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
'Test2' => (object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
Table::ACTION_EDIT => Table::LEVEL_OWN,
|
||||
],
|
||||
'Test3' => false,
|
||||
'Test4' => true,
|
||||
'Test5' => true,
|
||||
],
|
||||
[
|
||||
'Test1' => [
|
||||
'field1' => (object) [
|
||||
Table::ACTION_READ => Table::LEVEL_YES,
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
],
|
||||
'field2' => (object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
Table::ACTION_EDIT => Table::LEVEL_YES,
|
||||
],
|
||||
'field3' => (object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
],
|
||||
'field4' => (object) [
|
||||
Table::ACTION_READ => Table::LEVEL_YES,
|
||||
Table::ACTION_EDIT => Table::LEVEL_YES,
|
||||
],
|
||||
],
|
||||
'Test2' => [
|
||||
'field1' => (object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'assignment' => Table::LEVEL_YES,
|
||||
'portal' => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$expectedData = $this->getExpectedRawData();
|
||||
|
||||
$this->cacheKeyProvider->method('get')
|
||||
->willReturn('key');
|
||||
|
||||
$dataCacheAccess = new DataCacheAccess(
|
||||
dataCache: $this->createMock(DataCache::class),
|
||||
systemConfig: $this->createMock(SystemConfig::class),
|
||||
log: $this->createMock(Log::class),
|
||||
);
|
||||
|
||||
$map = new Map(
|
||||
table: $this->table,
|
||||
dataBuilder: $dataBuilder,
|
||||
cacheKeyProvider: $this->cacheKeyProvider,
|
||||
dataCacheAccess: $dataCacheAccess,
|
||||
);
|
||||
|
||||
$this->assertEquals($expectedData, $map->getData());
|
||||
|
||||
$this->assertEquals(
|
||||
['field2', 'field3'],
|
||||
$map->getScopeForbiddenFieldList('Test1', Table::ACTION_READ)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['field1', 'field3'],
|
||||
$map->getScopeForbiddenFieldList('Test1', Table::ACTION_EDIT)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['field2', 'field3'],
|
||||
$map->getScopeForbiddenAttributeList('Test1', Table::ACTION_READ)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['attr1a', 'attr1b', 'field3'],
|
||||
$map->getScopeForbiddenAttributeList('Test1', Table::ACTION_EDIT)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['attr1a', 'attr1b', 'field3'],
|
||||
$map->getScopeForbiddenAttributeList('Test1', Table::ACTION_EDIT)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['field1'],
|
||||
$map->getScopeForbiddenFieldList('Test2', Table::ACTION_READ)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
['field1'],
|
||||
$map->getScopeForbiddenFieldList('Test2', Table::ACTION_READ)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
[],
|
||||
$map->getScopeForbiddenFieldList('Test3', Table::ACTION_READ)
|
||||
);
|
||||
}
|
||||
|
||||
private function getExpectedRawData(): stdClass
|
||||
{
|
||||
return (object) [
|
||||
'table' => (object) [
|
||||
'Test1' => (object) [
|
||||
'read' => 'team',
|
||||
'stream' => 'no',
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
'create' => 'yes'
|
||||
],
|
||||
'Test2' => (object) [
|
||||
'read' => 'team',
|
||||
'stream' => 'no',
|
||||
'edit' => 'own',
|
||||
'delete' => 'no',
|
||||
'create' => 'yes'
|
||||
],
|
||||
'Test3' => false,
|
||||
'Test4' => true,
|
||||
'Test5' => true
|
||||
],
|
||||
'fieldTable' => (object) [
|
||||
'Test1' => (object) [
|
||||
'field1' => (object) [
|
||||
'read' => 'yes',
|
||||
'edit' => 'no'
|
||||
],
|
||||
'field2' => (object) [
|
||||
'read' => 'no',
|
||||
'edit' => 'yes'
|
||||
],
|
||||
'field3' => (object) [
|
||||
'read' => 'no',
|
||||
'edit' => 'no'
|
||||
]
|
||||
],
|
||||
'Test2' => (object) [
|
||||
'field1' => (object) [
|
||||
'read' => 'no',
|
||||
'edit' => 'no'
|
||||
]
|
||||
],
|
||||
'Test3' => (object) [],
|
||||
'Test4' => (object) []
|
||||
],
|
||||
'assignmentPermission' => 'yes',
|
||||
'portalPermission' => 'no',
|
||||
'fieldTableQuickAccess' => (object) [
|
||||
'Test1' => (object) [
|
||||
'attributes' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [
|
||||
'attr1a',
|
||||
'attr1b'
|
||||
],
|
||||
'no' => [
|
||||
'field2',
|
||||
'field3'
|
||||
]
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [
|
||||
'field2'
|
||||
],
|
||||
'no' => [
|
||||
'attr1a',
|
||||
'attr1b',
|
||||
'field3'
|
||||
]
|
||||
]
|
||||
],
|
||||
'fields' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [
|
||||
'field1'
|
||||
],
|
||||
'no' => [
|
||||
'field2',
|
||||
'field3'
|
||||
]
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [
|
||||
'field2'
|
||||
],
|
||||
'no' => [
|
||||
'field1',
|
||||
'field3'
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'Test2' => (object) [
|
||||
'attributes' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => [
|
||||
'field1'
|
||||
]
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => [
|
||||
'field1'
|
||||
]
|
||||
]
|
||||
],
|
||||
'fields' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => [
|
||||
'field1'
|
||||
]
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => [
|
||||
'field1'
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'Test3' => (object) [
|
||||
'attributes' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
]
|
||||
],
|
||||
'fields' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
]
|
||||
]
|
||||
],
|
||||
'Test4' => (object) [
|
||||
'attributes' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
]
|
||||
],
|
||||
'fields' => (object) [
|
||||
'read' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
],
|
||||
'edit' => (object) [
|
||||
'yes' => [],
|
||||
'no' => []
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
58
tests/unit/Espo/Core/Acl/Map/MetadataProviderTest.php
Normal file
58
tests/unit/Espo/Core/Acl/Map/MetadataProviderTest.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl\Map;
|
||||
|
||||
use Espo\Core\Acl\Map\MetadataProvider;
|
||||
use Espo\Core\Acl\Permission;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MetadataProviderTest extends TestCase
|
||||
{
|
||||
private $metadata;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
}
|
||||
|
||||
public function testGetPermissionList(): void
|
||||
{
|
||||
$provider = new MetadataProvider($this->metadata);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with(['app', 'acl', 'valuePermissionList'])
|
||||
->willReturn(['assignmentPermission', 'portalPermission']);
|
||||
|
||||
$this->assertEquals([Permission::ASSIGNMENT, 'portal'], $provider->getPermissionList());
|
||||
}
|
||||
}
|
||||
113
tests/unit/Espo/Core/Acl/ScopeCheckerDataTest.php
Normal file
113
tests/unit/Espo/Core/Acl/ScopeCheckerDataTest.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\Acl\AccessChecker\ScopeCheckerData;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ScopeCheckerDataTest extends TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testCheckerData0()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$this->assertFalse($checkerData->isOwn());
|
||||
$this->assertFalse($checkerData->inTeam());
|
||||
$this->assertFalse($checkerData->isShared());
|
||||
}
|
||||
|
||||
public function testCheckerData1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->setIsShared(true)
|
||||
->build();
|
||||
|
||||
$this->assertTrue($checkerData->isOwn());
|
||||
$this->assertTrue($checkerData->inTeam());
|
||||
$this->assertTrue($checkerData->isShared());
|
||||
}
|
||||
|
||||
public function testCheckerData2()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeamChecker(
|
||||
function (): bool {
|
||||
return true;
|
||||
}
|
||||
)
|
||||
->setIsSharedChecker(
|
||||
function (): bool {
|
||||
return true;
|
||||
}
|
||||
)
|
||||
->build();
|
||||
|
||||
$this->assertFalse($checkerData->isOwn());
|
||||
$this->assertTrue($checkerData->inTeam());
|
||||
$this->assertTrue($checkerData->isShared());
|
||||
}
|
||||
|
||||
public function testCheckerData3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwnChecker(
|
||||
function (): bool {
|
||||
return true;
|
||||
}
|
||||
)
|
||||
->setInTeamChecker(
|
||||
function (): bool {
|
||||
return false;
|
||||
}
|
||||
)
|
||||
->setIsSharedChecker(
|
||||
function (): bool {
|
||||
return false;
|
||||
}
|
||||
)
|
||||
->build();
|
||||
|
||||
$this->assertTrue($checkerData->isOwn());
|
||||
$this->assertFalse($checkerData->inTeam());
|
||||
$this->assertFalse($checkerData->isShared());
|
||||
}
|
||||
}
|
||||
435
tests/unit/Espo/Core/Acl/ScopeCheckerTest.php
Normal file
435
tests/unit/Espo/Core/Acl/ScopeCheckerTest.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl\AccessChecker\ScopeChecker,
|
||||
Acl\AccessChecker\ScopeCheckerData,
|
||||
Acl\ScopeData,
|
||||
Acl\Table,
|
||||
};
|
||||
|
||||
class ScopeCheckerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var ScopeChecker
|
||||
*/
|
||||
private $scopeChecker;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->scopeChecker = new ScopeChecker();
|
||||
}
|
||||
|
||||
public function testCheckerNoData1()
|
||||
{
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData2()
|
||||
{
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData3()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData4()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData5()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerActionNoData1()
|
||||
{
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerActionNoData2()
|
||||
{
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData2()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData4()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData5()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData6()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData7()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData8()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData9()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData10()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData11()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData12()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData13()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction2()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInTeam(false)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_TEAM,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction4()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInTeam(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_NO,
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
}
|
||||
106
tests/unit/Espo/Core/Acl/ScopeDataResolverTest.php
Normal file
106
tests/unit/Espo/Core/Acl/ScopeDataResolverTest.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\Acl\ScopeData;
|
||||
use Espo\Core\Acl\Table;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ScopeDataResolverTest extends TestCase
|
||||
{
|
||||
public function testResolve1(): void
|
||||
{
|
||||
$table = $this->createMock(Table::class);
|
||||
$resolver = new Table\ScopeDataResolver($table);
|
||||
|
||||
$table->expects($this->once())
|
||||
->method('getScopeData')
|
||||
->with('Test')
|
||||
->willReturn(ScopeData::fromRaw(true));
|
||||
|
||||
$this->assertTrue($resolver->resolve('Test')->isTrue());
|
||||
}
|
||||
|
||||
public function testResolve2(): void
|
||||
{
|
||||
$table = $this->createMock(Table::class);
|
||||
$resolver = new Table\ScopeDataResolver($table);
|
||||
|
||||
$table->expects($this->once())
|
||||
->method('getScopeData')
|
||||
->willReturnMap([
|
||||
['Test', ScopeData::fromRaw(false)]
|
||||
]);
|
||||
|
||||
$this->assertTrue($resolver->resolve('Test')->isFalse());
|
||||
}
|
||||
|
||||
public function testResolve3(): void
|
||||
{
|
||||
$table = $this->createMock(Table::class);
|
||||
$resolver = new Table\ScopeDataResolver($table);
|
||||
|
||||
$table->expects($this->once())
|
||||
->method('getScopeData')
|
||||
->with('Test')
|
||||
->willReturn(ScopeData::fromRaw((object) ['create' => 'yes', 'edit' => 'no']));
|
||||
|
||||
$result = $resolver->resolve('Test');
|
||||
|
||||
$this->assertEquals('yes', $result->getCreate());
|
||||
$this->assertEquals('no', $result->getEdit());
|
||||
}
|
||||
|
||||
public function testResolve4(): void
|
||||
{
|
||||
$table = $this->createMock(Table::class);
|
||||
$resolver = new Table\ScopeDataResolver($table);
|
||||
|
||||
$table->expects($this->once())
|
||||
->method('getScopeData')
|
||||
->with('Test')
|
||||
->willReturn(ScopeData::fromRaw((object) ['create' => 'yes', 'edit' => 'no']));
|
||||
|
||||
$this->assertTrue($resolver->resolve('boolean:Test')->isTrue());
|
||||
}
|
||||
|
||||
public function testResolve5(): void
|
||||
{
|
||||
$table = $this->createMock(Table::class);
|
||||
$resolver = new Table\ScopeDataResolver($table);
|
||||
|
||||
$table->expects($this->once())
|
||||
->method('getScopeData')
|
||||
->with('Test')
|
||||
->willReturn(ScopeData::fromRaw((object) ['create' => 'no', 'edit' => 'no']));
|
||||
|
||||
$this->assertTrue($resolver->resolve('boolean:Test')->isTrue());
|
||||
}
|
||||
}
|
||||
146
tests/unit/Espo/Core/Acl/ScopeDataTest.php
Normal file
146
tests/unit/Espo/Core/Acl/ScopeDataTest.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl;
|
||||
|
||||
use Espo\Core\Acl\ScopeData;
|
||||
use Espo\Core\Acl\Table;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
class ScopeDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testBooleanTrue()
|
||||
{
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$this->assertTrue($data->isBoolean());
|
||||
$this->assertTrue($data->isTrue());
|
||||
$this->assertFalse($data->isFalse());
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getDelete());
|
||||
}
|
||||
|
||||
public function testBooleanFalse()
|
||||
{
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$this->assertTrue($data->isBoolean());
|
||||
$this->assertTrue($data->isFalse());
|
||||
$this->assertFalse($data->isTrue());
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getDelete());
|
||||
}
|
||||
|
||||
public function testNotBoolean()
|
||||
{
|
||||
$data = ScopeData::fromRaw((object) []);
|
||||
|
||||
$this->assertFalse($data->isBoolean());
|
||||
|
||||
$this->assertFalse($data->isTrue());
|
||||
$this->assertFalse($data->isFalse());
|
||||
}
|
||||
|
||||
public function testInvalid()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
ScopeData::fromRaw(null);
|
||||
}
|
||||
|
||||
public function testRecord()
|
||||
{
|
||||
$raw = (object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
Table::ACTION_EDIT => Table::LEVEL_TEAM,
|
||||
Table::ACTION_DELETE => Table::LEVEL_NO,
|
||||
];
|
||||
|
||||
$data = ScopeData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_YES, $data->getCreate());
|
||||
$this->assertEquals(Table::LEVEL_ALL, $data->getRead());
|
||||
$this->assertEquals(Table::LEVEL_TEAM, $data->getEdit());
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getDelete());
|
||||
|
||||
$this->assertTrue($data->hasNotNo());
|
||||
}
|
||||
|
||||
public function testRecordEmpty()
|
||||
{
|
||||
$raw = (object) [];
|
||||
|
||||
$data = ScopeData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getDelete());
|
||||
|
||||
$this->assertFalse($data->hasNotNo());
|
||||
}
|
||||
|
||||
public function testRecordOnlyNo()
|
||||
{
|
||||
$raw = (object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_NO,
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
Table::ACTION_DELETE => Table::LEVEL_NO,
|
||||
];
|
||||
|
||||
$data = ScopeData::fromRaw($raw);
|
||||
|
||||
$this->assertEquals(Table::LEVEL_NO, $data->getDelete());
|
||||
|
||||
$this->assertFalse($data->hasNotNo());
|
||||
}
|
||||
|
||||
public function testAccessingProperty()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$data->read;
|
||||
}
|
||||
|
||||
public function testBadKey()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
ScopeData::fromRaw((object) [
|
||||
Table::ACTION_CREATE => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Acl\Table;
|
||||
|
||||
use Espo\Core\Acl\Table\DefaultCacheKeyProvider;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DefaultCacheKeyProviderTest extends TestCase
|
||||
{
|
||||
#[DataProvider('provider')]
|
||||
public function testKey(string $expected, string $userId, ?array $scopes = null): void
|
||||
{
|
||||
$user = $this->createMock(User::class);
|
||||
|
||||
$user->expects(self::any())
|
||||
->method('getId')
|
||||
->willReturn($userId);
|
||||
|
||||
$user->expects(self::any())
|
||||
->method('getScopes')
|
||||
->willReturn($scopes);
|
||||
|
||||
$provider = new DefaultCacheKeyProvider($user);
|
||||
|
||||
$this->assertEquals($expected, $provider->get());
|
||||
}
|
||||
|
||||
public static function provider(): array
|
||||
{
|
||||
return [
|
||||
['acl/01', '01', null],
|
||||
['acl/01/37f6e5e382faedc68e0769892e78d8d3', '01', ['Admin', 'Global']],
|
||||
['acl/01/99aa06d3014798d86001c324468d497f', '01', []],
|
||||
];
|
||||
}
|
||||
}
|
||||
115
tests/unit/Espo/Core/AclManagerTest.php
Normal file
115
tests/unit/Espo/Core/AclManagerTest.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core;
|
||||
|
||||
use Espo\Core\Acl\AccessChecker\AccessCheckerFactory;
|
||||
use Espo\Core\Acl\GlobalRestriction;
|
||||
use Espo\Core\Acl\Map\MapFactory;
|
||||
use Espo\Core\Acl\OwnershipChecker\OwnershipCheckerFactory;
|
||||
use Espo\Core\Acl\OwnerUserFieldProvider;
|
||||
use Espo\Core\Acl\Permission;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\Acl\Table\TableFactory;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
|
||||
use Espo\Core\Utils\Event\EventDispatcher;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AclManagerTest extends TestCase
|
||||
{
|
||||
/** @var AclManager */
|
||||
private $aclManager;
|
||||
/** @var TableFactory */
|
||||
private $tableFactory;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
private $table;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->table = $this->createMock(Table::class);
|
||||
|
||||
$accessCheckerFactory = $this->createMock(AccessCheckerFactory::class);
|
||||
$ownershipCheckerFactory = $this->createMock(OwnershipCheckerFactory::class);
|
||||
$this->tableFactory = $this->createMock(TableFactory::class);
|
||||
$mapFactory = $this->createMock(MapFactory::class);
|
||||
$globalRestriction = $this->createMock(GlobalRestriction::class);
|
||||
|
||||
$this->aclManager = new AclManager(
|
||||
accessCheckerFactory: $accessCheckerFactory,
|
||||
ownershipCheckerFactory: $ownershipCheckerFactory,
|
||||
tableFactory: $this->tableFactory,
|
||||
mapFactory: $mapFactory,
|
||||
globalRestriction: $globalRestriction,
|
||||
ownerUserFieldProvider: $this->createMock(OwnerUserFieldProvider::class),
|
||||
entityManager: $this->createMock(EntityManager::class),
|
||||
eventDispatcher: $this->createMock(EventDispatcher::class),
|
||||
);
|
||||
}
|
||||
|
||||
private function initTableFactory(User $user, Table $table): void
|
||||
{
|
||||
$this->tableFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($user)
|
||||
->willReturn($table);
|
||||
}
|
||||
|
||||
public function testGetPermissionLevel1(): void
|
||||
{
|
||||
$this->initTableFactory($this->user, $this->table);
|
||||
|
||||
$this->table
|
||||
->expects($this->once())
|
||||
->method('getPermissionLevel')
|
||||
->with(Permission::ASSIGNMENT)
|
||||
->willReturn(Table::LEVEL_YES);
|
||||
|
||||
$this->aclManager->getPermissionLevel($this->user, Permission::ASSIGNMENT);
|
||||
}
|
||||
|
||||
public function testGetPermissionLevel2(): void
|
||||
{
|
||||
$this->initTableFactory($this->user, $this->table);
|
||||
|
||||
$this->table
|
||||
->expects($this->once())
|
||||
->method('getPermissionLevel')
|
||||
->with(Permission::ASSIGNMENT)
|
||||
->willReturn(Table::LEVEL_YES);
|
||||
|
||||
$this->aclManager->getPermissionLevel($this->user, Permission::ASSIGNMENT);
|
||||
}
|
||||
}
|
||||
81
tests/unit/Espo/Core/Api/ActionProcessorTest.php
Normal file
81
tests/unit/Espo/Core/Api/ActionProcessorTest.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Api\ControllerActionProcessor;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
use Espo\Core\Api\ResponseWrapper;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Utils\ClassFinder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use tests\unit\testClasses\Controllers\TestController;
|
||||
|
||||
class ActionProcessorTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testAction1()
|
||||
{
|
||||
$classFinder = $this->createMock(ClassFinder::class);
|
||||
$injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
$response = $this->createMock(ResponseWrapper::class);
|
||||
|
||||
$actionProcessor = new ControllerActionProcessor($injectableFactory, $classFinder);
|
||||
|
||||
$controller = $this->getMockBuilder(TestController::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$classFinder
|
||||
->expects($this->once())
|
||||
->method('find')
|
||||
->with('Controllers', 'Test')
|
||||
->willReturn(TestController::class);
|
||||
|
||||
$request
|
||||
->expects($this->once())
|
||||
->method('getMethod')
|
||||
->willReturn('POST');
|
||||
|
||||
$injectableFactory
|
||||
->expects($this->once())
|
||||
->method('createWith')
|
||||
->with(TestController::class, ['name' => 'Test'])
|
||||
->willReturn($controller);
|
||||
|
||||
$controller
|
||||
->expects($this->once())
|
||||
->method('postActionHello')
|
||||
->with($request, $response);
|
||||
|
||||
$actionProcessor->process('Test', 'hello', $request, $response);
|
||||
}
|
||||
}
|
||||
272
tests/unit/Espo/Core/Api/AuthTest.php
Normal file
272
tests/unit/Espo/Core/Api/AuthTest.php
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Api\Auth;
|
||||
use Espo\Core\Api\Method;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Api\Route\ContentType;
|
||||
use Espo\Core\Authentication\Authentication;
|
||||
use Espo\Core\Authentication\AuthenticationData;
|
||||
use Espo\Core\Authentication\HeaderKey;
|
||||
use Espo\Core\Authentication\Login\MethodResolver;
|
||||
use Espo\Core\Authentication\Result;
|
||||
use Espo\Core\Authentication\Result\Data;
|
||||
use Espo\Core\Utils\Json;
|
||||
use Espo\Core\Utils\Log;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use RuntimeException;
|
||||
use Slim\Psr7\Factory\RequestFactory;
|
||||
use Slim\Psr7\Factory\StreamFactory;
|
||||
|
||||
class AuthTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testProcessNoAuth(): void
|
||||
{
|
||||
$request = $this->createRequestInstance();
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$authentication = $this->createMock(Authentication::class);
|
||||
$authentication
|
||||
->expects(self::once())
|
||||
->method('login')
|
||||
->willReturn(
|
||||
Result::secondStepRequired($this->createMock(User::class), Data::create())
|
||||
);
|
||||
|
||||
$auth = new Auth(
|
||||
log: $this->createMock(Log::class),
|
||||
authentication: $authentication,
|
||||
methodResolver: $this->createMock(MethodResolver::class),
|
||||
authRequired: false,
|
||||
);
|
||||
|
||||
$result = $auth->process($request, $response);
|
||||
|
||||
$this->assertTrue($result->isResolvedUseNoAuth());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testProcessAuthFail(): void
|
||||
{
|
||||
$request = $this->createRequestInstance();
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$authentication = $this->createMock(Authentication::class);
|
||||
$authentication
|
||||
->expects(self::once())
|
||||
->method('login')
|
||||
->willReturn(
|
||||
Result::fail()
|
||||
);
|
||||
|
||||
$auth = new Auth(
|
||||
log: $this->createMock(Log::class),
|
||||
authentication: $authentication,
|
||||
methodResolver: $this->createMock(MethodResolver::class),
|
||||
);
|
||||
|
||||
$result = $auth->process($request, $response);
|
||||
|
||||
$this->assertFalse($result->isResolved());
|
||||
$this->assertFalse($result->isResolvedUseNoAuth());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testCgiHeader(): void
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
method: Method::GET,
|
||||
headers: [
|
||||
'Http-Espo-Cgi-Auth' => 'Basic ' . base64_encode('test:1'),
|
||||
],
|
||||
);
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$authentication = $this->createMock(Authentication::class);
|
||||
$authentication
|
||||
->expects(self::once())
|
||||
->method('login')
|
||||
->with(
|
||||
AuthenticationData::create()
|
||||
->withUsername('test')
|
||||
->withPassword('1')
|
||||
)
|
||||
->willReturn(
|
||||
Result::success($this->createMock(User::class))
|
||||
);
|
||||
|
||||
$auth = new Auth(
|
||||
log: $this->createMock(Log::class),
|
||||
authentication: $authentication,
|
||||
methodResolver: $this->createMock(MethodResolver::class),
|
||||
authRequired: true,
|
||||
);
|
||||
|
||||
$result = $auth->process($request, $response);
|
||||
|
||||
$this->assertTrue($result->isResolved());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testCookie(): void
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
method: Method::GET,
|
||||
cookieParams: [
|
||||
'auth-token' => '001',
|
||||
],
|
||||
);
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$authentication = $this->createMock(Authentication::class);
|
||||
$authentication
|
||||
->expects(self::once())
|
||||
->method('login')
|
||||
->with(
|
||||
AuthenticationData::create()
|
||||
->withPassword('001')
|
||||
->withByTokenOnly(true)
|
||||
)
|
||||
->willReturn(
|
||||
Result::success($this->createMock(User::class))
|
||||
);
|
||||
|
||||
$auth = new Auth(
|
||||
log: $this->createMock(Log::class),
|
||||
authentication: $authentication,
|
||||
methodResolver: $this->createMock(MethodResolver::class),
|
||||
authRequired: true,
|
||||
);
|
||||
|
||||
$result = $auth->process($request, $response);
|
||||
|
||||
$this->assertTrue($result->isResolved());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testIgnoreCookie(): void
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
method: Method::POST,
|
||||
headers: [
|
||||
'Sec-Fetch-Mode' => 'navigate',
|
||||
'Content-Type' => ContentType::MULTIPART_FORM_DATA . '; charset=utf-8'
|
||||
],
|
||||
cookieParams: [
|
||||
'auth-token' => '001',
|
||||
]
|
||||
);
|
||||
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$authentication = $this->createMock(Authentication::class);
|
||||
$authentication
|
||||
->expects(self::never())
|
||||
->method('login');
|
||||
|
||||
$auth = new Auth(
|
||||
log: $this->createMock(Log::class),
|
||||
authentication: $authentication,
|
||||
methodResolver: $this->createMock(MethodResolver::class),
|
||||
authRequired: true,
|
||||
);
|
||||
|
||||
$result = $auth->process($request, $response);
|
||||
|
||||
$this->assertFalse($result->isResolved());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $headers
|
||||
* @param array<string, string> $queryParams
|
||||
* @param array<string, string> $cookieParams
|
||||
*/
|
||||
public static function createRequest(
|
||||
string $method,
|
||||
array $queryParams = [],
|
||||
array $headers = [],
|
||||
?string $body = null,
|
||||
array $cookieParams = [],
|
||||
): RequestWrapper {
|
||||
|
||||
$request = (new RequestFactory())
|
||||
->createRequest($method, 'http://localhost/?' . http_build_query($queryParams));
|
||||
|
||||
if (!$request instanceof ServerRequestInterface) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
|
||||
foreach ($headers as $name => $value) {
|
||||
$request = $request->withHeader($name, $value);
|
||||
}
|
||||
|
||||
$request = $request->withCookieParams($cookieParams);
|
||||
|
||||
if ($body) {
|
||||
$request = $request->withBody(
|
||||
(new StreamFactory)->createStream($body)
|
||||
);
|
||||
}
|
||||
|
||||
return new RequestWrapper($request, '', []);
|
||||
}
|
||||
|
||||
private function createRequestInstance(): RequestWrapper
|
||||
{
|
||||
return $this->createRequest(
|
||||
method: 'POST',
|
||||
headers: [
|
||||
'Content-Type' => 'application/json',
|
||||
HeaderKey::AUTHORIZATION => base64_encode('test:1'),
|
||||
],
|
||||
body: Json::encode((object) []),
|
||||
);
|
||||
}
|
||||
}
|
||||
95
tests/unit/Espo/Core/Api/ErrorOutputTest.php
Normal file
95
tests/unit/Espo/Core/Api/ErrorOutputTest.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Api\ConfigDataProvider;
|
||||
use Espo\Core\Api\ErrorOutput;
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Core\Api\Response;
|
||||
use Espo\Core\Utils\Log;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RuntimeException;
|
||||
|
||||
class ErrorOutputTest extends TestCase
|
||||
{
|
||||
public function testExceptionNotExposed(): void
|
||||
{
|
||||
$e = new RuntimeException();
|
||||
|
||||
$errorOutput = $this->createErrorOutput(exposeExceptions: false);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$response->expects(self::never())
|
||||
->method('setHeader')
|
||||
->with(ErrorOutput::HEADER_STATUS_REASON);
|
||||
|
||||
$errorOutput->process($request, $response, $e);
|
||||
}
|
||||
|
||||
public function testExceptionExposed(): void
|
||||
{
|
||||
$e = new RuntimeException("Test.");
|
||||
|
||||
$errorOutput = $this->createErrorOutput(exposeExceptions: true);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$response = $this->createMock(Response::class);
|
||||
|
||||
$response->expects(self::once())
|
||||
->method('setHeader')
|
||||
->with(ErrorOutput::HEADER_STATUS_REASON);
|
||||
|
||||
$errorOutput->process($request, $response, $e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ConfigDataProvider
|
||||
*/
|
||||
private function createConfig(bool $exposeExceptions): ConfigDataProvider
|
||||
{
|
||||
$config = $this->createMock(ConfigDataProvider::class);
|
||||
$config
|
||||
->expects(self::any())
|
||||
->method('exposeExceptions')
|
||||
->willReturn($exposeExceptions);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
private function createErrorOutput(bool $exposeExceptions): ErrorOutput
|
||||
{
|
||||
return new ErrorOutput(
|
||||
log: $this->createMock(Log::class),
|
||||
config: $this->createConfig(exposeExceptions: $exposeExceptions),
|
||||
);
|
||||
}
|
||||
}
|
||||
229
tests/unit/Espo/Core/Api/RequestTest.php
Normal file
229
tests/unit/Espo/Core/Api/RequestTest.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\ServerRequestInterface as Psr7Request;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Slim\Psr7\Factory\RequestFactory;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
|
||||
class RequestTest extends TestCase
|
||||
{
|
||||
private $request;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->request = $this->getMockBuilder(Psr7Request::class)->disableOriginalConstructor()->getMock();
|
||||
}
|
||||
|
||||
protected function createRequest(array $queryParams, array $routeParams = []) : RequestWrapper
|
||||
{
|
||||
$this->request
|
||||
->expects($this->any())
|
||||
->method('getQueryParams')
|
||||
->willReturn($queryParams);
|
||||
|
||||
return new RequestWrapper($this->request, '', $routeParams);
|
||||
}
|
||||
|
||||
public function testHasQueryParam()
|
||||
{
|
||||
$request = $this->createRequest([
|
||||
'id' => '1',
|
||||
]);
|
||||
|
||||
$this->assertTrue($request->hasQueryParam('id'));
|
||||
$this->assertFalse($request->hasQueryParam('test'));
|
||||
}
|
||||
|
||||
public function testHasRouteParam()
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
[
|
||||
],
|
||||
[
|
||||
'id' => '1',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertTrue($request->hasRouteParam('id'));
|
||||
$this->assertFalse($request->hasRouteParam('test'));
|
||||
}
|
||||
|
||||
public function testGetQueryParam()
|
||||
{
|
||||
$request = $this->createRequest([
|
||||
'id' => '1',
|
||||
]);
|
||||
|
||||
$this->assertEquals('1', $request->getQueryParam('id'));
|
||||
}
|
||||
|
||||
public function testGetRouteParam()
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
[
|
||||
],
|
||||
[
|
||||
'id' => '1',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals('1', $request->getRouteParam('id'));
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
$request = $this->createRequest(
|
||||
[
|
||||
'id' => '1',
|
||||
],
|
||||
[
|
||||
'id' => '2',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals('2', $request->get('id'));
|
||||
}
|
||||
|
||||
protected function createRequestWithBody(string $contents) : RequestWrapper
|
||||
{
|
||||
$body = $this->createMock(StreamInterface::class);
|
||||
|
||||
$body
|
||||
->expects($this->any())
|
||||
->method('getContents')
|
||||
->willReturn($contents);
|
||||
|
||||
$this->request
|
||||
->expects($this->any())
|
||||
->method('getBody')
|
||||
->willReturn($body);
|
||||
|
||||
$this->request
|
||||
->expects($this->any())
|
||||
->method('hasHeader')
|
||||
->with('Content-Type')
|
||||
->willReturn(true);
|
||||
|
||||
$this->request
|
||||
->expects($this->any())
|
||||
->method('getHeader')
|
||||
->with('Content-Type')
|
||||
->willReturn(['application/json']);
|
||||
|
||||
return new RequestWrapper($this->request);
|
||||
}
|
||||
|
||||
public function testGetParsedBody()
|
||||
{
|
||||
$original = (object) [
|
||||
'key1' => '1',
|
||||
'key2' => (object) [
|
||||
'key21' => [
|
||||
'211',
|
||||
'212',
|
||||
(object) [
|
||||
'2111' => '1',
|
||||
],
|
||||
],
|
||||
],
|
||||
'key3' => [
|
||||
'31',
|
||||
'32',
|
||||
null,
|
||||
],
|
||||
'key4' => null,
|
||||
];
|
||||
|
||||
$contents = json_encode($original);
|
||||
|
||||
$request = $this->createRequestWithBody($contents);
|
||||
|
||||
$parsed = $request->getParsedBody();
|
||||
|
||||
$anotherParsed = $request->getParsedBody();
|
||||
|
||||
$this->assertEquals($parsed, $original);
|
||||
|
||||
$this->assertEquals($parsed, $anotherParsed);
|
||||
|
||||
$this->assertNotSame($parsed, $anotherParsed);
|
||||
|
||||
$this->assertNotSame($parsed->key2, $anotherParsed->key2);
|
||||
|
||||
$this->assertNotSame($parsed->key2->key21[2], $anotherParsed->key2->key21[2]);
|
||||
}
|
||||
|
||||
public function testContentType1(): void
|
||||
{
|
||||
$request = (new RequestFactory())
|
||||
->createRequest('POST', 'http://localhost/?')
|
||||
->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
|
||||
$requestWrapped = new RequestWrapper($request);
|
||||
|
||||
$this->assertEquals('application/json', $requestWrapped->getContentType());
|
||||
}
|
||||
|
||||
public function testContentType2(): void
|
||||
{
|
||||
$request = (new RequestFactory())
|
||||
->createRequest('POST', 'http://localhost/?')
|
||||
->withHeader('Content-Type', 'application/json');
|
||||
|
||||
$requestWrapped = new RequestWrapper($request);
|
||||
|
||||
$this->assertEquals('application/json', $requestWrapped->getContentType());
|
||||
}
|
||||
|
||||
public function testContentTypeEmpty(): void
|
||||
{
|
||||
$request = (new RequestFactory())
|
||||
->createRequest('POST', 'http://localhost/?');
|
||||
|
||||
$requestWrapped = new RequestWrapper($request);
|
||||
|
||||
$this->assertEquals(null, $requestWrapped->getContentType());
|
||||
}
|
||||
|
||||
public function testHeaderAsArray(): void
|
||||
{
|
||||
$request = (new RequestFactory())
|
||||
->createRequest('POST', 'http://localhost/?')
|
||||
->withAddedHeader('Test', '1')
|
||||
->withAddedHeader('Test', '2');
|
||||
|
||||
$requestWrapped = new RequestWrapper($request);
|
||||
|
||||
$this->assertEquals(['1', '2'], $requestWrapped->getHeaderAsArray('Test'));
|
||||
}
|
||||
}
|
||||
61
tests/unit/Espo/Core/Api/ResponseTest.php
Normal file
61
tests/unit/Espo/Core/Api/ResponseTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use Slim\Psr7\Factory\ResponseFactory;
|
||||
use Espo\Core\Api\ResponseWrapper;
|
||||
|
||||
class ResponseTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testHeaderAsArray(): void
|
||||
{
|
||||
$response = (new ResponseFactory())
|
||||
->createResponse()
|
||||
->withAddedHeader('Test', '1')
|
||||
->withAddedHeader('Test', '2');
|
||||
|
||||
$wrapped = new ResponseWrapper($response);
|
||||
|
||||
$this->assertEquals(['1', '2'], $wrapped->getHeaderAsArray('Test'));
|
||||
}
|
||||
|
||||
public function testGetHeaderNames(): void
|
||||
{
|
||||
$response = (new ResponseFactory())
|
||||
->createResponse()
|
||||
->withAddedHeader('Test', '1')
|
||||
->withAddedHeader('Test', '2')
|
||||
->withAddedHeader('Content-Type', 'application/json');
|
||||
|
||||
$wrapped = new ResponseWrapper($response);
|
||||
|
||||
$this->assertEquals(['Test', 'Content-Type'], $wrapped->getHeaderNames());
|
||||
}
|
||||
}
|
||||
109
tests/unit/Espo/Core/Api/RouteProcessorTest.php
Normal file
109
tests/unit/Espo/Core/Api/RouteProcessorTest.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Api;
|
||||
|
||||
use Espo\Core\Api\AuthBuilderFactory;
|
||||
use Espo\Core\Api\ControllerActionProcessor;
|
||||
use Espo\Core\Api\ErrorOutput;
|
||||
use Espo\Core\Api\Method;
|
||||
use Espo\Core\Api\MiddlewareProvider;
|
||||
use Espo\Core\Api\ProcessData;
|
||||
use Espo\Core\Api\Route;
|
||||
use Espo\Core\Api\Route\ContentType;
|
||||
use Espo\Core\Api\RouteProcessor;
|
||||
use Espo\Core\ApplicationUser;
|
||||
use Espo\Core\Authentication\AuthenticationFactory;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Log;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Slim\Psr7\Factory\ResponseFactory;
|
||||
|
||||
class RouteProcessorTest extends TestCase
|
||||
{
|
||||
public function testConsumesFail(): void
|
||||
{
|
||||
$request = AuthTest::createRequest(
|
||||
method: Method::POST,
|
||||
headers: [
|
||||
'Content-Type' => ContentType::TEXT_PLAIN,
|
||||
],
|
||||
);
|
||||
|
||||
$route = new Route(
|
||||
method: Method::POST,
|
||||
route: '/test',
|
||||
adjustedRoute: '/test',
|
||||
params: [],
|
||||
noAuth: false,
|
||||
consumes: [
|
||||
ContentType::APPLICATION_JSON,
|
||||
],
|
||||
actionClassName: null,
|
||||
);
|
||||
|
||||
$errorOutput = $this->createMock(ErrorOutput::class);
|
||||
|
||||
$processor = new RouteProcessor(
|
||||
authenticationFactory: $this->createMock(AuthenticationFactory::class),
|
||||
authBuilderFactory: $this->createMock(AuthBuilderFactory::class),
|
||||
errorOutput: $errorOutput,
|
||||
config: $this->createMock(Config::class),
|
||||
log: $this->createMock(Log::class),
|
||||
applicationUser: $this->createMock(ApplicationUser::class),
|
||||
actionProcessor: $this->createMock(ControllerActionProcessor::class),
|
||||
middlewareProvider: $this->createMock(MiddlewareProvider::class),
|
||||
injectableFactory: $this->createMock(InjectableFactory::class),
|
||||
);
|
||||
|
||||
$response = (new ResponseFactory())->createResponse();
|
||||
|
||||
$errorOutput->expects(self::once())
|
||||
->method('process')
|
||||
->with(
|
||||
self::anything(),
|
||||
self::anything(),
|
||||
$this->callback(function ($e) {
|
||||
return $e instanceof BadRequest;
|
||||
})
|
||||
);
|
||||
|
||||
$processor->process(
|
||||
processData: new ProcessData(
|
||||
route: $route,
|
||||
basePath: '',
|
||||
routeParams: [],
|
||||
),
|
||||
request: $request->toPsr7(),
|
||||
response: $response,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication\AuthToken;
|
||||
|
||||
use Espo\Core\Authentication\AuthToken\Data;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AuthTokenDataTest extends TestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$authTokenData = Data::create([
|
||||
'passwordVersion' => 1,
|
||||
'ipAddress' => 'ip-address',
|
||||
'userId' => 'user-id',
|
||||
'portalId' => 'portal-id',
|
||||
'createSecret' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $authTokenData->getPasswordVersion());
|
||||
$this->assertEquals('ip-address', $authTokenData->getIpAddress());
|
||||
$this->assertEquals('user-id', $authTokenData->getUserId());
|
||||
$this->assertEquals('portal-id', $authTokenData->getPortalId());
|
||||
$this->assertTrue($authTokenData->toCreateSecret());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication;
|
||||
|
||||
use Espo\Core\Authentication\AuthenticationData;
|
||||
|
||||
class AuthenticationDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testCreate1(): void
|
||||
{
|
||||
$data = AuthenticationData::create()
|
||||
->withUsername('u')
|
||||
->withPassword('p')
|
||||
->withMethod(null);
|
||||
|
||||
$this->assertEquals('u', $data->getUsername());
|
||||
$this->assertEquals('p', $data->getPassword());
|
||||
$this->assertNull($data->getMethod());
|
||||
}
|
||||
|
||||
public function testCreate2(): void
|
||||
{
|
||||
$data = AuthenticationData::create()
|
||||
->withUsername(null)
|
||||
->withPassword(null)
|
||||
->withMethod('m');
|
||||
|
||||
$this->assertNull($data->getUsername());
|
||||
$this->assertNull($data->getPassword());
|
||||
$this->assertEquals('m', $data->getMethod());
|
||||
}
|
||||
}
|
||||
133
tests/unit/Espo/Core/Authentication/Jwt/TokenTest.php
Normal file
133
tests/unit/Espo/Core/Authentication/Jwt/TokenTest.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication\Jwt;
|
||||
|
||||
use Espo\Core\Authentication\Jwt\DefaultKeyFactory;
|
||||
use Espo\Core\Authentication\Jwt\Key;
|
||||
use Espo\Core\Authentication\Jwt\SignatureVerifiers\Hmac;
|
||||
use Espo\Core\Authentication\Jwt\SignatureVerifiers\Rsa;
|
||||
use Espo\Core\Authentication\Jwt\Token;
|
||||
use phpseclib3\Common\Functions\Strings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TokenTest extends TestCase
|
||||
{
|
||||
public function testToken1(): void
|
||||
{
|
||||
$raw = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibm" .
|
||||
"FtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.cThIIoDvwdueQB468K5xDc5633seEFoqwxjF_xSJyQQ";
|
||||
|
||||
$token = Token::create($raw);
|
||||
|
||||
$this->assertEquals('HS256', $token->getHeader()->getAlg());
|
||||
$this->assertEquals('1234567890', $token->getPayload()->getSub());
|
||||
$this->assertEquals('John Doe', $token->getPayload()->get('name'));
|
||||
}
|
||||
|
||||
public function testToken2(): void
|
||||
{
|
||||
$raw = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0Ij" .
|
||||
"oxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzgwMjIsIm5iZiI6MTUxNjIzODAyMywiYXV0aF90aW1lIjoiMTUxNjIzODAyNCJ9." .
|
||||
"7Z45aUyLR9o8lUaIvxkO7SzOhTaXgfXf_rEFYnvTPL8";
|
||||
|
||||
$token = Token::create($raw);
|
||||
|
||||
$this->assertEquals(1516238022, $token->getPayload()->getExp());
|
||||
$this->assertEquals(1516239022, $token->getPayload()->getIat());
|
||||
$this->assertEquals(1516238023, $token->getPayload()->getNbf());
|
||||
$this->assertEquals(1516238024, $token->getPayload()->getAuthTime());
|
||||
}
|
||||
|
||||
public function testVerifySignatureHS256(): void
|
||||
{
|
||||
$raw = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." .
|
||||
"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0" .
|
||||
"IjoxNTE2MjM5MDIyfQ.S2ZL7D-D3VeduQ44Cy2qLRFxHV43gRGSZtlfJ2MJ57g";
|
||||
|
||||
$token = Token::create($raw);
|
||||
|
||||
$this->assertEquals('HS256', $token->getHeader()->getAlg());
|
||||
$this->assertEquals('1234567890', $token->getPayload()->getSub());
|
||||
|
||||
$verifier1 = new Hmac('HS256', '123456789');
|
||||
$this->assertTrue($verifier1->verify($token));
|
||||
|
||||
$verifier2 = new Hmac('HS256', '0000000000');
|
||||
$this->assertFalse($verifier2->verify($token));
|
||||
|
||||
$verifier3 = new Hmac('HS512', '123456789');
|
||||
$this->assertFalse($verifier3->verify($token));
|
||||
}
|
||||
|
||||
public function testVerifySignatureRS256(): void
|
||||
{
|
||||
$raw =
|
||||
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjAwMSJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9l" .
|
||||
"IiwiaWF0IjoxNTE2MjM5MDIyfQ.ZIOKC5KV6E1omC_KnQHgG5h9Z8G3g8jc1uUiI0RkQITAM-oS_3qivauy5jJnMX_N9-Bz2ZZSQ6" .
|
||||
"4AA_LbELCSoLnQ4HJBRzK8XfNeTVwhebjelUc8b_qcWC16lUWydd1GFYQQYbPfis_EN0UNM5TvfPpZ24YPujxJqZ0vrOOM-T6U73PtQ" .
|
||||
"TLfErmdO8cd_drHc75lSmWvXjpRl7zAj9vGhO_nJRh3-tPGprkFMvC4FLWOF5L_4eS3bJhhj7GUxyYYNi2ATbO7SRCPUp2Ck_aiJNlbS" .
|
||||
"Vdhbt_2Ls8VGnSPDdPf9UDUiXqYadueqmyrRucbBNHYn46cehnuONJa3gMaSA";
|
||||
|
||||
$token = Token::create($raw);
|
||||
|
||||
$pem =
|
||||
"-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo\r\n" .
|
||||
"4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u\r\n" .
|
||||
"+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh\r\n" .
|
||||
"kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ\r\n" .
|
||||
"0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg\r\n" .
|
||||
"cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc\r\n" .
|
||||
"mwIDAQAB\r\n" .
|
||||
"-----END PUBLIC KEY-----\r\n";
|
||||
|
||||
$pk = openssl_pkey_get_public($pem);
|
||||
$keyData = openssl_pkey_get_details($pk);
|
||||
|
||||
$rawKey = (object) [
|
||||
'kid' => '001',
|
||||
'alg' => 'RS256',
|
||||
'kty' => 'RSA',
|
||||
'n' => Strings::base64url_encode($keyData['rsa']['n']),
|
||||
'e' => Strings::base64url_encode($keyData['rsa']['e']),
|
||||
];
|
||||
|
||||
$key = (new DefaultKeyFactory())->create($rawKey);
|
||||
|
||||
$verifier1 = new Rsa('RS256', [$key]);
|
||||
$this->assertTrue($verifier1->verify($token));
|
||||
|
||||
$verifier1 = new Rsa('RS256', [$this->createMock(Key::class), $key]);
|
||||
$this->assertTrue($verifier1->verify($token));
|
||||
|
||||
$verifier1 = new Rsa('RS512', [$key]);
|
||||
$this->assertFalse($verifier1->verify($token));
|
||||
}
|
||||
}
|
||||
162
tests/unit/Espo/Core/Authentication/Login/MethodResolverTest.php
Normal file
162
tests/unit/Espo/Core/Authentication/Login/MethodResolverTest.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication\Login;
|
||||
|
||||
use Espo\Core\Api\Method;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
use Espo\Core\Authentication\ConfigDataProvider;
|
||||
use Espo\Core\Authentication\Login\MetadataParams;
|
||||
use Espo\Core\Authentication\Login\MethodResolver;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Slim\Psr7\Factory\ServerRequestFactory;
|
||||
|
||||
class MethodResolverTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @param MetadataParams[] $paramsList
|
||||
* @param array{string, string} $headerPair
|
||||
*/
|
||||
#[DataProvider('provider')]
|
||||
public function testResolve(array $paramsList, array $headerPair, ?string $expected): void
|
||||
{
|
||||
$this->processTest($paramsList, $headerPair, $expected);
|
||||
}
|
||||
|
||||
public static function provider(): array
|
||||
{
|
||||
$paramsList1 = [
|
||||
new MetadataParams(
|
||||
method: 'Test',
|
||||
),
|
||||
new MetadataParams(
|
||||
method: 'ApiKey',
|
||||
api: true,
|
||||
credentialsHeader: 'X-Api-Key',
|
||||
),
|
||||
new MetadataParams(
|
||||
method: 'OAuth',
|
||||
api: true,
|
||||
credentialsHeader: 'Authorization',
|
||||
credentialsHeaderScheme: 'Bearer',
|
||||
),
|
||||
];
|
||||
|
||||
$paramsList2 = [
|
||||
new MetadataParams(
|
||||
method: 'Some',
|
||||
api: true,
|
||||
credentialsHeader: 'Authorization',
|
||||
),
|
||||
new MetadataParams(
|
||||
method: 'OAuth',
|
||||
api: true,
|
||||
credentialsHeader: 'Authorization',
|
||||
credentialsHeaderScheme: 'Bearer',
|
||||
),
|
||||
];
|
||||
|
||||
$paramsList3 = [
|
||||
new MetadataParams(
|
||||
method: 'OAuth',
|
||||
api: true,
|
||||
credentialsHeader: 'Authorization',
|
||||
credentialsHeaderScheme: 'Bearer',
|
||||
),
|
||||
new MetadataParams(
|
||||
method: 'Some',
|
||||
api: true,
|
||||
credentialsHeader: 'Authorization',
|
||||
),
|
||||
];
|
||||
|
||||
return [
|
||||
[
|
||||
$paramsList1,
|
||||
['Authorization', 'Bearer test'],
|
||||
'OAuth',
|
||||
],
|
||||
[
|
||||
$paramsList1,
|
||||
['X-Api-Key', 'test'],
|
||||
'ApiKey',
|
||||
],
|
||||
[
|
||||
$paramsList1,
|
||||
['Espo-Authorization', 'test'],
|
||||
null,
|
||||
],
|
||||
[
|
||||
$paramsList2,
|
||||
['Authorization', 'Bearer test'],
|
||||
'OAuth',
|
||||
],
|
||||
[
|
||||
$paramsList3,
|
||||
['Authorization', 'Bearer test'],
|
||||
'OAuth',
|
||||
],
|
||||
[
|
||||
$paramsList2,
|
||||
['Authorization', 'test'],
|
||||
'Some',
|
||||
],
|
||||
[
|
||||
$paramsList3,
|
||||
['Authorization', 'test'],
|
||||
'Some',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MetadataParams[] $paramsList
|
||||
* @param array{string, string} $headerPair
|
||||
*/
|
||||
private function processTest(array $paramsList, array $headerPair, ?string $expected): void
|
||||
{
|
||||
$config = $this->createMock(ConfigDataProvider::class);
|
||||
|
||||
$config
|
||||
->expects(self::any())
|
||||
->method('getLoginMetadataParamsList')
|
||||
->willReturn($paramsList);
|
||||
|
||||
$request = new RequestWrapper(
|
||||
psr7Request: (new ServerRequestFactory())->createServerRequest(Method::GET, 'http://localhost')
|
||||
->withHeader($headerPair[0], $headerPair[1]),
|
||||
);
|
||||
|
||||
$resolver = new MethodResolver($config);
|
||||
|
||||
$this->assertEquals($expected, $resolver->resolve($request));
|
||||
}
|
||||
}
|
||||
96
tests/unit/Espo/Core/Authentication/Logins/Oidc/SyncTest.php
Normal file
96
tests/unit/Espo/Core/Authentication/Logins/Oidc/SyncTest.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication\Logins\Oidc;
|
||||
|
||||
use Espo\Core\Acl\Cache\Clearer;
|
||||
use Espo\Core\ApplicationState;
|
||||
use Espo\Core\Authentication\Oidc\ConfigDataProvider;
|
||||
use Espo\Core\Authentication\Oidc\UserProvider\DefaultUserInfoPopulator;
|
||||
use Espo\Core\Authentication\Oidc\UserProvider\Sync;
|
||||
use Espo\Core\Authentication\Oidc\UserProvider\UsernameValidator;
|
||||
use Espo\Core\Authentication\Oidc\UserProvider\UserRepository;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\PasswordHash;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SyncTest extends TestCase
|
||||
{
|
||||
private ?Sync $sync = null;
|
||||
private ?Config $config = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$configDataProvider = $this->createMock(ConfigDataProvider::class);
|
||||
|
||||
$populator = new DefaultUserInfoPopulator();
|
||||
|
||||
$this->sync = new Sync(
|
||||
$this->createMock(UsernameValidator::class),
|
||||
$this->config,
|
||||
$configDataProvider,
|
||||
$this->createMock(UserRepository::class),
|
||||
$this->createMock(PasswordHash::class),
|
||||
$this->createMock(Clearer::class),
|
||||
$this->createMock(ApplicationState::class),
|
||||
$populator,
|
||||
);
|
||||
}
|
||||
|
||||
public function testNormalizeUsername(): void
|
||||
{
|
||||
$this->config
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->with('userNameRegularExpression')
|
||||
->willReturn('[^a-z0-9\-@_\.\s]');
|
||||
|
||||
$this->assertEquals(
|
||||
'test_name',
|
||||
$this->sync->normalizeUsername('test_name')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'test_name',
|
||||
$this->sync->normalizeUsername('test|name')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'test@name',
|
||||
$this->sync->normalizeUsername('test@name')
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'test_name',
|
||||
$this->sync->normalizeUsername('test name')
|
||||
);
|
||||
}
|
||||
}
|
||||
53
tests/unit/Espo/Core/Authentication/ResultDataTest.php
Normal file
53
tests/unit/Espo/Core/Authentication/ResultDataTest.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication;
|
||||
|
||||
use Espo\Core\Authentication\Result\Data as ResultData;
|
||||
|
||||
class ResultDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testCreate1(): void
|
||||
{
|
||||
$data = ResultData::create()
|
||||
->withMessage('hello')
|
||||
->withDataItem('test1', '1')
|
||||
->withDataItem('test2', '2');
|
||||
|
||||
$this->assertEquals(
|
||||
(object) [
|
||||
'test1' => '1',
|
||||
'test2' => '2',
|
||||
],
|
||||
$data->getData()
|
||||
);
|
||||
|
||||
$this->assertEquals('hello', $data->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Authentication\Util;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class IpAddressUtilTest extends TestCase
|
||||
{
|
||||
public function testWhitelist(): void
|
||||
{
|
||||
$util = new \Espo\Core\Authentication\Util\IpAddressUtil();
|
||||
|
||||
$this->assertTrue(
|
||||
$util->isInWhitelist('192.168.0.1', [
|
||||
'192.168.0.1',
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$util->isInWhitelist('192.168.0.1', [
|
||||
'192.168.0.0',
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$util->isInWhitelist('192.168.0.1', [
|
||||
'192.168.0.1',
|
||||
'192.168.0.1',
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$util->isInWhitelist('192.168.0.5', [
|
||||
'192.168.0.1',
|
||||
'192.168.0.1/24',
|
||||
])
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$util->isInWhitelist('0.0.0.5', [
|
||||
'192.168.0.1/24',
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
748
tests/unit/Espo/Core/Binding/BindingContainerTest.php
Normal file
748
tests/unit/Espo/Core/Binding/BindingContainerTest.php
Normal file
@@ -0,0 +1,748 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Binding;
|
||||
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\Binding;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\Binding\BindingLoader;
|
||||
use Espo\Core\Binding\ContextualBinder;
|
||||
use Espo\Core\Binding\Key\NamedClassKey;
|
||||
use Espo\Core\Binding\Key\NamedKey;
|
||||
|
||||
use Espo\Core\Binding\Key\QualifiedClassKey;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use ReflectionParameter;
|
||||
use ReflectionNamedType;
|
||||
|
||||
use tests\unit\testClasses\Core\Binding\Class0;
|
||||
use tests\unit\testClasses\Core\Binding\Class1;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass1Alt;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass2Alt;
|
||||
use tests\unit\testClasses\Core\Binding\SomeInterface1;
|
||||
use tests\unit\testClasses\Core\Binding\SomeInterface2;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass1;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass2;
|
||||
|
||||
class BindingContainerTest extends TestCase
|
||||
{
|
||||
private ?Binder $binder = null;
|
||||
private ?BindingLoader $loader = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->loader = $this->createMock(BindingLoader::class);
|
||||
|
||||
$data = new BindingData();
|
||||
|
||||
$this->binder = new Binder($data);
|
||||
|
||||
$this->loader
|
||||
->expects($this->any())
|
||||
->method('load')
|
||||
->willReturn($data);
|
||||
}
|
||||
|
||||
private function createClassMock(string $className): ReflectionClass
|
||||
{
|
||||
$class = $this->createMock(ReflectionClass::class);
|
||||
|
||||
$class
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->willReturn($className);
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
private function createParamMock(string $name, ?string $className = null, ?string $qualifier = null): ReflectionParameter
|
||||
{
|
||||
$param = $this->createMock(ReflectionParameter::class);
|
||||
|
||||
$class = null;
|
||||
|
||||
$type = $this->createMock(ReflectionNamedType::class);
|
||||
|
||||
if ($className) {
|
||||
$class = $this->createClassMock($className);
|
||||
|
||||
$type
|
||||
->expects($this->any())
|
||||
->method('isBuiltin')
|
||||
->willReturn(false);
|
||||
|
||||
$type
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->willReturn($className);
|
||||
}
|
||||
|
||||
$type
|
||||
->expects($this->any())
|
||||
->method('isBuiltin')
|
||||
->willReturn(true);
|
||||
|
||||
$param
|
||||
->expects($this->any())
|
||||
->method('getType')
|
||||
->willReturn($type);
|
||||
|
||||
$param
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->willReturn($name);
|
||||
|
||||
$param
|
||||
->expects($this->any())
|
||||
->method('getClass')
|
||||
->willReturn($class);
|
||||
|
||||
if ($qualifier) {
|
||||
$attribute = $this->createMock(ReflectionClass::class);
|
||||
|
||||
$param
|
||||
->method('getAttributes')
|
||||
->willReturn([$attribute]);
|
||||
|
||||
$attribute->method('newInstance')
|
||||
->willReturn((object) ['qualifier' => $qualifier]);
|
||||
}
|
||||
|
||||
return $param;
|
||||
}
|
||||
|
||||
protected function createContainer(): BindingContainer
|
||||
{
|
||||
return new BindingContainer($this->loader->load());
|
||||
}
|
||||
|
||||
public function testHasTrue(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasNoContextTrue(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam(null, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasFalse(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Hello');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasNoContextFalse(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Hello');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam(null, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextTrue0(): void
|
||||
{
|
||||
$this->binder
|
||||
->inContext('Espo\\Context', function (ContextualBinder $binder): void {
|
||||
$binder->bindService('Espo\\Test', 'test');
|
||||
});
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextTrue1(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextTrue2(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue('$test', 'Test Value');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextTrue3(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue(NamedKey::create('test'), 'Test Value');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextTrue4(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService(NamedClassKey::create('Espo\\Test', 'test'), 'service');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertTrue(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextFalse1(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\Hello');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextFalse2(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\ContextOther');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testHasContextFalse3(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue('$test', 'Test Value');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Other');
|
||||
|
||||
$param = $this->createParamMock('test');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetClassNameImplementation(): void
|
||||
{
|
||||
$this->binder->bindImplementation('Espo\\Test', 'Espo\\ImplTest');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::IMPLEMENTATION_CLASS_NAME, $binding->getType());
|
||||
$this->assertEquals('Espo\\ImplTest', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetClassNameFactory(): void
|
||||
{
|
||||
$this->binder->bindFactory('Espo\\Test', 'Espo\\TestFactory');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::FACTORY_CLASS_NAME, $binding->getType());
|
||||
$this->assertEquals('Espo\\TestFactory', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetService(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('test', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetCallback(): void
|
||||
{
|
||||
$this->binder->bindCallback(
|
||||
'Espo\\Test',
|
||||
function () {
|
||||
return 'test';
|
||||
}
|
||||
);
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CALLBACK, $binding->getType());
|
||||
|
||||
$this->assertIsCallable($binding->getValue());
|
||||
}
|
||||
|
||||
public function testBindInstance(): void
|
||||
{
|
||||
$className = 'Espo\\Core\\Application';
|
||||
|
||||
$instance = $this->createMock($className);
|
||||
|
||||
$this->binder->bindInstance($className, $instance);
|
||||
|
||||
$param = $this->createParamMock('test', $className);
|
||||
|
||||
$binding = $this->createContainer()->getByParam(null, $param);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
|
||||
$this->assertSame($instance, $binding->getValue());
|
||||
}
|
||||
|
||||
public function testContextBindInstance(): void
|
||||
{
|
||||
$className = 'Espo\\Core\\Application';
|
||||
|
||||
$instance = $this->createMock($className);
|
||||
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindInstance($className, $instance);
|
||||
|
||||
$param = $this->createParamMock('test', $className);
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
|
||||
$this->assertSame($instance, $binding->getValue());
|
||||
}
|
||||
|
||||
public function testContextGetCallback(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindCallback(
|
||||
'Espo\\Test',
|
||||
function () {
|
||||
return 'test';
|
||||
}
|
||||
);
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CALLBACK, $binding->getType());
|
||||
|
||||
$this->assertIsCallable($binding->getValue());
|
||||
}
|
||||
|
||||
public function testRebindGlobal(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$this->binder->bindService('Espo\\Test', 'testHello');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('testHello', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testBindInterfaceWithParamNameGlobal(): void
|
||||
{
|
||||
$this->binder->bindService('Espo\\Test $name', 'testName');
|
||||
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('name', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('testName', $binding->getValue());
|
||||
|
||||
$param = $this->createParamMock('hello', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('test', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testContextGetClassNameImplementation(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindImplementation('Espo\\Test', 'Espo\\ImplTest');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::IMPLEMENTATION_CLASS_NAME, $binding->getType());
|
||||
$this->assertEquals('Espo\\ImplTest', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testContextGetClassNameFactory(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindFactory('Espo\\Test', 'Espo\\TestFactory');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::FACTORY_CLASS_NAME, $binding->getType());
|
||||
$this->assertEquals('Espo\\TestFactory', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testNoContextClassName(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindImplementation('Espo\\Test', 'Espo\\ImplTest');
|
||||
|
||||
$class = $this->createClassMock('Espo\\AnotherContext');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$this->assertFalse(
|
||||
$this->createContainer()->hasByParam($class, $param)
|
||||
);
|
||||
}
|
||||
|
||||
public function testBindContextInterfaceWithParamNameGlobal(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test $name', 'testName');
|
||||
|
||||
$this->binder->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('name', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('testName', $binding->getValue());
|
||||
|
||||
$param = $this->createParamMock('hello', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('test', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetContextParamValue(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue('$test', 'Test Value');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
|
||||
$this->assertEquals('Test Value', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetContextInterfaceValue1(): void
|
||||
{
|
||||
$instance = (object) [];
|
||||
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue('Espo\\SomeClass $test', $instance);
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\SomeClass');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
$this->assertEquals($instance, $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetContextInterfaceValue2(): void
|
||||
{
|
||||
$instance = (object) [];
|
||||
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindValue(NamedClassKey::create('Espo\\SomeClass', 'test'), $instance);
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
$param = $this->createParamMock('test', 'Espo\\SomeClass');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
$this->assertEquals($instance, $binding->getValue());
|
||||
}
|
||||
|
||||
public function testGetContextService(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'test');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('test', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testRebindContextService(): void
|
||||
{
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'test');
|
||||
|
||||
$this->binder
|
||||
->for('Espo\\Context')
|
||||
->bindService('Espo\\Test', 'testHello');
|
||||
|
||||
$class = $this->createClassMock('Espo\\Context');
|
||||
|
||||
$param = $this->createParamMock('test', 'Espo\\Test');
|
||||
|
||||
$binding = $this->createContainer()->getByParam($class, $param);
|
||||
|
||||
$this->assertEquals(Binding::CONTAINER_SERVICE, $binding->getType());
|
||||
|
||||
$this->assertEquals('testHello', $binding->getValue());
|
||||
}
|
||||
|
||||
public function testBindingContainerBuilder1(): void
|
||||
{
|
||||
$container = BindingContainerBuilder::create()
|
||||
->bindImplementation(SomeInterface1::class, SomeClass1::class)
|
||||
->inContext(SomeClass1::class, function (ContextualBinder $binder): void {
|
||||
$binder->bindImplementation(SomeInterface2::class, SomeClass2::class);
|
||||
})
|
||||
->build();
|
||||
|
||||
$param1 = $this->createParamMock('test', SomeInterface1::class);
|
||||
$this->assertTrue($container->hasByParam(null, $param1));
|
||||
|
||||
$param2 = $this->createParamMock('test', SomeInterface2::class);
|
||||
$this->assertFalse($container->hasByParam(null, $param2));
|
||||
|
||||
$class3 = $this->createClassMock(SomeClass1::class);
|
||||
$param3 = $this->createParamMock('test', SomeInterface2::class);
|
||||
$this->assertTrue($container->hasByParam($class3, $param3));
|
||||
}
|
||||
|
||||
public function testTypedParamWithScalarBound1(): void
|
||||
{
|
||||
$container = BindingContainerBuilder::create()
|
||||
->inContext(Class0::class, function (ContextualBinder $binder): void {
|
||||
$binder->bindValue('$dep', 'test');
|
||||
})
|
||||
->build();
|
||||
|
||||
$class = new ReflectionClass(Class0::class);
|
||||
|
||||
$constructor = $class->getConstructor();
|
||||
|
||||
$params = $constructor->getParameters();
|
||||
|
||||
$this->assertFalse($container->hasByParam($class, $params[0]));
|
||||
}
|
||||
|
||||
public function testTypedParamWithScalarBound2(): void
|
||||
{
|
||||
$container = BindingContainerBuilder::create()
|
||||
->inContext(Class0::class, function (ContextualBinder $binder): void {
|
||||
$binder->bindValue(NamedKey::create('dep'), new Class1());
|
||||
})
|
||||
->build();
|
||||
|
||||
$class = new ReflectionClass(Class0::class);
|
||||
|
||||
$constructor = $class->getConstructor();
|
||||
|
||||
$params = $constructor->getParameters();
|
||||
|
||||
$binding = $container->getByParam($class, $params[0]);
|
||||
|
||||
$this->assertEquals(Binding::VALUE, $binding->getType());
|
||||
$this->assertInstanceOf(Class1::class, $binding->getValue());
|
||||
}
|
||||
|
||||
public function testBindingQualified(): void
|
||||
{
|
||||
$container = BindingContainerBuilder::create()
|
||||
->bindImplementation(SomeInterface1::class, SomeClass1::class)
|
||||
->bindImplementation(QualifiedClassKey::create(SomeInterface1::class, 'q1'), SomeClass1Alt::class)
|
||||
->bindImplementation(QualifiedClassKey::create(SomeInterface2::class, 'q3'), SomeClass2Alt::class)
|
||||
->inContext(SomeClass1::class, function (ContextualBinder $binder): void {
|
||||
$binder->bindImplementation(SomeInterface2::class, SomeClass2::class);
|
||||
$binder->bindImplementation(QualifiedClassKey::create(SomeInterface2::class, 'q2'), SomeClass2Alt::class);
|
||||
})
|
||||
->build();
|
||||
|
||||
$param1 = $this->createParamMock('test', SomeInterface1::class, 'q1');
|
||||
$this->assertTrue($container->hasByParam(null, $param1));
|
||||
$binding = $container->getByParam(null, $param1);
|
||||
$this->assertEquals(SomeClass1Alt::class, $binding->getValue());
|
||||
|
||||
//
|
||||
|
||||
$param2 = $this->createParamMock('test', SomeInterface1::class);
|
||||
$this->assertTrue($container->hasByParam(null, $param2));
|
||||
$binding = $container->getByParam(null, $param2);
|
||||
$this->assertEquals(SomeClass1::class, $binding->getValue());
|
||||
|
||||
//
|
||||
|
||||
$contextClass = $this->createClassMock(SomeClass1::class);
|
||||
|
||||
//
|
||||
|
||||
$param3 = $this->createParamMock('test', SomeInterface2::class, 'q2');
|
||||
$this->assertTrue($container->hasByParam($contextClass, $param3));
|
||||
$binding = $container->getByParam($contextClass, $param3);
|
||||
$this->assertEquals(SomeClass2Alt::class, $binding->getValue());
|
||||
|
||||
//
|
||||
|
||||
$param4 = $this->createParamMock('test', SomeInterface2::class);
|
||||
$this->assertTrue($container->hasByParam($contextClass, $param4));
|
||||
$binding = $container->getByParam($contextClass, $param4);
|
||||
$this->assertEquals(SomeClass2::class, $binding->getValue());
|
||||
|
||||
//
|
||||
|
||||
$param3 = $this->createParamMock('test', SomeInterface2::class, 'q3');
|
||||
$this->assertTrue($container->hasByParam($contextClass, $param3));
|
||||
$binding = $container->getByParam($contextClass, $param3);
|
||||
$this->assertEquals(SomeClass2Alt::class, $binding->getValue());
|
||||
}
|
||||
}
|
||||
216
tests/unit/Espo/Core/Console/CommandManagerTest.php
Normal file
216
tests/unit/Espo/Core/Console/CommandManagerTest.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Console;
|
||||
|
||||
use Espo\Core\ApplicationUser;
|
||||
use Espo\Core\Console\Exceptions\InvalidArgument;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Console\CommandManager;
|
||||
use Espo\Core\Console\Command;
|
||||
use Espo\Core\Console\Command\Params;
|
||||
use Espo\Core\Console\IO;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CommandManagerTest extends TestCase
|
||||
{
|
||||
private ?InjectableFactory $injectableFactory = null;
|
||||
private ?Metadata $metadata = null;
|
||||
private ?CommandManager $manager = null;
|
||||
|
||||
private $command;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
|
||||
$applicationUser = $this->createMock(ApplicationUser::class);
|
||||
|
||||
$this->manager = new CommandManager($this->injectableFactory, $this->metadata, $applicationUser);
|
||||
|
||||
$this->command = $this->createMock(Command::class);
|
||||
}
|
||||
|
||||
private function initTest(?array $allowedOptions = null, ?array $allowedFlags = null)
|
||||
{
|
||||
$className = 'Test';
|
||||
|
||||
$map = [
|
||||
[['app', 'consoleCommands', 'commandName', 'className'], null, $className],
|
||||
[['app', 'consoleCommands', 'commandName', 'noSystemUser'], null, false],
|
||||
];
|
||||
|
||||
if ($allowedOptions !== null) {
|
||||
$map[] = [['app', 'consoleCommands', 'commandName', 'allowedOptions'], null, $allowedOptions];
|
||||
}
|
||||
|
||||
if ($allowedFlags!== null) {
|
||||
$map[] = [['app', 'consoleCommands', 'commandName', 'allowedFlags'], null, $allowedFlags];
|
||||
}
|
||||
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap($map);
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->any())
|
||||
->method('create')
|
||||
->with($className)
|
||||
->willReturn($this->command);
|
||||
}
|
||||
|
||||
public function testWithCommandPhp(): void
|
||||
{
|
||||
$argv = ['command.php', 'command-name', 'a1', 'a2', '--flag', '--flag-a', '-f', '--option-one=test'];
|
||||
|
||||
$this->initTest();
|
||||
|
||||
$expectedParams = new Params(
|
||||
[
|
||||
'optionOne' => 'test',
|
||||
],
|
||||
['flag', 'flagA', 'f'],
|
||||
['a1', 'a2']
|
||||
);
|
||||
|
||||
$io = new IO();
|
||||
|
||||
$this->command
|
||||
->expects($this->once())
|
||||
->method('run')
|
||||
->with($expectedParams, $io);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
|
||||
public function testWithoutCommandPhp(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', 'a1', 'a2', '--flag', '--flag-a', '-f', '--option-one=test'];
|
||||
|
||||
$this->initTest();
|
||||
|
||||
$expectedParams = new Params(
|
||||
[
|
||||
'optionOne' => 'test',
|
||||
],
|
||||
['flag', 'flagA', 'f'],
|
||||
['a1', 'a2']
|
||||
);
|
||||
|
||||
$io = new IO();
|
||||
|
||||
$this->command
|
||||
->expects($this->once())
|
||||
->method('run')
|
||||
->with($expectedParams, $io);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
|
||||
public function testAllowedOptions(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', '--option-one=test'];
|
||||
|
||||
$this->initTest(['optionOne']);
|
||||
|
||||
$expectedParams = new Params(
|
||||
[
|
||||
'optionOne' => 'test',
|
||||
],
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
$io = new IO();
|
||||
|
||||
$this->command
|
||||
->expects($this->once())
|
||||
->method('run')
|
||||
->with($expectedParams, $io);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
|
||||
public function testNotAllowedOptions(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', '--option-bad=test'];
|
||||
|
||||
$this->initTest(['optionOne']);
|
||||
|
||||
$this->expectException(InvalidArgument::class);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
public function testAllowedFlags(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', '--flagOne', '-a'];
|
||||
|
||||
$this->initTest(null, ['flagOne', 'a']);
|
||||
|
||||
$expectedParams = new Params(
|
||||
[],
|
||||
['flagOne', 'a'],
|
||||
[]
|
||||
);
|
||||
|
||||
$io = new IO();
|
||||
|
||||
$this->command
|
||||
->expects($this->once())
|
||||
->method('run')
|
||||
->with($expectedParams, $io);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
|
||||
public function testNotAllowedFlags1(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', '--bad-flag'];
|
||||
|
||||
$this->initTest(null, ['flag1']);
|
||||
|
||||
$this->expectException(InvalidArgument::class);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
|
||||
public function testNotAllowedFlags2(): void
|
||||
{
|
||||
$argv = ['bin/command', 'command-name', '-b'];
|
||||
|
||||
$this->initTest(null, ['a']);
|
||||
|
||||
$this->expectException(InvalidArgument::class);
|
||||
|
||||
$this->manager->run($argv);
|
||||
}
|
||||
}
|
||||
46
tests/unit/Espo/Core/Console/IOTest.php
Normal file
46
tests/unit/Espo/Core/Console/IOTest.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Console;
|
||||
|
||||
use Espo\Core\Console\IO;
|
||||
|
||||
class IOTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testExitStatus(): void
|
||||
{
|
||||
$io = new IO();
|
||||
|
||||
$this->assertEquals(0, $io->getExitStatus());
|
||||
|
||||
$io->setExitStatus(1);
|
||||
|
||||
$this->assertEquals(1, $io->getExitStatus());
|
||||
}
|
||||
}
|
||||
68
tests/unit/Espo/Core/Console/ParamsTest.php
Normal file
68
tests/unit/Espo/Core/Console/ParamsTest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Console;
|
||||
|
||||
use Espo\Core\Console\Command\Params;
|
||||
|
||||
class ParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testParams()
|
||||
{
|
||||
$raw = [
|
||||
'argumentList' => ['a1', 'a2'],
|
||||
'flagList' => ['f1', 'f2', 'f3'],
|
||||
'options' => [
|
||||
'optionOne' => 'test',
|
||||
],
|
||||
];
|
||||
|
||||
$params = new Params(
|
||||
$raw['options'],
|
||||
$raw['flagList'],
|
||||
$raw['argumentList']
|
||||
);
|
||||
|
||||
$this->assertEquals($raw['argumentList'], $params->getArgumentList());
|
||||
$this->assertEquals($raw['flagList'], $params->getFlagList());
|
||||
$this->assertEquals($raw['options'], $params->getOptions());
|
||||
|
||||
$this->assertTrue($params->hasFlag('f1'));
|
||||
$this->assertFalse($params->hasFlag('f0'));
|
||||
|
||||
$this->assertTrue($params->hasOption('optionOne'));
|
||||
$this->assertFalse($params->hasOption('optionZero'));
|
||||
|
||||
$this->assertEquals('test', $params->getOption('optionOne'));
|
||||
$this->assertEquals(null, $params->getOption('optionTwo'));
|
||||
|
||||
$this->assertEquals('a1', $params->getArgument(0));
|
||||
$this->assertEquals(null, $params->getArgument(4));
|
||||
}
|
||||
}
|
||||
55
tests/unit/Espo/Core/Currency/RatesTest.php
Normal file
55
tests/unit/Espo/Core/Currency/RatesTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Currency;
|
||||
|
||||
use Espo\Core\Currency\Rates;
|
||||
|
||||
class RatesTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testRates1(): void
|
||||
{
|
||||
$rates = Rates
|
||||
::create('USD')
|
||||
->withRate('EUR', 1.2);
|
||||
|
||||
$this->assertEquals('USD', $rates->getBase());
|
||||
$this->assertEquals(true, $rates->hasRate('EUR'));
|
||||
$this->assertEquals(1.2, $rates->getRate('EUR'));
|
||||
|
||||
$this->assertEquals(['EUR' => 1.2, 'USD' => 1.0], $rates->toAssoc());
|
||||
}
|
||||
|
||||
public function testRates2(): void
|
||||
{
|
||||
$rates = Rates::fromAssoc(['EUR' => 1.2], 'USD');
|
||||
|
||||
$this->assertEquals(['EUR' => 1.2, 'USD' => 1.0], $rates->toAssoc());
|
||||
}
|
||||
}
|
||||
159
tests/unit/Espo/Core/Field/Address/AddressFormattersTest.php
Normal file
159
tests/unit/Espo/Core/Field/Address/AddressFormattersTest.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Address;
|
||||
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
};
|
||||
|
||||
use Espo\Classes\{
|
||||
AddressFormatters\Formatter1,
|
||||
AddressFormatters\Formatter2,
|
||||
AddressFormatters\Formatter3,
|
||||
AddressFormatters\Formatter4,
|
||||
};
|
||||
|
||||
class AddressFormattersTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testFormat1All()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$formatter = new Formatter1();
|
||||
|
||||
$expected =
|
||||
"street\n" .
|
||||
"city, state postalCode\n" .
|
||||
"country";
|
||||
|
||||
$result = $formatter->format($address);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFormat1NoState()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState(null)
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$formatter = new Formatter1();
|
||||
|
||||
$expected =
|
||||
"street\n" .
|
||||
"city postalCode\n" .
|
||||
"country";
|
||||
|
||||
$result = $formatter->format($address);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFormat2All()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$formatter = new Formatter2();
|
||||
|
||||
$expected =
|
||||
"street\n" .
|
||||
"postalCode city\n" .
|
||||
"state country";
|
||||
|
||||
$result = $formatter->format($address);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFormat3All()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$formatter = new Formatter3();
|
||||
|
||||
$expected =
|
||||
"country\n" .
|
||||
"state postalCode city\n" .
|
||||
"street";
|
||||
|
||||
$result = $formatter->format($address);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFormat4All()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$formatter = new Formatter4();
|
||||
|
||||
$expected =
|
||||
"street\n" .
|
||||
"city\n" .
|
||||
"country - state postalCode";
|
||||
|
||||
$result = $formatter->format($address);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
}
|
||||
132
tests/unit/Espo/Core/Field/Address/AddressTest.php
Normal file
132
tests/unit/Espo/Core/Field/Address/AddressTest.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Address;
|
||||
|
||||
use Espo\Core\{
|
||||
Field\Address,
|
||||
Field\Address\AddressFactory,
|
||||
};
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
class AddressTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testAddress1()
|
||||
{
|
||||
$address = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$this->assertEquals('street', $address->getStreet());
|
||||
$this->assertEquals('city', $address->getCity());
|
||||
$this->assertEquals('country', $address->getCountry());
|
||||
$this->assertEquals('state', $address->getState());
|
||||
$this->assertEquals('postalCode', $address->getPostalCode());
|
||||
}
|
||||
|
||||
public function testBuilderClone()
|
||||
{
|
||||
$addressOriginal = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$address = Address::createBuilder()
|
||||
->clone($addressOriginal)
|
||||
->build();
|
||||
|
||||
$this->assertEquals('street', $address->getStreet());
|
||||
$this->assertEquals('city', $address->getCity());
|
||||
$this->assertEquals('country', $address->getCountry());
|
||||
$this->assertEquals('state', $address->getState());
|
||||
$this->assertEquals('postalCode', $address->getPostalCode());
|
||||
}
|
||||
|
||||
public function testAddressWith()
|
||||
{
|
||||
$addressOriginal = Address::createBuilder()
|
||||
->setStreet('street')
|
||||
->setCity('city')
|
||||
->setCountry('country')
|
||||
->setState('state')
|
||||
->setPostalCode('postalCode')
|
||||
->build();
|
||||
|
||||
$address = $addressOriginal->withStreet('new street');
|
||||
|
||||
$this->assertEquals('new street', $address->getStreet());
|
||||
$this->assertEquals('city', $address->getCity());
|
||||
}
|
||||
|
||||
public function testCreateFromEntity()
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
['addressStreet', 'street'],
|
||||
['addressCity', 'city'],
|
||||
['addressCountry', 'country'],
|
||||
['addressState', null],
|
||||
['addressPostalCode', null],
|
||||
]);
|
||||
|
||||
$factory = new AddressFactory();
|
||||
|
||||
$address = $factory->createFromEntity($entity, 'address');
|
||||
|
||||
$this->assertEquals('street', $address->getStreet());
|
||||
$this->assertEquals('city', $address->getCity());
|
||||
$this->assertEquals('country', $address->getCountry());
|
||||
$this->assertEquals(null, $address->getState());
|
||||
$this->assertEquals(null, $address->getPostalCode());
|
||||
}
|
||||
|
||||
public function testCreateFromNothing()
|
||||
{
|
||||
$address = Address::create();
|
||||
|
||||
$this->assertEquals(null, $address->getState());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Currency;
|
||||
|
||||
use Espo\Core\Currency\ConfigDataProvider as CurrencyConfigDataProvider;
|
||||
use Espo\Core\Currency\InternalRatesProvider;
|
||||
use Espo\Core\Utils\Config;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RuntimeException;
|
||||
|
||||
class CurrencyConfigDataProviderTest extends TestCase
|
||||
{
|
||||
private $config;
|
||||
private $provider;
|
||||
private $ratesProvider;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->ratesProvider = $this->createMock(InternalRatesProvider::class);
|
||||
|
||||
$this->provider = new CurrencyConfigDataProvider(
|
||||
$this->config,
|
||||
$this->ratesProvider,
|
||||
);
|
||||
}
|
||||
|
||||
public function testDefaultCurrency()
|
||||
{
|
||||
$this->config
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('defaultCurrency')
|
||||
->willReturn('USD');
|
||||
|
||||
$currency = $this->provider->getDefaultCurrency();
|
||||
|
||||
$this->assertEquals('USD', $currency);
|
||||
}
|
||||
|
||||
public function testBaseCurrency()
|
||||
{
|
||||
$this->config
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('baseCurrency')
|
||||
->willReturn('USD');
|
||||
|
||||
$currency = $this->provider->getBaseCurrency();
|
||||
|
||||
$this->assertEquals('USD', $currency);
|
||||
}
|
||||
|
||||
public function testCurrencyList()
|
||||
{
|
||||
$this->config
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('currencyList')
|
||||
->willReturn(['USD', 'EUR']);
|
||||
|
||||
$result = $this->provider->getCurrencyList();
|
||||
|
||||
$this->assertEquals(['USD', 'EUR'], $result);
|
||||
}
|
||||
|
||||
public function testHasCurrency()
|
||||
{
|
||||
$this->config
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('currencyList')
|
||||
->willReturn(['USD', 'EUR']);
|
||||
|
||||
$result = $this->provider->hasCurrency('EUR');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testCurrencyRate1()
|
||||
{
|
||||
$this->ratesProvider
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn([
|
||||
'EUR' => 1.2,
|
||||
]);
|
||||
|
||||
$invokedCount = $this->exactly(2);
|
||||
|
||||
$this->config
|
||||
->expects($invokedCount)
|
||||
->method('get')
|
||||
->willReturnCallback(function ($param) use ($invokedCount) {
|
||||
if ($invokedCount->numberOfInvocations() === 1) {
|
||||
$this->assertEquals('baseCurrency', $param);
|
||||
|
||||
return 'USD';
|
||||
}
|
||||
|
||||
if ($invokedCount->numberOfInvocations() === 2) {
|
||||
$this->assertEquals('currencyList', $param);
|
||||
|
||||
return ['USD', 'EUR'];
|
||||
}
|
||||
|
||||
throw new RuntimeException();
|
||||
});
|
||||
|
||||
$result = $this->provider->getCurrencyRate('EUR');
|
||||
|
||||
$this->assertEquals(1.2, $result);
|
||||
}
|
||||
|
||||
public function testCurrencyRate2()
|
||||
{
|
||||
$this->ratesProvider
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn([
|
||||
'EUR' => 1.2,
|
||||
]);
|
||||
|
||||
$invokedCount = $this->exactly(2);
|
||||
|
||||
$this->config
|
||||
->expects($invokedCount)
|
||||
->method('get')
|
||||
->willReturnCallback(function ($param) use ($invokedCount) {
|
||||
if ($invokedCount->numberOfInvocations() === 1) {
|
||||
$this->assertEquals('baseCurrency', $param);
|
||||
|
||||
return 'USD';
|
||||
}
|
||||
|
||||
if ($invokedCount->numberOfInvocations() === 2) {
|
||||
$this->assertEquals('currencyList', $param);
|
||||
|
||||
return ['USD', 'EUR'];
|
||||
}
|
||||
|
||||
throw new RuntimeException();
|
||||
});
|
||||
|
||||
$result = $this->provider->getCurrencyRate('USD');
|
||||
|
||||
$this->assertEquals(1.0, $result);
|
||||
}
|
||||
}
|
||||
154
tests/unit/Espo/Core/Field/Currency/CurrencyConverterTest.php
Normal file
154
tests/unit/Espo/Core/Field/Currency/CurrencyConverterTest.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Currency;
|
||||
|
||||
use Espo\Core\{
|
||||
Field\Currency,
|
||||
Currency\Converter as CurrencyConverter,
|
||||
Currency\ConfigDataProvider as CurrencyConfigDataProvider,
|
||||
Currency\Rates as CurrencyRates,
|
||||
};
|
||||
|
||||
class CurrencyConverterTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testConvert1()
|
||||
{
|
||||
$currencyConfigDataProvider = $this->createMock(CurrencyConfigDataProvider::class);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('hasCurrency')
|
||||
->with('EUR')
|
||||
->willReturn(true);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('getCurrencyRate')
|
||||
->willReturnMap([
|
||||
['USD', 1.0],
|
||||
['EUR', 1.2],
|
||||
]);
|
||||
|
||||
$value = new Currency(2.0, 'USD');
|
||||
|
||||
$converter = new CurrencyConverter($currencyConfigDataProvider);
|
||||
|
||||
$convertedValue = $converter->convert($value, 'EUR');
|
||||
|
||||
$this->assertEquals('EUR', $convertedValue->getCode());
|
||||
|
||||
$this->assertEquals(round(2.0 / 1.2, 10), round($convertedValue->getAmount(), 10));
|
||||
}
|
||||
|
||||
public function testConvert2()
|
||||
{
|
||||
$currencyConfigDataProvider = $this->createMock(CurrencyConfigDataProvider::class);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('hasCurrency')
|
||||
->with('EUR')
|
||||
->willReturn(true);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('getCurrencyRate')
|
||||
->willReturnMap([
|
||||
['USD', 1.0],
|
||||
['EUR', 1.2],
|
||||
['UAH', 0.035],
|
||||
]);
|
||||
|
||||
$value = new Currency(2.0, 'UAH');
|
||||
|
||||
$converter = new CurrencyConverter($currencyConfigDataProvider);
|
||||
|
||||
$convertedValue = $converter->convert($value, 'EUR');
|
||||
|
||||
$this->assertEquals('EUR', $convertedValue->getCode());
|
||||
|
||||
$this->assertEquals(round(2.0 * 0.035 / 1.2, 10), round($convertedValue->getAmount(), 10));
|
||||
}
|
||||
|
||||
public function testConvertToDefault()
|
||||
{
|
||||
$currencyConfigDataProvider = $this->createMock(CurrencyConfigDataProvider::class);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('getDefaultCurrency')
|
||||
->willReturn('USD');
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('hasCurrency')
|
||||
->with('USD')
|
||||
->willReturn(true);
|
||||
|
||||
$currencyConfigDataProvider
|
||||
->expects($this->any())
|
||||
->method('getCurrencyRate')
|
||||
->willReturnMap([
|
||||
['USD', 1.0],
|
||||
['EUR', 1.2],
|
||||
]);
|
||||
|
||||
$value = new Currency(2.0, 'EUR');
|
||||
|
||||
$converter = new CurrencyConverter($currencyConfigDataProvider);
|
||||
|
||||
$convertedValue = $converter->convertToDefault($value);
|
||||
|
||||
$this->assertEquals('USD', $convertedValue->getCode());
|
||||
|
||||
$this->assertEquals(round(2.0 * 1.2, 10), round($convertedValue->getAmount(), 10));
|
||||
}
|
||||
|
||||
public function testConvertWithRates()
|
||||
{
|
||||
$currencyConfigDataProvider = $this->createMock(CurrencyConfigDataProvider::class);
|
||||
|
||||
$rates = CurrencyRates::fromAssoc([
|
||||
'USD' => 1.0,
|
||||
'EUR' => 1.2,
|
||||
'UAH' => 0.035,
|
||||
]);
|
||||
|
||||
$value = new Currency(2.0, 'UAH');
|
||||
|
||||
$converter = new CurrencyConverter($currencyConfigDataProvider);
|
||||
|
||||
$convertedValue = $converter->convertWithRates($value, 'EUR', $rates);
|
||||
|
||||
$this->assertEquals('EUR', $convertedValue->getCode());
|
||||
|
||||
$this->assertEquals(round(2.0 * 0.035 / 1.2, 10), round($convertedValue->getAmount(), 10));
|
||||
}
|
||||
}
|
||||
285
tests/unit/Espo/Core/Field/Currency/CurrencyTest.php
Normal file
285
tests/unit/Espo/Core/Field/Currency/CurrencyTest.php
Normal file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Currency;
|
||||
|
||||
use Espo\Core\Field\Currency;
|
||||
use Espo\Core\Field\Currency\CurrencyFactory;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class CurrencyTest extends TestCase
|
||||
{
|
||||
public function testValue1()
|
||||
{
|
||||
$value = Currency::create(2.0, 'USD');
|
||||
|
||||
$this->assertEquals(2.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testValue()
|
||||
{
|
||||
$value = Currency::create(0.5, 'USD');
|
||||
|
||||
$this->assertEquals('0.5', $value->getAmountAsString());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$value = (new Currency(2.0, 'USD'))->add(
|
||||
new Currency(1.0, 'USD')
|
||||
);
|
||||
|
||||
$this->assertEquals(3.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$value = (new Currency(2.0, 'USD'))->subtract(
|
||||
new Currency(3.0, 'USD')
|
||||
);
|
||||
|
||||
$this->assertEquals(-1.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testMultiply1()
|
||||
{
|
||||
$value = (new Currency(2.0, 'USD'))->multiply(3.0);
|
||||
|
||||
$this->assertEquals(6.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testMultiply2()
|
||||
{
|
||||
$value = (new Currency(2.0, 'USD'))->multiply(0.5);
|
||||
|
||||
$this->assertEquals('1.00000000000000', $value->getAmountAsString());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testDivide1()
|
||||
{
|
||||
$value = (new Currency(6.0, 'USD'))->divide(3.0);
|
||||
|
||||
$this->assertEquals(2.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testDivide2()
|
||||
{
|
||||
$value = (new Currency(6.0, 'USD'))->divide(0.5);
|
||||
|
||||
$this->assertEquals('12.00000000000000', $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testRound1()
|
||||
{
|
||||
$value = (new Currency(2.306, 'USD'))->round(2);
|
||||
|
||||
$this->assertEquals(2.31, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testRound2()
|
||||
{
|
||||
$value = (new Currency(2.306, 'USD'))->round(4);
|
||||
|
||||
$this->assertEquals(2.306, $value->getAmount());
|
||||
}
|
||||
|
||||
public function testRound3()
|
||||
{
|
||||
$value = (new Currency(2.306, 'USD'))->round(0);
|
||||
|
||||
$this->assertEquals(2, $value->getAmount());
|
||||
}
|
||||
|
||||
public function testRound4()
|
||||
{
|
||||
$value = (new Currency(-2.306, 'USD'))->round(2);
|
||||
|
||||
$this->assertEquals(-2.31, $value->getAmount());
|
||||
}
|
||||
|
||||
public function testRound5()
|
||||
{
|
||||
$value = (new Currency(-2.5, 'USD'))->round(0);
|
||||
|
||||
$this->assertEquals(-3, $value->getAmount());
|
||||
}
|
||||
|
||||
public function testBadAdd()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
(new Currency(2.0, 'USD'))->add(
|
||||
new Currency(1.0, 'EUR')
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetBadCode()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
new Currency(2.0, '');
|
||||
}
|
||||
|
||||
public function testCreateFromEntity()
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
['test', 10.0],
|
||||
['testCurrency', 'USD'],
|
||||
]);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('has')
|
||||
->willReturnMap([
|
||||
['test', true],
|
||||
['testCurrency', true],
|
||||
]);
|
||||
|
||||
$factory = new CurrencyFactory();
|
||||
|
||||
$value = $factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(10.0, $value->getAmount());
|
||||
$this->assertEquals('USD', $value->getCode());
|
||||
}
|
||||
|
||||
public function testCreatableFromEntityTrue()
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
['test', 5],
|
||||
['testCurrency', 'USD'],
|
||||
]);
|
||||
|
||||
$factory = new CurrencyFactory();
|
||||
|
||||
$this->assertTrue(
|
||||
$factory->isCreatableFromEntity($entity, 'test')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreatableFromEntityFalse()
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
['test', 5.0],
|
||||
['testCurrency', null],
|
||||
]);
|
||||
|
||||
$factory = new CurrencyFactory();
|
||||
|
||||
$this->assertFalse(
|
||||
$factory->isCreatableFromEntity($entity, 'test')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompare1(): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
1,
|
||||
Currency::create(2.0, 'USD')
|
||||
->compare(
|
||||
Currency::create(1.0, 'USD')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompare2(): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
0,
|
||||
Currency::create(2.1, 'USD')
|
||||
->compare(
|
||||
Currency::create(2.1, 'USD')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompare3(): void
|
||||
{
|
||||
$this->assertEquals(
|
||||
-1,
|
||||
Currency::create(2.1, 'USD')
|
||||
->compare(
|
||||
Currency::create(3.1, 'USD')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompare4(): void
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
Currency::create(2.1, 'EUR')
|
||||
->compare(
|
||||
Currency::create(2.1, 'USD')
|
||||
);
|
||||
}
|
||||
|
||||
public function testIsNegative1(): void
|
||||
{
|
||||
$this->assertTrue(Currency::create(-1.0, 'USD')->isNegative());
|
||||
}
|
||||
|
||||
public function testIsNegative2(): void
|
||||
{
|
||||
$this->assertFalse(Currency::create(1.0, 'USD')->isNegative());
|
||||
}
|
||||
|
||||
public function testIsNegative3(): void
|
||||
{
|
||||
$this->assertFalse(Currency::create(0.0, 'USD')->isNegative());
|
||||
}
|
||||
}
|
||||
274
tests/unit/Espo/Core/Field/Date/DateTest.php
Normal file
274
tests/unit/Espo/Core/Field/Date/DateTest.php
Normal file
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Date;
|
||||
|
||||
use Espo\Core\Field\Date;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use DateInterval;
|
||||
|
||||
class DateTest extends TestCase
|
||||
{
|
||||
public function testFromString()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toString());
|
||||
}
|
||||
|
||||
public function testFromDateTime()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01', new DateTimeZone('UTC'));
|
||||
|
||||
$value = Date::fromDateTime($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toString());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
Date::fromString('2021-05-A');
|
||||
}
|
||||
|
||||
public function testBad2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
Date::fromString('2021-05-1');
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
Date::fromString('');
|
||||
}
|
||||
|
||||
public function testGetDateTime()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toDateTime()->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testGetMethods()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$dt = new DateTimeImmutable('2021-05-01', new DateTimeZone('UTC'));
|
||||
|
||||
$this->assertEquals(1, $value->getDay());
|
||||
$this->assertEquals(5, $value->getMonth());
|
||||
$this->assertEquals(2021, $value->getYear());
|
||||
$this->assertEquals(6, $value->getDayOfWeek());
|
||||
|
||||
$this->assertEquals($dt->getTimestamp(), $value->toTimestamp());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->add(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-05-02', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->subtract(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-04-30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testModify()
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->modify('+1 month');
|
||||
|
||||
$this->assertEquals('2021-06-01', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testDiff(): void
|
||||
{
|
||||
$value1 = Date::fromString('2021-05-01');
|
||||
$value2 = Date::fromString('2021-05-02');
|
||||
|
||||
$this->assertEquals(1, $value1->diff($value2)->d);
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testToday(): void
|
||||
{
|
||||
$value1 = Date::createToday();
|
||||
$value2 = Date::createToday(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testComparison(): void
|
||||
{
|
||||
$value = Date::fromString('2021-05-01');
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isEqualTo(
|
||||
$value->modify('+1 day')->modify('-1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isEqualTo(
|
||||
$value->modify('+1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('+1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isLessThan(
|
||||
$value->modify('-1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('-1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThan(
|
||||
$value->modify('+1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value->modify('-1 day')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value->modify('+1 day')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddDays(): void
|
||||
{
|
||||
$value = Date::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2023-01-02'),
|
||||
$value->addDays(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2023-01-03'),
|
||||
$value->addDays(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2022-12-31'),
|
||||
$value->addDays(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMonths(): void
|
||||
{
|
||||
$value = Date::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2023-02-01'),
|
||||
$value->addMonths(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2023-03-01'),
|
||||
$value->addMonths(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2022-12-01'),
|
||||
$value->addMonths(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddYears(): void
|
||||
{
|
||||
$value = Date::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2024-01-01'),
|
||||
$value->addYears(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2025-01-01'),
|
||||
$value->addYears(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
Date::fromString('2022-01-01'),
|
||||
$value->addYears(-1)
|
||||
);
|
||||
}
|
||||
}
|
||||
408
tests/unit/Espo/Core/Field/DateTime/DateTimeTest.php
Normal file
408
tests/unit/Espo/Core/Field/DateTime/DateTimeTest.php
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\DateTime;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
use DateInterval;
|
||||
|
||||
class DateTimeTest extends TestCase
|
||||
{
|
||||
public function testFromString1()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
}
|
||||
|
||||
public function testFromString2()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20');
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:00', $value->toString());
|
||||
}
|
||||
|
||||
public function testFromDateTime1()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('UTC'));
|
||||
|
||||
$value = DateTime::fromDateTime($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
}
|
||||
|
||||
public function testFromDateTime2()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$value = DateTime::fromDateTime($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01 07:20:30', $value->toString());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTime::fromString('2021-05-A 10:20:30');
|
||||
}
|
||||
|
||||
public function testBad2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTime::fromString('2021-05-1 10:20:30');
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTime::fromString('');
|
||||
}
|
||||
|
||||
public function testGetDateTime()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toDateTime()->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testGetMethods()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('UTC'));
|
||||
|
||||
$this->assertEquals(1, $value->getDay());
|
||||
$this->assertEquals(5, $value->getMonth());
|
||||
$this->assertEquals(2021, $value->getYear());
|
||||
$this->assertEquals(6, $value->getDayOfWeek());
|
||||
$this->assertEquals(10, $value->getHour());
|
||||
$this->assertEquals(20, $value->getMinute());
|
||||
$this->assertEquals(30, $value->getSecond());
|
||||
|
||||
$this->assertEquals($dt->getTimestamp(), $value->toTimestamp());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->add(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-05-02 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->subtract(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-04-30 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testModify()
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->modify('+1 month');
|
||||
|
||||
$this->assertEquals('2021-06-01 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testWithTimezone()
|
||||
{
|
||||
$value = DateTime
|
||||
::fromString('2021-05-01 10:20:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
|
||||
$this->assertEquals(13, $value->getHour());
|
||||
}
|
||||
|
||||
public function getGetTimezone()
|
||||
{
|
||||
$value = DateTime
|
||||
::fromString('2021-05-01 10:20:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals(new DateTimeZone('Europe/Kyiv'), $value->getTimezone());
|
||||
}
|
||||
|
||||
public function testDiff(): void
|
||||
{
|
||||
$value1 = DateTime::fromString('2021-05-01 10:10:30');
|
||||
$value2 = DateTime::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals(10, $value1->diff($value2)->i);
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testNow(): void
|
||||
{
|
||||
$value = DateTime::createNow();
|
||||
|
||||
$this->assertNotNull($value);
|
||||
}
|
||||
|
||||
public function testWithTime(): void
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:10:30');
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:00',
|
||||
$value->withTime(0, 0, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:10:30',
|
||||
$value->withTime(0, null, null)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 10:00:00',
|
||||
$value->withTime(null, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 10:00:10',
|
||||
$value->withTime(null, 0, 10)->toString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testComparison(): void
|
||||
{
|
||||
$value = DateTime::fromString('2021-05-01 10:10:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isEqualTo(
|
||||
$value->withTimezone(new DateTimeZone('UTC'))
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isEqualTo(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isLessThan(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThan(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddDays(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-01-02 00:00:00'),
|
||||
$value->addDays(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-01-03 00:00:00'),
|
||||
$value->addDays(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-12-31 00:00:00'),
|
||||
$value->addDays(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMonths(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-02-01 00:00:00'),
|
||||
$value->addMonths(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-03-01 00:00:00'),
|
||||
$value->addMonths(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-12-01 00:00:00'),
|
||||
$value->addMonths(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddYears(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2024-01-01 00:00:00'),
|
||||
$value->addYears(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2025-01-01 00:00:00'),
|
||||
$value->addYears(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-01-01 00:00:00'),
|
||||
$value->addYears(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddHours(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-01-01 01:00:00'),
|
||||
$value->addHours(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-12-31 23:00:00'),
|
||||
$value->addHours(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addHours(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMinutes(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-01-01 00:01:00'),
|
||||
$value->addMinutes(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-12-31 23:59:00'),
|
||||
$value->addMinutes(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addMinutes(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddSeconds(): void
|
||||
{
|
||||
$value = DateTime::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2023-01-01 00:00:01'),
|
||||
$value->addSeconds(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTime::fromString('2022-12-31 23:59:59'),
|
||||
$value->addSeconds(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addSeconds(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testFromTimestamp(): void
|
||||
{
|
||||
$timestamp = 1664959621;
|
||||
|
||||
$value = DateTime::fromTimestamp($timestamp);
|
||||
|
||||
$this->assertEquals($timestamp, $value->toTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\DateTimeOptional;
|
||||
|
||||
use Espo\Core\Field\DateTimeOptional;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
use DateInterval;
|
||||
|
||||
class DateTimeOptionalDateTest extends TestCase
|
||||
{
|
||||
public function testFromString()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toString());
|
||||
|
||||
$this->assertTrue($value->isAllDay());
|
||||
}
|
||||
|
||||
public function testFromDateTime()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01', new DateTimeZone('UTC'));
|
||||
|
||||
$value = DateTimeOptional::fromDateTimeAllDay($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toString());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('2021-05-A');
|
||||
}
|
||||
|
||||
public function testBad2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('2021-05-1');
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('');
|
||||
}
|
||||
|
||||
public function testGetDateTime()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toDateTime()->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testGetTimezone()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals(new DateTimeZone('UTC'), $value->toDateTime()->getTimezone());
|
||||
}
|
||||
|
||||
public function testGetMethods()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$dt = new DateTimeImmutable('2021-05-01', new DateTimeZone('UTC'));
|
||||
|
||||
$this->assertEquals(1, $value->getDay());
|
||||
$this->assertEquals(5, $value->getMonth());
|
||||
$this->assertEquals(2021, $value->getYear());
|
||||
$this->assertEquals(6, $value->getDayOfWeek());
|
||||
|
||||
$this->assertEquals($dt->getTimestamp(), $value->toTimestamp());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->add(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-05-02', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->subtract(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-04-30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testModify()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$modifiedValue = $value->modify('+1 month');
|
||||
|
||||
$this->assertEquals('2021-06-01', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testWithTimezone()
|
||||
{
|
||||
$value = DateTimeOptional
|
||||
::fromString('2021-05-01')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals('2021-05-01 00:00:00', $value->toString());
|
||||
|
||||
$this->assertEquals(new DateTimeZone('Europe/Kyiv'), $value->getTimezone());
|
||||
|
||||
$this->assertFalse($value->isAllDay());
|
||||
}
|
||||
|
||||
public function testDiff(): void
|
||||
{
|
||||
$value1 = DateTimeOptional::fromString('2021-05-01');
|
||||
$value2 = DateTimeOptional::fromString('2021-05-02');
|
||||
|
||||
$this->assertEquals(1, $value1->diff($value2)->d);
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testToday(): void
|
||||
{
|
||||
$value1 = DateTimeOptional::createToday();
|
||||
$value2 = DateTimeOptional::createToday(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testAddDays(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-02'),
|
||||
$value->addDays(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-03'),
|
||||
$value->addDays(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-31'),
|
||||
$value->addDays(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMonths(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-02-01'),
|
||||
$value->addMonths(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-03-01'),
|
||||
$value->addMonths(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-01'),
|
||||
$value->addMonths(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddYears(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2024-01-01'),
|
||||
$value->addYears(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2025-01-01'),
|
||||
$value->addYears(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-01-01'),
|
||||
$value->addYears(-1)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\DateTimeOptionalTest;
|
||||
|
||||
use Espo\Core\Field\DateTimeOptional;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
use DateInterval;
|
||||
|
||||
class DateTimeOptionalTest extends TestCase
|
||||
{
|
||||
public function testFromString1()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
|
||||
$this->assertFalse($value->isAllDay());
|
||||
}
|
||||
|
||||
public function testFromString2()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20');
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:00', $value->toString());
|
||||
|
||||
$this->assertFalse($value->isAllDay());
|
||||
}
|
||||
|
||||
public function testFromDateTime1()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('UTC'));
|
||||
|
||||
$value = DateTimeOptional::fromDateTime($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
}
|
||||
|
||||
public function testFromDateTime2()
|
||||
{
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$value = DateTimeOptional::fromDateTime($dt);
|
||||
|
||||
$this->assertEquals('2021-05-01 07:20:30', $value->toString());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('2021-05-A 10:20:30');
|
||||
}
|
||||
|
||||
public function testBad2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('2021-05-1 10:20:30');
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
DateTimeOptional::fromString('');
|
||||
}
|
||||
|
||||
public function testGetDateTime()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals('2021-05-01', $value->toDateTime()->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function testGetMethods()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$dt = new DateTimeImmutable('2021-05-01 10:20:30', new DateTimeZone('UTC'));
|
||||
|
||||
$this->assertEquals(1, $value->getDay());
|
||||
$this->assertEquals(5, $value->getMonth());
|
||||
$this->assertEquals(2021, $value->getYear());
|
||||
$this->assertEquals(6, $value->getDayOfWeek());
|
||||
$this->assertEquals(10, $value->getHour());
|
||||
$this->assertEquals(20, $value->getMinute());
|
||||
$this->assertEquals(30, $value->getSecond());
|
||||
|
||||
$this->assertEquals($dt->getTimestamp(), $value->getTimestamp());
|
||||
}
|
||||
|
||||
public function testAdd()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->add(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-05-02 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testSubtract()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->subtract(DateInterval::createFromDateString('1 day'));
|
||||
|
||||
$this->assertEquals('2021-04-30 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testModify()
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$modifiedValue = $value->modify('+1 month');
|
||||
|
||||
$this->assertEquals('2021-06-01 10:20:30', $modifiedValue->toString());
|
||||
|
||||
$this->assertNotSame($modifiedValue, $value);
|
||||
}
|
||||
|
||||
public function testWithTimezone()
|
||||
{
|
||||
$value = DateTimeOptional
|
||||
::fromString('2021-05-01 10:20:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals('2021-05-01 10:20:30', $value->toString());
|
||||
|
||||
$this->assertEquals(13, $value->getHour());
|
||||
}
|
||||
|
||||
public function getGetTimezone()
|
||||
{
|
||||
$value = DateTimeOptional
|
||||
::fromString('2021-05-01 10:20:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertEquals(new DateTimeZone('Europe/Kyiv'), $value->getTimezone());
|
||||
}
|
||||
|
||||
public function testDiff(): void
|
||||
{
|
||||
$value1 = DateTimeOptional::fromString('2021-05-01 10:10:30');
|
||||
$value2 = DateTimeOptional::fromString('2021-05-01 10:20:30');
|
||||
|
||||
$this->assertEquals(10, $value1->diff($value2)->i);
|
||||
$this->assertEquals(0, $value1->diff($value2)->invert);
|
||||
}
|
||||
|
||||
public function testNow(): void
|
||||
{
|
||||
$value = DateTimeOptional::createNow();
|
||||
|
||||
$this->assertNotNull($value);
|
||||
}
|
||||
|
||||
|
||||
public function testWithTime1(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:10:30');
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:00',
|
||||
$value->withTime(0, 0, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:10:30',
|
||||
$value->withTime(0, null, null)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 10:00:00',
|
||||
$value->withTime(null, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 10:00:10',
|
||||
$value->withTime(null, 0, 10)->toString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testWithTime2(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01');
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:00',
|
||||
$value->withTime(0, 0, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:00',
|
||||
$value->withTime(0, null, null)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:00',
|
||||
$value->withTime(null, 0)->toString()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'2021-05-01 00:00:10',
|
||||
$value->withTime(null, 0, 10)->toString()
|
||||
);
|
||||
}
|
||||
|
||||
public function testComparison(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2021-05-01 10:10:30')
|
||||
->withTimezone(new DateTimeZone('Europe/Kyiv'));
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isEqualTo(
|
||||
$value->withTimezone(new DateTimeZone('UTC'))
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isEqualTo(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$value->isLessThan(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThan(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThan(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isGreaterThanOrEqualTo(
|
||||
$value->modify('-1 minute')
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$value->isLessThanOrEqualTo(
|
||||
$value->modify('+1 minute')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddDays(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-02 00:00:00'),
|
||||
$value->addDays(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-03 00:00:00'),
|
||||
$value->addDays(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-31 00:00:00'),
|
||||
$value->addDays(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMonths(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-02-01 00:00:00'),
|
||||
$value->addMonths(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-03-01 00:00:00'),
|
||||
$value->addMonths(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-01 00:00:00'),
|
||||
$value->addMonths(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddYears(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2024-01-01 00:00:00'),
|
||||
$value->addYears(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2025-01-01 00:00:00'),
|
||||
$value->addYears(2)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-01-01 00:00:00'),
|
||||
$value->addYears(-1)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddHours(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-01 01:00:00'),
|
||||
$value->addHours(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-31 23:00:00'),
|
||||
$value->addHours(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addHours(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMinutes(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-01 00:01:00'),
|
||||
$value->addMinutes(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-31 23:59:00'),
|
||||
$value->addMinutes(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addMinutes(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddSeconds(): void
|
||||
{
|
||||
$value = DateTimeOptional::fromString('2023-01-01 00:00:00');
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2023-01-01 00:00:01'),
|
||||
$value->addSeconds(1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
DateTimeOptional::fromString('2022-12-31 23:59:59'),
|
||||
$value->addSeconds(-1)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$value->addSeconds(0)
|
||||
);
|
||||
}
|
||||
|
||||
public function testFromTimestamp(): void
|
||||
{
|
||||
$timestamp = 1664959621;
|
||||
|
||||
$value = DateTimeOptional::fromTimestamp($timestamp);
|
||||
|
||||
$this->assertEquals($timestamp, $value->getTimestamp());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\EmailAddress;
|
||||
|
||||
use Espo\Core\Field\EmailAddress;
|
||||
use Espo\Core\Field\EmailAddress\EmailAddressGroupAttributeExtractor;
|
||||
use Espo\Core\Field\EmailAddressGroup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EmailAddressGroupAttributeExtractorTest extends TestCase
|
||||
{
|
||||
public function testExtract()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('ONE@test.com'),
|
||||
EmailAddress::create('two@test.com')->optedOut(),
|
||||
]);
|
||||
|
||||
$valueMap = (new EmailAddressGroupAttributeExtractor())->extract($group, 'emailAddress');
|
||||
|
||||
$this->assertEquals(
|
||||
(object) [
|
||||
'emailAddress' => 'ONE@test.com',
|
||||
'emailAddressData' => [
|
||||
(object) [
|
||||
'emailAddress' => 'ONE@test.com',
|
||||
'lower' => 'one@test.com',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'emailAddress' => 'two@test.com',
|
||||
'lower' => 'two@test.com',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
]
|
||||
],
|
||||
$valueMap
|
||||
);
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([]);
|
||||
|
||||
$valueMap = (new EmailAddressGroupAttributeExtractor())->extract($group, 'emailAddress');
|
||||
|
||||
$this->assertEquals(
|
||||
(object) [
|
||||
'emailAddress' => null,
|
||||
'emailAddressData' => [],
|
||||
],
|
||||
$valueMap
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\EmailAddress;
|
||||
|
||||
use Espo\Core\Field\EmailAddress\EmailAddressGroupFactory;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Repositories\EmailAddress as EmailAddressRepository;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use RuntimeException;
|
||||
|
||||
class EmailAddressGroupFactoryTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Metadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
/**
|
||||
* @var EmailAddressRepository
|
||||
*/
|
||||
private $emailAddressRepository;
|
||||
|
||||
/**
|
||||
* @var EmailAddressGroupFactory
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
public function setUp() : void
|
||||
{
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
|
||||
$entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$this->emailAddressRepository = $this->createMock(EmailAddressRepository::class);
|
||||
|
||||
$this->factory = new EmailAddressGroupFactory($this->metadata, $entityManager);
|
||||
|
||||
$entityManager
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->with('EmailAddress')
|
||||
->willReturn($this->emailAddressRepository);
|
||||
}
|
||||
|
||||
private function initField(string $entityType, string $field, string $type) : void
|
||||
{
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->with(['entityDefs', $entityType, 'fields', $field, 'type'])
|
||||
->willReturn($type);
|
||||
}
|
||||
|
||||
private function createEntityMock(string $entityType) : Entity
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('getEntityType')
|
||||
->willReturn($entityType);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function initEmailAddressRepository(Entity $entity, array $dataList) : void
|
||||
{
|
||||
$this->emailAddressRepository
|
||||
->expects($this->once())
|
||||
->method('getEmailAddressData')
|
||||
->with($entity)
|
||||
->willReturn($dataList);
|
||||
}
|
||||
|
||||
public function testIsCreatableFromEntityTrue() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'email');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->assertTrue($this->factory->isCreatableFromEntity($entity, 'test'));
|
||||
}
|
||||
|
||||
public function testIsCreatableFromEntityBad() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'varchar');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->assertFalse($this->factory->isCreatableFromEntity($entity, 'test'));
|
||||
}
|
||||
|
||||
public function testCreateException() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'varchar');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
$this->factory->createFromEntity($entity, 'test');
|
||||
}
|
||||
|
||||
public function testCreateFromEmailAddressRepository() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'email');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [
|
||||
(object) [
|
||||
'emailAddress' => 'ONE@test.com',
|
||||
'lower' => 'one@test.com',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'emailAddress' => 'TWO@test.com',
|
||||
'lower' => 'two@test.com',
|
||||
'primary' => false,
|
||||
'optOut' => false,
|
||||
'invalid' => true,
|
||||
],
|
||||
(object) [
|
||||
'emailAddress' => 'THREE@test.com',
|
||||
'lower' => 'three@test.com',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$this->initEmailAddressRepository($entity, $dataList);
|
||||
|
||||
$entity
|
||||
->method('has')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', false],
|
||||
['test', true],
|
||||
]
|
||||
);
|
||||
|
||||
$entity
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', null],
|
||||
['test', 'ONE@test.com'],
|
||||
]
|
||||
);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(3, $group->getCount());
|
||||
|
||||
$one = $group->getList()[0];
|
||||
$two = $group->getList()[1];
|
||||
$three = $group->getList()[2];
|
||||
|
||||
$this->assertEquals('ONE@test.com', $one->getAddress());
|
||||
|
||||
$this->assertTrue($two->isInvalid());
|
||||
|
||||
$this->assertTrue($three->isOptedOut());
|
||||
|
||||
$this->assertEquals('ONE@test.com', $group->getPrimary()->getAddress());
|
||||
}
|
||||
|
||||
public function testCreateFromDataAttribute() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'email');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [
|
||||
(object) [
|
||||
'emailAddress' => 'ONE@test.com',
|
||||
'lower' => 'one@test.com',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'emailAddress' => 'TWO@test.com',
|
||||
'lower' => 'two@test.com',
|
||||
'primary' => false,
|
||||
'optOut' => false,
|
||||
'invalid' => true,
|
||||
],
|
||||
(object) [
|
||||
'emailAddress' => 'THREE@test.com',
|
||||
'lower' => 'three@test.com',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$entity
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with('testData')
|
||||
->willReturn(true);
|
||||
|
||||
$entity
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('testData')
|
||||
->willReturn($dataList);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(3, $group->getCount());
|
||||
|
||||
$one = $group->getList()[0];
|
||||
$two = $group->getList()[1];
|
||||
$three = $group->getList()[2];
|
||||
|
||||
$this->assertEquals('ONE@test.com', $one->getAddress());
|
||||
|
||||
$this->assertTrue($two->isInvalid());
|
||||
|
||||
$this->assertTrue($three->isOptedOut());
|
||||
|
||||
$this->assertEquals('ONE@test.com', $group->getPrimary()->getAddress());
|
||||
}
|
||||
|
||||
public function testCreateEmpty1() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'email');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [];
|
||||
|
||||
$this->initEmailAddressRepository($entity, $dataList);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testCreateEmpty2() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'email');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [];
|
||||
|
||||
$this->initEmailAddressRepository($entity, $dataList);
|
||||
|
||||
$entity
|
||||
->method('has')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', false],
|
||||
['test', true],
|
||||
]
|
||||
);
|
||||
|
||||
$entity
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', null],
|
||||
['test', null],
|
||||
]
|
||||
);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\EmailAddress;
|
||||
|
||||
use Espo\Core\Field\EmailAddress;
|
||||
use Espo\Core\Field\EmailAddressGroup;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EmailAddressGroupTest extends TestCase
|
||||
{
|
||||
public function testEmpty()
|
||||
{
|
||||
$group = EmailAddressGroup::create();
|
||||
|
||||
$this->assertEquals(0, count($group->getAddressList()));
|
||||
$this->assertEquals(0, count($group->getSecondaryList()));
|
||||
|
||||
$this->assertNull($group->getPrimary());
|
||||
$this->assertNull($group->getPrimaryAddress());
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testDuplicate1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('one@test.com'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testDuplicate2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('ONE@test.com'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testWithPrimary1()
|
||||
{
|
||||
$primary = EmailAddress::create('primary@test.com')->invalid();
|
||||
|
||||
$group = EmailAddressGroup
|
||||
::create()
|
||||
->withPrimary($primary);
|
||||
|
||||
$this->assertEquals(1, count($group->getList()));
|
||||
$this->assertEquals(0, count($group->getSecondaryList()));
|
||||
|
||||
$this->assertNotNull($group->getPrimary());
|
||||
|
||||
$this->assertEquals('primary@test.com', $group->getPrimary()->getAddress());
|
||||
$this->assertEquals('primary@test.com', $group->getPrimaryAddress());
|
||||
|
||||
$primaryAnother = EmailAddress::create('primaryAnother@test.com');
|
||||
|
||||
$groupAnother = $group->withPrimary($primaryAnother);
|
||||
|
||||
$this->assertEquals(2, count($groupAnother->getList()));
|
||||
$this->assertEquals(1, count($groupAnother->getSecondaryList()));
|
||||
|
||||
$this->assertEquals('primaryAnother@test.com', $groupAnother->getPrimary()->getAddress());
|
||||
|
||||
|
||||
$this->assertEquals('primary@test.com', $groupAnother->getList()[1]->getAddress());
|
||||
$this->assertTrue($groupAnother->getList()[1]->isInvalid());
|
||||
|
||||
$this->assertTrue($groupAnother->hasAddress('primary@test.com'));
|
||||
$this->assertTrue($groupAnother->hasAddress('primaryAnother@test.com'));
|
||||
}
|
||||
|
||||
public function testWithPrimary2()
|
||||
{
|
||||
$address = EmailAddress::create('one@test.com')->invalid();
|
||||
|
||||
$group = EmailAddressGroup
|
||||
::create([$address])
|
||||
->withAdded(
|
||||
EmailAddress::create('two@test.com')
|
||||
)
|
||||
->withPrimary(
|
||||
EmailAddress::create('two@test.com')
|
||||
);
|
||||
|
||||
$this->assertEquals('two@test.com', $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithAdded1()
|
||||
{
|
||||
$address = EmailAddress::create('one@test.com')->invalid();
|
||||
|
||||
$group = EmailAddressGroup
|
||||
::create([$address])
|
||||
->withAdded(
|
||||
EmailAddress::create('two@test.com')
|
||||
);
|
||||
|
||||
$this->assertEquals('one@test.com', $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
}
|
||||
|
||||
public function testWithAddedList()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create()
|
||||
->withAddedList([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
]);
|
||||
|
||||
$this->assertEquals('one@test.com', $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved1()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
EmailAddress::create('three@test.com'),
|
||||
])
|
||||
->withRemoved(EmailAddress::create('two@test.com'));
|
||||
|
||||
$this->assertEquals('one@test.com', $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved2()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
EmailAddress::create('three@test.com'),
|
||||
])
|
||||
->withRemoved(EmailAddress::create('one@test.com'));
|
||||
|
||||
$this->assertEquals('two@test.com', $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved3()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
])
|
||||
->withRemoved(EmailAddress::create('one@test.com'));
|
||||
|
||||
$this->assertNull($group->getPrimary());
|
||||
|
||||
$this->assertEquals(0, count($group->getList()));
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testHasAddress()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
]);
|
||||
|
||||
$this->assertTrue($group->hasAddress('one@test.com'));
|
||||
$this->assertTrue($group->hasAddress('two@test.com'));
|
||||
|
||||
$this->assertFalse($group->hasAddress('four@test.com'));
|
||||
}
|
||||
|
||||
public function testGetByAddress()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
EmailAddress::create('three@test.com'),
|
||||
]);
|
||||
|
||||
$this->assertEquals('one@test.com', $group->getByAddress('one@test.com')->getAddress());
|
||||
|
||||
$this->assertNull($group->getByAddress('four@test.com'));
|
||||
}
|
||||
|
||||
public function testClone()
|
||||
{
|
||||
$group = EmailAddressGroup
|
||||
::create([
|
||||
EmailAddress::create('one@test.com'),
|
||||
EmailAddress::create('two@test.com'),
|
||||
EmailAddress::create('three@test.com'),
|
||||
]);
|
||||
|
||||
$cloned = clone $group;
|
||||
|
||||
$this->assertEquals('one@test.com', $cloned->getByAddress('one@test.com')->getAddress());
|
||||
|
||||
$this->assertEquals($cloned->getPrimary()->getAddress(), $group->getPrimary()->getAddress());
|
||||
|
||||
$this->assertNotSame($cloned->getPrimary(), $group->getPrimary());
|
||||
|
||||
$this->assertNotSame($cloned->getList()[1], $group->getList()[1]);
|
||||
}
|
||||
}
|
||||
82
tests/unit/Espo/Core/Field/EmailAddress/EmailAddressTest.php
Normal file
82
tests/unit/Espo/Core/Field/EmailAddress/EmailAddressTest.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\EmailAddress;
|
||||
|
||||
use Espo\Core\Field\EmailAddress;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EmailAddressTest extends TestCase
|
||||
{
|
||||
public function testInvalidAddress()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
EmailAddress::create('one');
|
||||
}
|
||||
|
||||
public function testInvalidEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
EmailAddress::create('');
|
||||
}
|
||||
|
||||
public function testCloneInvalid()
|
||||
{
|
||||
$address = EmailAddress::create('test@test.com')->invalid();
|
||||
|
||||
$this->assertEquals('test@test.com', $address->getAddress());
|
||||
|
||||
$this->assertTrue($address->isInvalid());
|
||||
$this->assertFalse($address->isOptedOut());
|
||||
}
|
||||
|
||||
public function testCloneOptedOut()
|
||||
{
|
||||
$address = EmailAddress::create('test@test.com')->optedOut();
|
||||
|
||||
$this->assertFalse($address->isInvalid());
|
||||
$this->assertTrue($address->isOptedOut());
|
||||
}
|
||||
|
||||
public function testCloneNotOptedOut()
|
||||
{
|
||||
$address = EmailAddress::create('test@test.com')
|
||||
->optedOut()
|
||||
->notOptedOut()
|
||||
->invalid()
|
||||
->notInvalid();
|
||||
|
||||
$this->assertFalse($address->isInvalid());
|
||||
$this->assertFalse($address->isOptedOut());
|
||||
}
|
||||
}
|
||||
60
tests/unit/Espo/Core/Field/Link/LinkTest.php
Normal file
60
tests/unit/Espo/Core/Field/Link/LinkTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\Link;
|
||||
|
||||
use Espo\Core\Field\Link;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class LinkTest extends TestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$value = Link::create('id');
|
||||
|
||||
$this->assertEquals('id', $value->getId());
|
||||
$this->assertEquals(null, $value->getName());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
Link::create('');
|
||||
}
|
||||
|
||||
public function testWithName()
|
||||
{
|
||||
$value = Link::create('id')->withName('Name');
|
||||
|
||||
$this->assertEquals('Name', $value->getName());
|
||||
}
|
||||
}
|
||||
179
tests/unit/Espo/Core/Field/LinkMultiple/LinkMultipleTest.php
Normal file
179
tests/unit/Espo/Core/Field/LinkMultiple/LinkMultipleTest.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\LinkMultiple;
|
||||
|
||||
use Espo\Core\Field\LinkMultiple;
|
||||
use Espo\Core\Field\LinkMultipleItem;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class LinkMultipleTest extends TestCase
|
||||
{
|
||||
public function testEmpty()
|
||||
{
|
||||
$value = LinkMultiple::create();
|
||||
|
||||
$this->assertEquals(0, count($value->getIdList()));
|
||||
$this->assertEquals(0, count($value->getList()));
|
||||
$this->assertEquals(0, $value->getCount());
|
||||
}
|
||||
|
||||
public function testDuplicate()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
LinkMultiple
|
||||
::create([
|
||||
LinkMultipleItem::create('1'),
|
||||
LinkMultipleItem::create('1'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testWithAdded1()
|
||||
{
|
||||
$item = LinkMultipleItem::create('1')->withName('test-1');
|
||||
|
||||
$group = LinkMultiple
|
||||
::create([$item])
|
||||
->withAdded(
|
||||
LinkMultipleItem::create('2')
|
||||
);
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
|
||||
$this->assertEquals('1', $group->getList()[0]->getId());
|
||||
$this->assertEquals('test-1', $group->getList()[0]->getName());
|
||||
|
||||
$this->assertEquals(null, $group->getList()[1]->getName());
|
||||
}
|
||||
|
||||
public function testWithAddedId()
|
||||
{
|
||||
$item = LinkMultipleItem::create('1')->withName('test-1');
|
||||
|
||||
$group = LinkMultiple
|
||||
::create([$item])
|
||||
->withAddedId('2');
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
|
||||
$this->assertEquals('1', $group->getList()[0]->getId());
|
||||
$this->assertEquals('test-1', $group->getList()[0]->getName());
|
||||
|
||||
$this->assertEquals('2', $group->getList()[1]->getId());
|
||||
}
|
||||
|
||||
public function testWithAddedIdList(): void
|
||||
{
|
||||
$item = LinkMultipleItem::create('1')->withName('test-1');
|
||||
|
||||
$group = LinkMultiple
|
||||
::create([$item])
|
||||
->withAddedIdList(['2', '3']);
|
||||
|
||||
$this->assertEquals(3, $group->getCount());
|
||||
|
||||
$this->assertEquals('1', $group->getList()[0]->getId());
|
||||
$this->assertEquals('test-1', $group->getList()[0]->getName());
|
||||
|
||||
$this->assertEquals('2', $group->getList()[1]->getId());
|
||||
}
|
||||
|
||||
public function testWithAddedList()
|
||||
{
|
||||
$group = LinkMultiple
|
||||
::create()
|
||||
->withAddedList([
|
||||
LinkMultipleItem::create('1'),
|
||||
LinkMultipleItem::create('2'),
|
||||
]);
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
}
|
||||
|
||||
public function testWithRemoved1()
|
||||
{
|
||||
$group = LinkMultiple
|
||||
::create([
|
||||
LinkMultipleItem::create('1'),
|
||||
LinkMultipleItem::create('2'),
|
||||
LinkMultipleItem::create('3'),
|
||||
])
|
||||
->withRemoved(LinkMultipleItem::create('1'));
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
}
|
||||
|
||||
public function testGetById()
|
||||
{
|
||||
$group = LinkMultiple
|
||||
::create([
|
||||
LinkMultipleItem::create('1'),
|
||||
LinkMultipleItem::create('2'),
|
||||
LinkMultipleItem::create('3'),
|
||||
]);
|
||||
|
||||
$this->assertEquals('1', $group->getById('1')->getId());
|
||||
|
||||
$this->assertNull($group->getById('4'));
|
||||
}
|
||||
|
||||
public function testClone()
|
||||
{
|
||||
$group = LinkMultiple
|
||||
::create([
|
||||
LinkMultipleItem::create('1'),
|
||||
LinkMultipleItem::create('2'),
|
||||
LinkMultipleItem::create('3'),
|
||||
]);
|
||||
|
||||
$cloned = clone $group;
|
||||
|
||||
$this->assertEquals('1', $cloned->getById('1')->getId());
|
||||
|
||||
$this->assertNotSame($cloned->getList()[1], $group->getList()[1]);
|
||||
}
|
||||
|
||||
public function testItemColumn()
|
||||
{
|
||||
$item = LinkMultipleItem
|
||||
::create('1')
|
||||
->withColumnValue('key', 'value');
|
||||
|
||||
$this->assertTrue($item->hasColumnValue('key'));
|
||||
|
||||
$this->assertFalse($item->hasColumnValue('key-bad'));
|
||||
|
||||
$this->assertEquals('value', $item->getColumnValue('key'));
|
||||
|
||||
$this->assertEquals(['key'], $item->getColumnList());
|
||||
}
|
||||
}
|
||||
68
tests/unit/Espo/Core/Field/LinkParent/LinkParentTest.php
Normal file
68
tests/unit/Espo/Core/Field/LinkParent/LinkParentTest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\LinkParent;
|
||||
|
||||
use Espo\Core\Field\LinkParent;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LinkParentTest extends TestCase
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$value = LinkParent::create('Test', 'id');
|
||||
|
||||
$this->assertEquals('Test', $value->getEntityType());
|
||||
$this->assertEquals('id', $value->getId());
|
||||
$this->assertEquals(null, $value->getName());
|
||||
}
|
||||
|
||||
public function testBad1()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
LinkParent::create('Test', '');
|
||||
}
|
||||
|
||||
public function testBad2()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
LinkParent::create('', 'id');
|
||||
}
|
||||
|
||||
public function testWithName()
|
||||
{
|
||||
$value = LinkParent::create('Test', 'id')->withName('Name');
|
||||
|
||||
$this->assertEquals('Name', $value->getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\PhoneNumber;
|
||||
|
||||
use Espo\Core\Field\PhoneNumber;
|
||||
use Espo\Core\Field\PhoneNumber\PhoneNumberGroupAttributeExtractor;
|
||||
use Espo\Core\Field\PhoneNumberGroup;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PhoneNumberGroupAttributeExtractorTest extends TestCase
|
||||
{
|
||||
public function testExtract()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+1')->withType('Test-1'),
|
||||
PhoneNumber::create('+2')->withType('Test-2')->optedOut(),
|
||||
]);
|
||||
|
||||
$valueMap = (new PhoneNumberGroupAttributeExtractor())->extract($group, 'phoneNumber');
|
||||
|
||||
$this->assertEquals(
|
||||
(object) [
|
||||
'phoneNumber' => '+1',
|
||||
'phoneNumberData' => [
|
||||
(object) [
|
||||
'phoneNumber' => '+1',
|
||||
'type' => 'Test-1',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'phoneNumber' => '+2',
|
||||
'type' => 'Test-2',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
]
|
||||
],
|
||||
$valueMap
|
||||
);
|
||||
}
|
||||
|
||||
public function testEmpty()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([]);
|
||||
|
||||
$valueMap = (new PhoneNumberGroupAttributeExtractor())->extract($group, 'phoneNumber');
|
||||
|
||||
$this->assertEquals(
|
||||
(object) [
|
||||
'phoneNumber' => null,
|
||||
'phoneNumberData' => [],
|
||||
],
|
||||
$valueMap
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\PhoneNumber;
|
||||
|
||||
use Espo\Core\Field\PhoneNumber\PhoneNumberGroupFactory;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
use Espo\Repositories\PhoneNumber as PhoneNumberRepository;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
||||
class PhoneNumberGroupFactoryTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Metadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* @var PhoneNumberRepository
|
||||
*/
|
||||
private $phoneNumberRepository;
|
||||
|
||||
/**
|
||||
* @var PhoneNumberGroupFactory
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
public function setUp() : void
|
||||
{
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
|
||||
$this->entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$this->phoneNumberRepository = $this->createMock(PhoneNumberRepository::class);
|
||||
|
||||
$this->factory = new PhoneNumberGroupFactory($this->metadata, $this->entityManager);
|
||||
|
||||
$this->entityManager
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->with('PhoneNumber')
|
||||
->willReturn($this->phoneNumberRepository);
|
||||
}
|
||||
|
||||
private function initField(string $entityType, string $field, string $type) : void
|
||||
{
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->with(['entityDefs', $entityType, 'fields', $field, 'type'])
|
||||
->willReturn($type);
|
||||
}
|
||||
|
||||
private function createEntityMock(string $entityType) : Entity
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('getEntityType')
|
||||
->willReturn($entityType);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function initPhoneNumberRepository(Entity $entity, array $dataList) : void
|
||||
{
|
||||
$this->phoneNumberRepository
|
||||
->expects($this->once())
|
||||
->method('getPhoneNumberData')
|
||||
->with($entity)
|
||||
->willReturn($dataList);
|
||||
}
|
||||
|
||||
public function testIsCreatableFromEntityTrue() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'phone');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->assertTrue($this->factory->isCreatableFromEntity($entity, 'test'));
|
||||
}
|
||||
|
||||
public function testIsCreatableFromEntityBad() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'varchar');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->assertFalse($this->factory->isCreatableFromEntity($entity, 'test'));
|
||||
}
|
||||
|
||||
public function testCreateException() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'varchar');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
$this->factory->createFromEntity($entity, 'test');
|
||||
}
|
||||
|
||||
public function testCreateFromPhoneNumberRepository() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'phone');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [
|
||||
(object) [
|
||||
'phoneNumber' => '+1',
|
||||
'type' => 'Test-1',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'phoneNumber' => '+2',
|
||||
'type' => 'Test-2',
|
||||
'primary' => false,
|
||||
'optOut' => false,
|
||||
'invalid' => true,
|
||||
],
|
||||
(object) [
|
||||
'phoneNumber' => '+3',
|
||||
'type' => 'Test-3',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$this->initPhoneNumberRepository($entity, $dataList);
|
||||
|
||||
$entity
|
||||
->method('has')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', false],
|
||||
['test', true],
|
||||
]
|
||||
);
|
||||
|
||||
$entity
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', null],
|
||||
['test', '+1'],
|
||||
]
|
||||
);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(3, $group->getCount());
|
||||
|
||||
$one = $group->getList()[0];
|
||||
$two = $group->getList()[1];
|
||||
$three = $group->getList()[2];
|
||||
|
||||
$this->assertEquals('+1', $one->getNumber());
|
||||
|
||||
$this->assertTrue($two->isInvalid());
|
||||
|
||||
$this->assertTrue($three->isOptedOut());
|
||||
|
||||
$this->assertEquals('Test-1', $one->getType());
|
||||
|
||||
$this->assertEquals('+1', $group->getPrimary()->getNumber());
|
||||
}
|
||||
|
||||
public function testCreateFromDataAttribute() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'phone');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [
|
||||
(object) [
|
||||
'phoneNumber' => '+1',
|
||||
'type' => '1',
|
||||
'primary' => true,
|
||||
'optOut' => false,
|
||||
'invalid' => false,
|
||||
],
|
||||
(object) [
|
||||
'phoneNumber' => '+2',
|
||||
'type' => '2',
|
||||
'primary' => false,
|
||||
'optOut' => false,
|
||||
'invalid' => true,
|
||||
],
|
||||
(object) [
|
||||
'phoneNumber' => '+3',
|
||||
'type' => '3',
|
||||
'primary' => false,
|
||||
'optOut' => true,
|
||||
'invalid' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$entity
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with('testData')
|
||||
->willReturn(true);
|
||||
|
||||
$entity
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with('testData')
|
||||
->willReturn($dataList);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(3, $group->getCount());
|
||||
|
||||
$one = $group->getList()[0];
|
||||
$two = $group->getList()[1];
|
||||
$three = $group->getList()[2];
|
||||
|
||||
$this->assertEquals('+1', $one->getNumber());
|
||||
|
||||
$this->assertTrue($two->isInvalid());
|
||||
|
||||
$this->assertTrue($three->isOptedOut());
|
||||
|
||||
$this->assertEquals('+1', $group->getPrimary()->getNumber());
|
||||
}
|
||||
|
||||
public function testCreateEmpty1() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'phone');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [];
|
||||
|
||||
$this->initPhoneNumberRepository($entity, $dataList);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testCreateEmpty2() : void
|
||||
{
|
||||
$this->initField('Test', 'test', 'phone');
|
||||
|
||||
$entity = $this->createEntityMock('Test');
|
||||
|
||||
$dataList = [];
|
||||
|
||||
$this->initPhoneNumberRepository($entity, $dataList);
|
||||
|
||||
$entity
|
||||
->method('has')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', false],
|
||||
['test', true],
|
||||
]
|
||||
);
|
||||
|
||||
$entity
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['testData', null],
|
||||
['test', null],
|
||||
]
|
||||
);
|
||||
|
||||
$group = $this->factory->createFromEntity($entity, 'test');
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
}
|
||||
237
tests/unit/Espo/Core/Field/PhoneNumber/PhoneNumberGroupTest.php
Normal file
237
tests/unit/Espo/Core/Field/PhoneNumber/PhoneNumberGroupTest.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\PhoneNumber;
|
||||
|
||||
use Espo\Core\Field\PhoneNumber;
|
||||
use Espo\Core\Field\PhoneNumberGroup;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class PhoneNumberGroupTest extends TestCase
|
||||
{
|
||||
public function testEmpty()
|
||||
{
|
||||
$group = PhoneNumberGroup::create();
|
||||
|
||||
$this->assertEquals(0, count($group->getNumberList()));
|
||||
$this->assertEquals(0, count($group->getSecondaryList()));
|
||||
|
||||
$this->assertNull($group->getPrimary());
|
||||
$this->assertNull($group->getPrimaryNumber());
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testDuplicate()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+100'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function testWithPrimary1()
|
||||
{
|
||||
$primary = PhoneNumber::create('+000')->invalid();
|
||||
|
||||
$group = PhoneNumberGroup
|
||||
::create()
|
||||
->withPrimary($primary);
|
||||
|
||||
$this->assertEquals(1, count($group->getList()));
|
||||
$this->assertEquals(0, count($group->getSecondaryList()));
|
||||
|
||||
$this->assertNotNull($group->getPrimary());
|
||||
|
||||
$this->assertEquals('+000', $group->getPrimary()->getNumber());
|
||||
$this->assertEquals('+000', $group->getPrimaryNumber());
|
||||
|
||||
$primaryAnother = PhoneNumber::create('+001');
|
||||
|
||||
$groupAnother = $group->withPrimary($primaryAnother);
|
||||
|
||||
$this->assertEquals(2, count($groupAnother->getList()));
|
||||
$this->assertEquals(1, count($groupAnother->getSecondaryList()));
|
||||
|
||||
$this->assertEquals('+001', $groupAnother->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals('+000', $groupAnother->getList()[1]->getNumber());
|
||||
$this->assertTrue($groupAnother->getList()[1]->isInvalid());
|
||||
|
||||
$this->assertTrue($groupAnother->hasNumber('+000'));
|
||||
$this->assertTrue($groupAnother->hasNumber('+001'));
|
||||
}
|
||||
|
||||
public function testWithPrimary2()
|
||||
{
|
||||
$number = PhoneNumber::create('+100')->invalid();
|
||||
|
||||
$group = PhoneNumberGroup
|
||||
::create([$number])
|
||||
->withAdded(
|
||||
PhoneNumber::create('+200')
|
||||
)
|
||||
->withPrimary(
|
||||
PhoneNumber::create('+200')
|
||||
);
|
||||
|
||||
$this->assertEquals('+200', $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithAdded1()
|
||||
{
|
||||
$number = PhoneNumber::create('+100')->invalid();
|
||||
|
||||
$group = PhoneNumberGroup
|
||||
::create([$number])
|
||||
->withAdded(
|
||||
PhoneNumber::create('+200')
|
||||
);
|
||||
|
||||
$this->assertEquals('+100', $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
|
||||
$this->assertEquals(2, $group->getCount());
|
||||
}
|
||||
|
||||
public function testWithAddedList()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create()
|
||||
->withAddedList([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
]);
|
||||
|
||||
$this->assertEquals('+100', $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved1()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
PhoneNumber::create('+300'),
|
||||
])
|
||||
->withRemoved(PhoneNumber::create('+200'));
|
||||
|
||||
$this->assertEquals('+100', $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved2()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
PhoneNumber::create('+300'),
|
||||
])
|
||||
->withRemoved(PhoneNumber::create('+100'));
|
||||
|
||||
$this->assertEquals('+200', $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertEquals(2, count($group->getList()));
|
||||
}
|
||||
|
||||
public function testWithRemoved3()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
])
|
||||
->withRemoved(PhoneNumber::create('+100'));
|
||||
|
||||
$this->assertNull($group->getPrimary());
|
||||
|
||||
$this->assertEquals(0, count($group->getList()));
|
||||
|
||||
$this->assertEquals(0, $group->getCount());
|
||||
}
|
||||
|
||||
public function testHasNumber()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
]);
|
||||
|
||||
$this->assertTrue($group->hasNumber('+100'));
|
||||
$this->assertTrue($group->hasNumber('+200'));
|
||||
|
||||
$this->assertFalse($group->hasNumber('+400'));
|
||||
}
|
||||
|
||||
public function testGetByNumber()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
PhoneNumber::create('+300'),
|
||||
]);
|
||||
|
||||
$this->assertEquals('+100', $group->getByNumber('+100')->getNumber());
|
||||
|
||||
$this->assertNull($group->getByNumber('+400'));
|
||||
}
|
||||
|
||||
public function testClone()
|
||||
{
|
||||
$group = PhoneNumberGroup
|
||||
::create([
|
||||
PhoneNumber::create('+100'),
|
||||
PhoneNumber::create('+200'),
|
||||
PhoneNumber::create('+300'),
|
||||
]);
|
||||
|
||||
$cloned = clone $group;
|
||||
|
||||
$this->assertEquals('+100', $cloned->getByNumber('+100')->getNumber());
|
||||
|
||||
$this->assertEquals($cloned->getPrimary()->getNumber(), $group->getPrimary()->getNumber());
|
||||
|
||||
$this->assertNotSame($cloned->getPrimary(), $group->getPrimary());
|
||||
|
||||
$this->assertNotSame($cloned->getList()[1], $group->getList()[1]);
|
||||
}
|
||||
}
|
||||
85
tests/unit/Espo/Core/Field/PhoneNumber/PhoneNumberTest.php
Normal file
85
tests/unit/Espo/Core/Field/PhoneNumber/PhoneNumberTest.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Field\PhoneNumber;
|
||||
|
||||
use Espo\Core\Field\PhoneNumber;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PhoneNumberTest extends TestCase
|
||||
{
|
||||
public function testInvalidEmpty()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
|
||||
PhoneNumber::create('');
|
||||
}
|
||||
|
||||
public function testCloneInvalid()
|
||||
{
|
||||
$number = PhoneNumber::create('+100')->invalid();
|
||||
|
||||
$this->assertEquals('+100', $number->getNumber());
|
||||
|
||||
$this->assertTrue($number->isInvalid());
|
||||
$this->assertFalse($number->isOptedOut());
|
||||
|
||||
$this->assertNull($number->getType());
|
||||
}
|
||||
|
||||
public function testCloneOptedOut()
|
||||
{
|
||||
$number = PhoneNumber::create('+100')->optedOut();
|
||||
|
||||
$this->assertFalse($number->isInvalid());
|
||||
$this->assertTrue($number->isOptedOut());
|
||||
}
|
||||
|
||||
public function testCloneWithType()
|
||||
{
|
||||
$number = PhoneNumber::createWithType('+100', 'Office');
|
||||
|
||||
$this->assertEquals('+100', $number->getNumber());
|
||||
$this->assertEquals('Office', $number->getType());
|
||||
}
|
||||
|
||||
public function testCloneNotOptedOut()
|
||||
{
|
||||
$number = PhoneNumber::create('+100')
|
||||
->optedOut()
|
||||
->notOptedOut()
|
||||
->invalid()
|
||||
->notInvalid();
|
||||
|
||||
$this->assertFalse($number->isInvalid());
|
||||
$this->assertFalse($number->isOptedOut());
|
||||
}
|
||||
}
|
||||
64
tests/unit/Espo/Core/FieldProcessing/LoaderParamsTest.php
Normal file
64
tests/unit/Espo/Core/FieldProcessing/LoaderParamsTest.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\FieldProcessing;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Loader\Params as LoaderParams,
|
||||
};
|
||||
|
||||
class LoaderParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testOne(): void
|
||||
{
|
||||
$select = [
|
||||
'id',
|
||||
'name',
|
||||
];
|
||||
|
||||
$params = LoaderParams
|
||||
::create()
|
||||
->withSelect($select);
|
||||
|
||||
$this->assertEquals(true, $params->hasInSelect('id'));
|
||||
$this->assertEquals(false, $params->hasInSelect('test'));
|
||||
|
||||
$this->assertEquals(true, $params->hasSelect());
|
||||
}
|
||||
|
||||
public function testTwo(): void
|
||||
{
|
||||
$params = LoaderParams
|
||||
::create();
|
||||
|
||||
|
||||
$this->assertEquals(false, $params->hasSelect());
|
||||
$this->assertEquals(false, $params->hasInSelect('test'));
|
||||
}
|
||||
}
|
||||
55
tests/unit/Espo/Core/FieldProcessing/SaverParamsTest.php
Normal file
55
tests/unit/Espo/Core/FieldProcessing/SaverParamsTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\FieldProcessing;
|
||||
|
||||
use Espo\Core\{
|
||||
FieldProcessing\Saver\Params,
|
||||
ORM\Repository\Option\SaveOption};
|
||||
|
||||
class SaverParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testOne(): void
|
||||
{
|
||||
$options = [
|
||||
SaveOption::SILENT => true,
|
||||
];
|
||||
|
||||
$params = Params
|
||||
::create()
|
||||
->withRawOptions($options);
|
||||
|
||||
$this->assertEquals(true, $params->getOption('silent'));
|
||||
$this->assertEquals(true, $params->hasOption('silent'));
|
||||
$this->assertEquals(null, $params->getOption('skipHooks'));
|
||||
$this->assertEquals(false, $params->hasOption('skipHooks'));
|
||||
|
||||
$this->assertEquals($options, $params->getRawOptions());
|
||||
}
|
||||
}
|
||||
82
tests/unit/Espo/Core/Formula/ArgumentListTest.php
Normal file
82
tests/unit/Espo/Core/Formula/ArgumentListTest.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Formula;
|
||||
|
||||
use Espo\Core\Formula\ArgumentList;
|
||||
|
||||
class ArgumentListTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
protected function tearDown() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testCount()
|
||||
{
|
||||
$list = new ArgumentList([]);
|
||||
$this->assertEquals(0, count($list));
|
||||
|
||||
$list = new ArgumentList([
|
||||
null,
|
||||
'1',
|
||||
(object) [],
|
||||
]);
|
||||
$this->assertEquals(3, count($list));
|
||||
}
|
||||
|
||||
public function testAccess()
|
||||
{
|
||||
$list = new ArgumentList([
|
||||
null,
|
||||
'1',
|
||||
(object) [],
|
||||
]);
|
||||
$this->assertEquals(null, $list[0]->getData());
|
||||
$this->assertEquals('1', $list[1]->getData());
|
||||
}
|
||||
|
||||
public function testIteration()
|
||||
{
|
||||
$list = new ArgumentList([
|
||||
null,
|
||||
'1',
|
||||
]);
|
||||
|
||||
$array = [];
|
||||
foreach ($list as $item) {
|
||||
$array[] = $item->getData();
|
||||
}
|
||||
$this->assertEquals(null, $array[0]);
|
||||
$this->assertEquals('1', $array[1]);
|
||||
}
|
||||
}
|
||||
2179
tests/unit/Espo/Core/Formula/EvaluatorTest.php
Normal file
2179
tests/unit/Espo/Core/Formula/EvaluatorTest.php
Normal file
File diff suppressed because it is too large
Load Diff
3131
tests/unit/Espo/Core/Formula/FormulaTest.php
Normal file
3131
tests/unit/Espo/Core/Formula/FormulaTest.php
Normal file
File diff suppressed because it is too large
Load Diff
2146
tests/unit/Espo/Core/Formula/ParserTest.php
Normal file
2146
tests/unit/Espo/Core/Formula/ParserTest.php
Normal file
File diff suppressed because it is too large
Load Diff
380
tests/unit/Espo/Core/Hook/DataProviderTest.php
Normal file
380
tests/unit/Espo/Core/Hook/DataProviderTest.php
Normal file
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Hook;
|
||||
|
||||
use Espo\Core\Hook\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use tests\unit\ReflectionHelper;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\DataCache;
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\Module\PathProvider;
|
||||
|
||||
class DataProviderTest extends TestCase
|
||||
{
|
||||
private string $filesPath = 'tests/unit/testData/Hooks';
|
||||
|
||||
private ?Config\SystemConfig $systemConfig = null;
|
||||
private ?PathProvider $pathProvider = null;
|
||||
private ?ReflectionHelper $reflectionHelper = null;
|
||||
private ?Metadata $metadata = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
$this->getMockBuilder(Metadata::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->systemConfig = $this->createMock(Config\SystemConfig::class);
|
||||
|
||||
$dataCache = $this->createMock(DataCache::class);
|
||||
$fileManager = new FileManager();
|
||||
$this->pathProvider = $this->createMock(PathProvider::class);
|
||||
|
||||
$dataProvider = new DataProvider(
|
||||
systemConfig: $this->systemConfig,
|
||||
fileManager: $fileManager,
|
||||
pathProvider: $this->pathProvider,
|
||||
dataCache: $dataCache,
|
||||
metadata: $this->metadata,
|
||||
);
|
||||
|
||||
$this->reflectionHelper = new ReflectionHelper($dataProvider);
|
||||
}
|
||||
|
||||
private function initPathProvider(string $folder): void
|
||||
{
|
||||
$this->pathProvider
|
||||
->method('getCustom')
|
||||
->willReturn($this->filesPath . '/' . $folder . '/custom/Espo/Custom/');
|
||||
|
||||
$this->pathProvider
|
||||
->method('getCore')
|
||||
->willReturn($this->filesPath . '/' . $folder . '/application/Espo/');
|
||||
|
||||
$this->pathProvider
|
||||
->method('getModule')
|
||||
->willReturnCallback(
|
||||
function (?string $moduleName) use ($folder): string {
|
||||
$path = $this->filesPath . '/' . $folder . '/application/Espo/Modules/{*}/';
|
||||
|
||||
if ($moduleName === null) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return str_replace('{*}', $moduleName, $path);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function testHookExists(): void
|
||||
{
|
||||
$data = [
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Stream',
|
||||
'order' => 8,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Notifications',
|
||||
'order' => 14,
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertTrue(
|
||||
$this->reflectionHelper->invokeMethod('hookExists', ['Espo\\Hooks\\Note\\Mentions', $data])
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflectionHelper->invokeMethod('hookExists', ['Espo\\Modules\\Crm\\Hooks\\Note\\Mentions', $data])
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflectionHelper->invokeMethod('hookExists', ['Espo\\Modules\\Test\\Hooks\\Note\\Mentions', $data])
|
||||
);
|
||||
$this->assertTrue(
|
||||
$this->reflectionHelper->invokeMethod('hookExists', ['Espo\\Modules\\Test\\Hooks\\Common\\Stream', $data])
|
||||
);
|
||||
$this->assertFalse(
|
||||
$this->reflectionHelper->invokeMethod('hookExists', ['Espo\\Hooks\\Note\\TestHook', $data])
|
||||
);
|
||||
}
|
||||
|
||||
public function testSortHooks(): void
|
||||
{
|
||||
$data = [
|
||||
'Common' =>
|
||||
[
|
||||
'afterSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\AssignmentEmailNotification',
|
||||
'order' => 9,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Notifications',
|
||||
'order' => 10,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Stream',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Formula',
|
||||
'order' => 5,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\NextNumber',
|
||||
'order' => 10,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\CurrencyConverted',
|
||||
'order' => 1,
|
||||
],
|
||||
],
|
||||
],
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
'afterSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Notifications',
|
||||
'order' => 14,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$result = [
|
||||
'Common' =>
|
||||
[
|
||||
'afterSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\AssignmentEmailNotification',
|
||||
'order' => 9,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Stream',
|
||||
'order' => 9,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Notifications',
|
||||
'order' => 10,
|
||||
],
|
||||
],
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\CurrencyConverted',
|
||||
'order' => 1,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\Formula',
|
||||
'order' => 5,
|
||||
],
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Common\\NextNumber',
|
||||
'order' => 10,
|
||||
],
|
||||
],
|
||||
],
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
'afterSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'Espo\\Hooks\\Note\\Notifications',
|
||||
'order' => 14,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflectionHelper->invokeMethod('sortHooks', [$data]));
|
||||
}
|
||||
|
||||
public function testCase1CustomHook(): void
|
||||
{
|
||||
$this->initPathProvider('testCase1');
|
||||
|
||||
$this->systemConfig
|
||||
->expects($this->exactly(2))
|
||||
->method('useCache')
|
||||
->willReturn(false);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->willReturn([
|
||||
'Crm',
|
||||
'Test',
|
||||
]);
|
||||
|
||||
$this->reflectionHelper->invokeMethod('load');
|
||||
|
||||
$result = [
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'tests\\unit\\testData\\Hooks\\testCase1\\custom\\Espo\\Custom\\Hooks\\Note\\Mentions',
|
||||
'order' => 7,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflectionHelper->getProperty('data'));
|
||||
}
|
||||
|
||||
public function testCase2ModuleHook1(): void
|
||||
{
|
||||
$this->initPathProvider('testCase2');
|
||||
|
||||
$this->systemConfig
|
||||
->expects($this->exactly(2))
|
||||
->method('useCache')
|
||||
->willReturn(false);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->willReturn([
|
||||
'Crm',
|
||||
'Test',
|
||||
]);
|
||||
|
||||
$this->reflectionHelper->invokeMethod('load');
|
||||
|
||||
$result = [
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' =>
|
||||
'tests\\unit\\testData\\Hooks\\testCase2\\application\\Espo\\Modules\\Crm\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflectionHelper->getProperty('data'));
|
||||
}
|
||||
|
||||
public function testCase2ModuleHookReverseModuleOrder(): void
|
||||
{
|
||||
$this->initPathProvider('testCase2');
|
||||
|
||||
$this->systemConfig
|
||||
->expects($this->exactly(2))
|
||||
->method('useCache')
|
||||
->willReturn(false);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->willReturn([
|
||||
'Test',
|
||||
'Crm',
|
||||
]);
|
||||
|
||||
$this->reflectionHelper->invokeMethod('load');
|
||||
|
||||
$result = [
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' =>
|
||||
'tests\\unit\\testData\\Hooks\\testCase2\\application\\Espo\\Modules\\Test\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflectionHelper->getProperty('data'));
|
||||
}
|
||||
|
||||
public function testCase3CoreHook()
|
||||
{
|
||||
$this->initPathProvider('testCase3');
|
||||
|
||||
$this->systemConfig
|
||||
->expects($this->exactly(2))
|
||||
->method('useCache')
|
||||
->willReturn(false);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('getModuleList')
|
||||
->willReturn([]);
|
||||
|
||||
$this->reflectionHelper->invokeMethod('load');
|
||||
|
||||
$result = [
|
||||
'Note' =>
|
||||
[
|
||||
'beforeSave' =>
|
||||
[
|
||||
[
|
||||
'className' => 'tests\\unit\\testData\\Hooks\\testCase3\\application\\Espo\\Hooks\\Note\\Mentions',
|
||||
'order' => 9,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($result, $this->reflectionHelper->getProperty('data'));
|
||||
}
|
||||
}
|
||||
330
tests/unit/Espo/Core/Htmlizer/HtmlizerTest.php
Normal file
330
tests/unit/Espo/Core/Htmlizer/HtmlizerTest.php
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Htmlizer;
|
||||
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Currency\PrecisionProvider;
|
||||
use Espo\Core\Htmlizer\Htmlizer;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\SelectBuilderFactory;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Utils\Language;
|
||||
use Espo\Core\Utils\Log;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Core\Utils\NumberUtil;
|
||||
use Espo\Core\Utils\DateTime;
|
||||
use Espo\Core\ORM\Entity;
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity as EntityAlias;
|
||||
use Espo\ORM\EntityManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use stdClass;
|
||||
|
||||
class HtmlizerTest extends TestCase
|
||||
{
|
||||
private ?Htmlizer $htmlizer;
|
||||
private ?DateTime $dateTime;
|
||||
private ?NumberUtil $number;
|
||||
private ?EntityManager $entityManager;
|
||||
|
||||
private $entityAttributes = [
|
||||
'id' => [
|
||||
'type' => EntityAlias::ID,
|
||||
],
|
||||
'name' => [
|
||||
'type' => EntityAlias::VARCHAR,
|
||||
'len' => 255,
|
||||
],
|
||||
'date' => [
|
||||
'type' => EntityAlias::DATE
|
||||
],
|
||||
'dateTime' => [
|
||||
'type' => EntityAlias::DATETIME
|
||||
],
|
||||
'int' => [
|
||||
'type' => EntityAlias::INT
|
||||
],
|
||||
'float' => [
|
||||
'type' => EntityAlias::FLOAT
|
||||
],
|
||||
'list' => [
|
||||
'type' => EntityAlias::JSON_ARRAY
|
||||
],
|
||||
'object' => [
|
||||
'type' => EntityAlias::JSON_OBJECT
|
||||
],
|
||||
'deleted' => [
|
||||
'type' => EntityAlias::BOOL,
|
||||
'default' => 0,
|
||||
]
|
||||
];
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
$this->entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$this->dateTime = new DateTime('MM/DD/YYYY', 'hh:mm A', 'Europe/Kyiv');
|
||||
$this->number = new NumberUtil('.', ',');
|
||||
|
||||
$this->htmlizer = $this->createHtmlizer();
|
||||
}
|
||||
|
||||
private function createHtmlizer(?AclManager $aclManager = null)
|
||||
{
|
||||
return new Htmlizer(
|
||||
dateTime: $this->dateTime,
|
||||
number: $this->number,
|
||||
selectBuilderFactory: $this->createMock(SelectBuilderFactory::class),
|
||||
user: $this->createMock(User::class),
|
||||
entityManager: $this->entityManager,
|
||||
metadata: $this->createMock(Metadata::class),
|
||||
language: $this->createMock(Language::class),
|
||||
config: $this->createMock(Config::class),
|
||||
log: $this->createMock(Log::class),
|
||||
injectableFactory: $this->createMock(InjectableFactory::class),
|
||||
precisionProvider: $this->createMock(PrecisionProvider::class),
|
||||
aclManager: $aclManager ?? $this->createMock(AclManager::class),
|
||||
);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{}
|
||||
|
||||
public function testRender()
|
||||
{
|
||||
$entity = new Entity(
|
||||
'Test',
|
||||
[
|
||||
'attributes' => $this->entityAttributes,
|
||||
],
|
||||
$this->entityManager
|
||||
);
|
||||
|
||||
$entity->set('name', 'test');
|
||||
$entity->set('date', '2015-09-15');
|
||||
$entity->set('dateTime', '2015-09-15 10:00:00');
|
||||
$entity->set('int', 3);
|
||||
$entity->set('float', 3.5);
|
||||
|
||||
$item1 = new stdClass();
|
||||
$item1->value = 1;
|
||||
|
||||
$item2 = new stdClass();
|
||||
$item2->value = 2000.5;
|
||||
|
||||
$list = [$item1, $item2];
|
||||
|
||||
$entity->set('list', $list);
|
||||
|
||||
$template = "{{name}} test {{date}} {{dateTime}} {{#each list}}{{value}} {{/each}}{{int}} {{float}}";
|
||||
|
||||
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('test test 09/15/2015 09/15/2015 01:00 PM 1 2,000.50 3 3.50', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{float}}";
|
||||
|
||||
$entity->set('float', 3);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('3.00', $html);
|
||||
|
||||
$entity->set('float', 3);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('3.00', $html);
|
||||
|
||||
$entity->set('float', 10000.50);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10,000.50', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{int}}";
|
||||
|
||||
$entity->set('int', 3000);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('3,000', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{float_RAW}}";
|
||||
|
||||
$entity->set('float', 10000.50);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10000.5', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{numberFormat float_RAW}}";
|
||||
|
||||
$entity->set('float', 10000.60);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10,001', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{numberFormat float_RAW decimals=2}}";
|
||||
|
||||
$entity->set('float', 10000.601);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10,000.60', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{numberFormat float_RAW decimals=0}}";
|
||||
|
||||
$entity->set('float', 10000.1);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10,000', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{numberFormat float_RAW decimals=2 decimalPoint='.' thousandsSeparator=' '}}";
|
||||
|
||||
$entity->set('float', 10000.60);
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('10 000.60', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{file name}}";
|
||||
|
||||
$entity->set('name', '1');
|
||||
$html = $this->htmlizer->render($entity, $template, skipInlineAttachmentHandling: true);
|
||||
$this->assertEquals('?entryPoint=attachment&id=1', $html);
|
||||
|
||||
//
|
||||
|
||||
$template = "{{#ifEqual name '1'}}hello{{/ifEqual}}";
|
||||
|
||||
$entity->set('name', '1');
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('hello', $html);
|
||||
|
||||
$template = "{{#ifNotEqual name '1'}}hello{{else}}test{{/ifNotEqual}}";
|
||||
$entity->set('name', '1');
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('test', $html);
|
||||
|
||||
$template = "{{#if (and (equal name 'test') true 1)}}test{{/if}}";
|
||||
$entity->set('name', 'test');
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('test', $html);
|
||||
|
||||
$template = "{{#if (or (equal name 'test') false 0)}}test{{/if}}";
|
||||
$entity->set('name', 'test');
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('test', $html);
|
||||
|
||||
$template = "{{#if (not false)}}test{{/if}}";
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('test', $html);
|
||||
|
||||
$template = "{{#ifEqual name '1'}}{{#ifEqual name '1'}}hello{{/ifEqual}}{{/ifEqual}}";
|
||||
|
||||
$entity->set('name', '1');
|
||||
$html = $this->htmlizer->render($entity, $template);
|
||||
$this->assertEquals('hello', $html);
|
||||
}
|
||||
|
||||
public function testIterate(): void
|
||||
{
|
||||
/** @noinspection HtmlUnknownAttribute */
|
||||
$template = "<ul><li iterate=\"{{items}}\">{{name}}</li></ul><ul><li iterate=\"{{items}}\">{{name}}</li></ul>";
|
||||
|
||||
$html = $this->htmlizer->render(null, $template, [
|
||||
'items' => [
|
||||
['name' => '1'],
|
||||
['name' => '2'],
|
||||
],
|
||||
]);
|
||||
|
||||
/** @noinspection HtmlUnknownAttribute */
|
||||
$expected = "<ul><li>1</li><li>2</li></ul><ul><li>1</li><li>2</li></ul>";
|
||||
|
||||
$this->assertEquals($expected, $html);
|
||||
}
|
||||
|
||||
public function testIf(): void
|
||||
{
|
||||
/** @noinspection HtmlUnknownAttribute */
|
||||
$template = "<ul><li x-if=\"{{and (equal 1 1) true}}\">1</li><li x-if=\"{{false}}\">2</li>".
|
||||
"<li x-if=\"{{1}}\">true</li></ul>";
|
||||
|
||||
$html = $this->htmlizer->render(null, $template, []);
|
||||
|
||||
/** @noinspection HtmlUnknownAttribute */
|
||||
$expected = "<ul><li>1</li><li>true</li></ul>";
|
||||
|
||||
$this->assertEquals($expected, $html);
|
||||
}
|
||||
|
||||
public function testAdditionalData(): void
|
||||
{
|
||||
$aclManager = $this->createMock(AclManager::class);
|
||||
|
||||
$aclManager->method('getScopeRestrictedAttributeList')
|
||||
->willReturn(['int', 'float']);
|
||||
|
||||
$htmlizer = $this->createHtmlizer(
|
||||
aclManager: $aclManager,
|
||||
);
|
||||
|
||||
$entity = new Entity(
|
||||
entityType: 'Test',
|
||||
defs: [
|
||||
'attributes' => $this->entityAttributes,
|
||||
],
|
||||
entityManager: $this->entityManager,
|
||||
);
|
||||
|
||||
$entity->setMultiple([
|
||||
'name' => 'test',
|
||||
'date' => '2030-09-15',
|
||||
'int' => 1,
|
||||
'float' => 2.0,
|
||||
]);
|
||||
|
||||
$additionalData = [
|
||||
'date' => 't1',
|
||||
'p1' => 'v1',
|
||||
'int' => 'v2',
|
||||
];
|
||||
|
||||
$template = "{{name}} {{date}} {{p1}} {{int}} {{float}}";
|
||||
|
||||
$html = $htmlizer->render($entity, $template, $additionalData);
|
||||
|
||||
$this->assertEquals('test t1 v1 v2 ', $html);
|
||||
}
|
||||
}
|
||||
120
tests/unit/Espo/Core/InjectableFactoryTest.php
Normal file
120
tests/unit/Espo/Core/InjectableFactoryTest.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core;
|
||||
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\Container;
|
||||
use Espo\Core\InjectableFactory;
|
||||
|
||||
use tests\integration\testClasses\Binding\SomeClass;
|
||||
use tests\integration\testClasses\Binding\SomeImplementation;
|
||||
use tests\integration\testClasses\Binding\SomeInterface;
|
||||
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass0;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass1;
|
||||
use tests\unit\testClasses\Core\Binding\SomeClass2;
|
||||
use tests\unit\testClasses\Core\Binding\SomeInterface1;
|
||||
use tests\unit\testClasses\Core\Binding\SomeInterface2;
|
||||
|
||||
class InjectableFactoryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testCreateWithBinding1(): void
|
||||
{
|
||||
$container = $this->createMock(Container::class);
|
||||
|
||||
$injectableFactory = new InjectableFactory($container);
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$instance = $this->createMock(SomeInterface::class);
|
||||
|
||||
$binder->bindInstance(SomeInterface::class, $instance);
|
||||
|
||||
$obj = $injectableFactory->createWithBinding(SomeClass::class, new BindingContainer($bindingData));
|
||||
|
||||
$this->assertNotNull($obj);
|
||||
|
||||
$this->assertSame($instance, $obj->get());
|
||||
}
|
||||
|
||||
public function testCreateWithBinding2(): void
|
||||
{
|
||||
$container = $this->createMock(Container::class);
|
||||
|
||||
$injectableFactory = new InjectableFactory($container);
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$binder
|
||||
->bindImplementation(SomeInterface1::class, SomeClass1::class)
|
||||
->bindImplementation(SomeInterface2::class, SomeClass2::class);
|
||||
|
||||
$obj = $injectableFactory->createWithBinding(SomeClass0::class, new BindingContainer($bindingData));
|
||||
|
||||
$this->assertNotNull($obj);
|
||||
}
|
||||
|
||||
public function testCreateResolved1(): void
|
||||
{
|
||||
$container = $this->createMock(Container::class);
|
||||
|
||||
$bindingContainer = BindingContainerBuilder::create()
|
||||
->bindImplementation(SomeInterface::class, SomeImplementation::class)
|
||||
->build();
|
||||
|
||||
$injectableFactory = new InjectableFactory($container, $bindingContainer);
|
||||
|
||||
$obj = $injectableFactory->createResolved(SomeInterface::class);
|
||||
|
||||
$this->assertInstanceOf(SomeImplementation::class, $obj);
|
||||
}
|
||||
|
||||
public function testCreateResolved2(): void
|
||||
{
|
||||
$container = $this->createMock(Container::class);
|
||||
|
||||
$bindingContainer = BindingContainerBuilder::create()->build();
|
||||
|
||||
$injectableFactory = new InjectableFactory($container, $bindingContainer);
|
||||
|
||||
$bindingContainer1 = BindingContainerBuilder::create()->build();
|
||||
|
||||
$obj = $injectableFactory->createResolved(SomeImplementation::class, $bindingContainer1);
|
||||
|
||||
$this->assertInstanceOf(SomeImplementation::class, $obj);
|
||||
}
|
||||
}
|
||||
56
tests/unit/Espo/Core/Job/DataTest.php
Normal file
56
tests/unit/Espo/Core/Job/DataTest.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use Espo\Core\Job\Job\Data;
|
||||
|
||||
class DataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testData1()
|
||||
{
|
||||
$data = Data
|
||||
::create((object) ['test' => '1'])
|
||||
->withTargetId('target-id')
|
||||
->withTargetType('target-type');
|
||||
|
||||
$this->assertEquals('1', $data->get('test'));
|
||||
$this->assertEquals('target-id', $data->getTargetId());
|
||||
$this->assertEquals('target-type', $data->getTargetType());
|
||||
}
|
||||
|
||||
public function testData2()
|
||||
{
|
||||
$data = Data
|
||||
::create(['test' => '1']);
|
||||
|
||||
$this->assertEquals('1', $data->get('test'));
|
||||
$this->assertEquals(null, $data->getTargetId());
|
||||
}
|
||||
}
|
||||
117
tests/unit/Espo/Core/Job/JobSchedulerTest.php
Normal file
117
tests/unit/Espo/Core/Job/JobSchedulerTest.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use Espo\Core\Field\DateTime as DateTimeField;
|
||||
use Espo\Core\Job\JobScheduler;
|
||||
use Espo\Core\Job\JobScheduler\Creator;
|
||||
use Espo\Core\Job\QueueName;
|
||||
use Espo\Core\Job\Job\Data;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use tests\unit\testClasses\Core\Job\TestJob;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateInterval;
|
||||
|
||||
class JobSchedulerTest extends TestCase
|
||||
{
|
||||
private ?JobScheduler\Creator $creator = null;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->creator = $this->createMock(JobScheduler\Creator::class);
|
||||
}
|
||||
|
||||
public function testSchedule1(): void
|
||||
{
|
||||
$scheduler = new JobScheduler($this->creator);
|
||||
|
||||
$time = new DateTimeImmutable();
|
||||
|
||||
$delay = DateInterval::createFromDateString('1 minute');
|
||||
|
||||
$expectedData = new Creator\Data(
|
||||
className: TestJob::class,
|
||||
queue: QueueName::Q0,
|
||||
group: null,
|
||||
data: new Data((object) ['test' => '1']),
|
||||
time: DateTimeField::fromDateTime($time)->addMinutes(1),
|
||||
);
|
||||
|
||||
$this->creator
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($expectedData);
|
||||
|
||||
$scheduler
|
||||
->setClassName(TestJob::class)
|
||||
->setQueue(QueueName::Q0)
|
||||
->setData([
|
||||
'test' => '1',
|
||||
])
|
||||
->setTime($time)
|
||||
->setDelay($delay)
|
||||
->schedule();
|
||||
}
|
||||
|
||||
public function testSchedule2(): void
|
||||
{
|
||||
$scheduler = new JobScheduler($this->creator);
|
||||
|
||||
$time = new DateTimeImmutable();
|
||||
|
||||
$expectedData = new Creator\Data(
|
||||
className: TestJob::class,
|
||||
queue: null,
|
||||
group: 'g-1',
|
||||
data: (new Data((object) ['test' => '1']))->withTargetType('TestType')->withTargetId('test-id'),
|
||||
time: DateTimeField::fromDateTime($time),
|
||||
);
|
||||
|
||||
$this->creator
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($expectedData);
|
||||
|
||||
$data = Data
|
||||
::create([
|
||||
'test' => '1',
|
||||
])
|
||||
->withTargetId('test-id')
|
||||
->withTargetType('TestType');
|
||||
|
||||
$scheduler
|
||||
->setClassName(TestJob::class)
|
||||
->setGroup('g-1')
|
||||
->setData($data)
|
||||
->setTime($time)
|
||||
->schedule();
|
||||
}
|
||||
}
|
||||
70
tests/unit/Espo/Core/Job/MetadataProviderTest.php
Normal file
70
tests/unit/Espo/Core/Job/MetadataProviderTest.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use Espo\Core\{
|
||||
Job\MetadataProvider,
|
||||
Utils\Metadata,
|
||||
};
|
||||
|
||||
class MetadataProviderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private $metadata;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
}
|
||||
|
||||
public function testGetPreparableJobNameList()
|
||||
{
|
||||
$this->metadata
|
||||
->method('get')
|
||||
->with(['app', 'scheduledJobs'])
|
||||
->willReturn([
|
||||
'Test1' => [
|
||||
'preparatorClassName' => "Test",
|
||||
],
|
||||
'Test2' => [
|
||||
'preparatorClassName' => "Test",
|
||||
],
|
||||
'Test3' => [],
|
||||
'Test4' => [
|
||||
'preparatorClassName' => null,
|
||||
],
|
||||
]);
|
||||
|
||||
$provider = new MetadataProvider($this->metadata);
|
||||
|
||||
$list = $provider->getPreparableJobNameList();
|
||||
|
||||
$this->assertEquals(['Test1', 'Test2'], $list);
|
||||
}
|
||||
}
|
||||
76
tests/unit/Espo/Core/Job/QueuePortionNumberProviderTest.php
Normal file
76
tests/unit/Espo/Core/Job/QueuePortionNumberProviderTest.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use Espo\Core\Job\QueueName;
|
||||
use Espo\Core\Job\QueuePortionNumberProvider;
|
||||
use Espo\Core\Utils\Config;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class QueuePortionNumberProviderTest extends TestCase
|
||||
{
|
||||
private $config;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->config = $this->createMock(Config::class);
|
||||
}
|
||||
|
||||
public function testDefault(): void
|
||||
{
|
||||
$provider = new QueuePortionNumberProvider($this->config);
|
||||
|
||||
$this->assertEquals(200, $provider->get(QueueName::Q0));
|
||||
$this->assertEquals(500, $provider->get(QueueName::Q1));
|
||||
$this->assertEquals(100, $provider->get(QueueName::E0));
|
||||
$this->assertEquals(200, $provider->get('TestDefault'));
|
||||
}
|
||||
|
||||
public function testConfig(): void
|
||||
{
|
||||
$this->config
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['jobQ0MaxPortion', null, 201],
|
||||
['jobQ1MaxPortion', null, 501],
|
||||
['jobE0MaxPortion', null, 101],
|
||||
['jobTestDefaultMaxPortion', null, 301]
|
||||
]
|
||||
);
|
||||
|
||||
$provider = new QueuePortionNumberProvider($this->config);
|
||||
|
||||
$this->assertEquals(201, $provider->get(QueueName::Q0));
|
||||
$this->assertEquals(501, $provider->get(QueueName::Q1));
|
||||
$this->assertEquals(101, $provider->get(QueueName::E0));
|
||||
$this->assertEquals(301, $provider->get('TestDefault'));
|
||||
}
|
||||
}
|
||||
255
tests/unit/Espo/Core/Job/QueueProcessor/PickerTest.php
Normal file
255
tests/unit/Espo/Core/Job/QueueProcessor/PickerTest.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job\QueueProcessor;
|
||||
|
||||
use Countable;
|
||||
use Espo\Core\Job\QueueProcessor\Params;
|
||||
use Espo\Core\Job\QueueProcessor\Picker;
|
||||
use Espo\Core\Job\QueueUtil;
|
||||
use Espo\Entities\Job;
|
||||
use Espo\ORM\Collection;
|
||||
use Espo\ORM\EntityCollection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PickerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param string[] $ids
|
||||
* @return Collection<Job>&Countable
|
||||
*/
|
||||
private function createCollection(array $ids): Collection&Countable
|
||||
{
|
||||
$output = new EntityCollection();
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$job = $this->createMock(Job::class);
|
||||
|
||||
$job->expects($this->any())
|
||||
->method('getId')
|
||||
->willReturn($id);
|
||||
|
||||
$output[] = $job;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $ids
|
||||
* @param iterable<Job> $pick
|
||||
*/
|
||||
private function assertPick(array $ids, iterable $pick): void
|
||||
{
|
||||
$pick = iterator_to_array($pick);
|
||||
|
||||
$this->assertSameSize($ids, $pick);
|
||||
|
||||
foreach ($pick as $i => $job) {
|
||||
$this->assertEquals($ids[$i], $job->getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float[] $weights
|
||||
* @param string[][] $idsGroups
|
||||
* @param string[] $idsExpected
|
||||
*/
|
||||
private function prepareAndTest(int $limit, array $weights, array $idsGroups, array $idsExpected): void
|
||||
{
|
||||
$util = $this->createMock(QueueUtil::class);
|
||||
|
||||
$params = Params::create()->withLimit($limit);
|
||||
|
||||
$paramList = [];
|
||||
|
||||
foreach ($weights as $i => $weight) {
|
||||
$paramList[] = $params
|
||||
->withWeight($weight)
|
||||
->withQueue('m' . $i);
|
||||
}
|
||||
|
||||
|
||||
$params = $params->withSubQueueParamsList($paramList);
|
||||
|
||||
$picker = new Picker($util);
|
||||
|
||||
$collections = [];
|
||||
|
||||
foreach ($idsGroups as $ids) {
|
||||
$collections[] = $this->createCollection($ids);
|
||||
}
|
||||
|
||||
$util->expects($this->any())
|
||||
->method('getPendingJobs')
|
||||
->willReturnOnConsecutiveCalls(...$collections);
|
||||
|
||||
$pick = $picker->pick($params);
|
||||
|
||||
$this->assertPick($idsExpected, $pick);
|
||||
}
|
||||
|
||||
public function testPick0(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [1.0],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2', 'a3', 'a4', 'a5'],
|
||||
],
|
||||
idsExpected:
|
||||
['a0', 'a1', 'a2', 'a3', 'a4', 'a5'],
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick1(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2', 'a3', 'a4', 'a5'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5'],
|
||||
],
|
||||
idsExpected: array_merge(
|
||||
['a0', 'a1', 'a2', 'a3', 'a4'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick2(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'],
|
||||
],
|
||||
idsExpected: array_merge(
|
||||
['a0', 'a1', 'a2'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick3(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2', 'a4', 'a5', 'a6', 'a7'],
|
||||
['b0', 'b1', 'b2'],
|
||||
],
|
||||
idsExpected:
|
||||
['a0', 'a1', 'a2', 'a4', 'a5', 'b0', 'b1', 'b2', 'a6', 'a7'],
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick4(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2'],
|
||||
['b0', 'b1', 'b2'],
|
||||
],
|
||||
idsExpected:
|
||||
['a0', 'a1', 'a2', 'b0', 'b1', 'b2'],
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick5(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 15,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10', 'b11', 'b12'],
|
||||
],
|
||||
idsExpected: array_merge(
|
||||
['a0', 'a1', 'a2'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10', 'b11'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick6(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
[],
|
||||
['b0', 'b1', 'b2'],
|
||||
],
|
||||
idsExpected:
|
||||
[ 'b0', 'b1', 'b2'],
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick7(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.5],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5'],
|
||||
],
|
||||
idsExpected: array_merge(
|
||||
['a0', 'a1', 'a2', 'a3', 'a4'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function testPick8(): void
|
||||
{
|
||||
$this->prepareAndTest(
|
||||
limit: 10,
|
||||
weights: [0.5, 0.3, 0.2],
|
||||
idsGroups: [
|
||||
['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6'],
|
||||
['b0', 'b1', 'b2', 'b3', 'b4', 'b5'],
|
||||
['c0', 'c1', 'c2', 'c3', 'c4', 'c5'],
|
||||
],
|
||||
idsExpected: array_merge(
|
||||
['a0', 'a1', 'a2', 'a3', 'a4'],
|
||||
['b0', 'b1', 'b2'],
|
||||
['c0', 'c1'],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
62
tests/unit/Espo/Core/Job/QueueProcessorParamsTest.php
Normal file
62
tests/unit/Espo/Core/Job/QueueProcessorParamsTest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Job;
|
||||
|
||||
use Espo\Core\Job\QueueProcessor\Params;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class QueueProcessorParamsTest extends TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testParams1()
|
||||
{
|
||||
$params = Params
|
||||
::create()
|
||||
->withLimit(10);
|
||||
|
||||
$this->assertEquals(10, $params->getLimit());
|
||||
$this->assertNull($params->getQueue());
|
||||
}
|
||||
|
||||
public function testParams2()
|
||||
{
|
||||
$params = Params
|
||||
::create()
|
||||
->withLimit(10)
|
||||
->withGroup('group-0')
|
||||
->withQueue('q0');
|
||||
|
||||
$this->assertEquals('q0', $params->getQueue());
|
||||
$this->assertEquals('group-0', $params->getGroup());
|
||||
}
|
||||
}
|
||||
123
tests/unit/Espo/Core/Log/HandlerListLoaderTest.php
Normal file
123
tests/unit/Espo/Core/Log/HandlerListLoaderTest.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Log;
|
||||
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Log\DefaultHandlerLoader;
|
||||
use Espo\Core\Log\EspoRotatingFileHandlerLoader;
|
||||
use Espo\Core\Log\Handler\EspoRotatingFileHandler;
|
||||
use Espo\Core\Log\HandlerListLoader;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class HandlerListLoaderTest extends TestCase
|
||||
{
|
||||
private $injectableFactory;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->injectableFactory = $this->getMockBuilder(InjectableFactory::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function testLoad1()
|
||||
{
|
||||
$defaultLoader = $this->getMockBuilder(DefaultHandlerLoader::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$listLoader = new HandlerListLoader($this->injectableFactory, $defaultLoader);
|
||||
|
||||
$dataList = [
|
||||
[
|
||||
'className' => 'Espo\\Core\\Log\\Handler\\EspoRotatingFileHandler',
|
||||
'params' => [
|
||||
'filename' => 'data/logs/test-1.log',
|
||||
],
|
||||
'level' => 'DEBUG',
|
||||
'formatter' => [
|
||||
'className' => 'Monolog\\Formatter\\LineFormatter',
|
||||
'params' => [
|
||||
'dateFormat' => 'Y-m-d H:i:s',
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'loaderClassName' => EspoRotatingFileHandlerLoader::class,
|
||||
'params' => [
|
||||
'filename' => 'data/logs/test-2.log',
|
||||
],
|
||||
'level' => 'NOTICE',
|
||||
],
|
||||
];
|
||||
|
||||
$handler1 = $this->getMockBuilder(EspoRotatingFileHandler::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$defaultLoader
|
||||
->expects($this->once())
|
||||
->method('load')
|
||||
->with($dataList[0], 'NOTICE')
|
||||
->willReturn($handler1);
|
||||
|
||||
$loader = $this->getMockBuilder(EspoRotatingFileHandlerLoader::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$handler = $this->getMockBuilder(EspoRotatingFileHandler::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with(EspoRotatingFileHandlerLoader::class)
|
||||
->willReturn($loader);
|
||||
|
||||
$params = [
|
||||
'filename' => 'data/logs/test-2.log',
|
||||
'level' => 'NOTICE',
|
||||
];
|
||||
|
||||
$loader
|
||||
->expects($this->once())
|
||||
->method('load')
|
||||
->with($params)
|
||||
->willReturn($handler);
|
||||
|
||||
$list = $listLoader->load($dataList, 'NOTICE');
|
||||
|
||||
$this->assertCount(2, $list);
|
||||
|
||||
$this->assertInstanceOf(EspoRotatingFileHandler::class, $list[0]);
|
||||
}
|
||||
}
|
||||
107
tests/unit/Espo/Core/Mail/Account/BouncedRecognizerTest.php
Normal file
107
tests/unit/Espo/Core/Mail/Account/BouncedRecognizerTest.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail\Account;
|
||||
|
||||
use Espo\Core\Mail\Account\GroupAccount\BouncedRecognizer;
|
||||
use Espo\Core\Mail\MessageWrapper;
|
||||
use Espo\Core\Mail\Parsers\MailMimeParser;
|
||||
|
||||
use Espo\ORM\EntityManager;
|
||||
|
||||
class BouncedRecognizerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected BouncedRecognizer $bouncedRecognizer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bouncedRecognizer = new BouncedRecognizer();
|
||||
}
|
||||
|
||||
private function createMessage(string $contents): MessageWrapper
|
||||
{
|
||||
$entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$parser = new MailMimeParser($entityManager);
|
||||
|
||||
return new MessageWrapper(0, null, $parser, $contents);
|
||||
}
|
||||
|
||||
public function testBounced1a(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_1.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertTrue($this->bouncedRecognizer->isHard($message));
|
||||
$this->assertEquals('0011aa', $this->bouncedRecognizer->extractQueueItemId($message));
|
||||
}
|
||||
|
||||
public function testBounced1b(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_1.eml');
|
||||
$contents = str_replace('MAILER-DAEMON', 'test', $contents);
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertTrue($this->bouncedRecognizer->isHard($message));
|
||||
}
|
||||
|
||||
public function testBounced2(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_2.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertFalse($this->bouncedRecognizer->isHard($message));
|
||||
}
|
||||
|
||||
public function testNotBounced1(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/test_email_1.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertFalse($this->bouncedRecognizer->isBounced($message));
|
||||
}
|
||||
|
||||
public function testBounced3(): void
|
||||
{
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/bounced_3.eml');
|
||||
|
||||
$message = $this->createMessage($contents);
|
||||
|
||||
$this->assertTrue($this->bouncedRecognizer->isBounced($message));
|
||||
$this->assertTrue($this->bouncedRecognizer->isHard($message));
|
||||
$this->assertEquals('5.4.1', $this->bouncedRecognizer->extractStatus($message));
|
||||
}
|
||||
}
|
||||
68
tests/unit/Espo/Core/Mail/Account/FetchDataTest.php
Normal file
68
tests/unit/Espo/Core/Mail/Account/FetchDataTest.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail\Account;
|
||||
|
||||
use Espo\Core\Mail\Account\FetchData;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
|
||||
class FetchDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testGetSet(): void
|
||||
{
|
||||
$raw = (object) [
|
||||
'lastUID' => (object) [
|
||||
'test' => '10',
|
||||
],
|
||||
'lastDate' => (object) [
|
||||
'test' => '2022-01-01 00:00:00',
|
||||
],
|
||||
];
|
||||
|
||||
$data = FetchData::fromRaw($raw, 0);
|
||||
|
||||
$this->assertEquals(10, $data->getLastUid('test'));
|
||||
$this->assertEquals('2022-01-01 00:00:00', $data->getLastDate('test')->toString());
|
||||
$this->assertEquals(null, $data->getLastUid('not-existing'));
|
||||
$this->assertEquals(null, $data->getLastDate('not-existing'));
|
||||
$this->assertEquals(false, $data->getForceByDate('test'));
|
||||
$this->assertEquals($raw, $data->getRaw());
|
||||
|
||||
$now = DateTime::createNow();
|
||||
|
||||
$data->setForceByDate('test', true);
|
||||
$data->setLastUid('test', 11);
|
||||
$data->setLastDate('test', $now);
|
||||
|
||||
$this->assertEquals(11, $data->getLastUid('test'));
|
||||
$this->assertEquals(true, $data->getForceByDate('test'));
|
||||
$this->assertEquals($now, $data->getLastDate('test'));
|
||||
}
|
||||
}
|
||||
298
tests/unit/Espo/Core/Mail/Account/FetcherTest.php
Normal file
298
tests/unit/Espo/Core/Mail/Account/FetcherTest.php
Normal file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail\Account;
|
||||
|
||||
use Espo\Core\Field\Date;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Mail\Account\Account;
|
||||
use Espo\Core\Mail\Account\FetchData;
|
||||
use Espo\Core\Mail\Account\Fetcher;
|
||||
use Espo\Core\Mail\Account\Fetcher\ConfigDataProvider;
|
||||
use Espo\Core\Mail\Account\Storage;
|
||||
use Espo\Core\Mail\Account\StorageFactory;
|
||||
use Espo\Core\Mail\Importer;
|
||||
use Espo\Core\Mail\ParserFactory;
|
||||
use Espo\Core\Utils\Log;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FetcherTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testFetchSinceDate(): void
|
||||
{
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$importer = $this->createMock(Importer::class);
|
||||
|
||||
$fetcher = $this->prepareFetcher($storage, $importer);
|
||||
|
||||
$fetchData = $this->prepareFetchData(
|
||||
lastUid: null,
|
||||
lastDate: null,
|
||||
uidValidity: null,
|
||||
);
|
||||
|
||||
$account = $this->prepareAccount($fetchData);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('selectFolder')
|
||||
->with('INBOX');
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getFolderStatus')
|
||||
->willReturn(new Storage\FolderStatus(uidValidity: 1));
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getUidsSinceDate')
|
||||
->with(DateTime::fromString('2026-01-01 00:00'))
|
||||
->willReturn([1, 2, 3]);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('close');
|
||||
|
||||
$importer
|
||||
->expects($this->exactly(3))
|
||||
->method('import');
|
||||
|
||||
$fetchData
|
||||
->expects($this->once())
|
||||
->method('setUidValidity')
|
||||
->with('INBOX', 1);
|
||||
|
||||
$fetchData
|
||||
->expects($this->once())
|
||||
->method('setLastUid')
|
||||
->with('INBOX', 3);
|
||||
|
||||
$fetcher->fetch($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testFetchSinceLastUid(): void
|
||||
{
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$importer = $this->createMock(Importer::class);
|
||||
|
||||
$fetcher = $this->prepareFetcher($storage, $importer);
|
||||
|
||||
$fetchData = $this->prepareFetchData(
|
||||
lastUid: 3,
|
||||
lastDate: DateTime::fromString('2026-01-02 00:00'),
|
||||
uidValidity: 1,
|
||||
);
|
||||
|
||||
$account = $this->prepareAccount($fetchData);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('selectFolder')
|
||||
->with('INBOX');
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getFolderStatus')
|
||||
->willReturn(new Storage\FolderStatus(uidValidity: 1));
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getUidsFromUid')
|
||||
->with(3)
|
||||
->willReturn([4]);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('close');
|
||||
|
||||
$importer
|
||||
->expects($this->exactly(1))
|
||||
->method('import');
|
||||
|
||||
$fetchData
|
||||
->expects($this->once())
|
||||
->method('setLastUid')
|
||||
->with('INBOX', 4);
|
||||
|
||||
$fetcher->fetch($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testFetchUidValidityBroken(): void
|
||||
{
|
||||
$storage = $this->createMock(Storage::class);
|
||||
$importer = $this->createMock(Importer::class);
|
||||
|
||||
$fetcher = $this->prepareFetcher($storage, $importer);
|
||||
|
||||
$fetchData = $this->prepareFetchData(
|
||||
lastUid: 3,
|
||||
lastDate: DateTime::fromString('2026-01-02 00:00'),
|
||||
uidValidity: 1,
|
||||
);
|
||||
|
||||
$account = $this->prepareAccount($fetchData);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('selectFolder')
|
||||
->with('INBOX');
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getFolderStatus')
|
||||
->willReturn(new Storage\FolderStatus(uidValidity: 2));
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('getUidsSinceDate')
|
||||
->with(DateTime::fromString('2026-01-02 00:00'))
|
||||
->willReturn([4]);
|
||||
|
||||
$storage
|
||||
->expects($this->once())
|
||||
->method('close');
|
||||
|
||||
$importer
|
||||
->expects($this->exactly(1))
|
||||
->method('import');
|
||||
|
||||
$fetchData
|
||||
->expects($this->once())
|
||||
->method('setUidValidity')
|
||||
->with('INBOX', 2);
|
||||
|
||||
$fetchData
|
||||
->expects($this->once())
|
||||
->method('setLastUid')
|
||||
->with('INBOX', 4);
|
||||
|
||||
$fetcher->fetch($account);
|
||||
}
|
||||
|
||||
private function prepareFetchData(
|
||||
?int $lastUid,
|
||||
?DateTime $lastDate,
|
||||
?int $uidValidity,
|
||||
): FetchData & MockObject {
|
||||
|
||||
$fetchData = $this->createMock(FetchData::class);
|
||||
|
||||
$fetchData
|
||||
->method('getLastUid')
|
||||
->willReturn($lastUid);
|
||||
|
||||
$fetchData
|
||||
->method('getLastDate')
|
||||
->willReturn($lastDate);
|
||||
|
||||
$fetchData
|
||||
->method('getUidValidity')
|
||||
->willReturn($uidValidity);
|
||||
|
||||
$fetchData
|
||||
->method('getForceByDate')
|
||||
->willReturn(false);
|
||||
|
||||
return $fetchData;
|
||||
}
|
||||
|
||||
private function prepareAccount(FetchData $fetchData): Account & MockObject
|
||||
{
|
||||
$account = $this->createMock(Account::class);
|
||||
|
||||
$account
|
||||
->method('isAvailableForFetching')
|
||||
->willReturn(true);
|
||||
|
||||
$account
|
||||
->method('getMonitoredFolderList')
|
||||
->willReturn(['INBOX']);
|
||||
|
||||
$account
|
||||
->expects($this->once())
|
||||
->method('getPortionLimit')
|
||||
->willReturn(5);
|
||||
|
||||
$account
|
||||
->expects($this->once())
|
||||
->method('getFetchData')
|
||||
->willReturn($fetchData);
|
||||
|
||||
$account
|
||||
->method('getFetchSince')
|
||||
->willReturn(Date::fromString('2026-01-01'));
|
||||
|
||||
$account
|
||||
->expects($this->once())
|
||||
->method('updateFetchData')
|
||||
->with($fetchData);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
private function prepareFetcher(
|
||||
Storage & MockObject $storage,
|
||||
Importer & MockObject $importer,
|
||||
): Fetcher {
|
||||
|
||||
$storageFactory = $this->createMock(StorageFactory::class);
|
||||
$configDataProvider = $this->createMock(ConfigDataProvider::class);
|
||||
$log = $this->createMock(Log::class);
|
||||
$parserFactory = $this->createMock(ParserFactory::class);
|
||||
$filtersProvider = $this->createMock(Fetcher\FiltersProvider::class);
|
||||
$unlocker = $this->createMock(Fetcher\Unlocker::class);
|
||||
$messageFactory = $this->createMock(Fetcher\MessageFactory::class);
|
||||
|
||||
$storageFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->willReturn($storage);
|
||||
|
||||
return new Fetcher(
|
||||
importer: $importer,
|
||||
storageFactory: $storageFactory,
|
||||
configDataProvider: $configDataProvider,
|
||||
log: $log,
|
||||
parserFactory: $parserFactory,
|
||||
filtersProvider: $filtersProvider,
|
||||
unlocker: $unlocker,
|
||||
messageFactory: $messageFactory,
|
||||
);
|
||||
}
|
||||
}
|
||||
227
tests/unit/Espo/Core/Mail/Event/EventTest.php
Normal file
227
tests/unit/Espo/Core/Mail/Event/EventTest.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail\Event;
|
||||
|
||||
use ICal\ICal;
|
||||
use ICal\Event;
|
||||
|
||||
use Espo\Core\Mail\Event\EventFactory;
|
||||
use Espo\Core\Mail\Event\Event as MailEvent;
|
||||
|
||||
class EventTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private $icsContents1 =
|
||||
"BEGIN:VCALENDAR
|
||||
METHOD:REQUEST
|
||||
PRODID:Microsoft Exchange Server 2010
|
||||
VERSION:2.0
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Jordan Standard Time
|
||||
BEGIN:STANDARD
|
||||
DTSTART:16010101T010000
|
||||
TZOFFSETFROM:+0300
|
||||
TZOFFSETTO:+0200
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1FR;BYMONTH=10
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:16010101T235959
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0300
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1TH;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
ORGANIZER;CN=Test Org:MAILTO:test-org@test.com
|
||||
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=Test-1:MAIL
|
||||
TO:test-1@test.com
|
||||
ATTENDEE;ROLE=REQ-PARTICIPANT;CN=Test-2:MAILTO:test-2@test.com
|
||||
UID:040000008200E00074C5B7101A82E008000000004679AD350342D501000000000000000
|
||||
010000000BB4B99DDF6B4934B8DC8B8BA92CF3645
|
||||
SUMMARY;LANGUAGE=en-US:test2
|
||||
DTSTART;TZID=Jordan Standard Time:20190729T180000
|
||||
DTEND;TZID=Jordan Standard Time:20190729T183000
|
||||
CLASS:PUBLIC
|
||||
PRIORITY:5
|
||||
DTSTAMP:20190724T093603Z
|
||||
TRANSP:OPAQUE
|
||||
STATUS:CONFIRMED
|
||||
SEQUENCE:0
|
||||
LOCATION;LANGUAGE=en-US:
|
||||
X-MICROSOFT-CDO-APPT-SEQUENCE:0
|
||||
X-MICROSOFT-CDO-OWNERAPPTID:2117584454
|
||||
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
|
||||
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
|
||||
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
|
||||
X-MICROSOFT-CDO-IMPORTANCE:1
|
||||
X-MICROSOFT-CDO-INSTTYPE:0
|
||||
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
|
||||
X-MICROSOFT-DISALLOW-COUNTER:FALSE
|
||||
X-MICROSOFT-LOCATIONS:[]
|
||||
BEGIN:VALARM
|
||||
DESCRIPTION:REMINDER
|
||||
TRIGGER;RELATED=START:-PT15M
|
||||
ACTION:DISPLAY
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
private $icsContents2 =
|
||||
"BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:Test-2a
|
||||
DTSTART;TZID=America/New_York:20130802T103400
|
||||
DTEND;TZID=America/New_York:20130802T110400
|
||||
LOCATION:1 Broadway Ave.\, Brooklyn
|
||||
DESCRIPTION: Description Test 1
|
||||
STATUS:CONFIRMED
|
||||
SEQUENCE:3
|
||||
BEGIN:VALARM
|
||||
TRIGGER:-PT10M
|
||||
DESCRIPTION:Pickup Reminder
|
||||
ACTION:DISPLAY
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
private $icsContents3 =
|
||||
"BEGIN:VCALENDAR
|
||||
PRODID:-//Google Inc//Google Calendar 70.9054//EN
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:REQUEST
|
||||
BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:20210810
|
||||
DTEND;VALUE=DATE:20210811
|
||||
DTSTAMP:20210810T091857Z
|
||||
ORGANIZER;CN=test:mailto:test@group.calendar.google.c
|
||||
om
|
||||
UID:4r15namb5v2h4dou58gkfajjbe@google.com
|
||||
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
|
||||
TRUE;CN=test.com;X-NUM-GUESTS=0:mailto:test@test.com
|
||||
X-MICROSOFT-CDO-OWNERAPPTID:1443094082
|
||||
CREATED:20210810T091748Z
|
||||
LAST-MODIFIED:20210810T091856Z
|
||||
LOCATION:
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:test ics 4
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
END:VCALENDAR";
|
||||
|
||||
public function testEvent1(): void
|
||||
{
|
||||
$ical = new ICal();
|
||||
|
||||
$ical->initString($this->icsContents1);
|
||||
|
||||
/* @var $event Event */
|
||||
$event = $ical->events()[0];
|
||||
|
||||
$espoEvent = MailEvent::create()
|
||||
->withUid($event->uid ?? null)
|
||||
->withDateStart($event->dtstart_tz ?? null)
|
||||
->withDateEnd($event->dtend_tz ?? null)
|
||||
->withName($event->summary ?? null)
|
||||
->withLocation($event->location ?? null)
|
||||
->withDescription($event->description ?? null)
|
||||
->withTimezone($ical->calendarTimeZone() ?? null)
|
||||
->withOrganizer($event->organizer)
|
||||
->withAttendees($event->attendee);
|
||||
|
||||
$this->assertEquals(
|
||||
'040000008200E00074C5B7101A82E008000000004679AD350342D501000000000000000' .
|
||||
'010000000BB4B99DDF6B4934B8DC8B8BA92CF3645',
|
||||
$espoEvent->getUid()
|
||||
);
|
||||
|
||||
$this->assertEquals('2019-07-29 15:00:00', $espoEvent->getDateStart());
|
||||
|
||||
$this->assertEquals('test-org@test.com', $espoEvent->getOrganizerEmailAddress());
|
||||
|
||||
$this->assertEquals(['test-1@test.com', 'test-2@test.com'], $espoEvent->getAttendeeEmailAddressList());
|
||||
}
|
||||
|
||||
public function testEvent2(): void
|
||||
{
|
||||
$ical = new ICal();
|
||||
|
||||
$ical->initString($this->icsContents2);
|
||||
|
||||
/* @var $event Event */
|
||||
$event = $ical->events()[0];
|
||||
|
||||
$espoEvent = MailEvent::create()
|
||||
->withUid($event->uid ?? null)
|
||||
->withDateStart($event->dtstart_tz ?? null)
|
||||
->withDateEnd($event->dtend_tz ?? null)
|
||||
->withName($event->summary ?? null)
|
||||
->withLocation($event->location ?? null)
|
||||
->withDescription($event->description ?? null)
|
||||
->withTimezone($ical->calendarTimeZone() ?? null)
|
||||
->withOrganizer($event->organizer)
|
||||
->withAttendees($event->attendee);
|
||||
|
||||
$this->assertEquals(
|
||||
null,
|
||||
$espoEvent->getUid()
|
||||
);
|
||||
|
||||
$this->assertEquals('2013-08-02 14:34:00', $espoEvent->getDateStart());
|
||||
|
||||
$this->assertEquals(null, $espoEvent->getOrganizerEmailAddress());
|
||||
|
||||
$this->assertEquals([], $espoEvent->getAttendeeEmailAddressList());
|
||||
|
||||
$this->assertEquals(
|
||||
"1 Broadway Ave., Brooklyn",
|
||||
$espoEvent->getLocation()
|
||||
);
|
||||
|
||||
$this->assertFalse($espoEvent->isAllDay());
|
||||
}
|
||||
|
||||
public function testEvent3(): void
|
||||
{
|
||||
$ical = new ICal();
|
||||
|
||||
$ical->initString($this->icsContents3);
|
||||
|
||||
$event = EventFactory::createFromU01jmg3Ical($ical);
|
||||
|
||||
$this->assertTrue($event->isAllDay());
|
||||
$this->assertEquals('2021-08-10', $event->getDateStart());
|
||||
$this->assertEquals('2021-08-10', $event->getDateEnd());
|
||||
}
|
||||
}
|
||||
295
tests/unit/Espo/Core/Mail/FiltersMatcherTest.php
Normal file
295
tests/unit/Espo/Core/Mail/FiltersMatcherTest.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail;
|
||||
|
||||
use Espo\Entities\Email;
|
||||
use Espo\Entities\EmailFilter;
|
||||
use Espo\Core\Mail\FiltersMatcher;
|
||||
use Espo\ORM\EntityManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FiltersMatcherTest extends TestCase
|
||||
{
|
||||
private $object;
|
||||
private $entityManager;
|
||||
private $emailDefs;
|
||||
private $filterDefs;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->object = new FiltersMatcher();
|
||||
$this->entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$this->emailDefs = [
|
||||
'attributes' => [
|
||||
'from' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'to' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'name' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'subject' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'body' => [
|
||||
'type' => 'text'
|
||||
],
|
||||
'bodyPlain' => [
|
||||
'type' => 'text'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$this->filterDefs = [
|
||||
'attributes' => [
|
||||
'from' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'to' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'subject' => [
|
||||
'type' => 'varchar'
|
||||
],
|
||||
'bodyContains' => [
|
||||
'type' => 'jsonArray'
|
||||
],
|
||||
'bodyContainsAll' => [
|
||||
'type' => 'jsonArray'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
protected function tearDown() : void
|
||||
{
|
||||
$this->object = NULL;
|
||||
}
|
||||
|
||||
protected function createEntity(string $entityType, string $className, array $defs)
|
||||
{
|
||||
return new $className($entityType, $defs, $this->entityManager);
|
||||
}
|
||||
|
||||
public function testMatch(): void
|
||||
{
|
||||
$email = $this->createEntity('Email', Email::class, $this->emailDefs);
|
||||
$email->set('from', 'test@tester');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$filter->set([
|
||||
'from' => 'test@tester'
|
||||
]);
|
||||
|
||||
$filterList = [$filter];
|
||||
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email = $this->createEntity('Email', Email::class, $this->emailDefs);
|
||||
$email->set('from', 'test@tester');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$filter->set([
|
||||
'from' => '*@tester'
|
||||
]);
|
||||
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('from', 'test@tester');
|
||||
$email->set('to', 'test@tester;baraka@tester');
|
||||
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$filter->set([
|
||||
'to' => 'baraka@tester'
|
||||
]);
|
||||
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('from', 'test@tester');
|
||||
$email->set('to', 'test@tester;baraka@man');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'to' => '*@tester'
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('subject', 'test hello man');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$filter->set([
|
||||
'subject' => '*hello*'
|
||||
]);
|
||||
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('name', 'test hello man');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'subject' => 'hello'
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
|
||||
$email->set('name', 'test hello man');
|
||||
$email->set('from', 'test@tester');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'subject' => '*hello*',
|
||||
'from' => 'test@tester'
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('name', 'test hello man');
|
||||
$email->set('from', 'hello@tester');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'subject' => '*hello*',
|
||||
'from' => 'test@tester'
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
|
||||
$email->set('name', 'test hello man');
|
||||
$email->set('body', 'one hello three');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'subject' => 'test hello man',
|
||||
'bodyContains' => ['hello']
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNull($this->object->findMatch($email, $filterList, true));
|
||||
|
||||
$email->set('name', 'test hello man');
|
||||
$email->set('body', 'one hello three');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'subject' => 'test hello man',
|
||||
'bodyContains' => ['hello']
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('name', 'Access information to the EspoCRM cloud');
|
||||
$email->set('from', 'no-reply@test.com');
|
||||
$email->set('to', 'info@test.com');
|
||||
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$filter->set([
|
||||
'subject' => 'Access information to the EspoCRM cloud',
|
||||
'from' => 'no-reply@test.com',
|
||||
'to' => 'info@test.com'
|
||||
]);
|
||||
|
||||
$this->assertTrue($this->object->match($email, $filter));
|
||||
|
||||
$email->set('body', 'test hello');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'bodyContainsAll' => ['test', 'hello'],
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('body', 'test');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'bodyContainsAll' => ['test', 'hello'],
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email->set('body', 'test hello one');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'bodyContains' => ['test', 'one'],
|
||||
'bodyContainsAll' => ['test', 'hello'],
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
}
|
||||
|
||||
public function testMatchBody()
|
||||
{
|
||||
$email = $this->createEntity('Email', Email::class, $this->emailDefs);
|
||||
$email->set('body', 'hello Man tester');
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'bodyContains' => ['man', 'red']
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNotNull($this->object->findMatch($email, $filterList));
|
||||
|
||||
$email = $this->createEntity('Email', Email::class, $this->emailDefs);
|
||||
$email->set('body', 'hello Man tester');
|
||||
$email->set('from', 'hello@test');
|
||||
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
$filter->set([
|
||||
'bodyContains' => ['man', 'red'],
|
||||
'from' => 'test@tester'
|
||||
]);
|
||||
$filterList = [$filter];
|
||||
$this->assertNull($this->object->findMatch($email, $filterList));
|
||||
}
|
||||
|
||||
public function testMatchEmpty(): void
|
||||
{
|
||||
$email = $this->createEntity('Email', Email::class, $this->emailDefs);
|
||||
$filter = $this->createEntity('EmailFilter', EmailFilter::class, $this->filterDefs);
|
||||
|
||||
$email->set([
|
||||
'name' => 'Test',
|
||||
'from' => 'test@test.com',
|
||||
'to' => 'test@test.com',
|
||||
'body' => 'Test',
|
||||
]);
|
||||
|
||||
$filter->set([
|
||||
'subject' => '',
|
||||
'bodyContains' => [''],
|
||||
'from' => '',
|
||||
'to' => '',
|
||||
]);
|
||||
|
||||
$this->assertNull($this->object->findMatch($email, [$filter]));
|
||||
}
|
||||
}
|
||||
73
tests/unit/Espo/Core/Mail/ImporterDataTest.php
Normal file
73
tests/unit/Espo/Core/Mail/ImporterDataTest.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail;
|
||||
|
||||
use Espo\Core\Mail\Importer\Data as ImporterData;
|
||||
|
||||
use Espo\Entities\EmailFilter;
|
||||
|
||||
class ImporterDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
function testData1()
|
||||
{
|
||||
$filter = $this->createMock(EmailFilter::class);
|
||||
|
||||
$data = ImporterData
|
||||
::create()
|
||||
->withTeamIdList(['t1'])
|
||||
->withUserIdList(['u1'])
|
||||
->withAssignedUserId('a1')
|
||||
->withFetchOnlyHeader(true)
|
||||
->withFolderData(['t' => '1'])
|
||||
->withFilterList([$filter]);
|
||||
|
||||
$this->assertEquals(['t1'], $data->getTeamIdList());
|
||||
$this->assertEquals(['u1'], $data->getUserIdList());
|
||||
$this->assertEquals('a1', $data->getAssignedUserId());
|
||||
$this->assertEquals(true, $data->fetchOnlyHeader());
|
||||
$this->assertEquals(['t' => '1'], $data->getFolderData());
|
||||
$this->assertEquals([$filter], $data->getFilterList());
|
||||
}
|
||||
|
||||
function testData2()
|
||||
{
|
||||
|
||||
$data = ImporterData
|
||||
::create()
|
||||
->withFetchOnlyHeader(false);
|
||||
|
||||
$this->assertEquals([], $data->getTeamIdList());
|
||||
$this->assertEquals([], $data->getUserIdList());
|
||||
$this->assertEquals(null, $data->getAssignedUserId());
|
||||
$this->assertEquals(false, $data->fetchOnlyHeader());
|
||||
$this->assertEquals([], $data->getFilterList());
|
||||
}
|
||||
}
|
||||
236
tests/unit/Espo/Core/Mail/ImporterTest.php
Normal file
236
tests/unit/Espo/Core/Mail/ImporterTest.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail;
|
||||
|
||||
use Espo\Entities\Email;
|
||||
|
||||
use Espo\Core\Notification\AssignmentNotificator;
|
||||
|
||||
use Espo\ORM\Metadata;
|
||||
use Espo\ORM\Value\ValueAccessor;
|
||||
use Espo\ORM\Value\ValueAccessorFactory;
|
||||
use Espo\Core\FieldProcessing\Relation\LinkMultipleSaver;
|
||||
use Espo\Core\Job\JobSchedulerFactory;
|
||||
use Espo\Core\Mail\Importer;
|
||||
use Espo\Core\Mail\Importer\Data as ImporterData;
|
||||
use Espo\Core\Mail\MessageWrapper;
|
||||
use Espo\Core\Mail\ParserFactory;
|
||||
use Espo\Core\Mail\Parsers\MailMimeParser;
|
||||
use Espo\Core\Notification\AssignmentNotificatorFactory;
|
||||
use Espo\Core\ORM\EntityManager;
|
||||
use Espo\Core\Repositories\Database;
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\ORM\Repository\RDBSelectBuilder;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ImporterTest extends TestCase
|
||||
{
|
||||
private $emailRepository;
|
||||
private $config;
|
||||
private $assignmentNotificatorFactory;
|
||||
private $parserFactory;
|
||||
private $linkMultipleSaver;
|
||||
private $parentFinder;
|
||||
private $jobSchedulerFactory;
|
||||
private $duplicateFinder;
|
||||
private $email;
|
||||
private $repositoryMap;
|
||||
private $entityManager;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$entityManager = $this->entityManager = $this->createMock(EntityManager::class);
|
||||
|
||||
$this->config = $this->createMock(Config::class);
|
||||
|
||||
$emailRepository = $this->createMock(Database::class);
|
||||
$emptyRepository = $this->createMock(Database::class);
|
||||
|
||||
$metadata = $this->createMock(Metadata::class);
|
||||
|
||||
$selectBuilder = $this->createMock(RDBSelectBuilder::class);
|
||||
|
||||
$this->assignmentNotificatorFactory = $this->createMock(AssignmentNotificatorFactory::class);
|
||||
$this->parserFactory = $this->createMock(ParserFactory::class);
|
||||
$this->linkMultipleSaver = $this->createMock(LinkMultipleSaver::class);
|
||||
|
||||
$this->parentFinder = $this->createMock(Importer\ParentFinder::class);
|
||||
|
||||
$this->parserFactory
|
||||
->expects($this->any())
|
||||
->method('create')
|
||||
->willReturnCallback(
|
||||
function () {
|
||||
return new MailMimeParser($this->entityManager);
|
||||
}
|
||||
);
|
||||
|
||||
$emailRepository
|
||||
->expects($this->any())
|
||||
->method('where')
|
||||
->willReturn($selectBuilder);
|
||||
|
||||
$emailRepository
|
||||
->expects($this->any())
|
||||
->method('select')
|
||||
->willReturn($selectBuilder);
|
||||
|
||||
$entityManager
|
||||
->expects($this->any())
|
||||
->method('getMetadata')
|
||||
->willReturn($metadata);
|
||||
|
||||
$metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn(null);
|
||||
|
||||
$emptyRepository
|
||||
->expects($this->any())
|
||||
->method('where')
|
||||
->willReturn($selectBuilder);
|
||||
|
||||
$this->emailRepository = $emailRepository;
|
||||
|
||||
$this->repositoryMap = [
|
||||
[Email::class, $this->emailRepository],
|
||||
//['Account', $emptyRepository],
|
||||
//['Contact', $emptyRepository],
|
||||
//['Lead', $emptyRepository],
|
||||
];
|
||||
|
||||
$valueAccessor = $this->createMock(ValueAccessor::class);
|
||||
$valueAccessorFactory = $this->createMock(ValueAccessorFactory::class);
|
||||
|
||||
$valueAccessorFactory
|
||||
->expects($this->any())
|
||||
->method('create')
|
||||
->willReturn(
|
||||
$valueAccessor
|
||||
);
|
||||
|
||||
$emailDefs = require('tests/unit/testData/Core/Mail/email_defs.php');
|
||||
//$attachmentDefs = require('tests/unit/testData/Core/Mail/attachment_defs.php');
|
||||
|
||||
$this->email = new Email('Email', $emailDefs, $entityManager, $valueAccessorFactory);
|
||||
//$attachment = new Attachment('Attachment', $attachmentDefs, $entityManager, $valueAccessorFactory);
|
||||
|
||||
$this->assignmentNotificatorFactory
|
||||
->expects($this->any())
|
||||
->method('create')
|
||||
->willReturn(
|
||||
$this->createMock(AssignmentNotificator::class)
|
||||
);
|
||||
|
||||
|
||||
$this->duplicateFinder = $this->createMock(Importer\DuplicateFinder::class);
|
||||
|
||||
$this->jobSchedulerFactory = $this->createMock(JobSchedulerFactory::class);
|
||||
}
|
||||
|
||||
public function testImport1(): void
|
||||
{
|
||||
$entityManager = $this->entityManager;
|
||||
$config = $this->config;
|
||||
$email = $this->email;
|
||||
|
||||
$entityManager
|
||||
->expects($this->any())
|
||||
->method('getRDBRepositoryByClass')
|
||||
->willReturnMap($this->repositoryMap);
|
||||
|
||||
$entityManager
|
||||
->expects($this->exactly(1))
|
||||
->method('saveEntity')
|
||||
->with($this->isInstanceOf(Email::class))
|
||||
->willReturnCallback(function (Email $entity) {
|
||||
$entity->set('id', 'test-id');
|
||||
});
|
||||
|
||||
$this->emailRepository
|
||||
->expects($this->once())
|
||||
->method('getNew')
|
||||
->willReturn($email);
|
||||
|
||||
$config
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
[
|
||||
['b2cMode', false]
|
||||
]
|
||||
);
|
||||
|
||||
$saver = $this->createMock(Importer\EmailSaver::class);
|
||||
|
||||
$saver
|
||||
->expects($this->exactly(1))
|
||||
->method('save')
|
||||
->with($this->isInstanceOf(Email::class));
|
||||
|
||||
$contents = file_get_contents('tests/unit/testData/Core/Mail/test_email_1.eml');
|
||||
|
||||
$importer = new Importer\DefaultImporter(
|
||||
entityManager: $entityManager,
|
||||
config: $config,
|
||||
notificatorFactory: $this->assignmentNotificatorFactory,
|
||||
parserFactory: $this->parserFactory,
|
||||
linkMultipleSaver: $this->linkMultipleSaver,
|
||||
duplicateFinder: $this->duplicateFinder,
|
||||
jobSchedulerFactory: $this->jobSchedulerFactory,
|
||||
parentFinder: $this->parentFinder,
|
||||
autoReplyDetector: $this->createMock(Importer\AutoReplyDetector::class),
|
||||
emailSaver: $saver,
|
||||
);
|
||||
|
||||
$message = new MessageWrapper(0, null, null, $contents);
|
||||
|
||||
$data = ImporterData
|
||||
::create()
|
||||
->withTeamIdList(['teamTestId'])
|
||||
->withUserIdList(['userTestId']);
|
||||
|
||||
$email = $importer->import($message, $data);
|
||||
|
||||
$this->assertEquals('test 3', $email->get('name'));
|
||||
|
||||
$userIdList = $email->getLinkMultipleIdList('users');
|
||||
$this->assertTrue(in_array('userTestId', $userIdList));
|
||||
|
||||
$this->assertStringContainsString('<br>Admin Test', $email->get('body'));
|
||||
$this->assertStringContainsString('Admin Test', $email->get('bodyPlain'));
|
||||
|
||||
$messageId = '<e558c4dfc2a0f0d60f5ebff474c97ffc/1466410740/1950@espo>';
|
||||
|
||||
$this->assertEquals($messageId, $email->get('messageId'));
|
||||
$this->assertEquals($messageId . '-r@test.com', $email->get('messageIdInternal'));
|
||||
}
|
||||
}
|
||||
72
tests/unit/Espo/Core/Mail/SenderParamsTest.php
Normal file
72
tests/unit/Espo/Core/Mail/SenderParamsTest.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail;
|
||||
|
||||
use Espo\Core\Mail\SenderParams;
|
||||
|
||||
class SenderParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testFromArray1(): void
|
||||
{
|
||||
$array = [
|
||||
'fromAddress' => 'test@test',
|
||||
'fromName' => 'name',
|
||||
'replyToAddress' => 'reply@test',
|
||||
'replyToName' => 'reply',
|
||||
];
|
||||
|
||||
$this->assertEquals($array, SenderParams::fromArray($array)->toArray());
|
||||
}
|
||||
|
||||
public function testFromArray2(): void
|
||||
{
|
||||
$array = [
|
||||
'fromAddress' => 'test@test',
|
||||
'fromName' => 'name',
|
||||
];
|
||||
|
||||
$this->assertEquals($array, SenderParams::fromArray($array)->toArray());
|
||||
}
|
||||
|
||||
public function testBuilding(): void
|
||||
{
|
||||
$params = SenderParams::create()
|
||||
->withFromAddress('test@test')
|
||||
->withFromName('name')
|
||||
->withReplyToAddress('r@test')
|
||||
->withReplyToName('r');
|
||||
|
||||
$this->assertEquals('test@test', $params->getFromAddress());
|
||||
$this->assertEquals('name', $params->getFromName());
|
||||
|
||||
$this->assertEquals('r@test', $params->getReplyToAddress());
|
||||
$this->assertEquals('r', $params->getReplyToName());
|
||||
}
|
||||
}
|
||||
91
tests/unit/Espo/Core/Mail/SmtpParamsTest.php
Normal file
91
tests/unit/Espo/Core/Mail/SmtpParamsTest.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Mail;
|
||||
|
||||
use Espo\Core\Mail\SmtpParams;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SmtpParamsTest extends TestCase
|
||||
{
|
||||
public function testFromArray1(): void
|
||||
{
|
||||
$array = [
|
||||
'server' => 'localhost',
|
||||
'port' => 587,
|
||||
'fromAddress' => 'test@test',
|
||||
'fromName' => 'name',
|
||||
'auth' => false,
|
||||
];
|
||||
|
||||
$this->assertEquals($array, SmtpParams::fromArray($array)->toArray());
|
||||
}
|
||||
|
||||
public function testFromArray2(): void
|
||||
{
|
||||
$array = [
|
||||
'server' => 'localhost',
|
||||
'port' => 587,
|
||||
'fromAddress' => 'test@test',
|
||||
'fromName' => 'name',
|
||||
'auth' => true,
|
||||
'connectionOptions' => ['test' => 'test'],
|
||||
'authMechanism' => 'login',
|
||||
'username' => 'tester',
|
||||
'password' => 'password',
|
||||
'security' => 'ssl',
|
||||
];
|
||||
|
||||
$this->assertEquals($array, SmtpParams::fromArray($array)->toArray());
|
||||
}
|
||||
|
||||
public function testBuilding(): void
|
||||
{
|
||||
$params = SmtpParams::create('localhost', 587)
|
||||
->withFromAddress('test@test')
|
||||
->withFromName('name')
|
||||
->withAuth()
|
||||
->withUsername('tester')
|
||||
->withPassword('test')
|
||||
->withAuthMechanism('login')
|
||||
->withConnectionOptions(['test' => 'test']);
|
||||
|
||||
$this->assertEquals('localhost', $params->getServer());
|
||||
$this->assertEquals(587, $params->getPort());
|
||||
|
||||
$this->assertEquals('test@test', $params->getFromAddress());
|
||||
$this->assertEquals('name', $params->getFromName());
|
||||
|
||||
$this->assertEquals(true, $params->useAuth());
|
||||
|
||||
$this->assertEquals('tester', $params->getUsername());
|
||||
$this->assertEquals('test', $params->getPassword());
|
||||
$this->assertEquals(['test' => 'test'], $params->getConnectionOptions());
|
||||
}
|
||||
}
|
||||
60
tests/unit/Espo/Core/MassAction/DataTest.php
Normal file
60
tests/unit/Espo/Core/MassAction/DataTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\MassAction;
|
||||
|
||||
use Espo\Core\{
|
||||
MassAction\Data,
|
||||
};
|
||||
|
||||
class DataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testData()
|
||||
{
|
||||
$original = (object) [
|
||||
'test' => 'hello',
|
||||
];
|
||||
|
||||
$data = Data::fromRaw($original);
|
||||
|
||||
$this->assertEquals('hello', $data->get('test'));
|
||||
|
||||
$this->assertTrue($data->has('test'));
|
||||
|
||||
$this->assertFalse($data->has('no'));
|
||||
|
||||
$this->assertEquals($data->getRaw(), $original);
|
||||
|
||||
$this->assertNotSame($data->getRaw(), $original);
|
||||
}
|
||||
}
|
||||
181
tests/unit/Espo/Core/MassAction/ParamsTest.php
Normal file
181
tests/unit/Espo/Core/MassAction/ParamsTest.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\MassAction;
|
||||
|
||||
use Espo\Core\{
|
||||
MassAction\Params,
|
||||
Select\SearchParams,
|
||||
};
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
class ParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp() : void
|
||||
{
|
||||
}
|
||||
|
||||
public function testFromRawIds()
|
||||
{
|
||||
$params = Params::fromRaw(
|
||||
[
|
||||
'ids' => ['1'],
|
||||
'entityType' => 'Test',
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals('Test', $params->getEntityType());
|
||||
|
||||
$this->assertEquals(['1'], $params->getIds());
|
||||
|
||||
$this->assertTrue($params->hasIds());
|
||||
}
|
||||
|
||||
public function testFromIds()
|
||||
{
|
||||
$params = Params::createWithIds('Test', ['1']);
|
||||
|
||||
$this->assertEquals('Test', $params->getEntityType());
|
||||
|
||||
$this->assertEquals(['1'], $params->getIds());
|
||||
}
|
||||
|
||||
public function testFromSearchParams()
|
||||
{
|
||||
$searchParams = $this->createMock(SearchParams::class);
|
||||
|
||||
$params = Params::createWithSearchParams('Test', $searchParams);
|
||||
|
||||
$this->assertEquals('Test', $params->getEntityType());
|
||||
|
||||
$this->assertEquals($searchParams, $params->getSearchParams());
|
||||
}
|
||||
|
||||
public function testFromRawSearchParams1()
|
||||
{
|
||||
$where = [
|
||||
[
|
||||
'type' => 'equals',
|
||||
'attribute' => 'name',
|
||||
'value' => 'test',
|
||||
]
|
||||
];
|
||||
|
||||
$params = Params::fromRaw(
|
||||
[
|
||||
'where' => $where,
|
||||
'searchParams' => [
|
||||
'primaryFilter' => 'testFilter',
|
||||
],
|
||||
],
|
||||
'Test'
|
||||
);
|
||||
|
||||
$searchParams = $params->getSearchParams();
|
||||
|
||||
$this->assertEquals('Test', $params->getEntityType());
|
||||
|
||||
$this->assertEquals($where, $searchParams->getWhere()->getRaw()['value']);
|
||||
|
||||
$this->assertEquals('testFilter', $searchParams->getPrimaryFilter());
|
||||
|
||||
$this->assertFalse($params->hasIds());
|
||||
}
|
||||
|
||||
public function testFromRawSearchParams2()
|
||||
{
|
||||
$where = [
|
||||
[
|
||||
'type' => 'equals',
|
||||
'attribute' => 'name',
|
||||
'value' => 'test',
|
||||
]
|
||||
];
|
||||
|
||||
$params = Params::fromRaw(
|
||||
[
|
||||
'searchParams' => [
|
||||
'primaryFilter' => 'testFilter',
|
||||
'where' => $where,
|
||||
],
|
||||
],
|
||||
'Test'
|
||||
);
|
||||
|
||||
$searchParams = $params->getSearchParams();
|
||||
|
||||
$this->assertEquals($where, $searchParams->getWhere()->getRaw()['value']);
|
||||
|
||||
$this->assertEquals('testFilter', $searchParams->getPrimaryFilter());
|
||||
|
||||
$this->assertFalse($params->hasIds());
|
||||
}
|
||||
|
||||
public function testFromRawSearchException1()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
|
||||
Params::fromRaw(
|
||||
[
|
||||
'ids' => ['1'],
|
||||
'searchParams' => [
|
||||
'primaryFilter' => 'testFilter',
|
||||
'where' => [],
|
||||
],
|
||||
],
|
||||
'Test'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSerialize1(): void
|
||||
{
|
||||
$params1 = Params::fromRaw(
|
||||
[
|
||||
'searchParams' => [
|
||||
'primaryFilter' => 'testFilter',
|
||||
'where' => [
|
||||
[
|
||||
'type' => 'equals',
|
||||
'attribute' => 'name',
|
||||
'value' => 'test',
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
'Test'
|
||||
);
|
||||
|
||||
$params2 = Params::fromSerializedRaw(base64_encode(serialize($params1)));
|
||||
|
||||
$this->assertEquals($params1, $params2);
|
||||
|
||||
$this->assertEquals('equals', $params2->getSearchParams()->getWhere()->getItemList()[0]->getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Notification;
|
||||
|
||||
use Espo\Core\Notification\AssignmentNotificator\Params;
|
||||
use Espo\Core\ORM\Repository\Option\SaveOption;
|
||||
|
||||
class AssignmentNotificatorParamsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testOne(): void
|
||||
{
|
||||
$options = [SaveOption::SILENT => true];
|
||||
|
||||
$params = Params
|
||||
::create()
|
||||
->withRawOptions($options);
|
||||
|
||||
$this->assertEquals(true, $params->getOption('silent'));
|
||||
$this->assertEquals(true, $params->hasOption('silent'));
|
||||
$this->assertEquals(null, $params->getOption('skipHooks'));
|
||||
$this->assertEquals(false, $params->hasOption('skipHooks'));
|
||||
|
||||
$this->assertEquals($options, $params->getRawOptions());
|
||||
}
|
||||
}
|
||||
89
tests/unit/Espo/Core/ORM/DatabaseParamsFactoryTest.php
Normal file
89
tests/unit/Espo/Core/ORM/DatabaseParamsFactoryTest.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\ORM;
|
||||
|
||||
use Espo\Core\ORM\DatabaseParamsFactory;
|
||||
use Espo\Core\Utils\Config;
|
||||
|
||||
class DatabaseParamsFactoryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testCreate(): void
|
||||
{
|
||||
$factory = new DatabaseParamsFactory($this->createConfig());
|
||||
|
||||
$params = $factory->create();
|
||||
|
||||
$this->assertEquals('test:host', $params->getHost());
|
||||
$this->assertEquals(10, $params->getPort());
|
||||
$this->assertEquals('name-db', $params->getName());
|
||||
$this->assertEquals('test-user', $params->getUsername());
|
||||
$this->assertEquals('test-password', $params->getPassword());
|
||||
$this->assertEquals('test-platform', $params->getPlatform());
|
||||
}
|
||||
|
||||
public function testCreateWithMergedAssoc(): void
|
||||
{
|
||||
$factory = new DatabaseParamsFactory($this->createConfig());
|
||||
|
||||
$params = $factory->createWithMergedAssoc([
|
||||
'host' => 'test:host2',
|
||||
'port' => 11,
|
||||
'dbname' => 'name2-db',
|
||||
'user' => 'test-user2',
|
||||
'password' => 'test-password2',
|
||||
]);
|
||||
|
||||
$this->assertEquals('test:host2', $params->getHost());
|
||||
$this->assertEquals(11, $params->getPort());
|
||||
$this->assertEquals('name2-db', $params->getName());
|
||||
$this->assertEquals('test-user2', $params->getUsername());
|
||||
$this->assertEquals('test-password2', $params->getPassword());
|
||||
$this->assertEquals('test-platform', $params->getPlatform());
|
||||
}
|
||||
|
||||
private function createConfig(): Config
|
||||
{
|
||||
$config = $this->createMock(Config::class);
|
||||
|
||||
$config->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
['database', null, ['d' => 'd']],
|
||||
['database.host', null, 'test:host'],
|
||||
['database.port', null, 10],
|
||||
['database.dbname', null, 'name-db'],
|
||||
['database.user', null, 'test-user'],
|
||||
['database.password', null, 'test-password'],
|
||||
['database.platform', null, 'test-platform'],
|
||||
]);
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
109
tests/unit/Espo/Core/Portal/Acl/ScopeCheckerDataTest.php
Normal file
109
tests/unit/Espo/Core/Portal/Acl/ScopeCheckerDataTest.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Portal\Acl;
|
||||
|
||||
use Espo\Core\{
|
||||
Portal\Acl\AccessChecker\ScopeCheckerData,
|
||||
|
||||
};
|
||||
|
||||
class ScopeCheckerDataTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function testCheckerData0()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$this->assertEquals(false, $checkerData->isOwn());
|
||||
$this->assertEquals(false, $checkerData->inAccount());
|
||||
$this->assertEquals(false, $checkerData->inContact());
|
||||
}
|
||||
|
||||
public function testCheckerData1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInAccount(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$this->assertEquals(true, $checkerData->isOwn());
|
||||
$this->assertEquals(true, $checkerData->inAccount());
|
||||
$this->assertEquals(true, $checkerData->inContact());
|
||||
}
|
||||
|
||||
public function testCheckerData2()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(false)
|
||||
->setInAccountChecker(
|
||||
function (): bool {
|
||||
return true;
|
||||
}
|
||||
)
|
||||
->build();
|
||||
|
||||
$this->assertEquals(false, $checkerData->isOwn());
|
||||
$this->assertEquals(true, $checkerData->inAccount());
|
||||
}
|
||||
|
||||
public function testCheckerData3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwnChecker(
|
||||
function (): bool {
|
||||
return false;
|
||||
}
|
||||
)
|
||||
->setInAccountChecker(
|
||||
function (): bool {
|
||||
return false;
|
||||
}
|
||||
)
|
||||
->setInContactChecker(
|
||||
function (): bool {
|
||||
return true;
|
||||
}
|
||||
)
|
||||
->build();
|
||||
|
||||
$this->assertEquals(false, $checkerData->isOwn());
|
||||
$this->assertEquals(false, $checkerData->inAccount());
|
||||
$this->assertEquals(true, $checkerData->inContact());
|
||||
}
|
||||
}
|
||||
529
tests/unit/Espo/Core/Portal/Acl/ScopeCheckerTest.php
Normal file
529
tests/unit/Espo/Core/Portal/Acl/ScopeCheckerTest.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Portal\Acl;
|
||||
|
||||
use Espo\Core\{
|
||||
Portal\Acl\AccessChecker\ScopeChecker,
|
||||
Portal\Acl\AccessChecker\ScopeCheckerData,
|
||||
Portal\Acl\Table,
|
||||
Acl\ScopeData,
|
||||
};
|
||||
|
||||
class ScopeCheckerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var ScopeChecker
|
||||
*/
|
||||
private $scopeChecker;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->scopeChecker = new ScopeChecker();
|
||||
}
|
||||
|
||||
public function testCheckerNoData1()
|
||||
{
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData2()
|
||||
{
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData3()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData4()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerNoData5()
|
||||
{
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerActionNoData1()
|
||||
{
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerActionNoData2()
|
||||
{
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData2a()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData2b()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_CONTACT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData4()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData5a()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInAccount(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData5b()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData6a()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInAccount(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData6b()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData7a()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData7b()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
|
||||
public function testCheckerData7c()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_CONTACT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData8()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_CREATE, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData9()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData10()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_OWN,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData11()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_CONTACT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData12()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInAccount(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerData13()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, Table::ACTION_READ, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction1()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInAccount(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(false);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(false, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction2()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(true);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction3()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInAccount(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_ACCOUNT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction4()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInAccount(false)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_READ => Table::LEVEL_CONTACT,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
|
||||
public function testCheckerDataNoAction5()
|
||||
{
|
||||
$checkerData = ScopeCheckerData
|
||||
::createBuilder()
|
||||
->setIsOwn(true)
|
||||
->setInContact(true)
|
||||
->build();
|
||||
|
||||
$data = ScopeData::fromRaw(
|
||||
(object) [
|
||||
Table::ACTION_CREATE => Table::LEVEL_NO,
|
||||
Table::ACTION_READ => Table::LEVEL_NO,
|
||||
],
|
||||
);
|
||||
|
||||
$result = $this->scopeChecker->check($data, null, $checkerData);
|
||||
|
||||
$this->assertEquals(true, $result);
|
||||
}
|
||||
}
|
||||
136
tests/unit/Espo/Core/Record/CreateParamsFetcherTest.php
Normal file
136
tests/unit/Espo/Core/Record/CreateParamsFetcherTest.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Record;
|
||||
|
||||
use Espo\Core\Record\CreateParamsFetcher;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CreateParamsFetcherTest extends TestCase
|
||||
{
|
||||
public function test1(): void
|
||||
{
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
|
||||
$request
|
||||
->method('hasHeader')
|
||||
->with('X-Skip-Duplicate-Check')
|
||||
->willReturn(true);
|
||||
|
||||
$request
|
||||
->method('getHeader')
|
||||
->willReturnMap(
|
||||
[
|
||||
['X-Skip-Duplicate-Check', 'true'],
|
||||
['X-Duplicate-Source-Id', null],
|
||||
]
|
||||
);
|
||||
|
||||
$params = (new CreateParamsFetcher())->fetch($request);
|
||||
|
||||
$this->assertTrue($params->skipDuplicateCheck());
|
||||
}
|
||||
|
||||
public function test2(): void
|
||||
{
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
|
||||
$request
|
||||
->method('hasHeader')
|
||||
->willReturn(true);
|
||||
|
||||
$request
|
||||
->method('getHeader')
|
||||
->willReturnMap(
|
||||
[
|
||||
['X-Skip-Duplicate-Check', 'false'],
|
||||
['X-Duplicate-Source-Id', null],
|
||||
]
|
||||
);
|
||||
|
||||
$params = (new CreateParamsFetcher())->fetch($request);
|
||||
|
||||
$this->assertFalse($params->skipDuplicateCheck());
|
||||
}
|
||||
|
||||
public function test3(): void
|
||||
{
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
|
||||
$request
|
||||
->method('hasHeader')
|
||||
->willReturn(false);
|
||||
|
||||
$params = (new CreateParamsFetcher())->fetch($request);
|
||||
|
||||
$this->assertFalse($params->skipDuplicateCheck());
|
||||
}
|
||||
|
||||
public function test4(): void
|
||||
{
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
|
||||
$request
|
||||
->method('hasHeader')
|
||||
->willReturn(true);
|
||||
|
||||
$request
|
||||
->method('getHeader')
|
||||
->willReturnMap(
|
||||
[
|
||||
['X-Skip-Duplicate-Check', 'TRUE'],
|
||||
['X-Duplicate-Source-Id', null],
|
||||
]
|
||||
);
|
||||
|
||||
$params = (new CreateParamsFetcher())->fetch($request);
|
||||
|
||||
$this->assertTrue($params->skipDuplicateCheck());
|
||||
}
|
||||
|
||||
public function test5(): void
|
||||
{
|
||||
$request = $this->createMock(RequestWrapper::class);
|
||||
|
||||
$request
|
||||
->method('hasHeader')
|
||||
->willReturn(false);
|
||||
|
||||
$request
|
||||
->method('getParsedBody')
|
||||
->willReturn((object) [
|
||||
'_skipDuplicateCheck' => true,
|
||||
]);
|
||||
|
||||
$params = (new CreateParamsFetcher())->fetch($request);
|
||||
|
||||
$this->assertTrue($params->skipDuplicateCheck());
|
||||
}
|
||||
}
|
||||
230
tests/unit/Espo/Core/Record/HookManagerTest.php
Normal file
230
tests/unit/Espo/Core/Record/HookManagerTest.php
Normal file
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Record;
|
||||
|
||||
use Espo\Core\{
|
||||
Acl,
|
||||
Binding\BindingContainer,
|
||||
Binding\BindingContainerBuilder,
|
||||
Record\HookManager,
|
||||
Record\Hook\Provider,
|
||||
Record\Hook\Type,
|
||||
Record\CreateParams,
|
||||
Record\ReadParams,
|
||||
Record\UpdateParams,
|
||||
Record\DeleteParams,
|
||||
InjectableFactory,
|
||||
Utils\Metadata};
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
|
||||
use tests\unit\testClasses\Core\Record\Hooks\{
|
||||
BeforeReadHook,
|
||||
BeforeCreateHook,
|
||||
BeforeUpdateHook,
|
||||
BeforeDeleteHook,
|
||||
BeforeLinkHook,
|
||||
BeforeUnlinkHook,
|
||||
};
|
||||
|
||||
class HookManagerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/**
|
||||
* @var InjectableFactory
|
||||
*/
|
||||
private $injectableFactory;
|
||||
|
||||
/**
|
||||
* @var Metadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
/**
|
||||
* @var HookManager
|
||||
*/
|
||||
private $manager;
|
||||
|
||||
/**
|
||||
* @var Entity
|
||||
*/
|
||||
private $entity;
|
||||
|
||||
private $entityType = 'Test';
|
||||
|
||||
private ?BindingContainer $bindingContainer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
|
||||
$acl = $this->createMock(Acl::class);
|
||||
$user = $this->createMock(User::class);
|
||||
|
||||
$this->bindingContainer = BindingContainerBuilder::create()
|
||||
->bindInstance(User::class, $user)
|
||||
->bindInstance(Acl::class, $acl)
|
||||
->build();
|
||||
|
||||
$provider = new Provider($this->metadata, $this->injectableFactory, $acl, $user);
|
||||
|
||||
$this->manager = new HookManager($provider);
|
||||
|
||||
$this->entity = $this->createEntity($this->entityType);
|
||||
}
|
||||
|
||||
public function testBeforeRead(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeReadHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_READ, [BeforeReadHook::class], [$hook]);
|
||||
|
||||
$params = ReadParams::create();
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $params);
|
||||
|
||||
$this->manager->processBeforeRead($this->entity, $params);
|
||||
}
|
||||
|
||||
public function testBeforeCreate(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeCreateHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_CREATE, [BeforeCreateHook::class], [$hook]);
|
||||
|
||||
$params = CreateParams::create();
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $params);
|
||||
|
||||
$this->manager->processBeforeCreate($this->entity, $params);
|
||||
}
|
||||
|
||||
public function testBeforeUpdate(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeUpdateHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_UPDATE, [BeforeUpdateHook::class], [$hook]);
|
||||
|
||||
$params = UpdateParams::create();
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $params);
|
||||
|
||||
$this->manager->processBeforeUpdate($this->entity, $params);
|
||||
}
|
||||
|
||||
public function testBeforeDelete(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeDeleteHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_DELETE, [BeforeDeleteHook::class], [$hook]);
|
||||
|
||||
$params = DeleteParams::create();
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $params);
|
||||
|
||||
$this->manager->processBeforeDelete($this->entity, $params);
|
||||
}
|
||||
|
||||
public function testBeforeLink(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeLinkHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_LINK, [BeforeLinkHook::class], [$hook]);
|
||||
|
||||
$link = 'test';
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $link, $this->entity);
|
||||
|
||||
$this->manager->processBeforeLink($this->entity, $link, $this->entity);
|
||||
}
|
||||
|
||||
public function testBeforeUnlink(): void
|
||||
{
|
||||
$hook = $this->createMock(BeforeUnlinkHook::class);
|
||||
|
||||
$this->initHooks(Type::BEFORE_UNLINK, [BeforeUnlinkHook::class], [$hook]);
|
||||
|
||||
$link = 'test';
|
||||
|
||||
$hook
|
||||
->expects($this->once())
|
||||
->method('process')
|
||||
->with($this->entity, $link, $this->entity);
|
||||
|
||||
$this->manager->processBeforeUnlink($this->entity, $link, $this->entity);
|
||||
}
|
||||
|
||||
private function createEntity(string $entityType): Entity
|
||||
{
|
||||
$entity = $this->createMock(Entity::class);
|
||||
|
||||
$entity
|
||||
->expects($this->any())
|
||||
->method('getEntityType')
|
||||
->willReturn($entityType);
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
private function initHooks(string $type, array $hookClassNameList, array $hookList): void
|
||||
{
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
["app.record.{$type}HookClassNameList", [], []],
|
||||
["recordDefs.$this->entityType.{$type}HookClassNameList", [], $hookClassNameList],
|
||||
]);
|
||||
|
||||
foreach ($hookClassNameList as $i => $className) {
|
||||
$this->injectableFactory
|
||||
->expects($this->any())
|
||||
->method('createWithBinding')
|
||||
->with($className, $this->bindingContainer)
|
||||
->willReturn($hookList[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
tests/unit/Espo/Core/Record/SearchParamsFetcherTest.php
Normal file
88
tests/unit/Espo/Core/Record/SearchParamsFetcherTest.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Record;
|
||||
|
||||
use Espo\Core\Record\SearchParamsFetcher;
|
||||
use Espo\Core\Api\RequestWrapper;
|
||||
|
||||
use Espo\Core\Utils\Config;
|
||||
use Espo\Core\Select\Text\MetadataProvider as TextMetadataProvider;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Slim\Psr7\Factory\RequestFactory;
|
||||
|
||||
class SearchParamsFetcherTest extends TestCase
|
||||
{
|
||||
private $config;
|
||||
private $textMetadataProvider;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->config = $this->createMocK(Config::class);
|
||||
$this->textMetadataProvider = $this->createMocK(TextMetadataProvider::class);
|
||||
|
||||
$this->config
|
||||
->method('get')
|
||||
->with('recordListMaxSizeLimit')
|
||||
->willReturn(null);
|
||||
}
|
||||
|
||||
public function testFetchJson1(): void
|
||||
{
|
||||
$raw = [
|
||||
'textFilter' => 'test*',
|
||||
'maxSize' => 10,
|
||||
];
|
||||
|
||||
$q = http_build_query(['searchParams' => json_encode($raw)]);
|
||||
|
||||
$request = (new RequestFactory)->createRequest('GET', 'http://localhost/?' . $q);
|
||||
|
||||
$fetcher = new SearchParamsFetcher($this->config, $this->textMetadataProvider);
|
||||
|
||||
$params = $fetcher->fetch(new RequestWrapper($request));
|
||||
|
||||
$this->assertEquals($raw['textFilter'], $params->getTextFilter());
|
||||
$this->assertEquals($raw['maxSize'], $params->getMaxSize());
|
||||
}
|
||||
|
||||
public function testFetchQuery(): void
|
||||
{
|
||||
$q = http_build_query(['attributeSelect' => 'a,b']);
|
||||
|
||||
$request = (new RequestFactory)->createRequest('GET', 'http://localhost/?' . $q);
|
||||
|
||||
$fetcher = new SearchParamsFetcher($this->config, $this->textMetadataProvider);
|
||||
|
||||
$params = $fetcher->fetch(new RequestWrapper($request));
|
||||
|
||||
$this->assertEquals(['a', 'b'], $params->getSelect());
|
||||
}
|
||||
}
|
||||
144
tests/unit/Espo/Core/Select/AccessControl/FilterFactoryTest.php
Normal file
144
tests/unit/Espo/Core/Select/AccessControl/FilterFactoryTest.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\AccessControl;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\AccessControl\FilterFactory;
|
||||
use Espo\Core\Select\AccessControl\Filters\OnlyOwn;
|
||||
use Espo\Core\Select\Helpers\FieldHelper;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Entities\User;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FilterFactoryTest extends TestCase
|
||||
{
|
||||
private $aclManager;
|
||||
private $acl;
|
||||
private $metadata;
|
||||
private $injectableFactory;
|
||||
private $factory;
|
||||
private $user;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->aclManager = $this->createMock(AclManager::class);
|
||||
$this->acl = $this->createMock(Acl::class);
|
||||
|
||||
$this->factory = new FilterFactory(
|
||||
$this->injectableFactory,
|
||||
$this->metadata,
|
||||
$this->aclManager,
|
||||
$this->acl,
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreate1()
|
||||
{
|
||||
$this->prepareFactoryTest(null, OnlyOwn::class, 'onlyOwn');
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$this->prepareFactoryTest('SomeClass', OnlyOwn::class, 'onlyOwn');
|
||||
}
|
||||
|
||||
protected function prepareFactoryTest(?string $className, string $defaultClassName, string $name)
|
||||
{
|
||||
$entityType = 'Test';
|
||||
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'accessControlFilterClassNameMap', $name], null, $className],
|
||||
]);
|
||||
|
||||
$className = $className ?? $defaultClassName;
|
||||
|
||||
$object = $this->createMock($defaultClassName);
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$binder
|
||||
->bindInstance(User::class, $this->user)
|
||||
->bindInstance(AclManager::class, $this->aclManager)
|
||||
->bindInstance(Acl::class, $this->acl);
|
||||
|
||||
$binder
|
||||
->for($className)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$binder
|
||||
->for(FieldHelper::class)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$bindingContainer = new BindingContainer($bindingData);
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->exactly(1))
|
||||
->method('createWithBinding')
|
||||
->with($className, $bindingContainer)
|
||||
->willReturn($object);
|
||||
|
||||
$resultObject = $this->factory->create(
|
||||
$entityType,
|
||||
$this->user,
|
||||
$name
|
||||
);
|
||||
|
||||
$this->assertEquals($object, $resultObject);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->factory->has($entityType, $name)
|
||||
);
|
||||
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'accessControlFilterClassNameMap', 'badName'], null, null],
|
||||
]);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->factory->has($entityType, 'badName')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\AccessControl;
|
||||
|
||||
use Espo\Core\Utils\Acl\UserAclManagerProvider;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Portal\Acl as PortalAcl;
|
||||
use Espo\Core\Portal\AclManager as PortalAclManager;
|
||||
use Espo\Core\Select\AccessControl\DefaultFilterResolver;
|
||||
use Espo\Core\Select\AccessControl\DefaultPortalFilterResolver;
|
||||
use Espo\Core\Select\AccessControl\FilterResolverFactory;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FilterResolverFactoryTest extends TestCase
|
||||
{
|
||||
private $injectableFactory;
|
||||
private $metadata;
|
||||
private $user;
|
||||
private $aclManager;
|
||||
private $acl;
|
||||
private $factory;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->aclManager = $this->createMock(AclManager::class);
|
||||
$this->acl = $this->createMock(Acl::class);
|
||||
|
||||
$this->factory = new FilterResolverFactory(
|
||||
$this->injectableFactory,
|
||||
$this->metadata,
|
||||
$this->aclManager,
|
||||
$this->acl,
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreate1()
|
||||
{
|
||||
$this->prepareFactoryTest(null);
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$this->prepareFactoryTest('SomeClass');
|
||||
}
|
||||
|
||||
public function testCreatePortal()
|
||||
{
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('isPortal')
|
||||
->willReturn(true);
|
||||
|
||||
$this->prepareFactoryTest(null);
|
||||
}
|
||||
|
||||
protected function prepareFactoryTest(?string $className)
|
||||
{
|
||||
$entityType = 'Test';
|
||||
|
||||
if (!$this->user->isPortal()) {
|
||||
$defaultClassName = DefaultFilterResolver::class;
|
||||
} else {
|
||||
$defaultClassName = DefaultPortalFilterResolver::class;
|
||||
}
|
||||
|
||||
$this->metadata
|
||||
->expects($this->once())
|
||||
->method('get')
|
||||
->with([
|
||||
'selectDefs', $entityType,
|
||||
!$this->user->isPortal() ?
|
||||
'accessControlFilterResolverClassName':
|
||||
'portalAccessControlFilterResolverClassName'
|
||||
])
|
||||
->willReturn($className);
|
||||
|
||||
$className = $className ?? $defaultClassName;
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$binder
|
||||
->bindInstance(User::class, $this->user)
|
||||
->bindInstance(AclManager::class, $this->aclManager)
|
||||
->bindInstance(Acl::class, $this->acl);
|
||||
|
||||
|
||||
if ($this->user->isPortal()) {
|
||||
$binder->bindInstance(PortalAcl::class, $this->acl);
|
||||
$binder->bindInstance(PortalAclManager::class, $this->aclManager);
|
||||
}
|
||||
|
||||
$binder
|
||||
->for($className)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$bindingContainer = new BindingContainer($bindingData);
|
||||
|
||||
$object = $this->createMock($defaultClassName);
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->once())
|
||||
->method('createWithBinding')
|
||||
->with($className, $bindingContainer)
|
||||
->willReturn($object);
|
||||
|
||||
$resultObject = $this->factory->create($entityType, $this->user);
|
||||
|
||||
$this->assertEquals($object, $resultObject);
|
||||
}
|
||||
}
|
||||
158
tests/unit/Espo/Core/Select/AccessControl/FilterResolverTest.php
Normal file
158
tests/unit/Espo/Core/Select/AccessControl/FilterResolverTest.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\AccessControl;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\Portal\Acl as AclPortal;
|
||||
use Espo\Core\Select\AccessControl\DefaultFilterResolver;
|
||||
use Espo\Core\Select\AccessControl\DefaultPortalFilterResolver;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FilterResolverTest extends TestCase
|
||||
{
|
||||
private $acl;
|
||||
private $aclPortal;
|
||||
private $entityType;
|
||||
private $resolver;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->acl = $this->createMock(Acl::class);
|
||||
$this->aclPortal = $this->createMock(AclPortal::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
}
|
||||
|
||||
public function testResolveRegularOnlyOwn()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'onlyOwn',
|
||||
$this->initResolveTest(false, 'checkReadOnlyOwn')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolveRegularOnlyTeam()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'onlyTeam',
|
||||
$this->initResolveTest(false, 'checkReadOnlyTeam')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolveRegularNo()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'no',
|
||||
$this->initResolveTest(false, 'checkReadNo')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolvePortalOnlyOwn()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'portalOnlyOwn',
|
||||
$this->initResolveTest(true, 'checkReadOnlyOwn')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolvePortalOnlyAccount()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'portalOnlyAccount',
|
||||
$this->initResolveTest(true, 'checkReadOnlyAccount')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolvePortalOnlyContact()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'portalOnlyContact',
|
||||
$this->initResolveTest(true, 'checkReadOnlyContact')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolvePortalNo()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'no',
|
||||
$this->initResolveTest(true, 'checkReadNo')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolveAll()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'all',
|
||||
$this->initResolveTest(false, 'checkReadAll')
|
||||
);
|
||||
}
|
||||
|
||||
public function testResolvePortalAll()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'portalAll',
|
||||
$this->initResolveTest(true, 'checkReadAll')
|
||||
);
|
||||
}
|
||||
|
||||
protected function initResolveTest(bool $isPortal = false, ?string $method = null): ?string
|
||||
{
|
||||
$acl = $this->acl;
|
||||
|
||||
if ($isPortal) {
|
||||
$acl = $this->aclPortal;
|
||||
}
|
||||
|
||||
if (!$isPortal) {
|
||||
$this->resolver = new DefaultFilterResolver(
|
||||
$this->entityType,
|
||||
$acl
|
||||
);
|
||||
}
|
||||
|
||||
if ($isPortal) {
|
||||
$this->resolver = new DefaultPortalFilterResolver(
|
||||
$this->entityType,
|
||||
$acl
|
||||
);
|
||||
}
|
||||
|
||||
if ($method) {
|
||||
$acl
|
||||
->expects($this->any())
|
||||
->method($method)
|
||||
->with($this->entityType)
|
||||
->willReturn(true);
|
||||
}
|
||||
|
||||
return $this->resolver->resolve();
|
||||
}
|
||||
}
|
||||
348
tests/unit/Espo/Core/Select/AccessControl/FiltersTest.php
Normal file
348
tests/unit/Espo/Core/Select/AccessControl/FiltersTest.php
Normal file
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\AccessControl;
|
||||
|
||||
use Espo\Core\Field\LinkMultiple;
|
||||
use Espo\Core\Field\LinkMultipleItem;
|
||||
use Espo\Core\Portal\Acl\OwnershipChecker\MetadataProvider;
|
||||
use Espo\Core\Select\AccessControl\Filter as AccessControlFilter;
|
||||
use Espo\Core\Select\AccessControl\Filters\No;
|
||||
use Espo\Core\Select\AccessControl\Filters\PortalOnlyAccount;
|
||||
use Espo\Core\Select\AccessControl\Filters\PortalOnlyContact;
|
||||
use Espo\Core\Select\AccessControl\Filters\PortalOnlyOwn;
|
||||
use Espo\Core\Select\Helpers\FieldHelper;
|
||||
use Espo\Core\Select\Helpers\RelationQueryHelper;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\Modules\Crm\Entities\Contact;
|
||||
use Espo\ORM\Defs;
|
||||
use Espo\ORM\Defs\RelationDefs;
|
||||
use Espo\ORM\Query\Part\Where\OrGroup;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use Espo\ORM\Type\RelationType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FiltersTest extends TestCase
|
||||
{
|
||||
private $queryBuilder;
|
||||
private $fieldHelper;
|
||||
private $user;
|
||||
private $entityType;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->fieldHelper = $this->createMock(FieldHelper::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
|
||||
$this->user->set('id', 'user-id');
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getId')
|
||||
->willReturn('user-id');
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getTeamIdList')
|
||||
->willReturn(['team-id']);
|
||||
}
|
||||
|
||||
public function testNo(): void
|
||||
{
|
||||
$filter = $this->createFilter(No::class);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with([
|
||||
'id' => null,
|
||||
]);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyAccount1(): void
|
||||
{
|
||||
$defs = $this->createMock(Defs::class);
|
||||
$metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
|
||||
$queryHelper = new RelationQueryHelper($defs);
|
||||
|
||||
$filter = new PortalOnlyAccount(
|
||||
'Test',
|
||||
$this->user,
|
||||
$this->fieldHelper,
|
||||
$metadataProvider,
|
||||
$queryHelper
|
||||
);
|
||||
|
||||
$metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getContactLink')
|
||||
->willReturn(
|
||||
RelationDefs::fromRaw([
|
||||
'type' => RelationType::BELONGS_TO_PARENT,
|
||||
'entityList' => [Contact::ENTITY_TYPE],
|
||||
], 'contact')
|
||||
);
|
||||
|
||||
$metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAccountLink')
|
||||
->willReturn(
|
||||
RelationDefs::fromRaw([
|
||||
'type' => RelationType::MANY_MANY,
|
||||
'entity' => [Account::ENTITY_TYPE],
|
||||
'midKeys' => ['nId', 'fId'],
|
||||
'relationName' => 'TestAccount'
|
||||
], 'account')
|
||||
);
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getAccounts')
|
||||
->willReturn(LinkMultiple::create([
|
||||
LinkMultipleItem::create('account-id')
|
||||
]));
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getContactId')
|
||||
->willReturn('contact-id');
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', true],
|
||||
]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with(
|
||||
$this->callback(function ($where) {
|
||||
if (!$where instanceof OrGroup) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($where->getRawValue()[0]['id=s'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $where->getItemCount() === 3;
|
||||
})
|
||||
)
|
||||
->willReturn($this->queryBuilder);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyAccount2(): void
|
||||
{
|
||||
$defs = $this->createMock(Defs::class);
|
||||
$metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
|
||||
$queryHelper = new RelationQueryHelper($defs);
|
||||
|
||||
$filter = new PortalOnlyAccount(
|
||||
'Test',
|
||||
$this->user,
|
||||
$this->fieldHelper,
|
||||
$metadataProvider,
|
||||
$queryHelper
|
||||
);
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getLinkMultipleIdList')
|
||||
->with('accounts')
|
||||
->willReturn([]);
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->with('contactId')
|
||||
->willReturn(null);
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', false],
|
||||
]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with([
|
||||
'id' => null,
|
||||
]);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyContact1(): void
|
||||
{
|
||||
$defs = $this->createMock(Defs::class);
|
||||
$metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
|
||||
$queryHelper = new RelationQueryHelper($defs);
|
||||
|
||||
$filter = new PortalOnlyContact(
|
||||
'Test',
|
||||
$this->user,
|
||||
$this->fieldHelper,
|
||||
$metadataProvider,
|
||||
$queryHelper
|
||||
);
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('getContactId')
|
||||
->willReturn('contact-id');
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', true],
|
||||
]);
|
||||
|
||||
$metadataProvider
|
||||
->expects($this->once())
|
||||
->method('getContactLink')
|
||||
->willReturn(
|
||||
RelationDefs::fromRaw([
|
||||
'type' => RelationType::BELONGS_TO,
|
||||
'entity' => Contact::ENTITY_TYPE,
|
||||
], 'contact')
|
||||
);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with(
|
||||
$this->callback(function ($where) {
|
||||
return $where instanceof OrGroup &&
|
||||
$where->getItemCount() === 2;
|
||||
})
|
||||
)
|
||||
->willReturn($this->queryBuilder);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyContact2()
|
||||
{
|
||||
$defs = $this->createMock(Defs::class);
|
||||
$metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
|
||||
$queryHelper = new RelationQueryHelper($defs);
|
||||
|
||||
$filter = new PortalOnlyContact(
|
||||
'Test',
|
||||
$this->user,
|
||||
$this->fieldHelper,
|
||||
$metadataProvider,
|
||||
$queryHelper
|
||||
);
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->with('contactId')
|
||||
->willReturn(null);
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', false],
|
||||
]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with([
|
||||
'id' => null,
|
||||
])
|
||||
->willReturn($this->queryBuilder);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyOwn1()
|
||||
{
|
||||
$filter = $this->createFilter(PortalOnlyOwn::class);
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', true],
|
||||
]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with([
|
||||
'createdById' => $this->user->getId(),
|
||||
])
|
||||
->willReturn($this->queryBuilder);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testPortalOnlyOwn2()
|
||||
{
|
||||
$filter = $this->createFilter(PortalOnlyOwn::class);
|
||||
|
||||
$this->initHelperMethods([
|
||||
['hasCreatedByField', false],
|
||||
]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with([
|
||||
'id' => null,
|
||||
])
|
||||
->willReturn($this->queryBuilder);
|
||||
|
||||
$filter->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
protected function initHelperMethods(array $map)
|
||||
{
|
||||
foreach ($map as $i => $item) {
|
||||
$this->fieldHelper
|
||||
->expects($this->once())
|
||||
->method($item[0])
|
||||
->willReturn($item[1]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function createFilter(string $className): AccessControlFilter
|
||||
{
|
||||
return new $className(
|
||||
$this->user,
|
||||
$this->fieldHelper
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Select\AccessControl\Applier as AccessControlFilterApplier;
|
||||
use Espo\Core\Select\AccessControl\Filter as AccessControlFilter;
|
||||
use Espo\Core\Select\AccessControl\FilterFactory as AccessControlFilterFactory;
|
||||
use Espo\Core\Select\AccessControl\FilterResolver;
|
||||
use Espo\Core\Select\AccessControl\FilterResolverFactory as AccessControlFilterResolverFactory;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AccessControlFilterApplierTest extends TestCase
|
||||
{
|
||||
private $filterFactory;
|
||||
private $filterResolverFactory;
|
||||
private $user;
|
||||
private $queryBuilder;
|
||||
private $filterResolver;
|
||||
private $filter;
|
||||
private $mandatoryFilter;
|
||||
private $entityType;
|
||||
private $applier;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->filterFactory = $this->createMock(AccessControlFilterFactory::class);
|
||||
$this->filterResolverFactory = $this->createMock(AccessControlFilterResolverFactory::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->filterResolver = $this->createMock(FilterResolver::class);
|
||||
$this->filter = $this->createMock(AccessControlFilter::class);
|
||||
$this->mandatoryFilter = $this->createMock(AccessControlFilter::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new AccessControlFilterApplier(
|
||||
entityType: $this->entityType,
|
||||
user: $this->user,
|
||||
accessControlFilterFactory: $this->filterFactory,
|
||||
accessControlFilterResolverFactory: $this->filterResolverFactory,
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$this->initApplierTest(true, true);
|
||||
|
||||
$this->applier->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testApply2()
|
||||
{
|
||||
$this->initApplierTest(true, false);
|
||||
|
||||
$this->applier->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
public function testApply3()
|
||||
{
|
||||
$this->initApplierTest(false, false);
|
||||
|
||||
$this->applier->apply($this->queryBuilder);
|
||||
}
|
||||
|
||||
protected function initApplierTest(bool $resolve, bool $hasFilter)
|
||||
{
|
||||
$this->filterResolverFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user)
|
||||
->willReturn($this->filterResolver);
|
||||
|
||||
$filterName = null;
|
||||
|
||||
if ($resolve) {
|
||||
$filterName = 'test';
|
||||
}
|
||||
|
||||
$this->filterResolver
|
||||
->expects($this->once())
|
||||
->method('resolve')
|
||||
->willReturn($filterName);
|
||||
|
||||
if (!$resolve) {
|
||||
$this->filterFactory
|
||||
->expects($this->never())
|
||||
->method('has');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->entityType, $filterName)
|
||||
->willReturn($hasFilter);
|
||||
|
||||
if (!$hasFilter) {
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->exactly(2))
|
||||
->method('create')
|
||||
->willReturnMap([
|
||||
[$this->entityType, $this->user, 'mandatory', $this->mandatoryFilter],
|
||||
[$this->entityType, $this->user, $filterName, $this->filter],
|
||||
]);
|
||||
|
||||
$this->filter
|
||||
->expects($this->once())
|
||||
->method('apply')
|
||||
->with($this->queryBuilder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Select\Bool\Applier as BoolFilterListApplier;
|
||||
use Espo\Core\Select\Bool\Filter as BoolFilter;
|
||||
use Espo\Core\Select\Bool\FilterFactory as BoolFilterFactory;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
|
||||
use Espo\ORM\Query\Part\WhereClause;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class BoolFilterListApplierTest extends TestCase
|
||||
{
|
||||
private $boolFilterFactory;
|
||||
private $user;
|
||||
private $queryBuilder;
|
||||
private $entityType;
|
||||
private $applier;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->boolFilterFactory = $this->createMock(BoolFilterFactory::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new BoolFilterListApplier(
|
||||
entityType: $this->entityType,
|
||||
user: $this->user,
|
||||
boolFilterFactory: $this->boolFilterFactory,
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$boolFilterList = ['test1', 'test2'];
|
||||
|
||||
$filter1 = $this->createFilterMock(['test' => '1']);
|
||||
$filter2 = $this->createFilterMock(['test' => '2']);
|
||||
|
||||
$this->initApplierTest($boolFilterList, [$filter1, $filter2], [true, true]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where');
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $boolFilterList);
|
||||
}
|
||||
|
||||
public function testApply2()
|
||||
{
|
||||
$boolFilterList = ['test1'];
|
||||
|
||||
$filter1 = $this->createFilterMock(['test' => '1']);
|
||||
|
||||
$this->initApplierTest($boolFilterList, [$filter1], [true]);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where');
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $boolFilterList);
|
||||
}
|
||||
|
||||
public function testApply3()
|
||||
{
|
||||
$boolFilterList = ['test1'];
|
||||
|
||||
$this->initApplierTest($boolFilterList, [null], [false]);
|
||||
|
||||
$this->expectException(BadRequest::class);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $boolFilterList);
|
||||
}
|
||||
|
||||
protected function initApplierTest(array $filterNameList, array $filterList, array $hasList)
|
||||
{
|
||||
$hasMap = [];
|
||||
$createMap = [];
|
||||
|
||||
foreach ($filterNameList as $i => $filterName) {
|
||||
$hasMap[] = [$this->entityType, $filterName, $hasList[$i]];
|
||||
|
||||
if (!$hasList[$i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$createMap[] = [$this->entityType, $this->user, $filterName, $filterList[$i]];
|
||||
}
|
||||
|
||||
$this->boolFilterFactory
|
||||
->expects($this->any())
|
||||
->method('has')
|
||||
->willReturnMap($hasMap);
|
||||
|
||||
$this->boolFilterFactory
|
||||
->expects($this->any())
|
||||
->method('create')
|
||||
->willReturnMap($createMap);
|
||||
}
|
||||
|
||||
protected function createFilterMock(array $rawWhereClause): BoolFilter
|
||||
{
|
||||
$filter = $this->createMock(BoolFilter::class);
|
||||
|
||||
$whereClause = $this->createMock(WhereClause::class);
|
||||
|
||||
$whereClause
|
||||
->expects($this->any())
|
||||
->method('getRawValue')
|
||||
->willReturn($rawWhereClause);
|
||||
|
||||
$filter
|
||||
->expects($this->any())
|
||||
->method('apply')
|
||||
->with($this->queryBuilder, $this->isInstanceOf(OrGroupBuilder::class));
|
||||
|
||||
return $filter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Acl\SystemRestriction;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Query\Part\OrderList;
|
||||
use Espo\ORM\Query\Part\Order;
|
||||
use Espo\Core\Select\Order\Applier as OrderApplier;
|
||||
use Espo\Core\Select\Order\Item;
|
||||
use Espo\Core\Select\Order\ItemConverter;
|
||||
use Espo\Core\Select\Order\ItemConverterFactory;
|
||||
use Espo\Core\Select\Order\MetadataProvider;
|
||||
use Espo\Core\Select\Order\Orderer;
|
||||
use Espo\Core\Select\Order\OrdererFactory;
|
||||
use Espo\Core\Select\Order\Params as OrderParams;
|
||||
use Espo\Core\Select\SearchParams;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class OrderApplierTest extends TestCase
|
||||
{
|
||||
private ?OrdererFactory $ordererFactory = null;
|
||||
|
||||
private $metadataProvider;
|
||||
private $itemConverterFactory;
|
||||
private $queryBuilder;
|
||||
private $params;
|
||||
private $entityType;
|
||||
private $applier;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
$this->itemConverterFactory = $this->createMock(ItemConverterFactory::class);
|
||||
$this->ordererFactory = $this->createMock(OrdererFactory::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->params = $this->createMock(OrderParams::class);
|
||||
|
||||
$aclManager = $this->createMock(AclManager::class);
|
||||
$user = $this->createMock(User::class);
|
||||
|
||||
$restriction = $this->createMock(SystemRestriction::class);
|
||||
$restriction
|
||||
->method('checkFieldRead')
|
||||
->willReturn(true);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new OrderApplier(
|
||||
entityType: $this->entityType,
|
||||
metadataProvider: $this->metadataProvider,
|
||||
itemConverterFactory: $this->itemConverterFactory,
|
||||
ordererFactory: $this->ordererFactory,
|
||||
aclManager: $aclManager,
|
||||
user: $user,
|
||||
systemRestriction: $restriction,
|
||||
);
|
||||
}
|
||||
|
||||
public function testApplyDefault()
|
||||
{
|
||||
$order = SearchParams::ORDER_DESC;
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('forceDefault')
|
||||
->willReturn(true);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrder')
|
||||
->willReturn($order);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getDefaultOrderBy')
|
||||
->with($this->entityType)
|
||||
->willReturn('testField');
|
||||
|
||||
$this->initApplyOrderTest('testField', $order, 'varchar');
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->params);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$order = SearchParams::ORDER_DESC;
|
||||
$orderBy = 'testField';
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('forceDefault')
|
||||
->willReturn(false);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrder')
|
||||
->willReturn($order);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrderBy')
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getDefaultOrderBy')
|
||||
->with($this->entityType)
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->initApplyOrderTest($orderBy, $order, 'varchar');
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->params);
|
||||
}
|
||||
|
||||
public function testApplyWithConverter()
|
||||
{
|
||||
$order = SearchParams::ORDER_DESC;
|
||||
$orderBy = 'testField';
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('forceDefault')
|
||||
->willReturn(false);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrder')
|
||||
->willReturn($order);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrderBy')
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getDefaultOrderBy')
|
||||
->with($this->entityType)
|
||||
->willReturn($orderBy);
|
||||
|
||||
$converterResult = OrderList::create([
|
||||
Order::fromString('hello')->withDesc(),
|
||||
]);
|
||||
|
||||
$this->initApplyOrderTest($orderBy, $order, 'varchar', $converterResult);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->params);
|
||||
}
|
||||
|
||||
public function testApplyNotExisting()
|
||||
{
|
||||
$order = SearchParams::ORDER_DESC;
|
||||
$orderBy = 'testField';
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('forceDefault')
|
||||
->willReturn(false);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrder')
|
||||
->willReturn($order);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrderBy')
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getDefaultOrderBy')
|
||||
->with($this->entityType)
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->initApplyOrderTest($orderBy, $order, 'varchar', null, true);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->params);
|
||||
}
|
||||
|
||||
public function testApplyWithOrderer()
|
||||
{
|
||||
$order = SearchParams::ORDER_DESC;
|
||||
$orderBy = 'testField';
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('forceDefault')
|
||||
->willReturn(false);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrder')
|
||||
->willReturn($order);
|
||||
|
||||
$this->params
|
||||
->expects($this->any())
|
||||
->method('getOrderBy')
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->ordererFactory
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn(true);
|
||||
|
||||
$orderer = $this->createMock(Orderer::class);
|
||||
|
||||
$this->ordererFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn($orderer);
|
||||
|
||||
$orderer
|
||||
->expects($this->once())
|
||||
->method('apply')
|
||||
->with($this->queryBuilder, Item::create($orderBy, $order));
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->params);
|
||||
}
|
||||
|
||||
protected function initApplyOrderTest(
|
||||
string $orderBy,
|
||||
string $order,
|
||||
string $fieldType,
|
||||
?OrderList $converterResult = null,
|
||||
bool $notExisting = false
|
||||
) {
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getFieldType')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn($fieldType);
|
||||
|
||||
$this->itemConverterFactory
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn(
|
||||
(bool) $converterResult
|
||||
);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('hasAttribute')
|
||||
->willReturnMap(
|
||||
[
|
||||
[$this->entityType, $orderBy, !$notExisting],
|
||||
[$this->entityType, 'id', true],
|
||||
]
|
||||
);
|
||||
|
||||
if ($converterResult) {
|
||||
$converter = $this->createMock(ItemConverter::class);
|
||||
|
||||
$this->itemConverterFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn($converter);
|
||||
|
||||
$item = Item::create($orderBy, $order);
|
||||
|
||||
$converter
|
||||
->expects($this->once())
|
||||
->method('convert')
|
||||
->with($item)
|
||||
->willReturn($converterResult);
|
||||
} else {
|
||||
if ($notExisting) {
|
||||
$this->expectException(BadRequest::class);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->once())
|
||||
->method('isAttributeParamUniqueTrue')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn(false);
|
||||
}
|
||||
|
||||
$expectedOrderBy = ($converterResult ? $this->orderListToArray($converterResult): null)
|
||||
?? [[$orderBy, $order]];
|
||||
|
||||
$expectedOrderBy[] = ['id', $order];
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('order')
|
||||
->with($expectedOrderBy);
|
||||
}
|
||||
|
||||
private function orderListToArray(OrderList $orderList): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($orderList as $order) {
|
||||
$list[] = [
|
||||
$order->getExpression()->getValue(),
|
||||
$order->getDirection(),
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Select\Primary\Applier as PrimaryFilterApplier;
|
||||
use Espo\Core\Select\Primary\Filter as PrimaryFilter;
|
||||
use Espo\Core\Select\Primary\FilterFactory as PrimaryFilterFactory;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PrimaryFilterApplierTest extends TestCase
|
||||
{
|
||||
private $filterFactory;
|
||||
private $user;
|
||||
private $queryBuilder;
|
||||
private $entityType;
|
||||
private $applier;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->filterFactory = $this->createMock(PrimaryFilterFactory::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new PrimaryFilterApplier(
|
||||
entityType: $this->entityType,
|
||||
user: $this->user,
|
||||
primaryFilterFactory: $this->filterFactory,
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$filterName = 'test';
|
||||
|
||||
$filter = $this->createMock(PrimaryFilter::class);
|
||||
|
||||
$filter
|
||||
->expects($this->once())
|
||||
->method('apply')
|
||||
->with($this->queryBuilder);
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->entityType, $filterName)
|
||||
->willReturn(true);
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user, $filterName)
|
||||
->willReturn($filter);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $filterName);
|
||||
}
|
||||
|
||||
public function testApply2()
|
||||
{
|
||||
$filterName = 'test';
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->once())
|
||||
->method('has')
|
||||
->with($this->entityType, $filterName)
|
||||
->willReturn(false);
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->never())
|
||||
->method('create');
|
||||
|
||||
$this->expectException(BadRequest::class);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $filterName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Select\SearchParams;
|
||||
use Espo\Core\Select\Select\Applier as SelectApplier;
|
||||
use Espo\Core\Select\Select\MetadataProvider;
|
||||
use Espo\Core\Utils\FieldUtil;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SelectApplierTest extends TestCase
|
||||
{
|
||||
private $metadataProvider;
|
||||
private $queryBuilder;
|
||||
private $applier;
|
||||
private $entityType;
|
||||
private $fieldUtil;
|
||||
private $searchParams;
|
||||
private $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->searchParams = $this->createMock(SearchParams::class);
|
||||
$this->fieldUtil = $this->createMock(FieldUtil::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new SelectApplier(
|
||||
$this->entityType,
|
||||
$this->user,
|
||||
$this->fieldUtil,
|
||||
$this->metadataProvider
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$this->initTestApply();
|
||||
}
|
||||
|
||||
public function testApplyPortal()
|
||||
{
|
||||
$this->initTestApply(true);
|
||||
}
|
||||
|
||||
protected function initTestApply(bool $isPortal = false)
|
||||
{
|
||||
$select = ['testSelect', 'testNotExisting', 'testText'];
|
||||
|
||||
$orderBy = 'testOrder';
|
||||
|
||||
$aclAttributeList = ['testAcl'];
|
||||
|
||||
$aclPortalAttributeList = ['testAclPortal'];
|
||||
|
||||
$dependencyMap = [
|
||||
'testSelect' => [
|
||||
'testDependency',
|
||||
],
|
||||
];
|
||||
|
||||
$aclAttribute = $aclAttributeList[0];
|
||||
|
||||
if ($isPortal) {
|
||||
$aclAttribute = $aclPortalAttributeList[0];
|
||||
}
|
||||
|
||||
$this->user
|
||||
->expects($this->any())
|
||||
->method('isPortal')
|
||||
->willReturn($isPortal);
|
||||
|
||||
$this->searchParams
|
||||
->expects($this->any())
|
||||
->method('getMaxTextAttributeLength')
|
||||
->willReturn(100);
|
||||
|
||||
$this->searchParams
|
||||
->expects($this->any())
|
||||
->method('getSelect')
|
||||
->willReturn($select);
|
||||
|
||||
$this->searchParams
|
||||
->expects($this->any())
|
||||
->method('getOrderBy')
|
||||
->willReturn($orderBy);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAclAttributeList')
|
||||
->willReturn($aclAttributeList);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAclPortalAttributeList')
|
||||
->willReturn($aclPortalAttributeList);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getSelectAttributesDependencyMap')
|
||||
->with($this->entityType)
|
||||
->willReturn($dependencyMap);
|
||||
|
||||
$this->fieldUtil
|
||||
->expects($this->once())
|
||||
->method('getAttributeList')
|
||||
->with($this->entityType, $orderBy)
|
||||
->willReturn([$orderBy]);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('hasAttribute')
|
||||
->willReturnMap(
|
||||
[
|
||||
[$this->entityType, 'id', true],
|
||||
[$this->entityType, 'testSelect', true],
|
||||
[$this->entityType, 'testNotExisting', false],
|
||||
[$this->entityType, 'testOrder', true],
|
||||
[$this->entityType, 'testAcl', true],
|
||||
[$this->entityType, 'testAclPortal', true],
|
||||
[$this->entityType, 'testDependency', true],
|
||||
[$this->entityType, 'testText', true],
|
||||
]
|
||||
);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('isAttributeNotStorable')
|
||||
->willReturn(false);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAttributeType')
|
||||
->willReturnMap(
|
||||
[
|
||||
[$this->entityType, 'id', Entity::ID],
|
||||
[$this->entityType, 'testSelect', Entity::VARCHAR],
|
||||
[$this->entityType, 'testOrder', Entity::VARCHAR],
|
||||
[$this->entityType, 'testAcl', Entity::VARCHAR],
|
||||
[$this->entityType, 'testAclPortal', Entity::VARCHAR],
|
||||
[$this->entityType, 'testDependency', Entity::VARCHAR],
|
||||
[$this->entityType, 'testText', Entity::TEXT],
|
||||
]
|
||||
);
|
||||
|
||||
$expected = [
|
||||
'id',
|
||||
$aclAttribute,
|
||||
'testSelect',
|
||||
['LEFT:(testText, 100)', 'testText'],
|
||||
'testOrder',
|
||||
'testDependency',
|
||||
];
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('select')
|
||||
->with($expected);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->searchParams);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Select\Text\Applier as TextFilterApplier;
|
||||
use Espo\Core\Select\Text\ConfigProvider;
|
||||
use Espo\Core\Select\Text\DefaultFilter;
|
||||
use Espo\Core\Select\Text\FilterFactory;
|
||||
use Espo\Core\Select\Text\FilterParams;
|
||||
use Espo\Core\Select\Text\FullTextSearch\Data as FullTextSearchData;
|
||||
use Espo\Core\Select\Text\FullTextSearch\DataComposer\Params as FullTextSearchDataComposerParams;
|
||||
use Espo\Core\Select\Text\FullTextSearch\DataComposerFactory as FullTextSearchDataComposerFactory;
|
||||
use Espo\Core\Select\Text\FullTextSearch\DefaultDataComposer as FullTextSearchDataComposer;
|
||||
use Espo\Core\Select\Text\MetadataProvider;
|
||||
use Espo\Core\Utils\Config;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Entity;
|
||||
use Espo\ORM\Query\Part\Expression as Expr;
|
||||
use Espo\ORM\Query\Part\Where\OrGroup;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TextFilterApplierTest extends TestCase
|
||||
{
|
||||
private $metadataProvider;
|
||||
private $queryBuilder;
|
||||
private $filterParams;
|
||||
private $config;
|
||||
private $fullTextSearchDataComposerFactory;
|
||||
private $filterFactory;
|
||||
private $applier;
|
||||
private $entityType;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$user = $this->createMock(User::class);
|
||||
$this->metadataProvider = $this->createMock(MetadataProvider::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->filterParams = $this->createMock(FilterParams::class);
|
||||
$this->config = $this->createMock(Config::class);
|
||||
$this->fullTextSearchDataComposerFactory = $this->createMock(FullTextSearchDataComposerFactory::class);
|
||||
$this->filterFactory = $this->createMock(FilterFactory::class);
|
||||
|
||||
$configProvider = $this->createMock(ConfigProvider::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new TextFilterApplier(
|
||||
$this->entityType,
|
||||
$user,
|
||||
$this->metadataProvider,
|
||||
$this->fullTextSearchDataComposerFactory,
|
||||
$this->filterFactory,
|
||||
$configProvider
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$this->initTest(false);
|
||||
}
|
||||
|
||||
public function testApply2()
|
||||
{
|
||||
$this->initTest(true);
|
||||
}
|
||||
|
||||
public function testApply3()
|
||||
{
|
||||
$this->initTest(false, '1000');
|
||||
}
|
||||
|
||||
protected function initTest(bool $noFullTextSearch = false, ?string $filter = null)
|
||||
{
|
||||
$filter = $filter ?? 'test';
|
||||
|
||||
$filterParams = $this->createMock(FilterParams::class);
|
||||
|
||||
$filterParams
|
||||
->expects($this->any())
|
||||
->method('noFullTextSearch')
|
||||
->willReturn($noFullTextSearch);
|
||||
|
||||
$this->config
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap(
|
||||
|
||||
[
|
||||
['textFilterUseContainsForVarchar', false],
|
||||
['textFilterContainsMinLength', 4],
|
||||
]
|
||||
|
||||
);
|
||||
|
||||
$configProvider = new ConfigProvider($this->config);
|
||||
|
||||
$defaultFilter = new DefaultFilter(
|
||||
$this->entityType,
|
||||
$this->metadataProvider,
|
||||
$configProvider
|
||||
);
|
||||
|
||||
$this->filterFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->willReturn(
|
||||
$defaultFilter
|
||||
);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getFullTextSearchOrderType')
|
||||
->with($this->entityType)
|
||||
->willReturn(null);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAttributeType')
|
||||
->willReturnMap(
|
||||
|
||||
[
|
||||
[$this->entityType, 'fieldVarchar', Entity::VARCHAR],
|
||||
[$this->entityType, 'fieldText', Entity::TEXT],
|
||||
[$this->entityType, 'fieldFullText', Entity::TEXT],
|
||||
[$this->entityType, 'fieldInt', Entity::INT],
|
||||
[$this->entityType, 'fieldForeign', Entity::FOREIGN],
|
||||
['ForeignEntityType', 'field', Entity::VARCHAR],
|
||||
]
|
||||
);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getAttributeRelationParam')
|
||||
->with($this->entityType, 'fieldForeign')
|
||||
->willReturn('link1');
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getRelationType')
|
||||
->with($this->entityType, 'link2')
|
||||
->willReturn(Entity::HAS_MANY);
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getRelationEntityType')
|
||||
->with($this->entityType, 'link2')
|
||||
->willReturn('ForeignEntityType');
|
||||
|
||||
$this->metadataProvider
|
||||
->expects($this->any())
|
||||
->method('getTextFilterAttributeList')
|
||||
->with($this->entityType)
|
||||
->willReturn(
|
||||
['fieldVarchar', 'fieldText', 'fieldFullText', 'fieldInt', 'fieldForeign', 'link2.field']
|
||||
);
|
||||
|
||||
if (!$noFullTextSearch) {
|
||||
$this->initFullTextSearchData($filter, ['fieldFullText'], 'TEST:(test)');
|
||||
}
|
||||
|
||||
$expectedWhere = [
|
||||
['fieldVarchar*' => $filter . '%'],
|
||||
['fieldText*' => '%' . $filter . '%']
|
||||
];
|
||||
|
||||
if (is_numeric($filter)) {
|
||||
$expectedWhere[] = ['fieldInt=' => intval($filter)];
|
||||
}
|
||||
|
||||
if ($noFullTextSearch) {
|
||||
$expectedWhere[] = ['fieldFullText*' => '%' . $filter . '%'];
|
||||
}
|
||||
|
||||
$expectedWhere[] = ['fieldForeign*' => $filter . '%'];
|
||||
$expectedWhere[] = ['link2.field*' => $filter . '%'];
|
||||
|
||||
if (!$noFullTextSearch) {
|
||||
$expectedWhere[] = ['NOT_EQUAL:(TEST:(test), 0):' => null];
|
||||
}
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('where')
|
||||
->with(OrGroup::fromRaw($expectedWhere));
|
||||
|
||||
$c = $this->exactly(2);
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($c)
|
||||
->method('leftJoin')
|
||||
->willReturnCallback(function ($link) use ($c) {
|
||||
if ($c->numberOfInvocations() === 1) {
|
||||
$this->assertEquals('link1', $link);
|
||||
}
|
||||
|
||||
if ($c->numberOfInvocations() === 2) {
|
||||
$this->assertEquals('link2', $link);
|
||||
}
|
||||
|
||||
return $this->queryBuilder;
|
||||
});
|
||||
|
||||
$this->queryBuilder
|
||||
->expects($this->once())
|
||||
->method('distinct');
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $filter, $this->filterParams);
|
||||
}
|
||||
|
||||
protected function initFullTextSearchData(string $filter, array $fieldList, string $expression)
|
||||
{
|
||||
$fullTextSearchData = $this->createMock(FullTextSearchData::class);
|
||||
|
||||
$fullTextSearchDataComposer = $this->createMock(FullTextSearchDataComposer::class);
|
||||
|
||||
$fullTextSearchDataComposerParams = FullTextSearchDataComposerParams::create();
|
||||
|
||||
$this->fullTextSearchDataComposerFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType)
|
||||
->willReturn($fullTextSearchDataComposer);
|
||||
|
||||
$fullTextSearchData
|
||||
->expects($this->any())
|
||||
->method('getFieldList')
|
||||
->willReturn($fieldList);
|
||||
|
||||
$fullTextSearchData
|
||||
->expects($this->any())
|
||||
->method('getExpression')
|
||||
->willReturn(Expr::create($expression));
|
||||
|
||||
$fullTextSearchDataComposer
|
||||
->expects($this->any())
|
||||
->method('compose')
|
||||
->with($filter, $fullTextSearchDataComposerParams)
|
||||
->willReturn($fullTextSearchData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
|
||||
|
||||
use Espo\Core\Select\Where\Applier as WhereApplier;
|
||||
use Espo\Core\Select\Where\Checker;
|
||||
use Espo\Core\Select\Where\CheckerFactory;
|
||||
use Espo\Core\Select\Where\Converter;
|
||||
use Espo\Core\Select\Where\ConverterFactory;
|
||||
use Espo\Core\Select\Where\Item as WhereItem;
|
||||
use Espo\Core\Select\Where\Params;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class WhereApplierTest extends TestCase
|
||||
{
|
||||
private $user;
|
||||
private $queryBuilder;
|
||||
private $whereItem;
|
||||
private $converterFactory;
|
||||
private $converter;
|
||||
private $checkerFactory;
|
||||
private $checker;
|
||||
private $params;
|
||||
private $entityType;
|
||||
private $applier;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->user = $this->createMock(User::class);
|
||||
$this->queryBuilder = $this->createMock(QueryBuilder::class);
|
||||
$this->whereItem = $this->createMock(WhereItem::class);
|
||||
$this->converterFactory = $this->createMock(ConverterFactory::class);
|
||||
$this->converter = $this->createMock(Converter::class);
|
||||
$this->checkerFactory = $this->createMock(CheckerFactory::class);
|
||||
$this->checker = $this->createMock(Checker::class);
|
||||
$this->params = $this->createMock(Params::class);
|
||||
|
||||
$this->entityType = 'Test';
|
||||
|
||||
$this->applier = new WhereApplier(
|
||||
$this->entityType,
|
||||
$this->user,
|
||||
$this->converterFactory,
|
||||
$this->checkerFactory
|
||||
);
|
||||
}
|
||||
|
||||
public function testApply1()
|
||||
{
|
||||
$this->checker
|
||||
->expects($this->once())
|
||||
->method('check')
|
||||
->with($this->whereItem, $this->params);
|
||||
|
||||
$this->checkerFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user)
|
||||
->willReturn($this->checker);
|
||||
|
||||
$this->converter
|
||||
->expects($this->once())
|
||||
->method('convert')
|
||||
->with($this->queryBuilder, $this->whereItem);
|
||||
|
||||
$this->converterFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user)
|
||||
->willReturn($this->converter);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->whereItem, $this->params);
|
||||
}
|
||||
|
||||
public function testApply2()
|
||||
{
|
||||
$this->checker
|
||||
->expects($this->once())
|
||||
->method('check')
|
||||
->with($this->whereItem, $this->params);
|
||||
|
||||
$this->checkerFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user)
|
||||
->willReturn($this->checker);
|
||||
|
||||
$this->converter
|
||||
->expects($this->once())
|
||||
->method('convert')
|
||||
->with($this->queryBuilder, $this->whereItem);
|
||||
|
||||
$this->converterFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->entityType, $this->user)
|
||||
->willReturn($this->converter);
|
||||
|
||||
$this->applier->apply($this->queryBuilder, $this->whereItem, $this->params);
|
||||
}
|
||||
}
|
||||
171
tests/unit/Espo/Core/Select/Applier/FactoryTest.php
Normal file
171
tests/unit/Espo/Core/Select/Applier/FactoryTest.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Applier;
|
||||
|
||||
use Espo\Core\Acl;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\AccessControl\Applier as AccessControlFilterApplier;
|
||||
use Espo\Core\Select\Applier\Appliers\Additional as AdditionalApplier;
|
||||
use Espo\Core\Select\Applier\Appliers\Limit as LimitApplier;
|
||||
use Espo\Core\Select\Applier\Factory as ApplierFactory;
|
||||
use Espo\Core\Select\Bool\Applier as BoolFilterListApplier;
|
||||
use Espo\Core\Select\Order\Applier as OrderApplier;
|
||||
use Espo\Core\Select\Primary\Applier as PrimaryFilterApplier;
|
||||
use Espo\Core\Select\Select\Applier as SelectApplier;
|
||||
use Espo\Core\Select\Text\Applier as TextFilterApplier;
|
||||
use Espo\Core\Select\Where\Applier as WhereApplier;
|
||||
|
||||
use Espo\Core\Utils\Acl\UserAclManagerProvider;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FactoryTest extends TestCase
|
||||
{
|
||||
private $aclManager;
|
||||
private $acl;
|
||||
private $injectableFactory;
|
||||
private $user;
|
||||
private $factory;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
|
||||
$userAclManagerProvider = $this->createMock(UserAclManagerProvider::class);
|
||||
|
||||
$this->aclManager = $this->createMock(AclManager::class);
|
||||
|
||||
$userAclManagerProvider
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn($this->aclManager);
|
||||
|
||||
$this->factory = new ApplierFactory(
|
||||
$this->injectableFactory,
|
||||
$userAclManagerProvider,
|
||||
);
|
||||
|
||||
$this->acl = $this->createMock(Acl::class);
|
||||
|
||||
$this->aclManager
|
||||
->expects($this->any())
|
||||
->method('createUserAcl')
|
||||
->willReturn($this->acl);
|
||||
}
|
||||
|
||||
public function testCreate1()
|
||||
{
|
||||
$this->prepareFactoryTest(SelectApplier::class, ApplierFactory::SELECT, 'createSelect');
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$this->prepareFactoryTest(
|
||||
BoolFilterListApplier::class, ApplierFactory::BOOL_FILTER_LIST, 'createBoolFilterList');
|
||||
}
|
||||
|
||||
public function testCreate3()
|
||||
{
|
||||
$this->prepareFactoryTest(TextFilterApplier::class, ApplierFactory::TEXT_FILTER, 'createTextFilter');
|
||||
}
|
||||
|
||||
public function testCreate4()
|
||||
{
|
||||
$this->prepareFactoryTest(WhereApplier::class, ApplierFactory::WHERE, 'createWhere');
|
||||
}
|
||||
|
||||
public function testCreate5()
|
||||
{
|
||||
$this->prepareFactoryTest(OrderApplier::class, ApplierFactory::ORDER, 'createOrder');
|
||||
}
|
||||
|
||||
public function testCreate6()
|
||||
{
|
||||
$this->prepareFactoryTest(LimitApplier::class, ApplierFactory::LIMIT, 'createLimit');
|
||||
}
|
||||
|
||||
public function testCreate7()
|
||||
{
|
||||
$this->prepareFactoryTest(AdditionalApplier::class, ApplierFactory::ADDITIONAL, 'createAdditional');
|
||||
}
|
||||
|
||||
public function testCreate8()
|
||||
{
|
||||
$this->prepareFactoryTest(
|
||||
PrimaryFilterApplier::class, ApplierFactory::PRIMARY_FILTER, 'createPrimaryFilter');
|
||||
}
|
||||
|
||||
public function testCreate9()
|
||||
{
|
||||
$this->prepareFactoryTest(
|
||||
AccessControlFilterApplier::class, ApplierFactory::ACCESS_CONTROL_FILTER, 'createAccessControlFilter');
|
||||
}
|
||||
|
||||
protected function prepareFactoryTest(string $defaultClassName, string $type, string $method)
|
||||
{
|
||||
$entityType = 'Test';
|
||||
|
||||
$applierClassName = $className ?? $defaultClassName;
|
||||
|
||||
$applier = $this->createMock($defaultClassName);
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$binder
|
||||
->bindInstance(User::class, $this->user)
|
||||
->bindInstance(AclManager::class, $this->aclManager)
|
||||
->bindInstance(Acl::class, $this->acl)
|
||||
->for($applierClassName)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$bindingContainer = new BindingContainer($bindingData);
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->once())
|
||||
->method('createWithBinding')
|
||||
->with($applierClassName, $bindingContainer)
|
||||
->willReturn($applier);
|
||||
|
||||
$resultApplier = $this->factory->$method(
|
||||
$entityType,
|
||||
$this->user,
|
||||
$type
|
||||
);
|
||||
|
||||
$this->assertEquals($applier, $resultApplier);
|
||||
}
|
||||
}
|
||||
145
tests/unit/Espo/Core/Select/Bool/FilterFactoryTest.php
Normal file
145
tests/unit/Espo/Core/Select/Bool/FilterFactoryTest.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Bool;
|
||||
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingContainer;
|
||||
use Espo\Core\Binding\BindingData;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\Bool\FilterFactory as BoolFilterFactory;
|
||||
use Espo\Core\Select\Bool\Filters\Followed;
|
||||
use Espo\Core\Select\Helpers\FieldHelper;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Entities\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FilterFactoryTest extends TestCase
|
||||
{
|
||||
private $injectableFactory;
|
||||
private $metadata;
|
||||
private $user;
|
||||
private $factory;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
|
||||
$this->factory = new BoolFilterFactory(
|
||||
$this->injectableFactory,
|
||||
$this->metadata
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreate1()
|
||||
{
|
||||
$this->prepareFactoryTest(null, Followed::class, 'followed');
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$this->prepareFactoryTest('SomeClass', Followed::class, 'followed');
|
||||
}
|
||||
|
||||
protected function prepareFactoryTest(?string $className, string $defaultClassName, string $name)
|
||||
{
|
||||
$entityType = 'Test';
|
||||
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'boolFilterClassNameMap', $name], null, $className],
|
||||
]);
|
||||
|
||||
$className = $className ?? $defaultClassName;
|
||||
|
||||
$object = $this->createMock($defaultClassName);
|
||||
|
||||
$bindingData = new BindingData();
|
||||
|
||||
$binder = new Binder($bindingData);
|
||||
|
||||
$binder
|
||||
->bindInstance(User::class, $this->user)
|
||||
->for($className)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$binder
|
||||
->for(FieldHelper::class)
|
||||
->bindValue('$entityType', $entityType);
|
||||
|
||||
$bindingContainer = new BindingContainer($bindingData);
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->once())
|
||||
->method('createWithBinding')
|
||||
->with($className, $bindingContainer)
|
||||
->willReturn($object);
|
||||
|
||||
$resultObject = $this->factory->create(
|
||||
$entityType,
|
||||
$this->user,
|
||||
$name
|
||||
);
|
||||
|
||||
$this->assertEquals($object, $resultObject);
|
||||
|
||||
$this->assertTrue(
|
||||
$this->factory->has($entityType, $name)
|
||||
);
|
||||
|
||||
$this->metadata
|
||||
->expects(self::any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[
|
||||
[
|
||||
'selectDefs',
|
||||
$entityType,
|
||||
'boolFilterClassNameMap',
|
||||
'badName',
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
['app', 'select', 'boolFilterClassNameMap', 'badName'],
|
||||
null,
|
||||
null
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->factory->has($entityType, 'badName')
|
||||
);
|
||||
}
|
||||
}
|
||||
118
tests/unit/Espo/Core/Select/Bool/FiltersTest.php
Normal file
118
tests/unit/Espo/Core/Select/Bool/FiltersTest.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Bool;
|
||||
|
||||
use Espo\Core\Select\Bool\Filters\OnlyMy;
|
||||
use Espo\Core\Select\Bool\Filters\Shared;
|
||||
use Espo\Core\Select\Helpers\FieldHelper;
|
||||
use Espo\Entities\User;
|
||||
use Espo\ORM\Defs;
|
||||
use Espo\ORM\Defs\EntityDefs;
|
||||
use Espo\ORM\Defs\RelationDefs;
|
||||
use Espo\ORM\Query\Part\Where\OrGroupBuilder;
|
||||
use Espo\ORM\Query\Select;
|
||||
use Espo\ORM\Query\SelectBuilder;
|
||||
use Espo\ORM\Type\RelationType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FiltersTest extends TestCase
|
||||
{
|
||||
public function testOnlyMyUsesMiddleConditions(): void
|
||||
{
|
||||
$user = $this->createMock(User::class);
|
||||
$user->method('getId')->willReturn('user-id');
|
||||
$user->method('isPortal')->willReturn(false);
|
||||
|
||||
$fieldHelper = $this->createMock(FieldHelper::class);
|
||||
$fieldHelper->method('hasAssignedUsersField')->willReturn(true);
|
||||
|
||||
$filter = new OnlyMy('Test', $user, $fieldHelper, $this->createDefs('assignedUsers', 'entityUser'));
|
||||
|
||||
$joinConditions = $this->applyAndGetJoinConditions($filter);
|
||||
|
||||
$this->assertEquals('Test', $joinConditions['assignedUsersMiddle.entityType'] ?? null);
|
||||
}
|
||||
|
||||
public function testSharedUsesMiddleConditions(): void
|
||||
{
|
||||
$user = $this->createMock(User::class);
|
||||
$user->method('getId')->willReturn('user-id');
|
||||
|
||||
$fieldHelper = $this->createMock(FieldHelper::class);
|
||||
$fieldHelper->method('hasCollaboratorsField')->willReturn(true);
|
||||
|
||||
$filter = new Shared('Test', $user, $fieldHelper, $this->createDefs('collaborators', 'entityCollaborator'));
|
||||
|
||||
$joinConditions = $this->applyAndGetJoinConditions($filter);
|
||||
|
||||
$this->assertEquals('Test', $joinConditions['collaboratorsMiddle.entityType'] ?? null);
|
||||
}
|
||||
|
||||
private function createDefs(string $link, string $relationName): Defs
|
||||
{
|
||||
$relationDefs = RelationDefs::fromRaw([
|
||||
'type' => RelationType::MANY_MANY,
|
||||
'entity' => User::ENTITY_TYPE,
|
||||
'relationName' => $relationName,
|
||||
'midKeys' => ['entityId', 'userId'],
|
||||
'conditions' => ['entityType' => 'Test'],
|
||||
], $link);
|
||||
|
||||
$entityDefs = $this->createMock(EntityDefs::class);
|
||||
$entityDefs->method('getRelation')->with($link)->willReturn($relationDefs);
|
||||
|
||||
$defs = $this->createMock(Defs::class);
|
||||
$defs->method('getEntity')->with('Test')->willReturn($entityDefs);
|
||||
|
||||
return $defs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function applyAndGetJoinConditions(OnlyMy|Shared $filter): array
|
||||
{
|
||||
$orGroupBuilder = new OrGroupBuilder();
|
||||
|
||||
$filter->apply(SelectBuilder::create()->from('Test'), $orGroupBuilder);
|
||||
|
||||
$rawValue = $orGroupBuilder->build()->getRawValue();
|
||||
|
||||
$subQuery = $rawValue['id=s'] ?? null;
|
||||
|
||||
$this->assertInstanceOf(Select::class, $subQuery);
|
||||
|
||||
$joins = $subQuery->getRaw()['joins'] ?? [];
|
||||
|
||||
$this->assertCount(1, $joins);
|
||||
|
||||
return $joins[0][2];
|
||||
}
|
||||
}
|
||||
162
tests/unit/Espo/Core/Select/Order/ItemConverterFactoryTest.php
Normal file
162
tests/unit/Espo/Core/Select/Order/ItemConverterFactoryTest.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM – Open Source CRM application.
|
||||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU Affero General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace tests\unit\Espo\Core\Select\Order;
|
||||
|
||||
use Espo\Entities\User;
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Select\Order\ItemConverter;
|
||||
use Espo\Core\Select\Order\ItemConverterFactory;
|
||||
use Espo\Core\Select\Order\ItemConverters\EnumType;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
|
||||
use Espo\Core\Binding\BindingContainerBuilder;
|
||||
use Espo\Core\Binding\ContextualBinder;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ItemConverterFactoryTest extends TestCase
|
||||
{
|
||||
private $injectableFactory;
|
||||
private $metadata;
|
||||
private $user;
|
||||
private $factory;
|
||||
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->injectableFactory = $this->createMock(InjectableFactory::class);
|
||||
$this->metadata = $this->createMock(Metadata::class);
|
||||
$this->user = $this->createMock(User::class);
|
||||
|
||||
$this->factory = new ItemConverterFactory(
|
||||
$this->injectableFactory,
|
||||
$this->metadata,
|
||||
$this->user
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreate1()
|
||||
{
|
||||
$this->prepareFactoryTest(null, EnumType::class);
|
||||
$this->prepareFactoryTest(null, EnumType::class, true);
|
||||
}
|
||||
|
||||
public function testCreate2()
|
||||
{
|
||||
$this->prepareFactoryTest(EnumType::class, null);
|
||||
$this->prepareFactoryTest(EnumType::class, null, true);
|
||||
}
|
||||
|
||||
protected function prepareFactoryTest(?string $className1, ?string $className2, bool $testHas = false)
|
||||
{
|
||||
$defaultClassName = ItemConverter::class;
|
||||
|
||||
$entityType = 'Test';
|
||||
|
||||
$field = 'name';
|
||||
|
||||
$type = 'varchar';
|
||||
|
||||
$object = $this->createMock($defaultClassName);
|
||||
|
||||
$className = $className1 ?? $className2 ?? null;
|
||||
|
||||
if (!$className1) {
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'orderItemConverterClassNameMap', $field], null, $className1],
|
||||
[['entityDefs', $entityType, 'fields', $field, 'type'], null, $type],
|
||||
[['app', 'select', 'orderItemConverterClassNameMap', $type], null, $className2],
|
||||
]);
|
||||
} else {
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'orderItemConverterClassNameMap', $field], null, $className1],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($testHas) {
|
||||
$this->assertTrue(
|
||||
$this->factory->has($entityType, $field)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$object = $this->createMock($className);
|
||||
|
||||
$container = BindingContainerBuilder::create()
|
||||
->bindInstance(User::class, $this->user)
|
||||
->inContext($className, function (ContextualBinder $binder) use ($entityType) {
|
||||
$binder->bindValue('$entityType', $entityType);
|
||||
})
|
||||
->build();
|
||||
|
||||
$this->injectableFactory
|
||||
->expects($this->once())
|
||||
->method('createWithBinding')
|
||||
->with(
|
||||
$className,
|
||||
$container
|
||||
)
|
||||
->willReturn($object);
|
||||
|
||||
$resultObject = $this->factory->create(
|
||||
$entityType,
|
||||
$field
|
||||
);
|
||||
|
||||
$this->assertEquals($object, $resultObject);
|
||||
}
|
||||
|
||||
public function testHasFalse()
|
||||
{
|
||||
$entityType = 'Test';
|
||||
|
||||
$field = 'name';
|
||||
|
||||
$type = 'varchar';
|
||||
|
||||
$this->metadata
|
||||
->expects($this->any())
|
||||
->method('get')
|
||||
->willReturnMap([
|
||||
[['selectDefs', $entityType, 'orderItemConverterClassNameMap', 'badName'], null, null],
|
||||
[['entityDefs', $entityType, 'fields', 'badName', 'type'], null, $type],
|
||||
[['app', 'select', 'orderItemConverterClassNameMap', $type], null, null],
|
||||
]);
|
||||
|
||||
$this->assertFalse(
|
||||
$this->factory->has($entityType, 'badName')
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user