      1: <?php
      2:
      3: /**
      4:  *
      5:  * Test cases for the AlphaController class.
      6:  *
      7:  * @package alpha::tests
      8:  * @since 1.0
      9:  * @author John Collins <dev@alphaframework.org>
     10:  * @version $Id: AlphaController_Test.php 1817 2014-10-21 22:30:07Z alphadevx $
     11:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     12:  * @copyright Copyright (c) 2014, John Collins (founder of Alpha Framework).
     13:  * All rights reserved.
     14:  *
     15:  * <pre>
     16:  * Redistribution and use in source and binary forms, with or
     17:  * without modification, are permitted provided that the
     18:  * following conditions are met:
     19:  *
     20:  * * Redistributions of source code must retain the above
     21:  *   copyright notice, this list of conditions and the
     22:  *   following disclaimer.
     23:  * * Redistributions in binary form must reproduce the above
     24:  *   copyright notice, this list of conditions and the
     25:  *   following disclaimer in the documentation and/or other
     26:  *   materials provided with the distribution.
     27:  * * Neither the name of the Alpha Framework nor the names
     28:  *   of its contributors may be used to endorse or promote
     29:  *   products derived from this software without specific
     30:  *   prior written permission.
     31:  *
     32:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     33:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     34:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     35:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     36:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     37:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     38:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     39:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     40:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     41:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     42:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     43:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     44:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     45:  * </pre>
     46:  *
     47:  */
     48: class AlphaController_Test extends PHPUnit_Framework_TestCase {
     49:     /**
     50:      * Sample controller for Testing with
     51:      *
     52:      * @var Search
     53:      * @since 1.0
     54:      */
     55:     private $controller;
     56:
     57:     /**
     58:      * An ArticleObject for Testing
     59:      *
     60:      * @var ArticleObject
     61:      * @since 1.0
     62:      */
     63:     private $article;
     64:
     65:     /**
     66:      * A PersonObject for Testing (any business object will do)
     67:      *
     68:      * @var PersonObject
     69:      * @since 1.0
     70:      */
     71:     private $person;
     72:
     73:     /**
     74:      * Test rights group
     75:      *
     76:      * @var RightsObject
     77:      * @since 1.0
     78:      */
     79:     private $group;
     80:
     81:     /**
     82:      * (non-PHPdoc)
     83:      * @see alpha/lib/PEAR/PHPUnit-3.2.9/PHPUnit/Framework/PHPUnit_Framework_TestCase::setUp()
     84:      *
     85:      * @since 1.0
     86:      */
     87:     protected function setUp() {
     88:         $tag = new TagObject();
     89:         $tag->rebuildTable();
     90:
     91:         $denum = new DEnum();
     92:         $denum->rebuildTable();
     93:
     94:         $item = new DEnumItem();
     95:         $item->rebuildTable();
     96:
     97:         $article = new ArticleObject();
     98:         $article->rebuildTable();
     99:
    100:         $this->controller = new Search();
    101:
    102:         $this->person = $this->createPersonObject('unitTestUser');
    103:         $this->person->rebuildTable();
    104:
    105:         $this->article = $this->createArticleObject('unitTestArticle');
    106:         $this->article->rebuildTable();
    107:
    108:         $this->group = new RightsObject();
    109:         $this->group->rebuildTable();
    110:         $this->group->set('name', 'Admin');
    111:         $this->group->save();
    112:
    113:         $lookup = $this->group->getMembers()->getLookup();
    114:         $lookup->setValue(array($_SESSION['currentUser']->getOID(), $this->group->getOID()));
    115:         $lookup->save();
    116:     }
    117:
    118:     /**
    119:      * (non-PHPdoc)
    120:      * @see alpha/lib/PEAR/PHPUnit-3.2.9/PHPUnit/Framework/PHPUnit_Framework_TestCase::tearDown()
    121:      *
    122:      * @since 1.0
    123:      */
    124:     protected function tearDown() {
    125:         $this->controller->abort();
    126:
    127:         $this->article->dropTable();
    128:         unset($this->article);
    129:
    130:         unset($this->controller);
    131:
    132:         $this->person->dropTable();
    133:         unset($this->person);
    134:
    135:         $this->group->dropTable();
    136:         $this->group->dropTable('Person2Rights');
    137:         unset($this->group);
    138:
    139:         $article = new ArticleObject();
    140:         $article->dropTable();
    141:
    142:         $tag = new TagObject();
    143:         $tag->dropTable();
    144:
    145:         $denum = new DEnum();
    146:         $denum->dropTable();
    147:
    148:         $item = new DEnumItem();
    149:         $item->dropTable();
    150:     }
    151:
    152:     /**
    153:      * Creates a person object for Testing
    154:      *
    155:      * @return PersonObject
    156:      * @since 1.0
    157:      */
    158:     private function createPersonObject($name) {
    159:         $person = new PersonObject();
    160:         $person->setDisplayname($name);
    161:         $person->set('email', $name.'@test.com');
    162:         $person->set('password', 'passwordTest');
    163:         $person->set('URL', 'http://unitTestUser/');
    164:
    165:         return $person;
    166:     }
    167:
    168:     /**
    169:      * Creates an article object for Testing
    170:      *
    171:      * @return ArticleObject
    172:      * @since 1.0
    173:      */
    174:     private function createArticleObject($name) {
    175:         $article = new ArticleObject();
    176:         $article->set('title', $name);
    177:         $article->set('description', 'unitTestArticleTagOne unitTestArticleTagTwo');
    178:         $article->set('author', 'unitTestArticleTagOne');
    179:         $article->set('content', 'unitTestArticleTagOne');
    180:
    181:         return $article;
    182:     }
    183:
    184:     /**
    185:      * Testing that objects are being added to the dirtyObjects array correctly
    186:      *
    187:      * @since 1.0
    188:      */
    189:     public function testMarkDirtyAdd() {
    190:         $this->controller->markDirty($this->person);
    191:
    192:         $dirtyObjects = $this->controller->getDirtyObjects();
    193:
    194:         $this->assertEquals('http://unitTestUser/', $dirtyObjects[0]->get('URL'), 'Testing that objects are being added to the dirtyObject array correctly');
    195:     }
    196:
    197:     /**
    198:      * Testing that objects are being added to the dirtyObject array correctly
    199:      * and that this array is in the session being shared by controllers
    200:      *
    201:      * @since 1.0
    202:      */
    203:     public function testMarkDirtySession() {
    204:         $this->person->set('email', 'changed@test.com');
    205:         $this->controller->markDirty($this->person);
    206:
    207:         // calling the constructor of the other controller will check the session
    208:         $controller2 = new Search();
    209:
    210:         $dirty = $controller2->getDirtyObjects();
    211:
    212:         $this->assertEquals('changed@test.com', $dirty[0]->get('email'), 'Testing that objects are being added to the dirtyObject array correctly and that this array is in the session being shared by controllers');
    213:     }
    214:
    215:     /**
    216:      * Testing that objects are being added to the newObjects array correctly
    217:      *
    218:      * @since 1.0
    219:      */
    220:     public function testMarkNewAdd() {
    221:         $this->controller->markNew($this->person);
    222:
    223:         $newObjects = $this->controller->getNewObjects();
    224:
    225:         $this->assertEquals('http://unitTestUser/', $newObjects[0]->get('URL'), 'Testing that objects are being added to the newObject array correctly');
    226:     }
    227:
    228:     /**
    229:      * Testing that objects are being added to the newObjects array correctly
    230:      * and that this array is in the session being shared by controllers
    231:      *
    232:      * @since 1.0
    233:      */
    234:     public function testMarkNewSession() {
    235:         $person = $this->createPersonObject('newuser');
    236:         $person->set('email', 'newuser@test.com');
    237:         $this->controller->markNew($person);
    238:
    239:         // calling the constructor of the other controller will check the session
    240:         $controller2 = new Search();
    241:
    242:         $new = $controller2->getNewObjects();
    243:
    244:         $this->assertEquals('newuser@test.com', $new[0]->get('email'), 'Testing that objects are being added to the newObjects array correctly and that this array is in the session being shared by controllers');
    245:     }
    246:
    247:     /**
    248:      * test cases to see if access rights on controllers are working as expected
    249:      *
    250:      * @since 1.0
    251:      */
    252:     public function testRightsAccess() {
    253:         $this->group = new RightsObject();
    254:         $this->group->set('name', 'testgroup');
    255:         $this->group->save();
    256:
    257:         $this->person->save();
    258:
    259:         $lookup = $this->person->getPropObject('rights')->getLookup();
    260:         $lookup->setValue(array($this->person->getOID(), $this->group->getOID()));
    261:         $lookup->save();
    262:
    263:         $admin = $_SESSION['currentUser'];
    264:         $_SESSION['currentUser'] = $this->person;
    265:
    266:         try {
    267:             $controller = new Search('testgroup');
    268:         }catch (PHPException $e) {
    269:             $this->fail('failed to access a controller that I have access to by rights group membership');
    270:         }
    271:
    272:         $_SESSION['currentUser'] = $admin;
    273:     }
    274:
    275:     /**
    276:      * test the getUnitDuration method for equality
    277:      *
    278:      * @since 1.0
    279:      */
    280:     public function testGetUnitDurationEqual() {
    281:         $controller1 = new Search();
    282:         $controller2 = new Search();
    283:         $controller1->setUnitEndTime(2005, 10, 30, 21, 15, 15);
    284:         $controller2->setUnitEndTime(2005, 10, 30, 21, 15, 15);
    285:
    286:         $this->assertEquals($controller1->getUnitDuration(), $controller2->getUnitDuration(), 'test the getUnitDuration method for equality');
    287:     }
    288:
    289:     /**
    290:      * Test the getUnitDuration method for greater than
    291:      *
    292:      * @since 1.0
    293:      */
    294:     public function testGetUnitDurationGreater() {
    295:         $controller1 = new Search();
    296:         $controller2 = new Search();
    297:         $controller1->setUnitEndTime(2006, 10, 30, 21, 15, 15);
    298:         $controller2->setUnitEndTime(2005, 10, 30, 21, 15, 15);
    299:
    300:         $this->assertTrue($controller1->getUnitDuration() > $controller2->getUnitDuration(), 'Test the getUnitDuration method for greater than');
    301:     }
    302:
    303:     /**
    304:      * Testing the setUnitOfWork method with a bad controller name
    305:      *
    306:      * @since 1.0
    307:      */
    308:     public function testSetUnitOfWorkBadControllerName() {
    309:         try {
    310:             $this->controller->setUnitOfWork(array('Search','Edit','Create','ListAll','BadControllerName'));
    311:             $this->fail('Passed a bad controller name BadControllerName to setUnitOfWork() and did not get the expected exception!');
    312:         }catch (IllegalArguementException $e) {
    313:             $this->assertEquals('', $this->controller->getFirstJob(), 'Testing the setUnitOfWork method with a bad controller name');
    314:         }
    315:     }
    316:
    317:     /**
    318:      * Testing the setUnitOfWork method and getNextJob
    319:      *
    320:      * @since 1.0
    321:      */
    322:     public function testSetUnitOfWorkNext() {
    323:         $this->controller->setName('Search');
    324:         $this->controller->setUnitOfWork(array('Search','Edit','Create','ListAll','Detail'));
    325:
    326:         $this->assertEquals('Edit', $this->controller->getNextJob(), 'Testing the setUnitOfWork method and getNextJob');
    327:     }
    328:
    329:     /**
    330:      * Testing the setUnitOfWork method and getFirstJob
    331:      *
    332:      * @since 1.0
    333:      */
    334:     public function testSetUnitOfWorkFirst() {
    335:         $this->controller->setName('ListAll');
    336:         $this->controller->setUnitOfWork(array('Search','Edit','Create','ListAll','Detail'));
    337:
    338:         $this->assertEquals('Search', $this->controller->getFirstJob(), 'Testing the setUnitOfWork method and getFirstJob');
    339:     }
    340:
    341:     /**
    342:      * Testing the setUnitOfWork method and getPreviousJob
    343:      *
    344:      * @since 1.0
    345:      */
    346:     public function testSetUnitOfWorkPrevious() {
    347:         $this->controller->setName('ListAll');
    348:         $this->controller->setUnitOfWork(array('Search','Edit','Create','ListAll','Detail'));
    349:
    350:         $this->assertEquals('Create', $this->controller->getPreviousJob(), 'Testing the setUnitOfWork method and getPreviousJob');
    351:     }
    352:
    353:     /**
    354:      * Testing the setUnitOfWork method and getLastJob
    355:      *
    356:      * @since 1.0
    357:      */
    358:     public function testSetUnitOfWorkLast() {
    359:         $this->controller->setName('ListAll');
    360:         $this->controller->setUnitOfWork(array('Search','Edit','Create','ListAll','Detail'));
    361:
    362:         $this->assertEquals('Detail', $this->controller->getLastJob(), 'Testing the setUnitOfWork method and getLastJob');
    363:     }
    364:
    365:     /**
    366:      * Testing the commit method for new and dirty objects
    367:      *
    368:      * @since 1.0
    369:      */
    370:     public function testCommit() {
    371:         $this->person->set('email', 'changed@test.com');
    372:         $this->controller->markDirty($this->person);
    373:
    374:         $person = $this->createPersonObject('newuser');
    375:         $person->set('email', 'newuser@test.com');
    376:         $this->controller->markNew($person);
    377:
    378:         try {
    379:             $this->controller->commit();
    380:         }catch (FailedUnitCommitException $e) {
    381:             $this->fail('Failed to commit the unit of work transaction for new and dirty objects');
    382:         }
    383:     }
    384:
    385:     /**
    386:      * Testing that we can load dirty and new objects post commit
    387:      *
    388:      * @since 1.0
    389:      */
    390:     public function testPostCommitLoad() {
    391:         $this->person->set('email', 'changed@test.com');
    392:         $this->controller->markDirty($this->person);
    393:
    394:         $person = $this->createPersonObject('newuser');
    395:         $person->set('email', 'newuser@test.com');
    396:         $this->controller->markNew($person);
    397:
    398:         try {
    399:             $this->controller->commit();
    400:         }catch (FailedUnitCommitException $e) {
    401:             $this->fail('Failed to commit the unit of work transaction for new and dirty objects');
    402:         }
    403:
    404:         $newPerson = new PersonObject();
    405:         try {
    406:             $newPerson->loadByAttribute('email', 'newuser@test.com');
    407:         }catch (BONotFoundException $e) {
    408:             $this->fail('Failed to load the new person that we commited in the unit of work');
    409:         }
    410:
    411:         $dirtyPerson = new PersonObject();
    412:         try {
    413:             $dirtyPerson->loadByAttribute('email', 'changed@test.com');
    414:         }catch (BONotFoundException $e) {
    415:             $this->fail('Failed to load the dirty person that we commited in the unit of work');
    416:         }
    417:     }
    418:
    419:     /**
    420:      * Testing that aborting a unit of work clears the list of new objects
    421:      *
    422:      * @since 1.0
    423:      */
    424:     public function testAbort() {
    425:         $person = $this->createPersonObject('newuser');
    426:         $person->set('email', 'newuser@test.com');
    427:         $this->controller->markNew($person);
    428:
    429:         // calling the constructor of the other controller will check the session
    430:         $controller2 = new Search();
    431:
    432:         $new = $controller2->getNewObjects();
    433:
    434:         $this->assertEquals('newuser@test.com', $new[0]->get('email'), 'Testing that objects are being added to the newObjects array correctly and that this array is in the session being shared by controllers');
    435:
    436:         // now abort the unit of work from the second controller, and confirm that the new object array is empty
    437:         $controller2->abort();
    438:
    439:         $new = $controller2->getNewObjects();
    440:
    441:         $this->assertEquals(0, count($new), 'Testing that aborting a unit of work clears the list of new objects');
    442:     }
    443:
    444:     /**
    445:      * Testing that the AlphaController constructor uses the controller name as the AlphaController->name (job) of the controller
    446:      *
    447:      * @since 1.0
    448:      */
    449:     public function testConstructorJobControllerName() {
    450:         $this->assertEquals('Search', $this->controller->getName(), 'Testing that the AlphaController constructor defaults to using the controller name as the AlphaController->name of the controller');
    451:     }
    452:
    453:     /**
    454:      * Testing that providing a bad BO name returns null
    455:      *
    456:      * @since 1.0
    457:      */
    458:     public function testGetCustomControllerName() {
    459:         $this->assertNull(AlphaController::getCustomControllerName('DoesNotExistObject', 'view'), 'Testing that providing a bad BO name returns null');
    460:     }
    461:
    462:     /**
    463:      * Testing the checkRights method with various account types
    464:      *
    465:      * @since 1.0
    466:      */
    467:     public function testCheckRights() {
    468:         $controller = new Search('Admin');
    469:         $admin = $_SESSION['currentUser'];
    470:         $_SESSION['currentUser'] = null;
    471:
    472:         $this->assertFalse($controller->checkRights(), 'Testing that a user with no session cannot access an Admin controller');
    473:         $controller = new Search('Public');
    474:         $this->assertTrue($controller->checkRights(), 'Testing that a user with no session can access a Public controller');
    475:
    476:         $_SESSION['currentUser'] = $admin;
    477:     }
    478:
    479:     /**
    480:      * Testing the checkSecurityFields method
    481:      *
    482:      * @since 1.0
    483:      */
    484:     public function testCheckSecurityFields() {
    485:         $securityFields = AlphaController::generateSecurityFields();
    486:
    487:         $_REQUEST['var1'] = $securityFields[0];
    488:         $_REQUEST['var2'] = $securityFields[1];
    489:
    490:         $this->assertTrue(AlphaController::checkSecurityFields(), 'Testing the checkSecurityFields method with valid security params');
    491:
    492:         $_REQUEST['var1'] = null;
    493:         $_REQUEST['var2'] = null;
    494:
    495:         $this->assertFalse(AlphaController::checkSecurityFields(), 'Testing the checkSecurityFields method with invalid security params');
    496:     }
    497:
    498:     /**
    499:      * Testing that a bad controller name passed to loadControllerDef will cause an exception
    500:      *
    501:      * @since 1.0
    502:      */
    503:     public function testLoadControllerDef() {
    504:         try {
    505:             $this->controller->loadControllerDef('DoesNotExist');
    506:             $this->fail('Testing that a bad controller name passed to loadControllerDef will cause an exception');
    507:         }catch (IllegalArguementException $e) {
    508:             $this->assertEquals('The class [DoesNotExist] is not defined anywhere!', $e->getMessage(), 'Testing that a bad controller name passed to loadControllerDef will cause an exception');
    509:         }
    510:     }
    511:
    512:     /**
    513:      * Testing that status messages can be shared between controllers via the session
    514:      *
    515:      * @since 1.0
    516:      */
    517:     public function testStatusMessages() {
    518:         $this->controller->setStatusMessage('test message');
    519:
    520:         $controller = new Search();
    521:
    522:         $this->assertEquals('test message', $controller->getStatusMessage(), 'Testing that status messages can be shared between controllers via the session');
    523:     }
    524:
    525:     /**
    526:      * Testing that a BO attached to a controller that contains tags will have those tags mapped to the controller's keywords
    527:      *
    528:      * @since 1.0
    529:      */
    530:     public function testTagsMapToMetaKeywords() {
    531:         AlphaDAO::begin();
    532:         $this->article->save();
    533:         AlphaDAO::commit();
    534:         $tags = $this->article->getPropObject('tags')->getRelatedObjects();
    535:
    536:         $found = false;
    537:         foreach($tags as $tag) {
    538:             if($tag->get('content') == 'unittestarticle') {
    539:                 $found = true;
    540:                 break;
    541:             }
    542:         }
    543:         $this->assertTrue($found, 'Testing the TagObject::tokenize method returns a tag called "unittestarticle"');
    544:
    545:         $this->controller->setBO($this->article);
    546:
    547:         $this->assertEquals('unittestarticle,unittestarticletagone,unittestarticletagtwo', $this->controller->getKeywords(), 'Testing that a BO attached to a controller that contains tags will have those tags mapped to the controller\'s keywords');
    548:
    549:     }
    550:
    551:     /**
    552:      * Testing the checkControllerDefExists method with good and bad input
    553:      *
    554:      * @since 1.2.1
    555:      */
    556:     public function testCheckControllerDefExists() {
    557:
    558:         $this->assertTrue(AlphaController::checkControllerDefExists('/'), 'Testing that the / controller always exists');
    559:         $this->assertTrue(AlphaController::checkControllerDefExists('Search'), 'Testing that a good controller classname returns true');
    560:         $this->assertFalse(AlphaController::checkControllerDefExists('DoesNotExist'), 'Testing that a bad controller classname returns false');
    561:     }
    562:
    563:     /**
    564:      * Testing the checkIfAccessingFromSecureURL method with good and bad input
    565:      *
    566:      * @since 1.2.1
    567:      */
    568:     public function testCheckIfAccessingFromSecureURL() {
    569:
    570:         global $config;
    571:
    572:         $oldToken = $_GET['tk'];
    573:         $oldRequestURI = $_SERVER['REQUEST_URI'];
    574:
    575:         $_GET['tk'] = null;
    576:         $_SERVER['REQUEST_URI'] = '/search';
    577:
    578:         $this->assertFalse(AlphaController::checkIfAccessingFromSecureURL(), 'Testing that the false is returned when tk is unavailable');
    579:
    580:         $_GET['tk'] = '8kqoeebEej0V-FN5-DOdA1HBDDieFcNWTib2yLSUNjq0B0FWzAupIA==';
    581:
    582:         $this->assertTrue(AlphaController::checkIfAccessingFromSecureURL(), 'Testing that the true is returned when tk is set in global _GET array');
    583:
    584:         $_GET['tk'] = null;
    585:         $_SERVER['REQUEST_URI'] = $config->get('app.url').'tk/8kqoeebEej0V-FN5-DOdA1HBDDieFcNWTib2yLSUNjq0B0FWzAupIA==';
    586:
    587:         $this->assertTrue(AlphaController::checkIfAccessingFromSecureURL(), 'Testing that the true is returned when tk is part of the mod_rewrite style URL');
    588:
    589:         $_GET['tk'] = $oldToken;
    590:         $_SERVER['REQUEST_URI'] = $oldRequestURI;
    591:     }
    592: }
    593:
    594: ?>