ValidatorTestCase.php 16 KB
Newer Older
1
<?php
zYne's avatar
zYne committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */

22
/**
zYne's avatar
zYne committed
23
 * Doctrine_Validator_TestCase
24 25 26
 * TestCase for Doctrine's validation component.
 * 
 * @todo More tests to cover the full interface of Doctrine_Validator_ErrorStack.
zYne's avatar
zYne committed
27 28 29 30 31 32 33 34
 *
 * @package     Doctrine
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
35
 */
zYne's avatar
zYne committed
36 37 38 39
class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase 
{
    public function prepareTables() 
    {
romanb's avatar
romanb committed
40 41 42
        $this->tables[] = 'ValidatorTest';
        $this->tables[] = 'ValidatorTest_Person';
        $this->tables[] = 'ValidatorTest_FootballPlayer';
43 44 45
        $this->tables[] = 'ValidatorTest_ClientModel';
        $this->tables[] = 'ValidatorTest_ClientToAddressModel';
        $this->tables[] = 'ValidatorTest_AddressModel';
46 47
        parent::prepareTables();
    }
zYne's avatar
zYne committed
48

zYne's avatar
zYne committed
49 50 51 52 53 54 55 56
    public function testIsValidType() 
    {
        $var = '123';
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
57 58

        $var = 123;
zYne's avatar
zYne committed
59 60 61 62 63
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
64 65

        $var = 123.12;
zYne's avatar
zYne committed
66 67 68 69 70
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
71 72

        $var = '123.12';
zYne's avatar
zYne committed
73 74 75 76 77
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
78 79

        $var = '';
zYne's avatar
zYne committed
80 81 82 83 84
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
85 86

        $var = null;
zYne's avatar
zYne committed
87 88 89 90 91
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'object'));
92 93

        $var = 'str';
zYne's avatar
zYne committed
94 95 96 97 98
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
99 100

        $var = array();
zYne's avatar
zYne committed
101 102 103 104 105
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'object'));
106 107
        
        $var = new Exception();
zYne's avatar
zYne committed
108 109 110 111 112
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'string'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'integer'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'float'));
        $this->assertFalse(Doctrine_Validator::isValidType($var, 'array'));
        $this->assertTrue(Doctrine_Validator::isValidType($var, 'object'));
113 114
    }

zYne's avatar
zYne committed
115

zYne's avatar
zYne committed
116 117
    public function testValidate2() 
    {
118 119 120 121 122 123 124 125
        $test = new ValidatorTest();
        $test->mymixed = "message";
        $test->myrange = 1;
        $test->myregexp = '123a';
        
        $validator = new Doctrine_Validator();
        $validator->validateRecord($test);

zYne's avatar
zYne committed
126
        $stack = $test->errorStack();
127 128 129

        $this->assertTrue($stack instanceof Doctrine_Validator_ErrorStack);

130 131 132 133
        $this->assertTrue(in_array('notnull', $stack['mystring']));
        $this->assertTrue(in_array('notblank', $stack['myemail2']));
        $this->assertTrue(in_array('range', $stack['myrange']));
        $this->assertTrue(in_array('regexp', $stack['myregexp']));
134 135 136 137 138 139
        $test->mystring = 'str';


        $test->save();
    }

zYne's avatar
zYne committed
140 141
    public function testValidate() 
    {
zYne's avatar
zYne committed
142
        $user = $this->connection->getTable('User')->find(4);
143

zYne's avatar
zYne committed
144 145 146 147
        $set = array('password' => 'this is an example of too long password',
                     'loginname' => 'this is an example of too long loginname',
                     'name' => 'valid name',
                     'created' => 'invalid');
148 149
        $user->setArray($set);
        $email = $user->Email;
zYne's avatar
zYne committed
150
        $email->address = 'zYne@invalid';
151 152 153 154 155 156 157

        $this->assertTrue($user->getModified() == $set);

        $validator = new Doctrine_Validator();
        $validator->validateRecord($user);


zYne's avatar
zYne committed
158
        $stack = $user->errorStack();
159 160

        $this->assertTrue($stack instanceof Doctrine_Validator_ErrorStack);
161 162 163
        $this->assertTrue(in_array('length', $stack['loginname']));
        $this->assertTrue(in_array('length', $stack['password']));
        $this->assertTrue(in_array('type', $stack['created']));
164 165

        $validator->validateRecord($email);
zYne's avatar
zYne committed
166
        $stack = $email->errorStack();
167
        $this->assertTrue(in_array('email', $stack['address']));
zYne's avatar
zYne committed
168
        $email->address = 'arnold@example.com';
169 170

        $validator->validateRecord($email);
zYne's avatar
zYne committed
171
        $stack = $email->errorStack();
172

173
        $this->assertTrue(in_array('unique', $stack['address']));
174 175 176 177 178
    }

    /**
     * Tests the Email validator. (Doctrine_Validator_Email)
     */
zYne's avatar
zYne committed
179 180
    public function testIsValidEmail() 
    {
181 182 183

        $validator = new Doctrine_Validator_Email();

184 185 186 187 188 189 190 191 192
        $this->assertFalse($validator->validate("example@example"));
        $this->assertFalse($validator->validate("example@@example"));
        $this->assertFalse($validator->validate("example@example."));
        $this->assertFalse($validator->validate("example@e.."));

        $this->assertTrue($validator->validate("null+doctrine@pookey.co.uk"));
        $this->assertTrue($validator->validate("null@pookey.co.uk"));
        $this->assertTrue($validator->validate("null@pookey.com"));
        $this->assertTrue($validator->validate("null@users.doctrine.pengus.net"));
193 194 195 196 197
    }

    /**
     * Tests saving records with invalid attributes.
     */
zYne's avatar
zYne committed
198 199
    public function testSave() 
    {
zYne's avatar
zYne committed
200
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
201 202 203 204 205 206 207 208
        $user = $this->connection->getTable("User")->find(4);
        try {
            $user->name = "this is an example of too long name not very good example but an example nevertheless";
            $user->save();
        } catch(Doctrine_Validator_Exception $e) {
            $this->assertEqual($e->count(), 1);
            $invalidRecords = $e->getInvalidRecords();
            $this->assertEqual(count($invalidRecords), 1);
zYne's avatar
zYne committed
209
            $stack = $invalidRecords[0]->errorStack();
210
            $this->assertTrue(in_array('length', $stack['name']));
211 212 213 214 215
        }

        try {
            $user = $this->connection->create("User");
            $user->Email->address = "jackdaniels@drinkmore.info...";
zYne's avatar
zYne committed
216
            $user->name = "this is an example of too long user name not very good example but an example nevertheless";
217 218
            $user->save();
            $this->fail();
219
        } catch (Doctrine_Validator_Exception $e) {
220 221
            $this->pass();
            $a = $e->getInvalidRecords();
romanb's avatar
romanb committed
222
            //var_dump($a[1]->getErrorStack());
223 224 225 226 227 228
            $this->assertTrue(is_array($a));
            //var_dump(array_search($user, $a));
            $emailStack = $user->Email->errorStack();
            $userStack  = $user->errorStack();            
            $this->assertTrue(in_array('email', $emailStack['address']));
            $this->assertTrue(in_array('length', $userStack['name']));
229 230
        }
        
zYne's avatar
zYne committed
231
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
232 233 234
    }

    /**
235
     * Tests whether the validate() callback works correctly
236 237
     * in descendants of Doctrine_Record.
     */
zYne's avatar
zYne committed
238 239
    public function testValidationHooks() 
    {
zYne's avatar
zYne committed
240
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
241 242 243
        
        // Tests validate() and validateOnInsert()
        $user = new User();
244 245
         try {
            $user->name = "I'm not The Saint";
246
            $user->password = "1234";
247 248 249 250 251
            $user->save();
        } catch(Doctrine_Validator_Exception $e) {
            $this->assertEqual($e->count(), 1);
            $invalidRecords = $e->getInvalidRecords();
            $this->assertEqual(count($invalidRecords), 1);
zYne's avatar
zYne committed
252 253

            $stack = $invalidRecords[0]->errorStack();
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

            $this->assertEqual($stack->count(), 2);
            $this->assertTrue(in_array('notTheSaint', $stack['name']));  // validate() hook constraint
            $this->assertTrue(in_array('pwNotTopSecret', $stack['password'])); // validateOnInsert() hook constraint
        }
        
        // Tests validateOnUpdate()
        $user = $this->connection->getTable("User")->find(4);
        try {
            $user->name = "The Saint";  // Set correct name
            $user->password = "Top Secret"; // Set correct password
            $user->loginname = "Somebody"; // Wrong login name!
            $user->save();
            $this->fail();
        } catch(Doctrine_Validator_Exception $e) {
            $invalidRecords = $e->getInvalidRecords();
            $this->assertEqual(count($invalidRecords), 1);
            
zYne's avatar
zYne committed
272
            $stack = $invalidRecords[0]->errorStack();
273 274
            
            $this->assertEqual($stack->count(), 1);
275
            $this->assertTrue(in_array('notNobody', $stack['loginname']));  // validateOnUpdate() hook constraint
276
        }
277
        
zYne's avatar
zYne committed
278
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
279
    }
280

281 282 283 284
    /**
     * Tests whether the validateOnInsert() callback works correctly
     * in descendants of Doctrine_Record.
     */
zYne's avatar
zYne committed
285 286
    public function testHookValidateOnInsert() 
    {
zYne's avatar
zYne committed
287
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
288 289 290 291
        
        $user = new User();
        $user->password = "1234";
        
292 293 294
        try {
            $user->save();
            $this->fail();
295
        } catch (Doctrine_Validator_Exception $ex) {
zYne's avatar
zYne committed
296
            $errors = $user->errorStack();
297
            $this->assertTrue(in_array('pwNotTopSecret', $errors['password']));
298 299
        }
        
zYne's avatar
zYne committed
300
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
301
    }
zYne's avatar
zYne committed
302

romanb's avatar
romanb committed
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
    /*
    public function testIssue()
    {
        $this->manager->setAttribute(Doctrine::ATTR_VLD, true);
        
        try {
            $person = new ValidatorTest_Person();
            $person->name = '';  // will raise a validation exception since name must be 'notblank'
            $person->is_football_player = true;
        
            $person->ValidatorTest_FootballPlayer->team_name = 'liverpool';
            $person->ValidatorTest_FootballPlayer->goals_count = 2;
        
            $person->save();
        }
        catch(Doctrine_Validator_Exception $e) {
            $this->fail("test");
            //var_dump($person->getErrorStack());
            //var_dump($person->ValidatorTest_FootballPlayer->getErrorStack());
        }
        
        $this->manager->setAttribute(Doctrine::ATTR_VLD, false);
    }
    */
zYne's avatar
zYne committed
327 328 329

     // @todo move to a separate test file (tests/Validator/UniqueTestCase) .

330
    public function testSetSameUniqueValueOnSameRecordThrowsNoException()
romanb's avatar
romanb committed
331
    {
zYne's avatar
zYne committed
332
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
romanb's avatar
romanb committed
333 334
        
        $r = new ValidatorTest_Person();
335
        $r->identifier = '1234';
romanb's avatar
romanb committed
336 337 338
        $r->save();
        
        $r = $this->connection->getTable('ValidatorTest_Person')->findAll()->getFirst();
339
        $r->identifier = 1234;
romanb's avatar
romanb committed
340 341 342
        try {
           $r->save();
        }
343
        catch (Doctrine_Validator_Exception $e) {
romanb's avatar
romanb committed
344 345 346
           $this->fail("Validator exception raised without reason!");
        }
        
347 348
        $r->delete(); // clean up
        
zYne's avatar
zYne committed
349
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
350 351 352 353
    }
    
    public function testSetSameUniqueValueOnDifferentRecordThrowsException()
    {
zYne's avatar
zYne committed
354
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
        
        $r = new ValidatorTest_Person();
        $r->identifier = '1234';
        $r->save();
        
        $r = new ValidatorTest_Person();
        $r->identifier = 1234;
        try {
            $r->save();
            $this->fail("No validator exception thrown on unique validation.");
        } catch (Doctrine_Validator_Exception $e) {
            $this->pass();
        }
        $r->delete(); // clean up
        
zYne's avatar
zYne committed
370
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
romanb's avatar
romanb committed
371
    }
372 373 374
    
    public function testValidationOnManyToManyRelations()
    {
zYne's avatar
zYne committed
375
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
376 377 378 379 380 381 382
        try {
            $client = new ValidatorTest_ClientModel();
            $client->short_name = 'test';
            $client->ValidatorTest_AddressModel[0]->state = 'az';
            $client->save();
            $this->fail();
        } catch (Doctrine_Validator_Exception $dve) {
zYne's avatar
zYne committed
383
            $s = $dve->getInvalidRecords();
384 385
            $this->assertEqual(1, count($dve->getInvalidRecords()));
            $stack = $client->ValidatorTest_AddressModel[0]->getErrorStack();
zYne's avatar
zYne committed
386

387 388 389 390 391 392 393 394 395 396
            $this->assertTrue(in_array('notnull', $stack['address1']));
            $this->assertTrue(in_array('notblank', $stack['address1']));
            $this->assertTrue(in_array('notnull', $stack['address2']));
            $this->assertTrue(in_array('notnull', $stack['city']));
            $this->assertTrue(in_array('notblank', $stack['city']));
            $this->assertTrue(in_array('usstate', $stack['state']));
            $this->assertTrue(in_array('notnull', $stack['zip']));
            $this->assertTrue(in_array('notblank', $stack['zip']));
        }
        
zYne's avatar
zYne committed
397
        $this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_NONE);
398
    }
zYne's avatar
zYne committed
399

400
}