diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 0c97ee8..7d98bf4 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -31,6 +31,7 @@ use Modules\Media\Models\PathSettings; use Modules\ContractManagement\Models\Contract; use Modules\ContractManagement\Models\NullContractType; use Modules\ContractManagement\Models\ContractMapper; +use phpOMS\Localization\ISO639x1Enum; /** * Api controller for the contracts module. @@ -186,7 +187,6 @@ final class ApiController extends Controller } $contractType = $this->createContractTypeFromRequest($request); - $contractType->setL11n($request->getData('title'), $request->getData('language')); $this->createModel($request->header->account, $contractType, ContractTypeMapper::class, 'contract_type', $request->getOrigin()); $this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Contract type', 'Contract type successfully created', $contractType); @@ -204,6 +204,7 @@ final class ApiController extends Controller private function createContractTypeFromRequest(RequestAbstract $request) : ContractType { $contractType = new ContractType(); + $contractType->setL11n($request->getData('title'), $request->getData('language') ?? ISO639x1Enum::_EN); return $contractType; } @@ -287,7 +288,9 @@ final class ApiController extends Controller private function validateContractTypeL11nCreate(RequestAbstract $request) : array { $val = []; - if (($val['title'] = empty($request->getData('title')))) { + if (($val['title'] = empty($request->getData('title'))) + || ($val['type'] = empty($request->getData('type'))) + ) { return $val; } diff --git a/Models/Contract.php b/Models/Contract.php index 6506b2f..d9c88cb 100755 --- a/Models/Contract.php +++ b/Models/Contract.php @@ -49,7 +49,7 @@ class Contract public string $description = ''; - public \DateTime $start; + public ?\DateTime $start = null; public ?\DateTime $end = null; @@ -82,6 +82,7 @@ class Contract { $this->createdAt = new \DateTimeImmutable('now'); $this->account = new NullAccount(); + $this->type = new ContractType(); } /** @@ -127,7 +128,19 @@ class Contract */ public function toArray() : array { - return []; + return [ + 'id' => $this->id, + 'title' => $this->title, + 'description' => $this->description, + 'start' => $this->start, + 'end' => $this->end, + 'duration' => $this->duration, + 'warning' => $this->warning, + 'responsible' => $this->responsible, + 'createdAt' => $this->createdAt, + 'costs' => $this->costs, + 'type' => $this->type, + ]; } /** diff --git a/Models/ContractType.php b/Models/ContractType.php index e700dfe..27eb374 100755 --- a/Models/ContractType.php +++ b/Models/ContractType.php @@ -45,15 +45,13 @@ class ContractType implements \JsonSerializable, ArrayableInterface /** * Constructor. * - * @param string $name Name/identifier of the attribute type + * @param string $name Name * * @since 1.0.0 */ public function __construct(string $name = '') { - if (!empty($name)) { - $this->setL11n($name); - } + $this->setL11n($name); } /** @@ -106,7 +104,10 @@ class ContractType implements \JsonSerializable, ArrayableInterface */ public function toArray() : array { - return []; + return [ + 'id' => $this->id, + 'l11n' => $this->l11n, + ]; } /** diff --git a/Models/ContractTypeL11n.php b/Models/ContractTypeL11n.php index 7da01e5..e9994ca 100755 --- a/Models/ContractTypeL11n.php +++ b/Models/ContractTypeL11n.php @@ -41,7 +41,7 @@ class ContractTypeL11n implements \JsonSerializable, ArrayableInterface * @var int|ContractType * @since 1.0.0 */ - protected int | ContractType $type = 0; + public int | ContractType $type = 0; /** * Language. @@ -88,29 +88,15 @@ class ContractTypeL11n implements \JsonSerializable, ArrayableInterface } /** - * Get attribute type + * Get language * - * @return int|ContractType + * @return string * * @since 1.0.0 */ - public function getType() : int | ContractType + public function getLanguage() : string { - return $this->type; - } - - /** - * Set type. - * - * @param int $type Type id - * - * @return void - * - * @since 1.0.0 - */ - public function setType(int $type) : void - { - $this->type = $type; + return $this->language; } /** @@ -132,7 +118,12 @@ class ContractTypeL11n implements \JsonSerializable, ArrayableInterface */ public function toArray() : array { - return []; + return [ + 'id' => $this->id, + 'title' => $this->title, + 'type' => $this->type, + 'language' => $this->language, + ]; } /** diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php new file mode 100644 index 0000000..7320305 --- /dev/null +++ b/tests/Controller/ApiControllerTest.php @@ -0,0 +1,247 @@ +app = new class() extends ApplicationAbstract + { + protected string $appName = 'Api'; + }; + + $this->app->dbPool = $GLOBALS['dbpool']; + $this->app->orgId = 1; + $this->app->accountManager = new AccountManager($GLOBALS['session']); + $this->app->appSettings = new CoreSettings(); + $this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/'); + $this->app->dispatcher = new Dispatcher($this->app); + $this->app->eventManager = new EventManager($this->app->dispatcher); + $this->app->eventManager->importFromFile(__DIR__ . '/../../../../Web/Api/Hooks.php'); + $this->app->sessionManager = new HttpSession(36000); + + $account = new Account(); + TestUtils::setMember($account, 'id', 1); + + $permission = new AccountPermission(); + $permission->setUnit(1); + $permission->setApp('backend'); + $permission->setPermission( + PermissionType::READ + | PermissionType::CREATE + | PermissionType::MODIFY + | PermissionType::DELETE + | PermissionType::PERMISSION + ); + + $account->addPermission($permission); + + $this->app->accountManager->add($account); + $this->app->router = new WebRouter(); + + $this->module = $this->app->moduleManager->get('ContractManagement'); + + TestUtils::setMember($this->module, 'app', $this->app); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractTypeCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', 'Test'); + $request->setData('language', ISO639x1Enum::_EN); + + $this->module->apiContractTypeCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->getId()); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractTypeCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->module->apiContractTypeCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractTypeL11nCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', 'Test'); + $request->setData('type', '1'); + $request->setData('language', ISO639x1Enum::_DE); + + $this->module->apiContractTypeL11nCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->getId()); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractTypeL11nCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->module->apiContractTypeL11nCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', 'Title'); + $request->setData('start', '2010-10-09'); + $request->setData('end', '2011-10-09'); + $request->setData('duration', '2'); + $request->setData('type', '1'); + + $this->module->apiContractCreate($request, $response); + self::assertGreaterThan(0, $response->get('')['response']->getId()); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->module->apiContractCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractDocCreate() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + if (!\is_file(__DIR__ . '/test_tmp.pdf')) { + \copy(__DIR__ . '/test.pdf', __DIR__ . '/test_tmp.pdf'); + } + + $request->header->account = 1; + $request->setData('contract', 1); + $request->setData('contract_title', 'Test title'); + + TestUtils::setMember($request, 'files', [ + 'file1' => [ + 'name' => 'test.pdf', + 'type' => 'pdf', + 'tmp_name' => __DIR__ . '/test_tmp.pdf', + 'error' => \UPLOAD_ERR_OK, + 'size' => \filesize(__DIR__ . '/test_tmp.pdf'), + ], + ]); + + $this->module->apiContractDocumentCreate($request, $response); + self::assertCount(1, $response->get('')['response']); + } + + /** + * @covers Modules\ContractManagement\Controller\ApiController + * @group module + */ + public function testApiContractDocCreateInvalidData() : void + { + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('invalid', '1'); + + $this->module->apiContractCreate($request, $response); + self::assertEquals(RequestStatusCode::R_400, $response->header->status); + } +} diff --git a/tests/Controller/test.pdf b/tests/Controller/test.pdf new file mode 100644 index 0000000..4a7256a --- /dev/null +++ b/tests/Controller/test.pdf @@ -0,0 +1,76 @@ +%PDF-1.5 +%µí®û +3 0 obj +<< /Length 4 0 R + /Filter /FlateDecode +>> +stream +xœmPËjÄ0 ¼û+æœX²å” +½·`è9 +›…BC“ìÿSy“@ ‹i¥ÑØ‹yÇb\Ç‘S()ŽJTâ)Ő°^Ñ×ÍøˆìÂ6Å‚õ‚é>ýàâ³Yп +·Ûe1nèÛ8Ÿb”u ˜¶…]͐ð̝hL°‘N5uFê¨Y”Â$II–œ9ü±øRMÈpz4‘úâ$÷I´«~›~²Î:êdžœs¤`…W…(âQKG-+Êsý2¯uÿª»ü¿•´×4IŒ]&F{ƒ•ñ¦I|<åÍ/ΐUe +endstream +endobj +4 0 obj + 224 +endobj +2 0 obj +<< + /ExtGState << + /a0 << /CA 1 /ca 1 >> + >> + /Pattern << /p5 5 0 R >> + /Font << + /f-0-0 6 0 R + >> +>> +endobj +7 0 obj +<< /Type /Page + /Parent 1 0 R + /MediaBox [ 0 0 595 841 ] + /Contents 3 0 R + /Group << + /Type /Group + /S /Transparency + /CS /DeviceRGB + >> + /Resources 2 0 R +>> +endobj +9 0 obj +<< /Length 10 0 R + /Filter /FlateDecode + /Type /XObject + /Subtype /Image + /Width 565 + /Height 532 + /ColorSpace /DeviceGray + /BitsPerComponent 8 +>> +stream +xœíÝg`TÅ೩$t’ÐbB/RB•""Ò»€¨x ýZP@PE”&R¤Di"A@/HÔJ!m³¹ H`“ìî™™÷œ9ßó[6ûͼîœ2EQ´Ä¹dß Á#?ïVÓýMˆ8y–èÔiûºÓIÜ +ýß¶ÖÎèïD4¬TÙFÝ^ŒKJçÞ¶éýZV+žýíˆÖöê4ãêù¤ŒÄŸÝüÝçÝjåBO¢ Îî~ín<~2É’abžŠ8¾sz6Wô7&P~¥Í›wþŠ +qyæjÊhUã%wôw'ây7ïöí´#§ì‰KÚÑê䚩ëçFWADqÍ×jÒ÷¡Ñvý¾X~üïõ_µñótCWD¸*X­ñŒ£{UçåKlô™eýè7GR^~çJŒa˜g6OÞ½N!t…„)Ÿj Nœ3s Ì·OïÙ0¡{%t©„W¿®}¸Ë5/iœmá‚®˜¨S®Gïe¡¢òòØýùÙÑUG™JõØ¸ä¢ØÀ<öm~tíĹ+}¸ü¶ú›jýRI1¡[€Ø)GÓÕwQyäÒGè& öq}eS442)fE7±]öú¿ŸE'&ÅÝ¢4Dé„GûMÂn®³p º1ˆM:ˆBgå™;_н·æyô›»_²nG ¡4-ÇÇÐyÑå²èf!ó³«Îô@· É@éV Ó‘¡‰ôxX‹J +:ˆNFfö6¢{o­yyÄat,²pýut‘tüzÜCg"k·Þ¥{oíÈ=ØÑ™ábÅ®(…n*ò˜kµåè4Øl×[èÖ")*‡AGÁÑ£Ð +F”žWÑ9°98ºÉŒ®à–øe¾ÌÄäâœÍ·pé¦ +Û|<`Èì™36<vçîôÍó`E×âÌÿ¶Nlõ¸ +‰q£R—Oͦ¶œ]= +È_´\…Æm[ô¼hÁŠ{w_Nˆ3›³ZmlÞ4©Š·o⪾ɽ‹Šßûo’9Ý,5«¢ü»õ7iþª +‡î »wË‘‰ÐW¶¶÷3Ø]\öÁ×õ&oQW¯ü4®[ßFÙ_~þì‡;­Õõ_,!êܷ퍴/SÑ%ꍷۗwÏ™27°^¡ìOî”*]·˜Ó-"ßìãPõÙ&²šý|jq¯Êٔɭµ†oš“nŸØ0¿× Àzå_øâc“âÓ]olwä‚´øl†Û<85ºº—¶Õ :ˆ]ÿ–ÑütXÓ×ʽä™ÑW‘|ß”¶ËØ? ´Gãï}Íà’ª:Dû +ÌeÛfªÅÅÄ_úgù½š/çÕÿ²®?'ÿƒÄ´?6§«ÙW¾GŸ;ìK0ošÐ¬€ÄuŠü;Íu-æÂÖåÁÚ½UÚæ+ÚRþaBâ³_›‹ +í)¿ÚÚ¸ ¿Ž*—e¾™j̧Íìt=毹u®P,·½—Õo¤ü{‹9þéÝwD3Ûÿõküf +I|3Uü·V³•åöÖO^övx¿¢n ?å٥ͽŽ6þÓ|#8¿Ï—ôfj*ßVËÚÕUëª+alê'%&>¹´‰ýÀ¦Xä7þåÉx3剽×]ß¹šê_p·_Ÿ|œåÉâ¸Ol¸ +m)æjN¾›©Žœ.mðð\H÷"Lþô=öôC-©?6 ÁY}2»zY“ëf*ÏVa +—^ï:ø1+£^š»æ'×ÃS3ߘé=Ht3ÕEhÃ=õÛ”:E˜ÖÑÓÊY˜Ù‰@¬èeMš›)·ŸD7]²° +ýØO|™bå­ôÊè¿æò@ÏRÜL5¾ZèÜ^Ey î9¬ÝýVØúÌí^Öô3•Sì«móÝ9ì®cžSÊÚ)d;‹YûO9>гÞo¦"¶Uèì…xNþ~óÁs1åŠxÏ‹;ãs —5óúôyì«ÉIùFT+Åm™Ñ„û‘¬ýåcÏ?8ñ@Ï ®”—w‹°çd*)æjðöžÏš‹8 Ò4Ëjï¤%聞 +â¯NéœOg³ŠMÎÊHMö÷À:¢®ûòìxñï[’n¾ýì¿ù@Ï¡[;•õÐÑe±›âw™w›Ä„ +­Àþî:cå¬×ððé‹(Ñôl±êóW +l#5œ\”þ,{ž%áÜþé +D/jaõ˜²Øá/ÀÅ?г…%éÚÚ¯Zzéà%ƒÉM)x‚S+Ü<~`ÍÐ.µ|T¯BrÀ§Ö¿ÒÚ2¸z61‡.mTÄ]ã+‹ÝLNÙï—®oš9t`µb"‡¤ôœZÿf׆µÃ=гMôå½Jjù†Êä¢ädºÏkbÜê¥Ãº”Ïp¸(ùvYÿ‚ ÿ²,—Ä¤SˆÖÓìvp®ÎJSV¥Þ=½åCÞ-禑wq¯°* ãþá)]¼Ý´x…ã¢({Õ×·{äˆ ƒ¼V(ºœ´LíµuWm?Ëý#ÓÚA\f*ù‚«­š›Ï‡‘—¶Õ­SWSO\ó¬4búâý·˜uŒ%~oH¿W4òÛý˜SrhŸqgý´Üš¹Ð7åõö/ûêûŸÏZ³ëh|Ã~û¾ûËfžšyò笸uð°¯+#û×CýGLJε›¿3 dמ3·n³í-͈¿÷çØ6¥ÑMýHòMGJˆŽžZþNß䜷@…ú|9÷Ñðˆ‡I;Oˆ½DóفþðWTN&¥Ã}»¿üɝAžÀûi“sžÂeª7ï1cÙî¢ã9tަ…mþ°†r 2™”fvo^txd>Ô÷u©X÷w>˜¶rDZˆ›Òÿ®d(:bՐ73˜‡(€I©mß“Œè“ëÿ=s,֥ߠ³÷]»)ÿ(”5‹%ê÷Nâ»!U¹Óv|Õã;{ˆ½€ÏY TÅ&&Ì_²+"ž¢òœã¾"»"²ûmþŽ·6g¾vˆ!S¡ +õ;w=mÛÁ›74þ’çNEQÝ‘žÏvÛ¾_❆uËf¶pˆ©Rßï8wõ®ÅB¿-™/ªCÒñ°m£CË[ }S=ŒscËâ\‘½òD7þ_^8ô]Á º +®ãßÞrøFlǁ¹ª=/PIÒµwOá¦Â Ç9%®éŒ›¡ñŒµ0“ŒY‚„uMŽ1Ïýí#[ib³É|ˆmÿt툰ÿÕë§Ÿ#¹n”~dRTÒˁvšaé,¨kr¯Ló!zmP~A7K¦~Â÷ŠÔ½Íbæ™›ú<û¡ùãOøäög¼v[_§Î yÛcRžµ2v Ã§pQ9Ë÷îä_ éš©á^›\SÈŸ³Ãl¹VEŠq)€ǘ¼Ï¤ü©cqûÆd$o;ƒLuÐ5ß$%™Chjs‡Tèæ×§yü_¾ù`J£›_Ÿ"jqŠjô‡Öö¦'YûÝs@QèÖשýðW†0.óЍ¯WÑï û¦È±¬›‡Xµ^‹·5Bkxg_K \ No newline at end of file diff --git a/tests/Models/ContractTest.php b/tests/Models/ContractTest.php new file mode 100644 index 0000000..45b6e47 --- /dev/null +++ b/tests/Models/ContractTest.php @@ -0,0 +1,86 @@ +contract = new Contract(); + } + + /** + * @covers Modules\ContractManagement\Models\Contract + * @group module + */ + public function testDefault() : void + { + self::assertEquals(0, $this->contract->getId()); + self::assertEquals([], $this->contract->getFiles()); + } + + /** + * @covers Modules\ContractManagement\Models\Contract + * @group module + */ + public function testMediaInputOutput() : void + { + $this->contract->addFile(new Media()); + self::assertCount(1, $this->contract->getFiles()); + } + + /** + * @covers Modules\ContractManagement\Models\Contract + * @group module + */ + public function testSerialize() : void + { + $this->contract->title = 'Title'; + $this->contract->description = 'Description'; + $this->contract->duration = 123; + $this->contract->warning = 2; + + $serialized = $this->contract->jsonSerialize(); + unset($serialized['createdAt']); + + self::assertEquals( + [ + 'id' => 0, + 'title' => 'Title', + 'description' => 'Description', + 'start' => null, + 'end' => null, + 'duration' => 123, + 'warning' => 2, + 'responsible' => null, + 'costs' => null, + 'type' => new ContractType(), + ], + $serialized + ); + } +} diff --git a/tests/Models/ContractTypeL11nTest.php b/tests/Models/ContractTypeL11nTest.php new file mode 100644 index 0000000..efa9e53 --- /dev/null +++ b/tests/Models/ContractTypeL11nTest.php @@ -0,0 +1,87 @@ +l11n = new ContractTypeL11n(); + } + + /** + * @covers Modules\ContractManagement\Models\ContractTypeL11n + * @group module + */ + public function testDefault() : void + { + self::assertEquals(0, $this->l11n->getId()); + self::assertEquals('', $this->l11n->title); + self::assertEquals(0, $this->l11n->type); + self::assertEquals(ISO639x1Enum::_EN, $this->l11n->getLanguage()); + } + + /** + * @covers Modules\ContractManagement\Models\ContractTypeL11n + * @group module + */ + public function testNameInputOutput() : void + { + $this->l11n->title = 'TestName'; + self::assertEquals('TestName', $this->l11n->title); + } + + /** + * @covers Modules\ContractManagement\Models\ContractTypeL11n + * @group module + */ + public function testLanguageInputOutput() : void + { + $this->l11n->setLanguage(ISO639x1Enum::_DE); + self::assertEquals(ISO639x1Enum::_DE, $this->l11n->getLanguage()); + } + + /** + * @covers Modules\ContractManagement\Models\ContractTypeL11n + * @group module + */ + public function testSerialize() : void + { + $this->l11n->title = 'Title'; + $this->l11n->type = 2; + $this->l11n->setLanguage(ISO639x1Enum::_DE); + + self::assertEquals( + [ + 'id' => 0, + 'title' => 'Title', + 'type' => 2, + 'language' => ISO639x1Enum::_DE, + ], + $this->l11n->jsonSerialize() + ); + } +} diff --git a/tests/Models/ContractTypeTest.php b/tests/Models/ContractTypeTest.php new file mode 100644 index 0000000..19a6917 --- /dev/null +++ b/tests/Models/ContractTypeTest.php @@ -0,0 +1,75 @@ +type = new ContractType(); + } + + /** + * @covers Modules\ContractManagement\Models\ContractType + * @group module + */ + public function testDefault() : void + { + self::assertEquals(0, $this->type->getId()); + self::assertEquals('', $this->type->getL11n()); + } + + /** + * @covers Modules\ContractManagement\Models\ContractType + * @group module + */ + public function testL11nInputOutput() : void + { + $this->type->setL11n('Test'); + self::assertEquals('Test', $this->type->getL11n()); + + $this->type->setL11n(new ContractTypeL11n(0, 'NewTest')); + self::assertEquals('NewTest', $this->type->getL11n()); + } + + /** + * @covers Modules\ContractManagement\Models\ContractType + * @group module + */ + public function testSerialize() : void + { + $this->type->type = 1; + + self::assertEquals( + [ + 'id' => 0, + 'l11n' => new ContractTypeL11n(), + ], + $this->type->jsonSerialize() + ); + } +} diff --git a/tests/Models/NullContract.php b/tests/Models/NullContract.php deleted file mode 100644 index 8ec6095..0000000 --- a/tests/Models/NullContract.php +++ /dev/null @@ -1,42 +0,0 @@ -getId()); - } -} diff --git a/tests/Models/NullContractType.php b/tests/Models/NullContractType.php deleted file mode 100644 index 1dee31e..0000000 --- a/tests/Models/NullContractType.php +++ /dev/null @@ -1,42 +0,0 @@ -getId()); - } -} diff --git a/tests/Models/NullContractTypeL11n.php b/tests/Models/NullContractTypeL11nTest.php similarity index 100% rename from tests/Models/NullContractTypeL11n.php rename to tests/Models/NullContractTypeL11nTest.php