. * * 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\Record; use Espo\Core\Application; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Exceptions\Conflict; use Espo\Core\Exceptions\Forbidden; use Espo\Core\Record\CreateParams; use Espo\Core\Record\ServiceContainer; use Espo\Core\Record\UpdateParams; use Espo\Core\Utils\Config\ConfigWriter; use Espo\Entities\User; use Espo\Modules\Crm\Entities\Account; use Espo\Modules\Crm\Entities\Lead; use Espo\ORM\EntityManager; use Espo\Tools\App\SettingsService as SettingsService; use tests\integration\Core\BaseTestCase; class FieldValidationTest extends BaseTestCase { private function setFieldsDefs(Application $app, string $entityType, array $data) { $metadata = $app->getContainer()->get('metadata'); $metadata->set('entityDefs', $entityType, [ 'fields' => $data, ]); $metadata->save(); } public function testRequiredVarchar1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, ], ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => null, ], CreateParams::create()); } public function testUpdateRequiredVarchar1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, ], ]); $entity = $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create( (object) [ 'name' => 'test' ], CreateParams::create() ); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->update( $entity->id, (object) [ 'name' => '', ], UpdateParams::create() ); } public function testRequiredVarchar2() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, ], ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create( (object) [ ], CreateParams::create() ); } public function testRequiredVarchar3() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, ], ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => 'test', ], CreateParams::create()); $this->assertTrue(true); } public function testMaxLength1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, 'maxLength' => 5, ], ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => '123456', ], CreateParams::create()); } public function testMaxLength2() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'name' => [ 'required' => true, 'maxLength' => 5, ] ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => '12345', ], CreateParams::create()); $this->assertTrue(true); } public function testRequiredLink1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'assignedUser' => [ 'required' => true, ] ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => 'test', 'assignedUserId' => null, ], CreateParams::create()); } private function getAdminUser(): User { $repository = $this->getContainer() ->getByClass(EntityManager::class) ->getRDBRepositoryByClass(User::class); $user = $repository ->where(['type' => User::TYPE_ADMIN]) ->findOne(); if (!$user) { $user = $repository->getNew(); $user->set('userName', 'test-admin'); $user->set('type', User::TYPE_ADMIN); $repository->save($user); } return $user; } public function testRequiredLink2() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'assignedUser' => [ 'required' => true, ] ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => 'test', 'assignedUserId' => $this->getAdminUser()->getId(), ], CreateParams::create()); $this->assertTrue(true); } public function testRequiredLinkMultiple1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Account', [ 'teams' => [ 'required' => true, ] ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Account') ->create((object) [ 'name' => 'test', 'teamsIds' => [], ], CreateParams::create()); } public function testRequiredCurrency1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'opportunityAmount' => [ 'required' => true, ] ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', 'opportunityAmount' => null, ], CreateParams::create()); } public function testRequiredCurrency2() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'opportunityAmount' => [ 'required' => true, ] ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', 'opportunityAmount' => 100, 'opportunityAmountCurrency' => null, ], CreateParams::create()); $this->assertTrue(true); } public function testRequiredCurrency3() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'opportunityAmount' => [ 'required' => true, ] ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', 'opportunityAmount' => 100, 'opportunityAmountCurrency' => 'USD', ], CreateParams::create()); $this->assertTrue(true); } public function testRequiredEnum1() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'status' => [ 'required' => true, 'default' => null, ] ]); $app = $this->createApplication(); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', ], CreateParams::create()); } public function testRequiredEnum2() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'status' => [ 'required' => true, ] ]); $this->expectException(BadRequest::class); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', 'status' => null, ], CreateParams::create()); } public function testRequiredEnum3() { $app = $this->createApplication(); $this->setFieldsDefs($app, 'Lead', [ 'status' => [ 'required' => true, ] ]); $app->getContainer() ->getByClass(ServiceContainer::class) ->get('Lead') ->create((object) [ 'lastName' => 'test', 'status' => 'New', ], CreateParams::create()); $this->assertTrue(true); } public function testSkipRequired() { /** @noinspection PhpUnhandledExceptionInspection */ $this->getContainer() ->getByClass(ServiceContainer::class) ->get('Meeting') ->create((object) [ 'name' => 'test', 'dateStart' => '2021-01-01 00:00:00', 'duration' => 1000, 'assignedUserId' => $this->getAdminUser()->getId(), ], CreateParams::create()); $this->assertTrue(true); } public function testSettings() { $service = $this->getContainer()->get('injectableFactory')->create(SettingsService::class); $this->expectException(BadRequest::class); $service->setConfigData((object) [ 'activitiesEntityList' => 'should-be-array', ]); } public function testCurrencyValid(): void { $service = $this->getContainer() ->getByClass(ServiceContainer::class) ->getByClass(Lead::class); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object) [ 'lastName' => 'Test 1', 'opportunityAmount' => '100.10', ], CreateParams::create()); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object) [ 'lastName' => 'Test 2', 'opportunityAmount' => '100', ], CreateParams::create()); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object) [ 'lastName' => 'Test 3', 'opportunityAmount' => '', ], CreateParams::create()); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object) [ 'lastName' => 'Test 4', 'opportunityAmount' => null, ], CreateParams::create()); $this->expectException(BadRequest::class); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object) [ 'lastName' => 'Test Bad 1', 'opportunityAmount' => 'bad-value', ], CreateParams::create()); } public function testPhoneNumber(): void { $service = $this->getContainer() ->getByClass(ServiceContainer::class) ->getByClass(Account::class); $configWriter = $this->getInjectableFactory()->create(ConfigWriter::class); $configWriter->set('phoneNumberExtensions', true); $configWriter->save(); /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object)[ 'name' => 'Test 1', 'phoneNumberData' => [ (object)[ 'phoneNumber' => '+38 09 044 433 22 ext. 001', ], ], ], CreateParams::create()); $thrown = false; try { /** @noinspection PhpUnhandledExceptionInspection */ $service->create((object)[ 'name' => 'Test 2', 'phoneNumberData' => [ (object)[ 'phoneNumber' => '+38 09 044 433 22 ext. ABC', ], (object)[ 'phoneNumber' => '+38 09 044 433 33 ext. 1234567', ], ], ], CreateParams::create()); } catch (BadRequest) { $thrown = true; } $this->assertTrue($thrown); } }