Guest User

Untitled

a guest
Jun 24th, 2018
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.13 KB | None | 0 0
  1. <?php namespace ApiCore;
  2.  
  3. use ApiExceptionsAPICoreException;
  4. use ApiExceptionsAPITransformationException;
  5. use ApiExceptionsAPIValidationException;
  6. use CrmValidation;
  7. use Component;
  8. use DB;
  9. use AppTraitsApiSaveTrait;
  10. use AppTraitsApiFileTrait;
  11. use AppRepositoriesContractMigrationInterface;
  12. use AppRepositoriesContractClientFeedbackInterface;
  13. use MockeryCountValidatorException;
  14. use ApiLibrariesApiResponse;
  15. use AppRepositoriesContractFileInterface;
  16. use AppRepositoriesContractMasterInterface;
  17. use AppTraitsApiApiDataConversionTrait;
  18. use ClientFeedback;
  19. use MigrationMapping;
  20. use Migration;
  21. use ComponentDetail;
  22. use FavouriteEditorCore;
  23.  
  24. /**
  25. * Class ClientFeedbackCore
  26. *
  27. * @package ApiCore
  28. */
  29. class ClientFeedbackCore
  30. {
  31. use SaveTrait, FileTrait, ApiDataConversionTrait;
  32.  
  33. /**
  34. * @var array
  35. */
  36. private $request = [];
  37.  
  38. /**
  39. * @var
  40. */
  41. private $migrationFlag;
  42.  
  43. /**
  44. * @var string
  45. */
  46. private $table = 'client_feedback';
  47.  
  48. /**
  49. * @var MigrationInterface
  50. */
  51. public $migrationRepo;
  52.  
  53. /**
  54. * @var ClientFeedbackInterface
  55. */
  56. public $clientFeedbackRepo;
  57.  
  58. /**
  59. * @var MasterInterface
  60. */
  61. public $masterRepo;
  62.  
  63. /**
  64. * @var FileInterface
  65. */
  66. public $fileRepo;
  67.  
  68.  
  69. /**
  70. * ClientFeedbackCore constructor.
  71. *
  72. * @param MigrationInterface $migrationInterface
  73. * @param ClientFeedbackInterface $clientFeedbackInterface
  74. * @param MasterInterface $masterInterface
  75. * @param FileInterface $fileInterface
  76. */
  77. public function __construct(
  78. MigrationInterface $migrationInterface,
  79. ClientFeedbackInterface $clientFeedbackInterface,
  80. MasterInterface $masterInterface,
  81. FileInterface $fileInterface
  82. ) {
  83.  
  84. $this->clientFeedbackRepo = $clientFeedbackInterface;
  85. $this->migrationRepo = $migrationInterface;
  86. $this->masterRepo = $masterInterface;
  87. $this->fileRepo = $fileInterface;
  88.  
  89. }
  90.  
  91. /**
  92. * @author pratik.joshi
  93. */
  94. public function init()
  95. {
  96. $this->migrationFlag = getMigrationStatus($this->table);
  97. }
  98.  
  99. /**
  100. * @param $request
  101. * @return array
  102. * @author pratik.joshi
  103. * @desc stores passed data into respective entities and then stores into migration tables. If any issue while insert/update exception is thrown.
  104. */
  105. public function store($request)
  106. {
  107. if ($request == null || empty($request))
  108. {
  109. throw new APIValidationException(trans('messages.exception.validation',['reason'=> 'request param is not provided']));
  110. }
  111.  
  112. $clientFeedbackId = $migrationClientFeedbackId = $favouriteEditorId = null;
  113. $errorMsgWhileSave = null;
  114. $clientFeedback = [];
  115.  
  116. $filesSaved = [];
  117. $categoryNamesForFiles = [];
  118.  
  119. $operation = config('constants.op_type.INSERT');
  120. $this->init();
  121.  
  122. if(
  123. keyExistsAndissetAndNotEmpty('id',$request)
  124. && CrmValidation::getRowCount($this->table, 'id', $request['id'])
  125. ) {
  126. $operation = config('constants.op_type.UPDATE');
  127. }
  128.  
  129. //Step 1: set up data based on the operation
  130. $this->request = $this->convertData($request,$operation);
  131.  
  132. //Step 2: Save data into repo, Not using facade as we cant reuse it, every facade will repeat insert update function
  133. if ($operation == config('constants.op_type.INSERT'))
  134. {
  135. $clientFeedback = $this->insertOrUpdateData($this->request, $this->clientFeedbackRepo);
  136. }
  137. else if($operation == config('constants.op_type.UPDATE'))
  138. {
  139. $clientFeedback = $this->insertOrUpdateData($this->request, $this->clientFeedbackRepo,$this->request['id']);
  140. }
  141.  
  142.  
  143. if ( !keyExistsAndissetAndNotEmpty('client_feedback_id',$clientFeedback[ 'data' ]) )
  144. {
  145. throw new APICoreException(trans('messages.exception.data_not_saved'));
  146. }
  147.  
  148. //If no exception thrown, save id
  149. $clientFeedbackId = $clientFeedback[ 'data' ][ 'client_feedback_id' ];
  150.  
  151. //Step 3: prepare array for mig repo & save()
  152. if($this->migrationFlag && $operation == config('constants.op_type.INSERT'))
  153. {
  154. $this->saveMigrationDataElseThrowException($this->table, $clientFeedback[ 'data' ][ 'client_feedback_id' ], 'client_feedback', $this->request['name']);
  155. }
  156. //If no exception thrown, save id
  157. $paramsForFileSave = [
  158. 'entity_id' => $clientFeedbackId,
  159. 'entity_type' => $this->clientFeedbackRepo->getModelName(),
  160. ];
  161.  
  162. //Step 4: Save datainto file, Save job feedback files with params : files array to save, migration data for files
  163. //The method prepareFileData will be called by passing multiple files, and some needed params for file which internally calls prepareData
  164. //$filePreparedData will be in format : $filePreparedData['field_cf_not_acceptable_four'][0] => whole file array(modified)
  165. $filePreparedData = $this->fileRepo->prepareFileData($this->request[ 'files' ], $this->masterRepo, $paramsForFileSave);
  166. $filesSaved = $this->fileRepo->filesInsertOrUpdate($filePreparedData);
  167. //If any file is not saved, it returns false, throw exception here
  168. if($filesSaved == false)
  169. {
  170. throw new APICoreException(trans('messages.exception.data_not_saved'));
  171. }
  172.  
  173. //Step 5: Save data for file in migra repo.
  174. //For each file type and each file in it, loop, Check for insert data
  175. if(getMigrationStatus('file') && array_key_exists('insert',$filesSaved) && count($filesSaved['insert']))
  176. {
  177. foreach ($filesSaved['insert'] as $singleFileSaved)
  178. {
  179. $fileId = $singleFileSaved['data']['file_id'];
  180. $wbTitle = $filesSaved['extra'][$fileId];
  181. $this->saveMigrationDataElseThrowException('file', $singleFileSaved['data']['file_id'], 'files', $wbTitle);
  182. }
  183. }
  184.  
  185. //We get created by or last modified by
  186. $createdOrLastModifiedBy = keyExistsAndissetAndNotEmpty('created_by',$this->request) ? $this->request['created_by'] : $this->request['last_modified_by'];
  187. //Calling FavouriteEditorCore as we want to save favorite or un-favorite editor
  188. $favouriteEditor = FavouriteEditorCore::core(
  189. $this->request[ 'component_id' ],
  190. $this->request[ 'rating' ],
  191. $this->request[ 'wb_user_id' ], $createdOrLastModifiedBy,
  192. $this->request[ 'same_editor_worker' ]
  193. );
  194.  
  195. if ( !issetAndNotEmpty($favouriteEditor[ 'data' ][ 'favourite_editor_id' ]) )
  196. {
  197. throw new APICoreException(trans('messages.exception.data_not_saved'));
  198. }
  199. //If no exception thrown, save id
  200. $favouriteEditorId = $favouriteEditor[ 'data' ][ 'favourite_editor_id' ];
  201. //repare array for mig repo & save()
  202. if(getMigrationStatus('favourite_editor') && $operation == 'insert')
  203. {
  204. $this->saveMigrationDataElseThrowException('favourite_editor', $favouriteEditor[ 'data' ][ 'favourite_editor_id' ], 'favourite_editor', null);
  205. }
  206. // Check if any error while saving
  207.  
  208. $dataToSave = [
  209. 'client_feedback_id' => $clientFeedbackId,
  210. 'files' => keyExistsAndissetAndNotEmpty('extra',$filesSaved) ? array_keys($filesSaved['extra']) : null,
  211. 'favourite_editor' => $favouriteEditorId
  212. ];
  213. //@todo : return standard response
  214. // Return final response to the WB.
  215. return [
  216. 'data' => $dataToSave,
  217. 'operation' => $operation,
  218. 'status' => ApiResponse::HTTP_OK,
  219. 'error_message' => isset($errorMsgWhileSave) ? $errorMsgWhileSave : null
  220. ];
  221.  
  222. }
  223.  
  224. /**
  225. * @param $request
  226. * @param $operation
  227. * @return array
  228. * @author pratik.joshi
  229. */
  230. public function convertData($request,$operation)
  231. {
  232. if(
  233. ($request == null || empty($request)) ||
  234. ($operation == null || empty($operation))
  235. )
  236. {
  237. throw new APIValidationException(trans('messages.exception.validation',['reason'=> 'either request or operation param is not provided']));
  238. }
  239. //If blank
  240. echo ' >> request';echo json_encode($request);
  241. echo ' >> operation';echo json_encode($operation);
  242.  
  243. //Normal data conversion
  244. $return = $this->basicDataConversion($request, $this->table, $operation);
  245. echo ' >> return after basicDC';echo json_encode($return);
  246. //Custom data conversion
  247. $return[ 'client_code' ] = $request[ 'client_code' ];
  248. $return[ 'component_id' ] = $request[ 'component_id' ];
  249.  
  250. if (isset( $request[ 'rating' ] ) )
  251. {
  252. $return[ 'rating' ] = $request[ 'field_cf_rating_value' ] =$request[ 'rating' ];
  253. }
  254.  
  255. //Add client feedback process status, in insert default it to unread
  256. if($operation == config('constants.op_type.INSERT'))
  257. {
  258. $return[ 'processing_status' ] = config('constants.processing_status.UNREAD');
  259. }
  260. else if($operation == config('constants.op_type.UPDATE'))
  261. {
  262. //@todo : lumen only picks config() in lumen only, explore on how to take it from laravel
  263. //if its set and its valid
  264. $processing_status_config = array_values(config('app_constants.client_feedback_processing_status')); // Get value from app constant
  265. if (isset( $request[ 'processing_status' ] ) && in_array($request['processing_status'],$processing_status_config))
  266. {
  267. $return[ 'processing_status' ] = $request[ 'field_cf_status_value' ] = $request[ 'processing_status' ] ;
  268. }
  269. }
  270.  
  271. //@todo : check for NO
  272. if (isset($request[ 'same_editor_worker' ])) {
  273. if($request[ 'same_editor_worker' ] == 'no')
  274. {
  275. $return[ 'wb_user_id' ] = null;
  276. }
  277. else
  278. {
  279. $return[ 'wb_user_id' ] = ComponentDetail::getLastWorkerId($request[ 'component_id' ]);
  280. }
  281. }
  282.  
  283. //Get job title and prepend with CF
  284. $return[ 'name' ] = 'CF_'.Component::getComponentTitleById($request[ 'component_id' ]);
  285.  
  286. //@todo check with EOS team for params
  287. $dataFieldValues = setDataValues(config('app_constants.data_fields.client_feedback'), $request);
  288. // unset which field we are storing in column
  289. $return[ 'data' ] = json_encode($dataFieldValues);
  290.  
  291. echo ' >> return '.__LINE__;echo json_encode($return);
  292.  
  293. echo ' >> request & return '.__LINE__;echo json_encode(array_merge($request, $return));
  294. return array_merge($request, $return);
  295. }
  296.  
  297.  
  298. /**
  299. * @param $crmTable
  300. * @param $crmId
  301. * @param $wbTable
  302. * @param $wbTitle
  303. * @return mixed
  304. * @throws APICoreException
  305. * @author pratik.joshi
  306. */
  307. public function saveMigrationDataElseThrowException($crmTable, $crmId, $wbTable, $wbTitle)
  308. {
  309. $dataToSave = Migration::prepareData([
  310. 'crm_table' => $crmTable,
  311. 'crm_id' => $crmId,
  312. 'whiteboard_table' => $wbTable,
  313. 'whiteboard_title' => $wbTitle
  314. ]);
  315. //Save into migration repo
  316. $migrationData = $this->insertOrUpdateData($dataToSave, $this->migrationRepo);
  317. if ( !keyExistsAndissetAndNotEmpty('migration_id',$migrationData[ 'data' ]) )
  318. {
  319. throw new APICoreException(trans('messages.exception.data_not_saved'));
  320. }
  321. return $migrationData[ 'data' ]['migration_id'];
  322. }
  323. }
  324.  
  325. <?php
  326.  
  327. use ApiCoreClientFeedbackCore;
  328. use AppRepositoriesContractMigrationInterface;
  329. use AppRepositoriesContractClientFeedbackInterface;
  330. use AppRepositoriesContractFileInterface;
  331. use AppRepositoriesContractMasterInterface;
  332.  
  333. class ClientFeedbackCoreTest extends TestCase
  334. {
  335.  
  336. public $mockClientFeedbackCore;
  337.  
  338. public $requestForConvertData;
  339.  
  340. public $returnBasicDataConversion;
  341.  
  342. public $operation;
  343.  
  344. public $convertedData;
  345.  
  346. public $mockMigrationRepo;
  347.  
  348. public $mockClientFeedbackRepo;
  349.  
  350. public $mockMasterRepo;
  351.  
  352. public $mockFileRepo;
  353.  
  354. public $clientFeedbackCore;
  355.  
  356. public $table;
  357.  
  358. public $saveFailedData;
  359.  
  360. public function setUp()
  361. {
  362. parent::setUp();
  363.  
  364. $this->requestForConvertData = [
  365. 'client_code' => 'SHBI',
  366. 'component_id' => '4556',
  367. 'same_editor_worker' => 'yes',
  368. 'created_by' => '83767',
  369. 'rating' => 'not-acceptable',
  370. 'files' =>
  371. [
  372. 'field_cf_not_acceptable_four' =>
  373. [
  374. 0 =>
  375. [
  376. 'created_by' => '83767',
  377. 'status' => '1',
  378. 'filename' => 'manuscript_0115.docx',
  379. 'filepath' => 'sites/all/files/15-01-17/client_feedback/1484497552_manuscript_011512.docx',
  380. 'filemime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  381. 'filesize' => '116710',
  382. 'timestamp' => '1484497552',
  383. ],
  384. ],
  385. ],
  386. ];
  387.  
  388. $this->returnBasicDataConversion = [
  389. 'crm_table' => 'client_feedback',
  390. 'active' => true,
  391. 'last_modified_date' => '2017-03-30 11:21:23',
  392. 'created_date' => '2017-03-30 11:21:23',
  393. 'created_by' => '83767',
  394. 'last_modified_by' => '83767',
  395. ];
  396.  
  397. $this->convertedData = [
  398. 'client_code' => 'SHBI',
  399. 'component_id' => '4556',
  400. 'same_editor_worker' => 'yes',
  401. 'created_by' => '83767',
  402. 'rating' => 'not-acceptable',
  403. 'files' =>
  404. [
  405. 'field_cf_not_acceptable_four' =>
  406. [
  407. 0 =>
  408. [
  409. 'created_by' => '83767',
  410. 'status' => '1',
  411. 'filename' => 'manuscript_0115.docx',
  412. 'filepath' => 'sites/all/files/15-01-17/client_feedback/1484497552_manuscript_011512.docx',
  413. 'filemime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  414. 'filesize' => '116710',
  415. 'timestamp' => '1484497552',
  416. ],
  417. ],
  418. ],
  419. 'field_cf_rating_value' => 'not-acceptable',
  420. 'crm_table' => 'client_feedback',
  421. 'active' => true,
  422. 'last_modified_date' => '2017-03-30 11:21:23',
  423. 'created_date' => '2017-03-30 11:21:23',
  424. 'last_modified_by' => '83767',
  425. 'processing_status' => 'unread',
  426. 'wb_user_id' => 1131,
  427. 'name' => 'CF_SHBI350',
  428. 'data' => '{"field_cf_acceptable_one":null,"field_cf_acceptable_two":null,"field_cf_acceptable_four":null,"field_cf_outstanding_one":null,"field_cf_outstanding_two":null,"field_cf_acceptable_three":null,"field_cf_outstanding_three":null,"field_cf_not_acceptable_one":null,"field_cf_not_acceptable_two":null,"field_cf_not_acceptable_three":null,"field_cf_acceptable_same_editor":null,"field_cf_outstanding_same_editor":null}',
  429. ];
  430.  
  431. $this->table = 'client_feedback';
  432.  
  433. $this->saveFailedData =
  434. [
  435. 'status' => 400,
  436. 'data' => null,
  437. 'operation' => 'insert',
  438. 'error_message' => 'data save failed error'
  439. ];
  440.  
  441. //Mocking start
  442. $this->mockMigrationRepo = Mockery::mock(MigrationInterface::class);
  443. $this->mockClientFeedbackRepo = Mockery::mock(ClientFeedbackInterface::class);
  444. $this->mockMasterRepo = Mockery::mock(MasterInterface::class);
  445. $this->mockFileRepo = Mockery::mock(FileInterface::class);
  446. //Set mock of the Core class
  447. $this->mockClientFeedbackCore = Mockery::mock(ClientFeedbackCore::class,
  448. [$this->mockMigrationRepo,
  449. $this->mockClientFeedbackRepo,
  450. $this->mockMasterRepo,
  451. $this->mockFileRepo])->makePartial();
  452. //Set expectations
  453. $this->mockClientFeedbackRepo
  454. ->shouldReceive('getModelName')->andReturn($this->table);
  455. //For insert data
  456. $this->mockClientFeedbackCore->shouldReceive('convertData')
  457. ->with($this->requestForConvertData, 'insert')
  458. ->andReturn($this->convertedData);
  459.  
  460.  
  461.  
  462. }
  463.  
  464. public function tearDown()
  465. {
  466. // DO NOT DELETE
  467. Mockery::close();
  468. parent::tearDown();
  469. }
  470.  
  471. /**
  472. * @test
  473. */
  474. public function method_exists()
  475. {
  476. $methodsToCheck = [
  477. 'init',
  478. 'store',
  479. 'convertData',
  480. ];
  481.  
  482. foreach ($methodsToCheck as $method) {
  483. $this->checkMethodExist($this->mockClientFeedbackCore, $method);
  484. }
  485. }
  486.  
  487. /**
  488. * @test
  489. */
  490. public function validate_convert_data_for_insert()
  491. {
  492. //Mock necessary methods
  493. $this->mockClientFeedbackCore->shouldReceive('basicDataConversion')
  494. ->with($this->requestForConvertData, 'client_feedback', 'insert')
  495. ->andReturn($this->returnBasicDataConversion);
  496.  
  497. ComponentDetail::shouldReceive('getLastWorkerId')
  498. ->with($this->requestForConvertData[ 'component_id' ])
  499. ->andReturn(1131);
  500.  
  501. Component::shouldReceive('getComponentTitleById')
  502. ->with($this->requestForConvertData[ 'component_id' ])
  503. ->andReturn('SHBI350');
  504.  
  505. $actual = $this->mockClientFeedbackCore->convertData($this->requestForConvertData, 'insert');
  506. $this->assertEquals($this->convertedData, $actual);
  507.  
  508. }
  509.  
  510. /**
  511. * @test
  512. */
  513. public function validate_convert_data_without_params()
  514. {
  515. $errorMessage = '';
  516. try{
  517. $this->mockClientFeedbackCore->convertData(null, null);
  518. }
  519. catch (Exception $e){
  520. $errorMessage = $e->getMessage();
  521. }
  522. $this->assertEquals('API Validation Error: Reason: either request or operation param is not provided', $errorMessage);
  523.  
  524. }
  525.  
  526. /**
  527. * @test
  528. */
  529. public function validate_store_without_params()
  530. {
  531. $errorMessage = '';
  532. try{
  533. $this->mockClientFeedbackCore->store(null);
  534. }
  535. catch (Exception $e){
  536. $errorMessage = $e->getMessage();
  537. }
  538. $this->assertEquals('API Validation Error: Reason: request param is not provided', $errorMessage);
  539.  
  540. }
  541.  
  542. /**
  543. * @test
  544. */
  545. public function validate_store_client_feedback_save_fail()
  546. {
  547. $errorMessage = '';
  548.  
  549. /* $this->mockClientFeedbackCore->shouldReceive('convertData')
  550. ->with($this->requestForConvertData, 'insert')
  551. ->andReturn($this->convertedData);*/
  552.  
  553. //For insert, mock separately
  554. //@todo : with() attribute does not work here : ->with($this->convertedData,$this->mockClientFeedbackRepo)
  555. $this->mockClientFeedbackCore->shouldReceive('insertOrUpdateData')
  556. ->andReturn($this->saveFailedData);
  557. try {
  558.  
  559. $this->mockClientFeedbackCore->store($this->convertedData);
  560. } catch
  561. (Exception $e) {
  562. $errorMessage = $e->getMessage();
  563. }
  564. $this->assertEquals('MigrationError: Data not saved',
  565. $errorMessage);
  566. }
  567.  
  568.  
  569. public function validate_store_migration_save_fail()
  570. {
  571. //saveMigrationDataElseThrowException
  572. $this->mockClientFeedbackCore->shouldReceive('saveMigrationDataElseThrowException')
  573. ->with('crmTable', 123, 'wbTable', 'wbTitle')
  574. ->andReturn($this->saveFailedData);
  575. try {
  576.  
  577. $this->mockClientFeedbackCore->store($this->convertedData);
  578. } catch
  579. (Exception $e) {
  580. $errorMessage = $e->getMessage();
  581. }
  582. $this->assertEquals('MigrationError: Data not saved',
  583. $errorMessage);
  584.  
  585. }
  586.  
  587. public function validate_store_file_save_fail()
  588. {
  589.  
  590. }
  591.  
  592. public function validate_store_favourite_editor_save_fail()
  593. {
  594.  
  595. }
  596.  
  597. public function validate_store_proper_save()
  598. {
  599.  
  600. }
  601.  
  602. }
  603.  
  604. Approach to make the programmer an “Engineer”
  605. Very lesser bug after development
  606. Software Engineer feel confident about his development
Add Comment
Please, Sign In to add comment