All Data Structures Functions Variables Pages
ZurmoWalkthroughBaseTest.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
41  {
42  private $testModelIds = array();
43 
44  public function setUp()
45  {
46  parent::setUp();
47  Yii::app()->user->clearStates(); //reset session.
48  Yii::app()->clientScript->reset();
49  $_GET = null;
50  $_REQUEST = null;
51  $_POST = null;
52  $_COOKIE = null;
53  }
54 
58  protected function logoutCurrentUserLoginNewUserAndGetByUsername($username)
59  {
60  //clear states does not log the user out.
61  //todo: actually log user out and then back in.
62  Yii::app()->user->clearStates(); //reset session.
63  Yii::app()->language = Yii::app()->getConfigLanguageValue();
64  Yii::app()->timeZoneHelper->setTimeZone(Yii::app()->getConfigTimeZoneValue());
65  $user = User::getByUsername($username);
66  //todo: actually run login?
67  Yii::app()->user->userModel = $user;
68  //Mimic page request to page request behavior where the php cache would be reset.
70  //todo: maybe call GeneralCache forgetAllPHPCache and also expand PermissionsCache
71  //to have flags for php cache forgetting only.
72  //todo: can we somehow use behavior to do these type of loads like languageHelper->load()?
73  //this way we can utilize the same process as the normal production run of the application.
74  Yii::app()->languageHelper->load();
75  Yii::app()->timeZoneHelper->load();
76  return $user;
77  }
78 
83  protected function runControllerWithNoExceptionsAndGetContent($route, $empty = false)
84  {
85  $_SERVER['REQUEST_URI'] = '/index.php';
86  $this->startOutputBuffer();
87  try
88  {
89  Yii::app()->runController($route);
90  $content = $this->endAndGetOutputBuffer();
91  $this->doApplicationScriptPathsAllExist();
92  if ($empty)
93  {
94  $this->assertEmpty($content);
95  }
96  else
97  {
98  $this->assertNotEmpty($content);
99  }
100  return $content;
101  }
102  catch (ExitException $e)
103  {
104  $this->endPrintOutputBufferAndFail();
105  }
106  }
107 
113  {
114  $_SERVER['REQUEST_URI'] = '/index.php';
115  $this->startOutputBuffer();
116  try
117  {
118  Yii::app()->runController($route);
119  $this->endPrintOutputBufferAndFail();
120  }
121  catch (ExitException $e)
122  {
123  $content = $this->endAndGetOutputBuffer();
124  $this->doApplicationScriptPathsAllExist();
125  return $content;
126  }
127  }
128 
134  {
135  $_SERVER['REQUEST_URI'] = '/index.php';
136  $this->startOutputBuffer();
137  try
138  {
139  Yii::app()->runController($route);
140  $this->endPrintOutputBufferAndFail();
141  }
142  catch (RedirectException $e)
143  {
144  $content = $this->endAndGetOutputBuffer();
145  $this->doApplicationScriptPathsAllExist();
146  $this->assertEmpty($content);
147  return $e->getUrl();
148  }
149  }
150 
155  protected function runControllerWithRedirectExceptionAndGetContent($route, $compareUrl = null,
156  $compareUrlContains = false)
157  {
158  $_SERVER['REQUEST_URI'] = '/index.php';
159  $this->startOutputBuffer();
160  try
161  {
162  Yii::app()->runController($route);
163  $this->endPrintOutputBufferAndFail();
164  }
165  catch (RedirectException $e)
166  {
167  $content = $this->endAndGetOutputBuffer();
168  $this->doApplicationScriptPathsAllExist();
169  if ($compareUrl != null)
170  {
171  if ($compareUrlContains)
172  {
173  $pos = strpos($e->getUrl(), $compareUrl);
174  if ($pos === false)
175  {
176  $this->fail($e->getUrl());
177  }
178  }
179  else
180  {
181  $this->assertEquals($compareUrl, $e->getUrl());
182  }
183  }
184  if (!empty($content))
185  {
186  echo $content;
187  }
188  $this->assertEmpty($content);
189  return $content;
190  }
191  }
192 
198  {
199  $_SERVER['REQUEST_URI'] = '/index.php';
200  $this->startOutputBuffer();
201  try
202  {
203  Yii::app()->runController($route);
204  $this->endPrintOutputBufferAndFail();
205  }
207  {
208  $content = $this->endAndGetOutputBuffer();
209  $this->doApplicationScriptPathsAllExist();
210  return $content;
211  }
212  }
213 
219  {
220  $_SERVER['REQUEST_URI'] = '/index.php';
221  $this->startOutputBuffer();
222  try
223  {
224  Yii::app()->runController($route);
225  $this->endPrintOutputBufferAndFail();
226  }
227  catch (NotSupportedException $e)
228  {
229  $content = $this->endAndGetOutputBuffer();
230  $this->doApplicationScriptPathsAllExist();
231  return $content;
232  }
233  }
234 
240  {
241  $_SERVER['REQUEST_URI'] = '/index.php';
242  $this->startOutputBuffer();
243  try
244  {
245  Yii::app()->runController($route);
246  $this->endPrintOutputBufferAndFail();
247  }
248  catch (NotFoundException $e)
249  {
250  $content = $this->endAndGetOutputBuffer();
251  $this->doApplicationScriptPathsAllExist();
252  return $content;
253  }
254  }
255 
256  protected function runControllerShouldResultInAccessFailureAndGetContent($route)
257  {
258  $content = $this->runControllerWithExitExceptionAndGetContent($route);
259  $this->assertContains('You have tried to access a page you do not have access to.', $content);
260  return $content;
261  }
262 
263  protected function runControllerShouldResultInAjaxAccessFailureAndGetContent($route)
264  {
265  $content = $this->runControllerWithExitExceptionAndGetContent($route);
266  $this->assertContains('failure', $content);
267  return $content;
268  }
269 
270  protected function resetGetArray()
271  {
272  $_GET = array();
273  }
274 
275  protected function setGetArray($data)
276  {
277  $this->resetGetArray();
278  foreach ($data as $key => $value)
279  {
280  $_GET[$key] = $value;
281  }
282  }
283 
284  protected function resetPostArray()
285  {
286  $_POST = array();
287  }
288 
289  protected function setPostArray($data)
290  {
291  $this->resetPostArray();
292  foreach ($data as $key => $value)
293  {
294  $_POST[$key] = $value;
295  }
296  // this is to get getIsPostRequest() working in CHTTPRequest
297  $_SERVER['REQUEST_METHOD'] = 'POST';
298  }
299 
300  protected static function getModelIdByModelNameAndName($modelName, $name)
301  {
302  $models = $modelName::getByName($name);
303  return $models[0]->id;
304  }
305 
306  protected function doApplicationScriptPathsAllExist()
307  {
308  foreach (Yii::app()->getClientScript()->getScriptFiles() as $scriptsPathsByPosition)
309  {
310  foreach ($scriptsPathsByPosition as $position => $scriptPath)
311  {
312  if (strpos($scriptPath, 'http') === false)
313  {
314  $this->assertTrue(file_exists($scriptPath), $scriptPath . 'does not exist and it should.');
315  }
316  }
317  }
318  }
319 
320  protected function createCheckBoxCustomFieldByModule($moduleClassName, $name)
321  {
322  $extraPostData = array( 'defaultValue' => '1', 'isAudited' => '1');
323  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'CheckBox', $extraPostData, null, true);
324  }
325 
326  protected function createCurrencyValueCustomFieldByModule($moduleClassName, $name)
327  {
328  $extraPostData = array( 'isAudited' => '1', 'isRequired' => '1');
329  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'CurrencyValue', $extraPostData, null, true);
330  }
331 
332  protected function createDateCustomFieldByModule($moduleClassName, $name)
333  {
334  $extraPostData = array( 'defaultValueCalculationType' => '', 'isAudited' => '1', 'isRequired' => '1');
335  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Date', $extraPostData, null, true);
336  }
337 
338  protected function createDateNotRequiredCustomFieldByModule($moduleClassName, $name)
339  {
340  $extraPostData = array( 'defaultValueCalculationType' => '', 'isAudited' => '1');
341  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Date', $extraPostData, null, true);
342  }
343 
344  protected function createDateTimeCustomFieldByModule($moduleClassName, $name)
345  {
346  $extraPostData = array( 'defaultValueCalculationType' => '', 'isAudited' => '1', 'isRequired' => '1');
347  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'DateTime', $extraPostData, null, true);
348  }
349 
350  protected function createDecimalCustomFieldByModule($moduleClassName, $name)
351  {
352  $extraPostData = array( 'defaultValue' => '123', 'isAudited' => '1', 'isRequired' => '1',
353  'maxLength' => '18', 'precisionLength' => '2');
354  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Decimal', $extraPostData, null, true);
355  }
356 
357  protected function createIntegerCustomFieldByModule($moduleClassName, $name)
358  {
359  $extraPostData = array( 'defaultValue' => '123', 'isAudited' => '1', 'isRequired' => '1',
360  'maxLength' => '11', 'minValue' => '2', 'maxValue' => '400');
361  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Integer', $extraPostData, null, true);
362  }
363 
364  protected function createPhoneCustomFieldByModule($moduleClassName, $name)
365  {
366  $extraPostData = array( 'defaultValue' => '5423', 'isAudited' => '1', 'isRequired' => '1',
367  'maxLength' => '20');
368  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Phone', $extraPostData, null, true);
369  }
370 
371  protected function createTextCustomFieldByModule($moduleClassName, $name)
372  {
373  $extraPostData = array( 'defaultValue' => 'aText', 'isAudited' => '1', 'isRequired' => '1',
374  'maxLength' => '255');
375  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Text', $extraPostData, null, true);
376  }
377 
378  protected function createTextAreaCustomFieldByModule($moduleClassName, $name)
379  {
380  $extraPostData = array( 'defaultValue' => 'aTextDesc', 'isAudited' => '1', 'isRequired' => '1');
381  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'TextArea', $extraPostData, null, true);
382  }
383 
384  protected function createUrlCustomFieldByModule($moduleClassName, $name)
385  {
386  $extraPostData = array( 'defaultValue' => 'http://www.zurmo.com', 'isAudited' => '1', 'isRequired' => '1',
387  'maxLength' => '200');
388  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'Url', $extraPostData, null, true);
389  }
390 
391  protected function createDropDownCustomFieldByModule($moduleClassName, $name)
392  {
393  $extraPostData = array( 'defaultValueOrder' => '2',
394  'isAudited' => '1',
395  'isRequired' => '1',
396  'customFieldDataData' => array(
397  'a', 'b', 'c'
398  ),
399  'customFieldDataLabels' => array(
400  'fr' => array('aFr', 'bFr', 'cFr'),
401  'de' => array('aDe', 'bDe', 'cDe'),
402  )
403  );
404  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'DropDown', $extraPostData, null, true);
405  }
406 
407  protected function createDependentDropDownCustomFieldByModule($moduleClassName, $name)
408  {
409  $customFieldDataData = array('countrylist' => array('aaaa', 'bbbb'),
410  'statelist' => array('aaa1', 'aaa2', 'bbb1', 'bbb2'),
411  'citylist' => array('aa1', 'ab1', 'aa2', 'ab2', 'ba1', 'bb1', 'ba2', 'bb2')
412  );
413  $customFieldDataLabelsFr = array('countrylist' => array('aaaa Fr', 'bbbb Fr'),
414  'statelist' => array('aaa1 Fr', 'aaa2 Fr', 'bbb1 Fr', 'bbb2 Fr'),
415  'citylist' => array('aa1 Fr', 'ab1 Fr', 'aa2 Fr', 'ab2 Fr', 'ba1 Fr', 'bb1 Fr', 'ba2 Fr', 'bb2 Fr')
416  );
417  $customFieldDataLabelsDe = array('countrylist' => array('aaaa De', 'bbbb De'),
418  'statelist' => array('aaa1 De', 'aaa2 De', 'bbb1 De', 'bbb2 De'),
419  'citylist' => array('aa1 De', 'ab1 De', 'aa2 De', 'ab2 De', 'ba1 De', 'bb1 De', 'ba2 De', 'bb2 De')
420  );
421  $extraPostData = array(
422  'defaultValueOrder' => '1',
423  'isAudited' => '1',
424  'isRequired' => '0',
425  'customFieldDataData' => $customFieldDataData[$name],
426  'customFieldDataLabels' => array(
427  'fr' => $customFieldDataLabelsFr[$name],
428  'de' => $customFieldDataLabelsDe[$name],
429  )
430  );
431  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'DropDown', $extraPostData, null, true);
432  }
433 
434  protected function createRadioDropDownCustomFieldByModule($moduleClassName, $name)
435  {
436  $extraPostData = array( 'defaultValueOrder' => '2',
437  'isAudited' => '1',
438  'isRequired' => '1',
439  'customFieldDataData' => array(
440  'd', 'e', 'f'
441  ));
442  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'RadioDropDown', $extraPostData, null, true);
443  }
444 
445  protected function createMultiSelectDropDownCustomFieldByModule($moduleClassName, $name)
446  {
447  $extraPostData = array( 'defaultValueOrder' => '1',
448  'isAudited' => '1',
449  'isRequired' => '1',
450  'customFieldDataData' => array(
451  'ff', 'gg', 'hh', 'rr'
452  ));
453  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'MultiSelectDropDown', $extraPostData, null, true);
454  }
455 
456  protected function createTagCloudCustomFieldByModule($moduleClassName, $name)
457  {
458  $extraPostData = array( 'defaultValueOrder' => '1',
459  'isAudited' => '1',
460  'isRequired' => '1',
461  'customFieldDataData' => array('reading', 'writing', 'surfing', 'gardening'),
462  'customFieldDataLabels' => array(
463  'fr' => array('reading fr', 'writing fr', 'surfing fr', 'gardening fr'),
464  'de' => array('reading de', 'writing de', 'surfing de', 'gardening de'),
465  ));
466  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'TagCloud', $extraPostData, null, true);
467  }
468 
469  protected function createCalculatedNumberCustomFieldByModule($moduleClassName, $name)
470  {
471  $formulaForModule = array('AccountsModule' => 'employees + annualRevenue',
472  'ContactsModule' => 'decimalCstm + integerCstm',
473  'MeetingsModule' => 'decimalCstm - integerCstm',
474  'NotesModule' => 'decimalCstm + integerCstm',
475  'OpportunitiesModule' => 'decimalCstm * integerCstm',
476  'TasksModule' => 'decimalCstm * integerCstm',
477  'ProductTemplatesModule' => 'decimalCstm * integerCstm',
478  'ProductsModule' => 'decimalCstm * integerCstm',
479  'ProjectsModule' => 'decimalCstm * integerCstm');
480 
481  $extraPostData = array('formula' => $formulaForModule[$moduleClassName]);
482  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'CalculatedNumber', $extraPostData, null, true);
483  }
484 
485  protected function createDropDownDependencyCustomFieldByModule($moduleClassName, $name)
486  {
487  $mappingData = array(
488  array('attributeName' => 'countrylistCstm'),
489  array('attributeName' => 'statelistCstm',
490  'valuesToParentValues' => array('aaa1' => 'aaaa',
491  'aaa2' => 'aaaa',
492  'bbb1' => 'bbbb',
493  'bbb2' => 'bbbb'
494  )
495  ),
496  array('attributeName' => 'citylistCstm',
497  'valuesToParentValues' => array('aa1' => 'aaa1',
498  'ab1' => 'aaa1',
499  'aa2' => 'aaa2',
500  'ab2' => 'aaa2',
501  'ba1' => 'bbb1',
502  'bb1' => 'bbb1',
503  'ba2' => 'bbb2',
504  'bb2' => 'bbb2',
505  )
506  ),
507  array('attributeName' => '')
508  );
509 
510  $extraPostData = array('mappingData' => $mappingData);
511  $this->createCustomAttributeWalkthroughSequence($moduleClassName, $name, 'DropDownDependency', $extraPostData, null, true);
512  }
513 
514  protected function createModuleEditBadValidationPostData()
515  {
516  return array('singularModuleLabels' =>
517  array('de' => '', 'it' => 'forget everything but this', 'es' => '', 'en' => '', 'fr' => ''),
518  'pluralModuleLabels' =>
519  array('de' => '', 'it' => '', 'es' => '', 'en' => '', 'fr' => '')
520  );
521  }
522 
523  protected function createModuleEditGoodValidationPostData($singularName)
524  {
525  assert('strtolower($singularName) == $singularName'); // Not Coding Standard
526  $pluralName = $singularName .'s';
527  return array('singularModuleLabels' =>
528  array('de' => $singularName, 'it' => $singularName, 'es' => $singularName,
529  'en' => $singularName, 'fr' => $singularName),
530  'pluralModuleLabels' =>
531  array( 'de' => $pluralName, 'it' => $pluralName, 'es' => $pluralName,
532  'en' => $pluralName, 'fr' => $pluralName)
533  );
534  }
535 
536  protected function createAttributeLabelBadValidationPostData()
537  {
538  return array('de' => '', 'it' => 'forget everything but this', 'es' => '', 'en' => '', 'fr' => ''
539  );
540  }
541 
542  protected function createAttributeLabelGoodValidationPostData($name)
543  {
544  assert('strtolower($name) == $name'); // Not Coding Standard
545  return array('de' => $name . ' de', 'it' => $name . ' it', 'es' => $name . ' es',
546  'en' => $name . ' en', 'fr' => $name . ' fr'
547  );
548  }
549 
550  protected function createCustomAttributeWalkthroughSequence($moduleClassName,
551  $name,
552  $attributeTypeName,
553  $extraPostData,
554  $attributeName = null,
555  $isCustomField = false)
556  {
557  assert('$name[0] == strtolower($name[0])'); // Not Coding Standard
558  assert('is_array($extraPostData)'); // Not Coding Standard
559  $formName = $attributeTypeName . 'AttributeForm';
560  $this->setGetArray(array( 'moduleClassName' => $moduleClassName,
561  'attributeTypeName' => $attributeTypeName,
562  'attributeName' => $attributeName));
563  $this->resetPostArray();
564  //Now test going to the user interface edit view.
565  $content = $this->runControllerWithNoExceptionsAndGetContent('designer/default/attributeEdit');
566 
567  //Now validate save with failed validation.
568  $this->setPostArray(array( 'ajax' => 'edit-form',
569  $formName => array_merge(array(
570  'attributeLabels' => $this->createAttributeLabelBadValidationPostData($name),
571  'attributeName' => $name,
572  ), $extraPostData)));
573  $content = $this->runControllerWithExitExceptionAndGetContent('designer/default/attributeEdit');
574  $this->assertTrue(strlen($content) > 50); //approximate, but should definetely be larger than 50.
575  //Now validate save with successful validation.
576  $this->setPostArray(array( 'ajax' => 'edit-form',
577  $formName => array_merge(array(
578  'attributeLabels' => $this->createAttributeLabelGoodValidationPostData($name),
579  'attributeName' => $name,
580  ), $extraPostData)));
581  $content = $this->runControllerWithExitExceptionAndGetContent('designer/default/attributeEdit');
582  $this->assertEquals('[]', $content);
583 
584  //Now save successfully.
585  $this->setPostArray(array( 'save' => 'Save',
586  $formName => array_merge(array(
587  'attributeLabels' => $this->createAttributeLabelGoodValidationPostData($name),
588  'attributeName' => $name,
589  ), $extraPostData)));
590  $this->runControllerWithRedirectExceptionAndGetContent('designer/default/attributeEdit');
591 
592  //Now confirm everything did in fact save correctly.
594  $modelClassName = $moduleClassName::getPrimaryModelName();
595  $newModel = new $modelClassName(false);
596  $compareData = array(
597  'de' => $name . ' de',
598  'it' => $name . ' it',
599  'es' => $name . ' es',
600  'en' => $name . ' en',
601  'fr' => $name . ' fr',
602  );
603  if ($isCustomField)
604  {
605  $name = $name . 'Cstm';
606  }
607  if ($attributeTypeName != "CalculatedNumber" && $attributeTypeName != "DropDownDependency")
608  {
609  $this->assertEquals(
610  $compareData, $newModel->getAttributeLabelsForAllActiveLanguagesByAttributeName($name));
611  }
612  if ($attributeTypeName != "CalculatedNumber" && $attributeTypeName != "DropDownDependency")
613  {
614  //Now test going to the user interface edit view for the existing attribute.
615  $this->setGetArray(array( 'moduleClassName' => $moduleClassName,
616  'attributeTypeName' => $attributeTypeName,
617  'attributeName' => $name));
618  // if we don't do this attributeName from POST will override and result in duplicate columns.
619  // Frontend also doesn't send attributeName in POST on edit.
620  unset($_POST[$formName]['attributeName']);
621  $content = $this->runControllerWithRedirectExceptionAndGetContent('designer/default/attributeEdit');
622  }
623  }
624 
625  private function buildAttributesArrayFromPostArray($postArray)
626  {
627  $testAttributes = array();
628  foreach ($postArray as $moduleClass => $values)
629  {
630  foreach ($values as $attribute => $value)
631  {
632  if (is_array($value))
633  {
634  $testAttributes[$attribute] = $this->buildAttributesArrayFromPostArray(array('dummy' => $value));
635  }
636  else
637  {
638  $testAttributes[] = $attribute;
639  }
640  }
641  }
642  return $testAttributes;
643  }
644 
652  protected function checkCopyActionResponseAttributeValuesFromPostArray($model, $postArray, $linkClass = null,
653  $controllerId = null)
654  {
656  $model,
657  $this->buildAttributesArrayFromPostArray($postArray),
658  $linkClass,
659  $controllerId
660  );
661  }
662 
672  protected function checkCopyActionResponseAttributeValues($model, $testAttributes, $linkClass = null, $controllerId = null)
673  {
674  $moduleClassName = $model::getModuleClassName();
675  if ($controllerId == null)
676  {
677  $controllerId = $moduleClassName::getDirectoryName();
678  }
679  $this->setGetArray(array('id' => $model->id));
680  $this->resetPostArray();
681  $response = $this->runControllerWithNoExceptionsAndGetContent($controllerId . '/default/copy');
682  return $this->checkResponseAgainstAttributeArray($response, $model, get_class($model), $testAttributes, $linkClass);
683  }
684 
685  private function checkResponseAgainstAttributeArray($response, $model, $class, $testAttributes, $linkClass = null)
686  {
687  $attributesValid = true;
688  $matchRulesBase = array();
689  $matchRulesBase[] = '/id="%testAttribute%".*?>%value%<\/t/';
690  $matchRulesBase[] = '/id="%testAttribute%".*?value="%value%"/';
691  $matchRulesBase[] = '/id="%testAttribute%">.*?<option value="%value%" selected="selected"/s';
692  foreach ($testAttributes as $relation => $testAttribute)
693  {
694  if (is_array($testAttribute))
695  {
696  $attributesValid = $attributesValid && $this->checkResponseAgainstAttributeArray($response, $model->{$relation}, $class . '_' . $relation, $testAttribute, $linkClass);
697  }
698  else
699  {
700  $matchResult = false;
701  $matchRules = str_replace(
702  array('%testAttribute%', '%value%'),
703  array($class . '_' . $testAttribute, str_replace('/', '\/', $model->{$testAttribute})),
704  $matchRulesBase
705  );
706  foreach ($matchRules as $matchRule)
707  {
708  $matchResult = $matchResult || preg_match($matchRule, $response);
709  }
710  $this->assertTrue($matchResult, $class . '_' . $testAttribute . '==' . $model->{$testAttribute});
711  $attributesValid = $attributesValid && $matchResult;
712  }
713  }
714  return (bool)$attributesValid;
715  }
716 
723  protected function updateModelValuesFromPostArray($model, $postArray)
724  {
725  foreach ($postArray as $moduleClass => $attributeValues)
726  {
727  $this->assertInstanceOf($moduleClass, $model);
728  $model->setAttributes($attributeValues);
729  }
730  }
731 
738  protected function assertModelHasValuesFromPostArray($model, $postArray)
739  {
740  foreach ($postArray as $moduleClass => $attributeValues)
741  {
742  $this->assertInstanceOf($moduleClass, $model);
743  foreach ($attributeValues as $attribute => $attributeValue)
744  {
745  if (is_array($attributeValue))
746  {
747  $this->assertModelHasValuesFromPostArray($model->{$attribute}, array(get_class($model->{$attribute}) => $attributeValue));
748  }
749  else
750  {
751  $this->assertEquals($attributeValue, $model->{$attribute});
752  }
753  }
754  }
755  }
756  }
757 ?>
static getByUsername($username)
Definition: User.php:49
static forgetAll($onlyForgetPhpCache=false)
static forgetAll()
runControllerWithRedirectExceptionAndGetContent($route, $compareUrl=null, $compareUrlContains=false)
checkCopyActionResponseAttributeValues($model, $testAttributes, $linkClass=null, $controllerId=null)
updateModelValuesFromPostArray($model, $postArray)
runControllerWithAccessDeniedSecurityExceptionAndGetContent($route)
checkCopyActionResponseAttributeValuesFromPostArray($model, $postArray, $linkClass=null, $controllerId=null)
logoutCurrentUserLoginNewUserAndGetByUsername($username)
assertModelHasValuesFromPostArray($model, $postArray)
runControllerWithNoExceptionsAndGetContent($route, $empty=false)
Generated on Sat Mar 28 2020 07:10:46