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,80 @@
|
||||
<?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\integration\Espo\Tools\Activities;
|
||||
|
||||
use Espo\Core\Api\Request;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\Modules\Crm\Entities\CaseObj;
|
||||
use Espo\Modules\Crm\Tools\Activities\Api\GetComposeAddressList;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class ComposeEmailAddressListTest extends BaseTestCase
|
||||
{
|
||||
public function testGetGetAddressList(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$account = $em->createEntity(Account::ENTITY_TYPE, [
|
||||
'name' => 'Test',
|
||||
'emailAddress' => 'test@test.com',
|
||||
]);
|
||||
|
||||
$case = $em->createEntity(CaseObj::ENTITY_TYPE, [
|
||||
'accountId' => $account->getId(),
|
||||
]);
|
||||
|
||||
$action = $this->getInjectableFactory()
|
||||
->create(GetComposeAddressList::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
|
||||
$request
|
||||
->expects($this->any())
|
||||
->method('getRouteParam')
|
||||
->willReturnMap([
|
||||
['parentType', CaseObj::ENTITY_TYPE],
|
||||
['id', $case->getId()]
|
||||
]);
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
$response = $action->process($request);
|
||||
|
||||
$list = json_decode($response->getBody());
|
||||
|
||||
$this->assertEquals([
|
||||
(object) [
|
||||
'emailAddress' => 'test@test.com',
|
||||
'name' => $account->get('name'),
|
||||
'entityId' => $account->getId(),
|
||||
'entityType' => Account::ENTITY_TYPE,
|
||||
]
|
||||
], $list);
|
||||
}
|
||||
}
|
||||
61
tests/integration/Espo/Tools/App/LanguageTest.php
Normal file
61
tests/integration/Espo/Tools/App/LanguageTest.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\integration\Espo\Tools\App;
|
||||
|
||||
use Espo\Tools\App\LanguageService;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class LanguageTest extends BaseTestCase
|
||||
{
|
||||
public function testAclDependency(): void
|
||||
{
|
||||
$this->createUser('tester', [
|
||||
'data' => [
|
||||
'Lead' => false,
|
||||
'Opportunity' => [
|
||||
'create' => 'no',
|
||||
'read' => 'own',
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
'stream' => 'no',
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
$this->authenticate('tester');
|
||||
|
||||
$data = $this->getInjectableFactory()->create(LanguageService::class)->getDataForFrontend();
|
||||
|
||||
$data = json_decode(json_encode($data));
|
||||
|
||||
$this->assertNotNull($data?->Lead?->options?->source);
|
||||
$this->assertNull($data?->Lead?->options?->status ?? null);
|
||||
}
|
||||
}
|
||||
73
tests/integration/Espo/Tools/App/MetadataTest.php
Normal file
73
tests/integration/Espo/Tools/App/MetadataTest.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\integration\Espo\Tools\App;
|
||||
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Espo\Tools\App\MetadataService;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class MetadataTest extends BaseTestCase
|
||||
{
|
||||
public function testAclDependency(): void
|
||||
{
|
||||
$metadata = $this->getContainer()->getByClass(Metadata::class);
|
||||
|
||||
$metadata->set('app', 'metadata', [
|
||||
'aclDependencies' => [
|
||||
'entityDefs.Campaign' => [
|
||||
'anyScopeList' => ['Opportunity'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$metadata->save();
|
||||
|
||||
$this->createUser('tester', [
|
||||
'data' => [
|
||||
'Lead' => false,
|
||||
'Opportunity' => [
|
||||
'create' => 'no',
|
||||
'read' => 'own',
|
||||
'edit' => 'no',
|
||||
'delete' => 'no',
|
||||
'stream' => 'no',
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
$this->authenticate('tester');
|
||||
|
||||
$data = $this->getInjectableFactory()->create(MetadataService::class)->getDataForFrontend();
|
||||
|
||||
$this->assertIsArray($data?->entityDefs?->Lead?->fields?->source?->options);
|
||||
$this->assertNull($data->entityDefs->Lead->fields->name ?? null);
|
||||
$this->assertNotNull($data?->entityDefs->Campaign ?? null);
|
||||
}
|
||||
}
|
||||
@@ -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\integration\Espo\Tools\AppSecret;
|
||||
|
||||
use Espo\Core\Utils\Crypt;
|
||||
use Espo\Entities\AppSecret;
|
||||
use Espo\Tools\AppSecret\SecretProvider;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class SecretProviderTest extends BaseTestCase
|
||||
{
|
||||
public function testGet(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$provider = $this->getInjectableFactory()->create(SecretProvider::class);
|
||||
|
||||
$secret = $em->getRDBRepositoryByClass(AppSecret::class)->getNew();
|
||||
$crypt = $this->getInjectableFactory()->create(Crypt::class);
|
||||
|
||||
$value = 'hello';
|
||||
|
||||
$secret
|
||||
->setName('test')
|
||||
->setSecretValue($crypt->encrypt($value));
|
||||
|
||||
$em->saveEntity($secret);
|
||||
|
||||
$this->assertEquals(
|
||||
$value,
|
||||
$provider->get('test')
|
||||
);
|
||||
|
||||
$this->assertNull($provider->get('Test'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?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\integration\Espo\Tools\DynamicLogic;
|
||||
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Record\CreateParams;
|
||||
use Espo\Core\Record\ServiceContainer;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\Modules\Crm\Entities\Contact;
|
||||
use Espo\Tools\EntityManager\EntityManager;
|
||||
use Espo\Tools\FieldManager\FieldManager;
|
||||
use Espo\Tools\LinkManager\LinkManager;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class CascadingFieldsTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testLinkMultiple(): void
|
||||
{
|
||||
$emTool = $this->getInjectableFactory()->create(EntityManager::class);
|
||||
$lmTool = $this->getInjectableFactory()->create(LinkManager::class);
|
||||
$fmTool = $this->getInjectableFactory()->create(FieldManager::class);
|
||||
|
||||
$emTool->create('MyTest', 'Base');
|
||||
|
||||
$lmTool->create([
|
||||
'link' => 'accounts',
|
||||
'linkForeign' => 'tests',
|
||||
'linkType' => 'manyToMany',
|
||||
'entity' => 'CMyTest',
|
||||
'entityForeign' => Account::ENTITY_TYPE,
|
||||
'label' => 'Account',
|
||||
'labelForeign' => 'Test',
|
||||
'relationName' => 'testAccount',
|
||||
'linkMultipleField' => true,
|
||||
'linkMultipleFieldForeign' => true,
|
||||
]);
|
||||
|
||||
$lmTool->create([
|
||||
'link' => 'contacts',
|
||||
'linkForeign' => 'tests',
|
||||
'linkType' => 'manyToMany',
|
||||
'entity' => 'CMyTest',
|
||||
'entityForeign' => Contact::ENTITY_TYPE,
|
||||
'label' => 'Contact',
|
||||
'labelForeign' => 'Test',
|
||||
'relationName' => 'testContact',
|
||||
'linkMultipleField' => true,
|
||||
'linkMultipleFieldForeign' => true,
|
||||
]);
|
||||
|
||||
$fmTool->update('CMyTest', 'contacts', [
|
||||
'dynamicLogicCascading' => [
|
||||
'items' => [
|
||||
[
|
||||
'localField' => 'accounts',
|
||||
'foreignField' => 'accounts',
|
||||
'matchRequired' => true,
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->reCreateApplication();
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$a1 = $em->createEntity(Account::ENTITY_TYPE);
|
||||
$a2 = $em->createEntity(Account::ENTITY_TYPE);
|
||||
|
||||
$c1A12 = $em->createEntity(Contact::ENTITY_TYPE, [
|
||||
'accountsIds' => [$a1->getId(), $a2->getId()],
|
||||
'accountId' => $a1->getId(),
|
||||
]);
|
||||
|
||||
$c2A1 = $em->createEntity(Contact::ENTITY_TYPE, [
|
||||
'accountsIds' => [$a1->getId()],
|
||||
'accountId' => $a1->getId(),
|
||||
]);
|
||||
|
||||
$service = $this->getContainer()->getByClass(ServiceContainer::class)->get('CMyTest');
|
||||
|
||||
//
|
||||
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountsIds' => [$a1->getId()],
|
||||
'contactsIds' => [$c2A1->getId()],
|
||||
], CreateParams::create());
|
||||
|
||||
//
|
||||
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountsIds' => [$a1->getId(), $a2->getId()],
|
||||
'contactsIds' => [$c1A12->getId()],
|
||||
], CreateParams::create());
|
||||
|
||||
//
|
||||
|
||||
$thrown = false;
|
||||
|
||||
try {
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountsIds' => [$a1->getId(), $a2->getId()],
|
||||
'contactsIds' => [$c2A1->getId()],
|
||||
], CreateParams::create());
|
||||
} catch (BadRequest) {
|
||||
$thrown = true;
|
||||
}
|
||||
|
||||
$this->assertTrue($thrown);
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testLink(): void
|
||||
{
|
||||
$emTool = $this->getInjectableFactory()->create(EntityManager::class);
|
||||
$lmTool = $this->getInjectableFactory()->create(LinkManager::class);
|
||||
$fmTool = $this->getInjectableFactory()->create(FieldManager::class);
|
||||
|
||||
$emTool->create('MyTest', 'Base');
|
||||
|
||||
$lmTool->create([
|
||||
'link' => 'account',
|
||||
'linkForeign' => 'tests',
|
||||
'linkType' => 'manyToOne',
|
||||
'entity' => 'CMyTest',
|
||||
'entityForeign' => Account::ENTITY_TYPE,
|
||||
'label' => 'Account',
|
||||
'labelForeign' => 'Test',
|
||||
'linkMultipleField' => true,
|
||||
'linkMultipleFieldForeign' => true,
|
||||
]);
|
||||
|
||||
$lmTool->create([
|
||||
'link' => 'contact',
|
||||
'linkForeign' => 'tests',
|
||||
'linkType' => 'manyToOne',
|
||||
'entity' => 'CMyTest',
|
||||
'entityForeign' => Contact::ENTITY_TYPE,
|
||||
'label' => 'Contact',
|
||||
'labelForeign' => 'Test',
|
||||
'linkMultipleField' => true,
|
||||
'linkMultipleFieldForeign' => true,
|
||||
]);
|
||||
|
||||
$fmTool->update('CMyTest', 'contact', [
|
||||
'dynamicLogicCascading' => [
|
||||
'items' => [
|
||||
[
|
||||
'localField' => 'account',
|
||||
'foreignField' => 'accounts',
|
||||
'matchRequired' => true,
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->reCreateApplication();
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$a1 = $em->createEntity(Account::ENTITY_TYPE);
|
||||
$a2 = $em->createEntity(Account::ENTITY_TYPE);
|
||||
|
||||
$c1A12 = $em->createEntity(Contact::ENTITY_TYPE, [
|
||||
'accountsIds' => [$a1->getId(), $a2->getId()],
|
||||
'accountId' => $a1->getId(),
|
||||
]);
|
||||
|
||||
$c2A1 = $em->createEntity(Contact::ENTITY_TYPE, [
|
||||
'accountsIds' => [$a1->getId()],
|
||||
'accountId' => $a1->getId(),
|
||||
]);
|
||||
|
||||
$service = $this->getContainer()->getByClass(ServiceContainer::class)->get('CMyTest');
|
||||
|
||||
//
|
||||
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountId' => $a1->getId(),
|
||||
'contactId' => $c2A1->getId(),
|
||||
], CreateParams::create());
|
||||
|
||||
//
|
||||
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountId' => $a2->getId(),
|
||||
'contactId' => $c1A12->getId(),
|
||||
], CreateParams::create());
|
||||
|
||||
//
|
||||
|
||||
$thrown = false;
|
||||
|
||||
try {
|
||||
$service->create((object) [
|
||||
'name' => 't1',
|
||||
'accountId' => $a2->getId(),
|
||||
'contactId' => $c2A1->getId(),
|
||||
], CreateParams::create());
|
||||
} catch (BadRequest) {
|
||||
$thrown = true;
|
||||
}
|
||||
|
||||
$this->assertTrue($thrown);
|
||||
}
|
||||
}
|
||||
235
tests/integration/Espo/Tools/EmailTemplate/ProcessorTest.php
Normal file
235
tests/integration/Espo/Tools/EmailTemplate/ProcessorTest.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?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 integration\Espo\Tools\EmailTemplate;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Espo\Core\Binding\Binder;
|
||||
use Espo\Core\Binding\BindingProcessor;
|
||||
use Espo\Core\Field\Link;
|
||||
use Espo\Core\Field\LinkMultiple;
|
||||
use Espo\Core\Utils\DateTime\Clock;
|
||||
use Espo\Entities\EmailTemplate;
|
||||
use Espo\Entities\Team;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\Modules\Crm\Entities\Lead;
|
||||
use Espo\Tools\EmailTemplate\Data as TemplateData;
|
||||
use Espo\Tools\EmailTemplate\Params as TemplateParams;
|
||||
use Espo\Tools\EmailTemplate\Processor;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class ProcessorTest extends BaseTestCase
|
||||
{
|
||||
public function testProcessAccess(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$team = $em->getRDBRepositoryByClass(Team::class)->getNew();
|
||||
$team
|
||||
->setName('Team 1');
|
||||
$em->saveEntity($team);
|
||||
|
||||
$user = $em->getRDBRepositoryByClass(User::class)->getNew();
|
||||
$user
|
||||
->setFirstName('Test')
|
||||
->setLastName('Hello')
|
||||
->setUserName('test')
|
||||
->setDefaultTeam(Link::fromEntity($team))
|
||||
->setTeams(LinkMultiple::create()->withAddedId($team->getId()));
|
||||
$em->saveEntity($user);
|
||||
|
||||
$template1 = $em->getRDBRepositoryByClass(EmailTemplate::class)->getNew();
|
||||
$template1->setMultiple([
|
||||
'subject' => '{Lead.name} {Lead.assignedUser.name} {Lead.assignedUser.password}',
|
||||
'body' => '{Lead.name} {Lead.assignedUser.name} {Lead.assignedUser.password}',
|
||||
]);
|
||||
$em->saveEntity($template1);
|
||||
|
||||
$template2 = $em->getRDBRepositoryByClass(EmailTemplate::class)->getNew();
|
||||
$template2->setMultiple([
|
||||
'subject' => '{{name}} {{assignedUser.name}} {{assignedUser.password}}',
|
||||
'body' => '{{name}} {{assignedUser.name}} {{assignedUser.password}}',
|
||||
]);
|
||||
$em->saveEntity($template2);
|
||||
|
||||
$template3 = $em->getRDBRepositoryByClass(EmailTemplate::class)->getNew();
|
||||
$template3->setMultiple([
|
||||
'subject' => '{{name}} {{password}} {{defaultTeam.name}}',
|
||||
'body' => '{User.name} {User.password} {User.defaultTeam.name}',
|
||||
]);
|
||||
$em->saveEntity($template3);
|
||||
|
||||
$template4 = $em->getRDBRepositoryByClass(EmailTemplate::class)->getNew();
|
||||
$template4->setMultiple([
|
||||
'subject' => '{{name}} {{password}} {{defaultTeam.name}}',
|
||||
'body' => '{User.name} {User.password} {User.defaultTeam.name}',
|
||||
]);
|
||||
$em->saveEntity($template4);
|
||||
|
||||
$lead = $em->getRDBRepositoryByClass(Lead::class)->getNew();
|
||||
$lead
|
||||
->setFirstName('Lead')
|
||||
->setLastName('Abc')
|
||||
->setAssignedUser($user);
|
||||
$em->saveEntity($lead);
|
||||
|
||||
$processor = $this->getInjectableFactory()->create(Processor::class);
|
||||
|
||||
$params = TemplateParams::create()
|
||||
->withApplyAcl(false);
|
||||
|
||||
$data = TemplateData::create();
|
||||
|
||||
//
|
||||
|
||||
$emailData1 = $processor->process($template1, $params, $data->withParent($lead));
|
||||
|
||||
$this->assertEquals(
|
||||
'Lead Abc Test Hello {Lead.assignedUser.password}',
|
||||
$emailData1->getSubject(),
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'Lead Abc Test Hello {Lead.assignedUser.password}',
|
||||
$emailData1->getBody(),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$emailData2 = $processor->process($template2, $params, $data->withParent($lead));
|
||||
|
||||
$this->assertEquals(
|
||||
'Lead Abc Test Hello ',
|
||||
$emailData2->getSubject(),
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'Lead Abc Test Hello ',
|
||||
$emailData2->getBody(),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$emailData3 = $processor->process($template3, $params, $data->withParent($user));
|
||||
|
||||
$this->assertEquals(
|
||||
'Test Hello ',
|
||||
$emailData3->getSubject(),
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'Test Hello {User.password} {User.defaultTeam.name}',
|
||||
$emailData3->getBody(),
|
||||
);
|
||||
}
|
||||
|
||||
public function testProcessAndCleanup(): void
|
||||
{
|
||||
$this->setConfigParams([
|
||||
'dateFormat' => 'MM/DD/YYYY',
|
||||
]);
|
||||
|
||||
$clock = $this->createMock(Clock::class);
|
||||
$clock->method('now')
|
||||
->willReturn(new DateTimeImmutable('2030-01-02 00:00'));
|
||||
|
||||
$this->setApplication(
|
||||
$this->createApplication(
|
||||
binding: new class ($clock) implements BindingProcessor {
|
||||
|
||||
public function __construct(private Clock $clock) {}
|
||||
|
||||
public function process(Binder $binder): void
|
||||
{
|
||||
$binder->bindInstance(Clock::class, $this->clock);
|
||||
}
|
||||
},
|
||||
reuse: true,
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
|
||||
$account->setName('Account 1');
|
||||
$em->saveEntity($account);
|
||||
|
||||
$lead = $em->getRDBRepositoryByClass(Lead::class)->getNew();
|
||||
$lead->setFirstName('One');
|
||||
$em->saveEntity($lead);
|
||||
$em->refreshEntity($lead);
|
||||
|
||||
$template1 = $em->getRDBRepositoryByClass(EmailTemplate::class)->getNew();
|
||||
$template1->setMultiple([
|
||||
'subject' => 'Test {Person.firstName} test {Account.name}',
|
||||
'body' => 'Test {Person.name} test {Account.name} {today}.',
|
||||
]);
|
||||
$em->saveEntity($template1);
|
||||
|
||||
//
|
||||
|
||||
$processor = $this->getInjectableFactory()->create(Processor::class);
|
||||
|
||||
$params = TemplateParams::create()
|
||||
->withApplyAcl(false);
|
||||
|
||||
$data = TemplateData::create();
|
||||
|
||||
//
|
||||
|
||||
$emailData1 = $processor->process($template1, $params, $data->withParent($account));
|
||||
|
||||
$this->assertEquals(
|
||||
'Test test Account 1',
|
||||
$emailData1->getSubject(),
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'Test test Account 1 01/02/2030.',
|
||||
$emailData1->getBody(),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$emailData2 = $processor->process($template1, $params, $data->withParent($lead));
|
||||
|
||||
$this->assertEquals(
|
||||
'Test One test {Account.name}',
|
||||
$emailData2->getSubject(),
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'Test One test {Account.name} 01/02/2030.',
|
||||
$emailData2->getBody(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?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\integration\Espo\Tools\EntityTypeManager;
|
||||
|
||||
use Espo\Core\Templates\Entities\BasePlus;
|
||||
use Espo\Tools\EntityManager\EntityManager;
|
||||
use integration\Core\NoTransaction;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
#[NoTransaction]
|
||||
class EntityTypeManagerTest extends BaseTestCase
|
||||
{
|
||||
private const string PARAM_CATEGORIES = 'categories';
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testCreateUpdateDelete(): void
|
||||
{
|
||||
$name = 'TestEntityType';
|
||||
|
||||
$tool = $this->getInjectableFactory()->create(EntityManager::class);
|
||||
|
||||
$tool->create($name, BasePlus::TEMPLATE_TYPE, [
|
||||
'stream' => true,
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
$tool->update('C' . $name, [
|
||||
'stream' => false,
|
||||
self::PARAM_CATEGORIES => true,
|
||||
]);
|
||||
|
||||
$this->reCreateApplication();
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$this->assertTrue($em->hasRepository("C$name"));
|
||||
$this->assertTrue($em->hasRepository("C{$name}Category"));
|
||||
|
||||
//
|
||||
|
||||
$tool->delete('C' . $name);
|
||||
|
||||
$this->reCreateApplication();
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$this->assertFalse($em->hasRepository("C{$name}Category"));
|
||||
$this->assertFalse($em->hasRepository("C$name"));
|
||||
}
|
||||
}
|
||||
257
tests/integration/Espo/Tools/Import/ImportTest.php
Normal file
257
tests/integration/Espo/Tools/Import/ImportTest.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?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 integration\Espo\Tools\Import;
|
||||
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Entities\Attachment;
|
||||
use Espo\Entities\Role;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\Modules\Crm\Entities\Contact;
|
||||
use Espo\Tools\Import\Import;
|
||||
use Espo\Tools\Import\Params;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class ImportTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testRelateOnImport(): void
|
||||
{
|
||||
$metadata = $this->getMetadata();
|
||||
|
||||
$metadata->set('entityDefs', Contact::ENTITY_TYPE, [
|
||||
'fields' => [
|
||||
'accountType' => [
|
||||
'relateOnImport' => true,
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$metadata->save();
|
||||
|
||||
//
|
||||
|
||||
$this->createUser('test', [
|
||||
Role::FIELD_DATA => [
|
||||
'Import' => true,
|
||||
Account::ENTITY_TYPE => [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
Contact::ENTITY_TYPE => [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
Table::ACTION_EDIT => Table::LEVEL_ALL,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->authenticate('test');
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
//
|
||||
|
||||
$attachment = $em->getRDBRepositoryByClass(Attachment::class)->getNew();
|
||||
$attachment
|
||||
->setName('test.csv')
|
||||
->setType('text/csv')
|
||||
->setRole(Import::FILE_ROLE)
|
||||
->setContents(
|
||||
<<<'EOT'
|
||||
lastName,accountType
|
||||
Test,Partner
|
||||
```
|
||||
EOT
|
||||
);
|
||||
$em->saveEntity($attachment);
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
|
||||
$account->setType(Account::TYPE_PARTNER);
|
||||
$em->saveEntity($account);
|
||||
|
||||
$import = $this->getInjectableFactory()->create(Import::class);
|
||||
|
||||
$import
|
||||
->setUser($this->getContainer()->getByClass(User::class))
|
||||
->setEntityType(Contact::ENTITY_TYPE)
|
||||
->setParams(
|
||||
Params::create()
|
||||
)
|
||||
->setAttachmentId($attachment->getId())
|
||||
->setAttributeList(['lastName', 'accountType']);
|
||||
|
||||
$import->run();
|
||||
|
||||
$contact = $em->getRDBRepositoryByClass(Contact::class)
|
||||
->where(['lastName' => 'Test'])
|
||||
->findOne();
|
||||
|
||||
$this->assertNotNull($contact);
|
||||
$this->assertEquals($account->getId(), $contact->getAccount()?->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testRelateByForeignName(): void
|
||||
{
|
||||
$this->createUser('test', [
|
||||
Role::FIELD_DATA => [
|
||||
'Import' => true,
|
||||
Account::ENTITY_TYPE => [
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
Contact::ENTITY_TYPE => [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
Table::ACTION_EDIT => Table::LEVEL_ALL,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->authenticate('test');
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
//
|
||||
|
||||
$attachment = $em->getRDBRepositoryByClass(Attachment::class)->getNew();
|
||||
$attachment
|
||||
->setName('test.csv')
|
||||
->setType('text/csv')
|
||||
->setRole(Import::FILE_ROLE)
|
||||
->setContents(
|
||||
<<<'EOT'
|
||||
lastName,accountName
|
||||
Test,Hello
|
||||
```
|
||||
EOT
|
||||
);
|
||||
$em->saveEntity($attachment);
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
|
||||
$account->setName('Hello');
|
||||
$em->saveEntity($account);
|
||||
|
||||
$import = $this->getInjectableFactory()->create(Import::class);
|
||||
|
||||
$import
|
||||
->setEntityType(Contact::ENTITY_TYPE)
|
||||
->setParams(
|
||||
Params::create()
|
||||
)
|
||||
->setAttachmentId($attachment->getId())
|
||||
->setAttributeList(['lastName', 'accountName']);
|
||||
|
||||
$import->run();
|
||||
|
||||
$contact = $em->getRDBRepositoryByClass(Contact::class)
|
||||
->where(['lastName' => 'Test'])
|
||||
->findOne();
|
||||
|
||||
$this->assertNotNull($contact);
|
||||
$this->assertEquals($account->getId(), $contact->getAccount()?->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testDefaultValues(): void
|
||||
{
|
||||
$this->createUser('test', [
|
||||
Role::FIELD_DATA => [
|
||||
'Import' => true,
|
||||
Account::ENTITY_TYPE => [
|
||||
Table::ACTION_CREATE => Table::LEVEL_YES,
|
||||
Table::ACTION_READ => Table::LEVEL_ALL,
|
||||
],
|
||||
],
|
||||
Role::FIELD_FIELD_DATA => [
|
||||
Account::ENTITY_TYPE => [
|
||||
'type' => [
|
||||
Table::ACTION_READ => Table::LEVEL_YES,
|
||||
Table::ACTION_EDIT => Table::LEVEL_NO,
|
||||
],
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$this->authenticate('test');
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
//
|
||||
|
||||
$attachment = $em->getRDBRepositoryByClass(Attachment::class)->getNew();
|
||||
$attachment
|
||||
->setName('test.csv')
|
||||
->setType('text/csv')
|
||||
->setRole(Import::FILE_ROLE)
|
||||
->setContents(
|
||||
<<<'EOT'
|
||||
name
|
||||
Test
|
||||
```
|
||||
EOT
|
||||
);
|
||||
$em->saveEntity($attachment);
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
|
||||
$account->setType(Account::TYPE_PARTNER);
|
||||
$em->saveEntity($account);
|
||||
|
||||
$import = $this->getInjectableFactory()->create(Import::class);
|
||||
|
||||
$import
|
||||
->setEntityType(Account::ENTITY_TYPE)
|
||||
->setParams(
|
||||
Params::create()->withDefaultValues([
|
||||
'type' => Account::TYPE_PARTNER,
|
||||
'description' => 'Test.',
|
||||
])
|
||||
)
|
||||
->setAttachmentId($attachment->getId())
|
||||
->setAttributeList(['name']);
|
||||
|
||||
$import->run();
|
||||
|
||||
//
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)
|
||||
->where(['name' => 'Test'])
|
||||
->findOne();
|
||||
|
||||
$this->assertNotNull($account);
|
||||
$this->assertNull($account->getType());
|
||||
$this->assertEquals('Test.', $account->getDescription());
|
||||
}
|
||||
}
|
||||
91
tests/integration/Espo/Tools/Lock/LockTest.php
Normal file
91
tests/integration/Espo/Tools/Lock/LockTest.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\integration\Espo\Tools\Lock;
|
||||
|
||||
use Espo\Core\Action\ActionFactory;
|
||||
use Espo\Core\Action\Data;
|
||||
use Espo\Core\Action\Params;
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Modules\Crm\Entities\Account;
|
||||
use Espo\ORM\Exceptions\ValidationException;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class LockTest extends BaseTestCase
|
||||
{
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
public function testLock1(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$account = $em->getRDBRepositoryByClass(Account::class)->getNew();
|
||||
$account->setName('Test');
|
||||
$em->saveEntity($account);
|
||||
|
||||
$account->set(Field::IS_LOCKED, true);
|
||||
$em->saveEntity($account);
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
|
||||
$account->setName('Test 1');
|
||||
$em->saveEntity($account);
|
||||
|
||||
//
|
||||
|
||||
$actionFactory = $this->getInjectableFactory()->create(ActionFactory::class);
|
||||
|
||||
$actionFactory->create('Unlock', Account::ENTITY_TYPE)->process(
|
||||
params: new Params(
|
||||
entityType: Account::ENTITY_TYPE,
|
||||
id: $account->getId(),
|
||||
),
|
||||
data: Data::fromRaw((object) [])
|
||||
);
|
||||
|
||||
|
||||
$em->refreshEntity($account);
|
||||
|
||||
$this->assertFalse($account->get(Field::IS_LOCKED));
|
||||
|
||||
//
|
||||
|
||||
$actionFactory->create('Lock', Account::ENTITY_TYPE)->process(
|
||||
params: new Params(
|
||||
entityType: Account::ENTITY_TYPE,
|
||||
id: $account->getId(),
|
||||
),
|
||||
data: Data::fromRaw((object) [])
|
||||
);
|
||||
|
||||
|
||||
$em->refreshEntity($account);
|
||||
|
||||
$this->assertTrue($account->get(Field::IS_LOCKED));
|
||||
}
|
||||
}
|
||||
79
tests/integration/Espo/Tools/Merge/MergeTest.php
Normal file
79
tests/integration/Espo/Tools/Merge/MergeTest.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\integration\Espo\Tools\Merge;
|
||||
|
||||
use Espo\Core\Action\Actions\Merge\Merger;
|
||||
use Espo\Core\Action\Params;
|
||||
use Espo\Core\Field\DateTimeOptional;
|
||||
use Espo\Modules\Crm\Entities\Lead;
|
||||
use Espo\Modules\Crm\Entities\Meeting;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class MergeTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testMerge(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$lead1 = $em->getRepositoryByClass(Lead::class)->getNew();
|
||||
$lead1->setLastName('L 1');
|
||||
$em->saveEntity($lead1);
|
||||
|
||||
$lead2 = $em->getRepositoryByClass(Lead::class)->getNew();
|
||||
$lead2->setLastName('L 2');
|
||||
$em->saveEntity($lead2);
|
||||
|
||||
$meeting = $em->getRepositoryByClass(Meeting::class)->getNew();
|
||||
$meeting->setParent($lead2);
|
||||
$meeting->setName('M');
|
||||
$meeting->setDateStart(DateTimeOptional::createNow());
|
||||
$em->saveEntity($meeting);
|
||||
|
||||
$merger = $this->getInjectableFactory()->create(Merger::class);
|
||||
|
||||
$merger->process(
|
||||
params: new Params(Lead::ENTITY_TYPE, $lead1->getId()),
|
||||
sourceIdList: [$lead2->getId()],
|
||||
data: (object) [],
|
||||
);
|
||||
|
||||
$em->refreshEntity($meeting);
|
||||
|
||||
$this->assertEquals($lead1->getId(), $meeting->getParent()?->getId());
|
||||
$this->assertEquals(Lead::ENTITY_TYPE, $meeting->getParent()?->getEntityType());
|
||||
|
||||
$this->assertNull(
|
||||
$em->getEntityById(Lead::ENTITY_TYPE, $lead2->getId())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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\integration\Espo\Tools\Notification;
|
||||
|
||||
use Espo\Core\Select\SearchParams;
|
||||
use Espo\Entities\User;
|
||||
use Espo\Tools\Notification\RecordService;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class RecordServiceTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testGet(): void
|
||||
{
|
||||
$this->createUser('tester');
|
||||
$this->authenticate('tester');
|
||||
|
||||
$service = $this->getInjectableFactory()->create(RecordService::class);
|
||||
|
||||
$user = $this->getContainer()->getByClass(User::class);
|
||||
|
||||
$service->get($user, SearchParams::create());
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
1523
tests/integration/Espo/Tools/OAuthServer/AuthorizationServerTest.php
Normal file
1523
tests/integration/Espo/Tools/OAuthServer/AuthorizationServerTest.php
Normal file
File diff suppressed because it is too large
Load Diff
200
tests/integration/Espo/Tools/OAuthServer/CleanupTest.php
Normal file
200
tests/integration/Espo/Tools/OAuthServer/CleanupTest.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?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 integration\Espo\Tools\OAuthServer;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\DateTime\Clock;
|
||||
use Espo\Tools\OAuthServer\Cleanup\GeneralCleanup;
|
||||
use Espo\Tools\OAuthServer\Entities\AccessToken;
|
||||
use Espo\Tools\OAuthServer\Entities\AuthorizationCode;
|
||||
use Espo\Tools\OAuthServer\Entities\RefreshToken;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class CleanupTest extends BaseTestCase
|
||||
{
|
||||
public function testCleanupAuthTokens(): void
|
||||
{
|
||||
$now = DateTime::fromString('2030-01-01 00:00');
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$accessToken1 = $em->getRDBRepositoryByClass(AccessToken::class)->getNew();
|
||||
$accessToken1->setExpiresAt($now->addHours(1));
|
||||
$em->saveEntity($accessToken1);
|
||||
|
||||
$accessToken2 = $em->getRDBRepositoryByClass(AccessToken::class)->getNew();
|
||||
$accessToken2->setExpiresAt($now->addHours(1));
|
||||
$em->saveEntity($accessToken2);
|
||||
|
||||
$refreshToken = $em->getRDBRepositoryByClass(RefreshToken::class)->getNew();
|
||||
$refreshToken
|
||||
->setAccessToken($accessToken2)
|
||||
->setExpiresAt($now->addMonths(3));
|
||||
$em->saveEntity($refreshToken);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertNotNull(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)->getById($accessToken1->getId())
|
||||
);
|
||||
|
||||
$this->assertNotNull(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)->getById($accessToken2->getId())
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$now = $now->addDays(15)->addHours(1);
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertFalse(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)->getById($accessToken1->getId()) !== null
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)->getById($accessToken2->getId()) !== null
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$refreshToken->setRevoked();
|
||||
$em->saveEntity($refreshToken);
|
||||
|
||||
//
|
||||
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertFalse(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)->getById($accessToken2->getId()) !== null
|
||||
);
|
||||
}
|
||||
|
||||
public function testCleanupRefreshTokens(): void
|
||||
{
|
||||
$now = DateTime::fromString('2030-01-01 00:00');
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$refreshToken = $em->getRDBRepositoryByClass(RefreshToken::class)->getNew();
|
||||
$refreshToken
|
||||
->setExpiresAt($now->addMonths(1));
|
||||
$em->saveEntity($refreshToken);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertNotNull(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)->getById($refreshToken->getId())
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$now = $now->addMonths(1)->addDays(15);
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertFalse(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)->getById($refreshToken->getId()) !== null
|
||||
);
|
||||
}
|
||||
|
||||
public function testCleanupAuthorizationCode(): void
|
||||
{
|
||||
$now = DateTime::fromString('2030-01-01 00:00');
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$code = $em->getRDBRepositoryByClass(AuthorizationCode::class)->getNew();
|
||||
$code
|
||||
->setExpiresAt($now->addHours(1));
|
||||
$em->saveEntity($code);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertNotNull(
|
||||
$em->getRDBRepositoryByClass(AuthorizationCode::class)->getById($code->getId())
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$now = $now->addHours(1)->addDays(15);
|
||||
|
||||
$this->reCreateApplicationWithNow($now);
|
||||
|
||||
//
|
||||
|
||||
$cleanup = $this->getInjectableFactory()->create(GeneralCleanup::class);
|
||||
$cleanup->process();
|
||||
|
||||
$this->assertFalse(
|
||||
$em->getRDBRepositoryByClass(AuthorizationCode::class)->getById($code->getId()) !== null
|
||||
);
|
||||
}
|
||||
|
||||
private function reCreateApplicationWithNow(DateTime $now): void
|
||||
{
|
||||
$clock = $this->createMock(Clock::class);
|
||||
$clock->expects(self::any())
|
||||
->method('now')
|
||||
->willReturn($now->toDateTime());
|
||||
|
||||
$this->reCreateApplication(
|
||||
reuse: true,
|
||||
binding: $this->prepareBinding(function ($binder) use ($clock) {
|
||||
$binder->bindInstance(Clock::class, $clock);
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
167
tests/integration/Espo/Tools/OAuthServer/ConnectedAppTest.php
Normal file
167
tests/integration/Espo/Tools/OAuthServer/ConnectedAppTest.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?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 integration\Espo\Tools\OAuthServer;
|
||||
|
||||
use Espo\Core\Acl\Scope;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Tools\OAuthServer\ClientType;
|
||||
use Espo\Tools\OAuthServer\ConnectedApp\ConnectedAppService;
|
||||
use Espo\Tools\OAuthServer\Entities\AccessToken;
|
||||
use Espo\Tools\OAuthServer\Entities\Client;
|
||||
use Espo\Tools\OAuthServer\Entities\RefreshToken;
|
||||
use Espo\Tools\OAuthServer\Repository\AccessTokenRepository;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class ConnectedAppTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testListAndDisconnect(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$user1 = $this->createUser('test-1');
|
||||
$user2 = $this->createUser('test-2');
|
||||
|
||||
$client1 = $this->createClient('Test 1');
|
||||
$client2 = $this->createClient('Test 2');
|
||||
|
||||
//
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)
|
||||
->getNew()
|
||||
->setClient($client1)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user1)
|
||||
);
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)
|
||||
->getNew()
|
||||
->setClient($client2)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user1)
|
||||
);
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)
|
||||
->getNew()
|
||||
->setClient($client1)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user1)
|
||||
);
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)
|
||||
->getNew()
|
||||
->setClient($client1)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user1)
|
||||
);
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(AccessToken::class)
|
||||
->getNew()
|
||||
->setClient($client2)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user1)
|
||||
);
|
||||
|
||||
$em->saveEntity(
|
||||
$em->getRDBRepositoryByClass(RefreshToken::class)
|
||||
->getNew()
|
||||
->setClient($client1)
|
||||
->setExpiresAt(DateTime::createNow()->addHours(1))
|
||||
->setUser($user2)
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$accessTokenRepo = $this->getInjectableFactory()->create(AccessTokenRepository::class);
|
||||
|
||||
$service = $this->getInjectableFactory()->create(ConnectedAppService::class);
|
||||
|
||||
$apps = $service->getList($user1);
|
||||
|
||||
$this->assertCount(2, $apps);
|
||||
$this->assertEquals($client1->getIdentifier(), $apps[0]->id);
|
||||
|
||||
$this->assertEquals(
|
||||
1,
|
||||
$accessTokenRepo
|
||||
->findActiveForClientIdAndUser($client1->getId(), $user1->getId())
|
||||
->count(),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$service->disconnect($user1, $client1->getIdentifier());
|
||||
|
||||
$apps = $service->getList($user1);
|
||||
|
||||
$this->assertCount(1, $apps);
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$accessTokenRepo
|
||||
->findActiveForClientIdAndUser($client1->getId(), $user1->getId())
|
||||
->count(),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$apps = $service->getList($user2);
|
||||
|
||||
$this->assertCount(1, $apps);
|
||||
|
||||
//
|
||||
|
||||
$apps = $service->getList($user2);
|
||||
|
||||
$this->assertCount(1, $apps);
|
||||
}
|
||||
|
||||
private function createClient(string $name): Client
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$client = $em->getRDBRepositoryByClass(Client::class)->getNew();
|
||||
$client
|
||||
->setName($name)
|
||||
->setScopes([Scope::GLOBAL])
|
||||
->setClientType(ClientType::Confidential)
|
||||
->setRedirectUris(['http://localhost/oauth/callback']);
|
||||
$em->saveEntity($client);
|
||||
|
||||
return $client;
|
||||
}
|
||||
}
|
||||
153
tests/integration/Espo/Tools/OAuthServer/ExpirationTest.php
Normal file
153
tests/integration/Espo/Tools/OAuthServer/ExpirationTest.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?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 integration\Espo\Tools\OAuthServer;
|
||||
|
||||
use Espo\Core\Field\Date;
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\DateTime\Clock;
|
||||
use Espo\Tools\OAuthServer\Entities\AccessToken;
|
||||
use Espo\Tools\OAuthServer\Entities\AuthorizationCode;
|
||||
use Espo\Tools\OAuthServer\Entities\Client;
|
||||
use Espo\Tools\OAuthServer\Entities\ClientSecret;
|
||||
use Espo\Tools\OAuthServer\Entities\RefreshToken;
|
||||
use Espo\Tools\OAuthServer\Jobs\OAuthServerControl;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class ExpirationTest extends BaseTestCase
|
||||
{
|
||||
public function testExpire(): void
|
||||
{
|
||||
$now = DateTime::fromString('2030-01-01 00:00');
|
||||
|
||||
$clock = $this->createClock($now);
|
||||
|
||||
$this->reCreateApplication(
|
||||
reuse: true,
|
||||
noUser: true,
|
||||
binding: $this->prepareBinding(function ($binder) use ($clock) {
|
||||
$binder->bindInstance(Clock::class, $clock);
|
||||
}),
|
||||
);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$client = $em->getRDBRepositoryByClass(Client::class)->getNew();
|
||||
$em->saveEntity($client);
|
||||
|
||||
//
|
||||
|
||||
$expirationDate = Date::fromDateTime($now->toDateTime())->addMonths(1);
|
||||
$expiresAt = DateTime::fromDateTime($now->toDateTime())->addMonths(1);
|
||||
|
||||
$secret = $em->getRDBRepositoryByClass(ClientSecret::class)->getNew();
|
||||
$secret
|
||||
->setClient($client)
|
||||
->setExpirationDate($expirationDate);
|
||||
$em->saveEntity($secret);
|
||||
|
||||
$code = $em->getRDBRepositoryByClass(AuthorizationCode::class)->getNew();
|
||||
$code
|
||||
->setClient($client)
|
||||
->setExpiresAt($expiresAt);
|
||||
$em->saveEntity($code);
|
||||
|
||||
$accessToken = $em->getRDBRepositoryByClass(AccessToken::class)->getNew();
|
||||
$accessToken
|
||||
->setClient($client)
|
||||
->setExpiresAt($expiresAt);
|
||||
$em->saveEntity($accessToken);
|
||||
|
||||
$refreshToken = $em->getRDBRepositoryByClass(RefreshToken::class)->getNew();
|
||||
$refreshToken
|
||||
->setClient($client)
|
||||
->setExpiresAt($expiresAt);
|
||||
$em->saveEntity($refreshToken);
|
||||
|
||||
//
|
||||
|
||||
$job = $this->getInjectableFactory()->create(OAuthServerControl::class);
|
||||
|
||||
$job->run();
|
||||
|
||||
$em->refreshEntity($secret);
|
||||
$em->refreshEntity($code);
|
||||
$em->refreshEntity($accessToken);
|
||||
$em->refreshEntity($refreshToken);
|
||||
|
||||
$this->assertTrue($secret->isActive());
|
||||
$this->assertTrue($code->isActive());
|
||||
$this->assertTrue($accessToken->isActive());
|
||||
$this->assertTrue($refreshToken->isActive());
|
||||
|
||||
//
|
||||
|
||||
$now = $now->addMonths(1);
|
||||
|
||||
$clock = $this->createClock($now);
|
||||
|
||||
$this->reCreateApplication(
|
||||
reuse: true,
|
||||
noUser: true,
|
||||
binding: $this->prepareBinding(function ($binder) use ($clock) {
|
||||
$binder->bindInstance(Clock::class, $clock);
|
||||
}),
|
||||
);
|
||||
|
||||
//
|
||||
|
||||
$job = $this->getInjectableFactory()->create(OAuthServerControl::class);
|
||||
|
||||
$job->run();
|
||||
|
||||
$em->refreshEntity($secret);
|
||||
$em->refreshEntity($code);
|
||||
$em->refreshEntity($accessToken);
|
||||
$em->refreshEntity($refreshToken);
|
||||
|
||||
$this->assertTrue($secret->isExpired());
|
||||
$this->assertFalse($secret->isActive());
|
||||
$this->assertFalse($secret->isRevoked());
|
||||
|
||||
$this->assertTrue($code->isExpired());
|
||||
$this->assertTrue($accessToken->isExpired());
|
||||
$this->assertTrue($refreshToken->isExpired());
|
||||
}
|
||||
|
||||
private function createClock(DateTime $now): Clock
|
||||
{
|
||||
$clock = $this->createMock(Clock::class);
|
||||
|
||||
$clock->expects(self::any())
|
||||
->method('now')
|
||||
->willReturn($now->toDateTime());
|
||||
|
||||
return $clock;
|
||||
}
|
||||
}
|
||||
51
tests/integration/Espo/Tools/Object/MetadataProviderTest.php
Normal file
51
tests/integration/Espo/Tools/Object/MetadataProviderTest.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?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\integration\Espo\Tools\Object;
|
||||
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Modules\Crm\Entities\Meeting;
|
||||
use Espo\Modules\Crm\Entities\Opportunity;
|
||||
use Espo\Modules\Crm\Entities\Task;
|
||||
use Espo\Tools\Object\MetadataProvider;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class MetadataProviderTest extends BaseTestCase
|
||||
{
|
||||
public function testGetLinks(): void
|
||||
{
|
||||
$provider = $this->getInjectableFactory()->create(MetadataProvider::class);
|
||||
|
||||
$this->assertEquals(Field::ACCOUNT, $provider->getAccountLink(Opportunity::ENTITY_TYPE));
|
||||
$this->assertEquals(Field::ACCOUNT, $provider->getAccountLink(Meeting::ENTITY_TYPE));
|
||||
|
||||
$this->assertEquals(Field::PARENT, $provider->getParentLink(Meeting::ENTITY_TYPE));
|
||||
$this->assertEquals(Field::PARENT, $provider->getParentLink(Task::ENTITY_TYPE));
|
||||
}
|
||||
}
|
||||
237
tests/integration/Espo/Tools/Pipeline/PipelineTest.php
Normal file
237
tests/integration/Espo/Tools/Pipeline/PipelineTest.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\integration\Espo\Tools\Pipeline;
|
||||
|
||||
use Espo\Classes\AppParams\Pipelines;
|
||||
use Espo\Core\Acl\Table;
|
||||
use Espo\Core\AclManager;
|
||||
use Espo\Core\Exceptions\BadRequest;
|
||||
use Espo\Core\Field\Date;
|
||||
use Espo\Core\Name\Field;
|
||||
use Espo\Core\Record\CreateParams;
|
||||
use Espo\Core\Record\DeleteParams;
|
||||
use Espo\Core\Record\ServiceContainer;
|
||||
use Espo\Core\Record\UpdateParams;
|
||||
use Espo\Entities\Pipeline;
|
||||
use Espo\Entities\PipelineStage;
|
||||
use Espo\Entities\Role;
|
||||
use Espo\Entities\Team;
|
||||
use Espo\Modules\Crm\Entities\Opportunity;
|
||||
use Espo\Tools\EntityManager\EntityManager as EntityManagerTool;
|
||||
use integration\Core\NoTransaction;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
#[NoTransaction]
|
||||
class PipelineTest extends BaseTestCase
|
||||
{
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
*/
|
||||
public function testPipeline1(): void
|
||||
{
|
||||
$this->initPipeline(Opportunity::ENTITY_TYPE);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$role = $em->getRDBRepositoryByClass(Role::class)->getNew();
|
||||
$role
|
||||
->set(Field::NAME, 'Test')
|
||||
->setRawData([
|
||||
Opportunity::ENTITY_TYPE => [
|
||||
Table::ACTION_EDIT => Table::LEVEL_TEAM,
|
||||
],
|
||||
]);
|
||||
$em->saveEntity($role);
|
||||
|
||||
$team = $em->createEntity(Team::ENTITY_TYPE, [
|
||||
Field::NAME => 'Test',
|
||||
'rolesIds' => [$role->getId()],
|
||||
]);
|
||||
|
||||
$user1 = $this->createUser([
|
||||
'userName' => 'test-1',
|
||||
'teamsIds' => [$team->getId()],
|
||||
]);
|
||||
|
||||
$pipelineService = $this->getContainer()
|
||||
->getByClass(ServiceContainer::class)
|
||||
->getByClass(Pipeline::class);
|
||||
|
||||
$pipelineStageService = $this->getContainer()
|
||||
->getByClass(ServiceContainer::class)
|
||||
->getByClass(PipelineStage::class);
|
||||
|
||||
$oppService = $this->getContainer()
|
||||
->getByClass(ServiceContainer::class)
|
||||
->getByClass(Opportunity::class);
|
||||
|
||||
//
|
||||
|
||||
$pipeline1 = $pipelineService->create((object) [
|
||||
Field::NAME => 'Test 1',
|
||||
Pipeline::FIELD_ENTITY_TYPE => Opportunity::ENTITY_TYPE,
|
||||
Pipeline::FIELD_IS_AVAILABLE_FOR_ALL => false,
|
||||
], CreateParams::create())->getEntity();
|
||||
|
||||
$this->assertCount(6, $pipeline1->getStages());
|
||||
|
||||
//
|
||||
|
||||
$pipeline2 = $pipelineService->create((object) [
|
||||
Field::NAME => 'Test 2',
|
||||
Pipeline::FIELD_ENTITY_TYPE => Opportunity::ENTITY_TYPE,
|
||||
Pipeline::FIELD_IS_AVAILABLE_FOR_ALL => false,
|
||||
Field::TEAMS . 'Ids' => [$team->getId()],
|
||||
], CreateParams::create())->getEntity();
|
||||
|
||||
foreach ($pipeline2->getStages() as $stage) {
|
||||
$pipelineStageService->delete($stage->getId(), DeleteParams::create());
|
||||
}
|
||||
|
||||
$stage2_1 = $pipelineStageService->create((object) [
|
||||
Field::NAME => 'Open',
|
||||
PipelineStage::ATTR_PIPELINE_ID => $pipeline2->getId(),
|
||||
PipelineStage::FIELD_MAPPED_STATUS => 'Prospecting',
|
||||
], CreateParams::create())->getEntity();
|
||||
|
||||
$pipelineStageService->create((object) [
|
||||
Field::NAME => 'Closed Won',
|
||||
PipelineStage::ATTR_PIPELINE_ID => $pipeline2->getId(),
|
||||
PipelineStage::FIELD_MAPPED_STATUS => Opportunity::STAGE_CLOSED_WON,
|
||||
], CreateParams::create());
|
||||
|
||||
$pipelineStageService->create((object) [
|
||||
Field::NAME => 'Closed Lost',
|
||||
PipelineStage::ATTR_PIPELINE_ID => $pipeline2->getId(),
|
||||
PipelineStage::FIELD_MAPPED_STATUS => Opportunity::STAGE_CLOSED_LOST,
|
||||
], CreateParams::create());
|
||||
|
||||
$thrown = false;
|
||||
|
||||
try {
|
||||
// Non-existing status.
|
||||
$pipelineStageService->create((object) [
|
||||
Field::NAME => 'Test',
|
||||
PipelineStage::ATTR_PIPELINE_ID => $pipeline2->getId(),
|
||||
PipelineStage::FIELD_MAPPED_STATUS => 'Test',
|
||||
], CreateParams::create());
|
||||
} catch (BadRequest) {
|
||||
$thrown = true;
|
||||
}
|
||||
|
||||
$this->assertTrue($thrown);
|
||||
|
||||
$em->refreshEntity($pipeline2);
|
||||
|
||||
$this->assertCount(3, $pipeline2->getStages());
|
||||
|
||||
//
|
||||
|
||||
$opp = $oppService->create((object) [
|
||||
Field::NAME => 'Opp 1',
|
||||
Field::PIPELINE . 'Id' => $pipeline1->getId(),
|
||||
Field::PIPELINE_STAGE . 'Id' => $pipeline1->getStages()[0]->getId(),
|
||||
Opportunity::FIELD_CLOSE_DATE => Date::fromString('2026-01-01')->toString(),
|
||||
Opportunity::FIELD_AMOUNT => 1000,
|
||||
], CreateParams::create())->getEntity();
|
||||
|
||||
$opp = $oppService->update($opp->getId(), (object) [
|
||||
Field::PIPELINE . 'Id' => $pipeline2->getId(),
|
||||
Field::PIPELINE_STAGE . 'Id' => $pipeline2->getStages()[0]->getId(),
|
||||
], UpdateParams::create())->getEntity();
|
||||
|
||||
$this->assertEquals('Prospecting', $opp->getStage());
|
||||
|
||||
//
|
||||
|
||||
$opp = $oppService->create((object) [
|
||||
Field::NAME => 'Opp 2',
|
||||
Field::PIPELINE . 'Id' => $pipeline1->getId(),
|
||||
Field::PIPELINE_STAGE . 'Id' => $pipeline1->getStages()[4]->getId(),
|
||||
Opportunity::FIELD_CLOSE_DATE => Date::fromString('2026-01-01')->toString(),
|
||||
Opportunity::FIELD_AMOUNT => 1000,
|
||||
], CreateParams::create())->getEntity();
|
||||
|
||||
$this->assertEquals(Opportunity::STAGE_CLOSED_WON, $opp->getStage());
|
||||
|
||||
//
|
||||
|
||||
$opp = $oppService->create((object) [
|
||||
Field::NAME => 'Opp 3',
|
||||
Opportunity::FIELD_CLOSE_DATE => Date::fromString('2026-01-01')->toString(),
|
||||
Opportunity::FIELD_AMOUNT => 1000,
|
||||
], CreateParams::create());
|
||||
|
||||
$this->assertEquals($pipeline1->getId(), $opp->getEntity()->get(Field::PIPELINE . 'Id'));
|
||||
$this->assertEquals($pipeline1->getStages()[0]->getId(), $opp->getEntity()->get(Field::PIPELINE_STAGE . 'Id'));
|
||||
|
||||
//
|
||||
|
||||
$pipelinesParam = $this->getInjectableFactory()->create(Pipelines::class);
|
||||
|
||||
$pipelines = $pipelinesParam->get();
|
||||
|
||||
$this->assertCount(2, $pipelines[Opportunity::ENTITY_TYPE]);
|
||||
|
||||
//
|
||||
|
||||
$this->auth($user1->getUserName());
|
||||
$this->reCreateApplication(reuse: true);
|
||||
|
||||
$pipelinesParam = $this->getInjectableFactory()->create(Pipelines::class);
|
||||
|
||||
$pipelines = $pipelinesParam->get();
|
||||
|
||||
$this->assertCount(1, $pipelines[Opportunity::ENTITY_TYPE]);
|
||||
|
||||
//
|
||||
|
||||
$aclManager = $this->getContainer()->getByClass(AclManager::class);
|
||||
|
||||
$this->assertFalse($aclManager->checkEntityRead($user1, $pipeline1));
|
||||
$this->assertTrue($aclManager->checkEntityRead($user1, $pipeline2));
|
||||
|
||||
$this->assertTrue($aclManager->checkEntityRead($user1, $stage2_1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
* @noinspection PhpArrayKeyDoesNotMatchArrayShapeInspection
|
||||
* @noinspection PhpSameParameterValueInspection
|
||||
*/
|
||||
private function initPipeline(string $entityType): void
|
||||
{
|
||||
$entityManager = $this->getInjectableFactory()->create(EntityManagerTool::class);
|
||||
|
||||
$entityManager->update($entityType, [
|
||||
'pipelines' => true
|
||||
]);
|
||||
}
|
||||
}
|
||||
79
tests/integration/Espo/Tools/WorkingTime/UtilityTest.php
Normal file
79
tests/integration/Espo/Tools/WorkingTime/UtilityTest.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\integration\Espo\Tools\WorkingTime;
|
||||
|
||||
use Espo\Core\Field\DateTime;
|
||||
use Espo\Core\Utils\Config\ConfigWriter;
|
||||
use Espo\Entities\WorkingTimeCalendar;
|
||||
use Espo\Tools\WorkingTime\CalendarUtilityFactory;
|
||||
use tests\integration\Core\BaseTestCase;
|
||||
|
||||
class UtilityTest extends BaseTestCase
|
||||
{
|
||||
public function testUtilityUser(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$calendar = $em->createEntity(WorkingTimeCalendar::ENTITY_TYPE);
|
||||
|
||||
$user = $this->createUser('test');
|
||||
$user->set('workingTimeCalendarId', $calendar->getId());
|
||||
$em->saveEntity($user);
|
||||
|
||||
$utility = $this->getInjectableFactory()
|
||||
->create(CalendarUtilityFactory::class)
|
||||
->createForUser($user);
|
||||
|
||||
$this->assertTrue($utility->isWorkingDay(DateTime::fromString('2024-02-23 00:00')));
|
||||
$this->assertFalse($utility->isWorkingDay(DateTime::fromString('2024-02-24 00:00')));
|
||||
$this->assertFalse($utility->isWorkingDay(DateTime::fromString('2024-02-25 00:00')));
|
||||
$this->assertTrue($utility->isWorkingDay(DateTime::fromString('2024-02-26 00:00')));
|
||||
}
|
||||
|
||||
public function testUtilityGlobal(): void
|
||||
{
|
||||
$em = $this->getEntityManager();
|
||||
|
||||
$calendar = $em->createEntity(WorkingTimeCalendar::ENTITY_TYPE);
|
||||
|
||||
$configWriter = $this->getInjectableFactory()->create(ConfigWriter::class);
|
||||
$configWriter->set('workingTimeCalendarId', $calendar->getId());
|
||||
$configWriter->save();
|
||||
|
||||
$utility = $this->getInjectableFactory()
|
||||
->create(CalendarUtilityFactory::class)
|
||||
->createGlobal();
|
||||
|
||||
$this->assertTrue($utility->isWorkingDay(DateTime::fromString('2024-02-23 00:00')));
|
||||
$this->assertFalse($utility->isWorkingDay(DateTime::fromString('2024-02-24 00:00')));
|
||||
$this->assertFalse($utility->isWorkingDay(DateTime::fromString('2024-02-25 00:00')));
|
||||
$this->assertTrue($utility->isWorkingDay(DateTime::fromString('2024-02-26 00:00')));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user