Browse Source

Merge branch 'master' into 3.next

Jose Lorenzo Rodriguez 10 years ago
parent
commit
3ed6b06964

+ 4 - 0
src/Auth/BaseAuthenticate.php

@@ -153,6 +153,10 @@ abstract class BaseAuthenticate implements EventListenerInterface
             $finder = key($finder);
         }
 
+        if (!isset($options['username'])) {
+            $options['username'] = $username;
+        }
+
         $query = $table->find($finder, $options);
 
         return $query;

+ 17 - 0
src/Cache/Cache.php

@@ -445,6 +445,23 @@ class Cache
         $engine = static::engine($config);
         return $engine->clear($check);
     }
+    
+    /**
+     * Delete all keys from the cache from all configurations.
+     *
+     * @param bool $check if true will check expiration, otherwise delete all
+     * @return array Status code. For each configuration, it reports the status of the operation
+     */
+    public static function clearAll($check = false)
+    {
+        $status = [];
+        
+        foreach (self::configured() as $config) {
+            $status[$config] = self::clear($check, $config);
+        }
+        
+        return $status;
+    }
 
     /**
      * Delete all keys from the cache belonging to the same group.

+ 2 - 2
src/Controller/Component/CookieComponent.php

@@ -252,7 +252,7 @@ class CookieComponent extends Component
         $cookie = $this->request->cookies[$first];
         $config = $this->configKey($first);
         $this->_loaded[$first] = true;
-        $this->_values[$first] = $this->_decrypt($cookie, $config['encryption']);
+        $this->_values[$first] = $this->_decrypt($cookie, $config['encryption'], $config['key']);
     }
 
     /**
@@ -310,7 +310,7 @@ class CookieComponent extends Component
 
         $this->_response->cookie([
             'name' => $name,
-            'value' => $this->_encrypt($value, $config['encryption']),
+            'value' => $this->_encrypt($value, $config['encryption'], $config['key']),
             'expire' => $expires->format('U'),
             'path' => $config['path'],
             'domain' => $config['domain'],

+ 13 - 8
src/Utility/CookieCryptTrait.php

@@ -46,7 +46,7 @@ trait CookieCryptTrait
      * @param string $value Value to encrypt
      * @param string|bool $encrypt Encryption mode to use. False
      *   disabled encryption.
-     * @param string|null $key Used as the security salt only in this time for tests if specified.
+     * @param string|null $key Used as the security salt if specified.
      * @return string Encoded values
      */
     protected function _encrypt($value, $encrypt, $key = null)
@@ -60,7 +60,7 @@ trait CookieCryptTrait
         $this->_checkCipher($encrypt);
         $prefix = "Q2FrZQ==.";
         $cipher = null;
-        if (!isset($key)) {
+        if ($key === null) {
             $key = $this->_getCookieEncryptionKey();
         }
         if ($encrypt === 'rijndael') {
@@ -95,17 +95,18 @@ trait CookieCryptTrait
      *
      * @param array $values Values to decrypt
      * @param string|bool $mode Encryption mode
+     * @param string|null $key Used as the security salt if specified.
      * @return string decrypted string
      */
-    protected function _decrypt($values, $mode)
+    protected function _decrypt($values, $mode, $key = null)
     {
         if (is_string($values)) {
-            return $this->_decode($values, $mode);
+            return $this->_decode($values, $mode, $key);
         }
 
         $decrypted = [];
         foreach ($values as $name => $value) {
-            $decrypted[$name] = $this->_decode($value, $mode);
+            $decrypted[$name] = $this->_decode($value, $mode, $key);
         }
         return $decrypted;
     }
@@ -115,9 +116,10 @@ trait CookieCryptTrait
      *
      * @param string $value The value to decode & decrypt.
      * @param string|false $encrypt The encryption cipher to use.
+     * @param string|null $key Used as the security salt if specified.
      * @return string Decoded value.
      */
-    protected function _decode($value, $encrypt)
+    protected function _decode($value, $encrypt, $key)
     {
         if (!$encrypt) {
             return $this->_explode($value);
@@ -125,11 +127,14 @@ trait CookieCryptTrait
         $this->_checkCipher($encrypt);
         $prefix = 'Q2FrZQ==.';
         $value = base64_decode(substr($value, strlen($prefix)));
+        if ($key === null) {
+            $key = $this->_getCookieEncryptionKey();
+        }
         if ($encrypt === 'rijndael') {
-            $value = Security::rijndael($value, $this->_getCookieEncryptionKey(), 'decrypt');
+            $value = Security::rijndael($value, $key, 'decrypt');
         }
         if ($encrypt === 'aes') {
-            $value = Security::decrypt($value, $this->_getCookieEncryptionKey());
+            $value = Security::decrypt($value, $key);
         }
         return $this->_explode($value);
     }

+ 1 - 0
src/Utility/Inflector.php

@@ -39,6 +39,7 @@ class Inflector
         '/(x|ch|ss|sh)$/i' => '\1es',
         '/([^aeiouy]|qu)y$/i' => '\1ies',
         '/(hive)$/i' => '\1s',
+        '/(chef)$/i' => '\1s',
         '/(?:([^f])fe|([lre])f)$/i' => '\1\2ves',
         '/sis$/i' => 'ses',
         '/([ti])um$/i' => '\1a',

+ 3 - 2
src/Validation/Validation.php

@@ -83,7 +83,7 @@ class Validation
      */
     public static function notBlank($check)
     {
-        if (empty($check) && $check !== '0') {
+        if (empty($check) && $check !== '0' && $check !== 0) {
             return false;
         }
         return static::_check($check, '/[^\s]+/m');
@@ -481,7 +481,8 @@ class Validation
         if (empty($methods[$type])) {
             throw new \InvalidArgumentException('Unsupported parser type given.');
         }
-        return (Time::{$methods[$type]}($check, $format) !== null);
+        $method = $methods[$type];
+        return (Time::$method($check, $format) !== null);
     }
 
     /**

+ 37 - 0
tests/TestCase/Auth/FormAuthenticateTest.php

@@ -320,6 +320,43 @@ class FormAuthenticateTest extends TestCase
     }
 
     /**
+     * Test using custom finder
+     *
+     * @return void
+     */
+    public function testFinderOptions()
+    {
+        $request = new Request('posts/index');
+        $request->data = [
+            'username' => 'mariano',
+            'password' => 'password'
+        ];
+
+        $this->auth->config([
+            'userModel' => 'AuthUsers',
+            'finder' => 'username'
+        ]);
+
+        $result = $this->auth->authenticate($request, $this->response);
+        $expected = [
+            'id' => 1,
+            'username' => 'mariano',
+        ];
+        $this->assertEquals($expected, $result);
+
+        $this->auth->config([
+            'finder' => ['username' => ['username' => 'nate']]
+        ]);
+
+        $result = $this->auth->authenticate($request, $this->response);
+        $expected = [
+            'id' => 5,
+            'username' => 'nate',
+        ];
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
      * test password hasher settings
      *
      * @return void

+ 31 - 0
tests/TestCase/Cache/CacheTest.php

@@ -558,6 +558,37 @@ class CacheTest extends TestCase
     }
 
     /**
+     * test clearAll() method
+     *
+     * @return void
+     */
+    public function testClearAll()
+    {
+        Cache::config('configTest', [
+            'engine' => 'File',
+            'path' => TMP . 'tests'
+        ]);
+        Cache::config('anotherConfigTest', [
+            'engine' => 'File',
+            'path' => TMP . 'tests'
+        ]);
+
+        Cache::write('key_1', 'hello', 'configTest');
+        Cache::write('key_2', 'hello again', 'anotherConfigTest');
+
+        $this->assertSame(Cache::read('key_1', 'configTest'), 'hello');
+        $this->assertSame(Cache::read('key_2', 'anotherConfigTest'), 'hello again');
+
+        $result = Cache::clearAll();
+        $this->assertTrue($result['configTest']);
+        $this->assertTrue($result['anotherConfigTest']);
+        $this->assertFalse(Cache::read('key_1', 'configTest'));
+        $this->assertFalse(Cache::read('key_2', 'anotherConfigTest'));
+        Cache::drop('configTest');
+        Cache::drop('anotherConfigTest');
+    }
+
+    /**
      * Test toggling enabled state of cache.
      *
      * @return void

+ 39 - 0
tests/TestCase/Controller/Component/CookieComponentTest.php

@@ -363,6 +363,45 @@ class CookieComponentTest extends TestCase
     }
 
     /**
+     * Test writing with a custom encryption key using ConfigKey
+     *
+     * @return void
+     */
+    public function testWriteConfigKeyWithCustomEncryptionKey()
+    {
+        $name = 'sampleCookieTest';
+        $value = 'some data';
+        $encryption = 'aes';
+        $prefix = "Q2FrZQ==.";
+        $key = 'justanotherencryptionkeyjustanotherencryptionkey';
+
+        $this->Cookie->configKey($name, compact('key', 'encryption'));
+        $this->Cookie->write($name, $value);
+
+        $cookie = $this->Controller->response->cookie($name);
+
+        $this->assertEquals($value, Security::decrypt(base64_decode(substr($cookie['value'], strlen($prefix))), $key));
+    }
+
+    /**
+     * Test reading with a custom encryption key using ConfigKey
+     *
+     * @return void
+     */
+    public function testReadConfigKeyWithCustomEncryptionKey()
+    {
+        $name = 'sampleCookieTest';
+        $value = 'some data';
+        $encryption = 'aes';
+        $key = 'justanotherencryptionkeyjustanotherencryptionkey';
+
+        $this->Cookie->configKey($name, compact('key', 'encryption'));
+        $this->Cookie->write($name, $value);
+
+        $this->assertEquals('some data', $this->Cookie->read($name));
+    }
+
+    /**
      * test delete with httpOnly
      *
      * @return void

+ 97 - 0
tests/TestCase/Database/QueryTest.php

@@ -30,6 +30,8 @@ class QueryTest extends TestCase
 
     public $fixtures = ['core.articles', 'core.authors', 'core.comments'];
 
+    public $autoFixtures = false;
+
     const ARTICLE_COUNT = 3;
     const AUTHOR_COUNT = 4;
     const COMMENT_COUNT = 6;
@@ -111,6 +113,7 @@ class QueryTest extends TestCase
      */
     public function testSelectFieldsFromTable()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query->select(['body', 'author_id'])->from('articles')->execute();
         $this->assertEquals(['body' => 'First Article Body', 'author_id' => 1], $result->fetch('assoc'));
@@ -139,6 +142,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAliasedFieldsFromTable()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query->select(['text' => 'comment', 'article_id'])->from('comments')->execute();
         $this->assertEquals(['text' => 'First Comment for First Article', 'article_id' => 1], $result->fetch('assoc'));
@@ -176,6 +180,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAliasedTables()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query->select(['text' => 'a.body', 'a.author_id'])
             ->from(['a' => 'articles'])->execute();
@@ -205,6 +210,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWithJoins()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title', 'name'])
@@ -238,6 +244,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWithJoinsConditions()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title', 'name'])
@@ -280,6 +287,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAliasedJoins()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title', 'name'])
@@ -322,6 +330,7 @@ class QueryTest extends TestCase
      */
     public function testSelectLeftJoin()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $time = new \DateTime('2007-03-18 10:45:23');
         $types = ['created' => 'datetime'];
@@ -353,6 +362,7 @@ class QueryTest extends TestCase
      */
     public function testSelectInnerJoin()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $time = new \DateTime('2007-03-18 10:45:23');
         $types = ['created' => 'datetime'];
@@ -372,6 +382,7 @@ class QueryTest extends TestCase
      */
     public function testSelectRightJoin()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $this->skipIf(
             $this->connection->driver() instanceof \Cake\Database\Driver\Sqlite,
             'SQLite does not support RIGHT joins'
@@ -399,6 +410,7 @@ class QueryTest extends TestCase
      */
     public function testSelectJoinWithCallback()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $types = ['created' => 'datetime'];
         $result = $query
@@ -446,6 +458,7 @@ class QueryTest extends TestCase
      */
     public function testSelectSimpleWhere()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -472,6 +485,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorMoreThan()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['comment'])
@@ -490,6 +504,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorLessThan()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -508,6 +523,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorLessThanEqual()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -525,6 +541,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorMoreThanEqual()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -542,6 +559,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorNotEqual()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -560,6 +578,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorLike()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -578,6 +597,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorLikeExpansion()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -595,6 +615,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorNotLike()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -612,6 +633,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereUnary()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -635,6 +657,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereTypes()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -713,6 +736,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereArrayType()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -735,6 +759,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereArrayTypeEmpty()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -751,6 +776,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereArrayTypeEmptyWithExpression()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -768,6 +794,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrWhere()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -788,6 +815,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAndWhere()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -818,6 +846,7 @@ class QueryTest extends TestCase
      */
     public function testSelectExpressionNesting()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -854,6 +883,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrWhereNoPreviousCondition()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -874,6 +904,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAndWhereNoPreviousCondition()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -894,6 +925,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereUsingClosure()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -941,6 +973,7 @@ class QueryTest extends TestCase
      */
     public function testTupleWithClosureExpression()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('comments')
@@ -969,6 +1002,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAndWhereUsingClosure()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1003,6 +1037,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrWhereUsingClosure()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1041,6 +1076,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereUsingExpressionInField()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1063,6 +1099,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereOperatorMethods()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['title'])
@@ -1238,6 +1275,7 @@ class QueryTest extends TestCase
      */
     public function testInValueCast()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1304,6 +1342,7 @@ class QueryTest extends TestCase
      */
     public function testInValueCast2()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1373,6 +1412,7 @@ class QueryTest extends TestCase
      */
     public function testWhereWithBetween()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1399,6 +1439,7 @@ class QueryTest extends TestCase
      */
     public function testWhereWithBetweenComplex()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1427,6 +1468,7 @@ class QueryTest extends TestCase
      */
     public function testWhereWithBetweenWithExpressionField()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1454,6 +1496,7 @@ class QueryTest extends TestCase
      */
     public function testWhereWithBetweenWithExpressionParts()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1481,6 +1524,7 @@ class QueryTest extends TestCase
      */
     public function testSelectExpressionComposition()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1561,6 +1605,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWhereNot()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1619,6 +1664,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrderBy()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])
@@ -1683,6 +1729,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrderByString()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('articles')
@@ -1701,6 +1748,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrderAsc()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('articles')
@@ -1741,6 +1789,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrderDesc()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->select(['id'])
             ->from('articles')
@@ -1781,6 +1830,7 @@ class QueryTest extends TestCase
      */
     public function testSelectGroup()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
@@ -1811,6 +1861,7 @@ class QueryTest extends TestCase
      */
     public function testSelectDistinct()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['author_id'])
@@ -1833,6 +1884,7 @@ class QueryTest extends TestCase
      */
     public function testSelectDistinctON()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id', 'author_id'])
@@ -1926,6 +1978,7 @@ class QueryTest extends TestCase
      */
     public function testSelectHaving()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
@@ -1958,6 +2011,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOrHaving()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
@@ -2005,6 +2059,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAndHaving()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['total' => 'count(author_id)', 'author_id'])
@@ -2049,6 +2104,7 @@ class QueryTest extends TestCase
      */
     public function testSelectLimit()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query->select('id')->from('articles')->limit(1)->execute();
         $this->assertCount(1, $result);
@@ -2065,6 +2121,7 @@ class QueryTest extends TestCase
      */
     public function testSelectOffset()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $query = new Query($this->connection);
         $result = $query->select('id')->from('comments')
             ->limit(1)
@@ -2123,6 +2180,7 @@ class QueryTest extends TestCase
      */
     public function testSelectPage()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query->select('id')->from('comments')
             ->limit(1)
@@ -2164,6 +2222,7 @@ class QueryTest extends TestCase
      */
     public function testSubqueryInSelect()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Comments');
         $query = new Query($this->connection);
         $subquery = (new Query($this->connection))
             ->select('name')
@@ -2208,6 +2267,7 @@ class QueryTest extends TestCase
      */
     public function testSuqueryInFrom()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $subquery = (new Query($this->connection))
             ->select(['id', 'comment'])
@@ -2236,6 +2296,7 @@ class QueryTest extends TestCase
      */
     public function testSubqueryInWhere()
     {
+        $this->loadFixtures('Authors', 'Comments');
         $query = new Query($this->connection);
         $subquery = (new Query($this->connection))
             ->select(['id'])
@@ -2280,6 +2341,7 @@ class QueryTest extends TestCase
      */
     public function testSubqueryInJoin()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $subquery = (new Query($this->connection))->select('*')->from('authors');
 
         $query = new Query($this->connection);
@@ -2309,6 +2371,7 @@ class QueryTest extends TestCase
      */
     public function testUnion()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Comments');
         $union = (new Query($this->connection))->select(['id', 'title'])->from(['a' => 'articles']);
         $query = new Query($this->connection);
         $result = $query->select(['id', 'comment'])
@@ -2349,6 +2412,7 @@ class QueryTest extends TestCase
      */
     public function testUnionOrderBy()
     {
+        $this->loadFixtures('Articles', 'Comments');
         $this->skipIf(
             ($this->connection->driver() instanceof \Cake\Database\Driver\Sqlite ||
             $this->connection->driver() instanceof \Cake\Database\Driver\Sqlserver),
@@ -2378,6 +2442,7 @@ class QueryTest extends TestCase
      */
     public function testUnionAll()
     {
+        $this->loadFixtures('Authors', 'Articles', 'Comments');
         $union = (new Query($this->connection))->select(['id', 'title'])->from(['a' => 'articles']);
         $query = new Query($this->connection);
         $result = $query->select(['id', 'comment'])
@@ -2409,6 +2474,7 @@ class QueryTest extends TestCase
      */
     public function testDecorateResults()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id', 'title'])
@@ -2461,6 +2527,7 @@ class QueryTest extends TestCase
      */
     public function testDeleteWithFrom()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
 
         $query->delete()
@@ -2483,6 +2550,7 @@ class QueryTest extends TestCase
      */
     public function testDeleteWithAliasedFrom()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
 
         $query->delete()
@@ -2505,6 +2573,7 @@ class QueryTest extends TestCase
      */
     public function testDeleteNoFrom()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
 
         $query->delete('authors')
@@ -2526,6 +2595,7 @@ class QueryTest extends TestCase
      */
     public function testSelectAndDeleteOnSameQuery()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
         $result = $query->select()
             ->delete('authors')
@@ -2543,6 +2613,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateSimple()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
         $query->update('authors')
             ->set('name', 'mark')
@@ -2562,6 +2633,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateMultipleFields()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->update('articles')
             ->set('title', 'mark', 'string')
@@ -2588,6 +2660,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateMultipleFieldsArray()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->update('articles')
             ->set([
@@ -2616,6 +2689,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateWithExpression()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
 
         $expr = $query->newExpr()->equalFields('article_id', 'user_id');
@@ -2643,6 +2717,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateArrayFields()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $date = new \DateTime;
         $query->update('comments')
@@ -2673,6 +2748,7 @@ class QueryTest extends TestCase
      */
     public function testUpdateSetCallable()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $date = new \DateTime;
         $query->update('comments')
@@ -2731,6 +2807,7 @@ class QueryTest extends TestCase
      */
     public function testInsertSimple()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->insert(['title', 'body'])
             ->into('articles')
@@ -2774,6 +2851,7 @@ class QueryTest extends TestCase
      */
     public function testInsertSparseRow()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->insert(['title', 'body'])
             ->into('articles')
@@ -2815,6 +2893,7 @@ class QueryTest extends TestCase
      */
     public function testInsertMultipleRowsSparse()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->insert(['title', 'body'])
             ->into('articles')
@@ -2859,6 +2938,7 @@ class QueryTest extends TestCase
      */
     public function testInsertFromSelect()
     {
+        $this->loadFixtures('Authors', 'Articles');
         $select = (new Query($this->connection))->select(['name', "'some text'", 99])
             ->from('authors')
             ->where(['id' => 1]);
@@ -2912,6 +2992,7 @@ class QueryTest extends TestCase
      */
     public function testInsertFailureMixingTypesArrayFirst()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->insert(['name'])
             ->into('articles')
@@ -2926,6 +3007,7 @@ class QueryTest extends TestCase
      */
     public function testInsertFailureMixingTypesQueryFirst()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->insert(['name'])
             ->into('articles')
@@ -2940,6 +3022,7 @@ class QueryTest extends TestCase
      */
     public function testInsertExpressionValues()
     {
+        $this->loadFixtures('Articles', 'Authors');
         $query = new Query($this->connection);
         $query->insert(['title', 'author_id'])
             ->into('articles')
@@ -3006,6 +3089,7 @@ class QueryTest extends TestCase
      */
     public function testSQLFunctions()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query->select(
             function ($q) {
@@ -3108,6 +3192,7 @@ class QueryTest extends TestCase
      */
     public function testDefaultTypes()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $this->assertEquals([], $query->defaultTypes());
         $types = ['id' => 'integer', 'created' => 'datetime'];
@@ -3136,6 +3221,7 @@ class QueryTest extends TestCase
      */
     public function testBind()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $results = $query->select(['id', 'comment'])
             ->from('comments')
@@ -3163,6 +3249,7 @@ class QueryTest extends TestCase
      */
     public function testAppendSelect()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $sql = $query
             ->select(['id', 'title'])
@@ -3453,6 +3540,7 @@ class QueryTest extends TestCase
      */
     public function testIsNullWithExpressions()
     {
+        $this->loadFixtures('Authors');
         $query = new Query($this->connection);
         $subquery = (new Query($this->connection))
             ->select(['id'])
@@ -3508,6 +3596,7 @@ class QueryTest extends TestCase
      */
     public function testDirectIsNull()
     {
+        $this->loadFixtures('Authors');
         $sql = (new Query($this->connection))
             ->select(['name'])
             ->from(['authors'])
@@ -3532,6 +3621,7 @@ class QueryTest extends TestCase
      */
     public function testDirectIsNotNull()
     {
+        $this->loadFixtures('Authors');
         $sql = (new Query($this->connection))
             ->select(['name'])
             ->from(['authors'])
@@ -3555,6 +3645,7 @@ class QueryTest extends TestCase
      */
     public function testSqlCaseStatement()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $publishedCase = $query
             ->newExpr()
@@ -3642,6 +3733,7 @@ class QueryTest extends TestCase
      */
     public function testUnbufferedQuery()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $result = $query->select(['body', 'author_id'])
             ->from('articles')
@@ -3677,6 +3769,7 @@ class QueryTest extends TestCase
      */
     public function testDeepClone()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->select(['id', 'title' => $query->func()->concat(['title' => 'literal', 'test'])])
             ->from('articles')
@@ -3729,6 +3822,7 @@ class QueryTest extends TestCase
      */
     public function testSelectTypeConversion()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $query
             ->select(['id', 'comment', 'the_date' => 'created'])
@@ -3782,6 +3876,7 @@ class QueryTest extends TestCase
      */
     public function testRemoveJoin()
     {
+        $this->loadFixtures('Articles');
         $query = new Query($this->connection);
         $query->select(['id', 'title'])
             ->from('articles')
@@ -3803,6 +3898,7 @@ class QueryTest extends TestCase
      */
     public function testBetweenExpressionAndTypeMap()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $query->select('id')
             ->from('comments')
@@ -3932,6 +4028,7 @@ class QueryTest extends TestCase
      */
     public function testSelectWithObjFetchType()
     {
+        $this->loadFixtures('Comments');
         $query = new Query($this->connection);
         $result = $query
             ->select(['id'])

+ 1 - 0
tests/TestCase/Network/SocketTest.php

@@ -441,6 +441,7 @@ class SocketTest extends TestCase
     public function testConfigContext()
     {
         $this->skipIf(!extension_loaded('openssl'), 'OpenSSL is not enabled cannot test SSL.');
+        $this->skipIf(!empty(getenv('http_proxy')) || !empty(getenv('https_proxy')), 'Proxy detected and cannot test SSL.');
         $config = [
             'host' => 'smtp.gmail.com',
             'port' => 465,

+ 184 - 156
tests/TestCase/Utility/InflectorTest.php

@@ -89,94 +89,108 @@ class InflectorTest extends TestCase
     /**
      * testInflectingSingulars method
      *
+     * @dataProvider singularizeProvider
      * @return void
      */
-    public function testInflectingSingulars()
+    public function testInflectingSingulars($singular, $plural)
     {
-        $this->assertEquals('categoria', Inflector::singularize('categorias'));
-        $this->assertEquals('menu', Inflector::singularize('menus'));
-        $this->assertEquals('news', Inflector::singularize('news'));
-        $this->assertEquals('food_menu', Inflector::singularize('food_menus'));
-        $this->assertEquals('Menu', Inflector::singularize('Menus'));
-        $this->assertEquals('FoodMenu', Inflector::singularize('FoodMenus'));
-        $this->assertEquals('house', Inflector::singularize('houses'));
-        $this->assertEquals('powerhouse', Inflector::singularize('powerhouses'));
-        $this->assertEquals('quiz', Inflector::singularize('quizzes'));
-        $this->assertEquals('Bus', Inflector::singularize('Buses'));
-        $this->assertEquals('bus', Inflector::singularize('buses'));
-        $this->assertEquals('matrix_row', Inflector::singularize('matrix_rows'));
-        $this->assertEquals('matrix', Inflector::singularize('matrices'));
-        $this->assertEquals('vertex', Inflector::singularize('vertices'));
-        $this->assertEquals('index', Inflector::singularize('indices'));
-        $this->assertEquals('Alias', Inflector::singularize('Aliases'));
-        $this->assertEquals('Alias', Inflector::singularize('Alias'));
-        $this->assertEquals('Media', Inflector::singularize('Media'));
-        $this->assertEquals('NodeMedia', Inflector::singularize('NodeMedia'));
-        $this->assertEquals('alumnus', Inflector::singularize('alumni'));
-        $this->assertEquals('bacillus', Inflector::singularize('bacilli'));
-        $this->assertEquals('cactus', Inflector::singularize('cacti'));
-        $this->assertEquals('focus', Inflector::singularize('foci'));
-        $this->assertEquals('fungus', Inflector::singularize('fungi'));
-        $this->assertEquals('nucleus', Inflector::singularize('nuclei'));
-        $this->assertEquals('octopus', Inflector::singularize('octopuses'));
-        $this->assertEquals('radius', Inflector::singularize('radii'));
-        $this->assertEquals('stimulus', Inflector::singularize('stimuli'));
-        $this->assertEquals('syllabus', Inflector::singularize('syllabi'));
-        $this->assertEquals('terminus', Inflector::singularize('termini'));
-        $this->assertEquals('virus', Inflector::singularize('viruses'));
-        $this->assertEquals('person', Inflector::singularize('people'));
-        $this->assertEquals('glove', Inflector::singularize('gloves'));
-        $this->assertEquals('dove', Inflector::singularize('doves'));
-        $this->assertEquals('life', Inflector::singularize('lives'));
-        $this->assertEquals('knife', Inflector::singularize('knives'));
-        $this->assertEquals('wolf', Inflector::singularize('wolves'));
-        $this->assertEquals('slave', Inflector::singularize('slaves'));
-        $this->assertEquals('shelf', Inflector::singularize('shelves'));
-        $this->assertEquals('taxi', Inflector::singularize('taxis'));
-        $this->assertEquals('tax', Inflector::singularize('taxes'));
-        $this->assertEquals('Tax', Inflector::singularize('Taxes'));
-        $this->assertEquals('AwesomeTax', Inflector::singularize('AwesomeTaxes'));
-        $this->assertEquals('fax', Inflector::singularize('faxes'));
-        $this->assertEquals('wax', Inflector::singularize('waxes'));
-        $this->assertEquals('niche', Inflector::singularize('niches'));
-        $this->assertEquals('cave', Inflector::singularize('caves'));
-        $this->assertEquals('grave', Inflector::singularize('graves'));
-        $this->assertEquals('wave', Inflector::singularize('waves'));
-        $this->assertEquals('bureau', Inflector::singularize('bureaus'));
-        $this->assertEquals('genetic_analysis', Inflector::singularize('genetic_analyses'));
-        $this->assertEquals('doctor_diagnosis', Inflector::singularize('doctor_diagnoses'));
-        $this->assertEquals('paranthesis', Inflector::singularize('parantheses'));
-        $this->assertEquals('Cause', Inflector::singularize('Causes'));
-        $this->assertEquals('colossus', Inflector::singularize('colossuses'));
-        $this->assertEquals('diagnosis', Inflector::singularize('diagnoses'));
-        $this->assertEquals('basis', Inflector::singularize('bases'));
-        $this->assertEquals('analysis', Inflector::singularize('analyses'));
-        $this->assertEquals('curve', Inflector::singularize('curves'));
-        $this->assertEquals('cafe', Inflector::singularize('cafes'));
-        $this->assertEquals('roof', Inflector::singularize('roofs'));
-        $this->assertEquals('foe', Inflector::singularize('foes'));
-        $this->assertEquals('database', Inflector::singularize('databases'));
-        $this->assertEquals('cookie', Inflector::singularize('cookies'));
-        $this->assertEquals('thief', Inflector::singularize('thieves'));
-        $this->assertEquals('potato', Inflector::singularize('potatoes'));
-        $this->assertEquals('hero', Inflector::singularize('heroes'));
-        $this->assertEquals('buffalo', Inflector::singularize('buffaloes'));
-        $this->assertEquals('baby', Inflector::singularize('babies'));
-        $this->assertEquals('tooth', Inflector::singularize('teeth'));
-        $this->assertEquals('goose', Inflector::singularize('geese'));
-        $this->assertEquals('foot', Inflector::singularize('feet'));
-        $this->assertEquals('objective', Inflector::singularize('objectives'));
-        $this->assertEquals('archive', Inflector::singularize('archives'));
-        $this->assertEquals('brief', Inflector::singularize('briefs'));
-        $this->assertEquals('quota', Inflector::singularize('quotas'));
-        $this->assertEquals('curve', Inflector::singularize('curves'));
-        $this->assertEquals('body_curve', Inflector::singularize('body_curves'));
-        $this->assertEquals('metadata', Inflector::singularize('metadata'));
-        $this->assertEquals('files_metadata', Inflector::singularize('files_metadata'));
-        $this->assertEquals('address', Inflector::singularize('addresses'));
-        $this->assertEquals('sieve', Inflector::singularize('sieves'));
-        $this->assertEquals('blue_octopus', Inflector::singularize('blue_octopuses'));
-        $this->assertEquals('', Inflector::singularize(''));
+        $this->assertEquals($singular, Inflector::singularize($plural));
+    }
+
+    /**
+     * Data provider for testing singularize()
+     *
+     * @return array
+     */
+    public function singularizeProvider()
+    {
+        return [
+            ['categoria', 'categorias'],
+            ['menu', 'menus'],
+            ['news', 'news'],
+            ['food_menu', 'food_menus'],
+            ['Menu', 'Menus'],
+            ['FoodMenu', 'FoodMenus'],
+            ['house', 'houses'],
+            ['powerhouse', 'powerhouses'],
+            ['quiz', 'quizzes'],
+            ['Bus', 'Buses'],
+            ['bus', 'buses'],
+            ['matrix_row', 'matrix_rows'],
+            ['matrix', 'matrices'],
+            ['vertex', 'vertices'],
+            ['index', 'indices'],
+            ['Alias', 'Aliases'],
+            ['Alias', 'Alias'],
+            ['Media', 'Media'],
+            ['NodeMedia', 'NodeMedia'],
+            ['alumnus', 'alumni'],
+            ['bacillus', 'bacilli'],
+            ['cactus', 'cacti'],
+            ['focus', 'foci'],
+            ['fungus', 'fungi'],
+            ['nucleus', 'nuclei'],
+            ['octopus', 'octopuses'],
+            ['radius', 'radii'],
+            ['stimulus', 'stimuli'],
+            ['syllabus', 'syllabi'],
+            ['terminus', 'termini'],
+            ['virus', 'viruses'],
+            ['person', 'people'],
+            ['glove', 'gloves'],
+            ['dove', 'doves'],
+            ['life', 'lives'],
+            ['knife', 'knives'],
+            ['wolf', 'wolves'],
+            ['slave', 'slaves'],
+            ['shelf', 'shelves'],
+            ['taxi', 'taxis'],
+            ['tax', 'taxes'],
+            ['Tax', 'Taxes'],
+            ['AwesomeTax', 'AwesomeTaxes'],
+            ['fax', 'faxes'],
+            ['wax', 'waxes'],
+            ['niche', 'niches'],
+            ['cave', 'caves'],
+            ['grave', 'graves'],
+            ['wave', 'waves'],
+            ['bureau', 'bureaus'],
+            ['genetic_analysis', 'genetic_analyses'],
+            ['doctor_diagnosis', 'doctor_diagnoses'],
+            ['paranthesis', 'parantheses'],
+            ['Cause', 'Causes'],
+            ['colossus', 'colossuses'],
+            ['diagnosis', 'diagnoses'],
+            ['basis', 'bases'],
+            ['analysis', 'analyses'],
+            ['curve', 'curves'],
+            ['cafe', 'cafes'],
+            ['roof', 'roofs'],
+            ['foe', 'foes'],
+            ['database', 'databases'],
+            ['cookie', 'cookies'],
+            ['thief', 'thieves'],
+            ['potato', 'potatoes'],
+            ['hero', 'heroes'],
+            ['buffalo', 'buffaloes'],
+            ['baby', 'babies'],
+            ['tooth', 'teeth'],
+            ['goose', 'geese'],
+            ['foot', 'feet'],
+            ['objective', 'objectives'],
+            ['archive', 'archives'],
+            ['brief', 'briefs'],
+            ['quota', 'quotas'],
+            ['curve', 'curves'],
+            ['body_curve', 'body_curves'],
+            ['metadata', 'metadata'],
+            ['files_metadata', 'files_metadata'],
+            ['address', 'addresses'],
+            ['sieve', 'sieves'],
+            ['blue_octopus', 'blue_octopuses'],
+            ['chef', 'chefs'],
+            ['', ''],
+        ];
     }
 
     /**
@@ -204,80 +218,94 @@ class InflectorTest extends TestCase
     /**
      * testInflectingPlurals method
      *
+     * @dataProvider pluralizeProvider
      * @return void
      */
-    public function testInflectingPlurals()
+    public function testInflectingPlurals($plural, $singular)
+    {
+        $this->assertEquals($plural, Inflector::pluralize($singular));
+    }
+
+    /**
+     * Data provider for testing pluralize()
+     *
+     * @return array
+     */
+    public function pluralizeProvider()
     {
-        $this->assertEquals('axmen', Inflector::pluralize('axman'));
-        $this->assertEquals('men', Inflector::pluralize('man'));
-        $this->assertEquals('women', Inflector::pluralize('woman'));
-        $this->assertEquals('humans', Inflector::pluralize('human'));
-        $this->assertEquals('axmen', Inflector::pluralize('axman'));
-        $this->assertEquals('men', Inflector::pluralize('man'));
-        $this->assertEquals('women', Inflector::pluralize('woman'));
-        $this->assertEquals('humans', Inflector::pluralize('human'));
-        $this->assertEquals('categorias', Inflector::pluralize('categoria'));
-        $this->assertEquals('houses', Inflector::pluralize('house'));
-        $this->assertEquals('powerhouses', Inflector::pluralize('powerhouse'));
-        $this->assertEquals('Buses', Inflector::pluralize('Bus'));
-        $this->assertEquals('buses', Inflector::pluralize('bus'));
-        $this->assertEquals('menus', Inflector::pluralize('menu'));
-        $this->assertEquals('news', Inflector::pluralize('news'));
-        $this->assertEquals('food_menus', Inflector::pluralize('food_menu'));
-        $this->assertEquals('Menus', Inflector::pluralize('Menu'));
-        $this->assertEquals('FoodMenus', Inflector::pluralize('FoodMenu'));
-        $this->assertEquals('quizzes', Inflector::pluralize('quiz'));
-        $this->assertEquals('matrix_rows', Inflector::pluralize('matrix_row'));
-        $this->assertEquals('matrices', Inflector::pluralize('matrix'));
-        $this->assertEquals('vertices', Inflector::pluralize('vertex'));
-        $this->assertEquals('indices', Inflector::pluralize('index'));
-        $this->assertEquals('Aliases', Inflector::pluralize('Alias'));
-        $this->assertEquals('Aliases', Inflector::pluralize('Aliases'));
-        $this->assertEquals('Media', Inflector::pluralize('Media'));
-        $this->assertEquals('NodeMedia', Inflector::pluralize('NodeMedia'));
-        $this->assertEquals('alumni', Inflector::pluralize('alumnus'));
-        $this->assertEquals('bacilli', Inflector::pluralize('bacillus'));
-        $this->assertEquals('cacti', Inflector::pluralize('cactus'));
-        $this->assertEquals('foci', Inflector::pluralize('focus'));
-        $this->assertEquals('fungi', Inflector::pluralize('fungus'));
-        $this->assertEquals('nuclei', Inflector::pluralize('nucleus'));
-        $this->assertEquals('octopuses', Inflector::pluralize('octopus'));
-        $this->assertEquals('radii', Inflector::pluralize('radius'));
-        $this->assertEquals('stimuli', Inflector::pluralize('stimulus'));
-        $this->assertEquals('syllabi', Inflector::pluralize('syllabus'));
-        $this->assertEquals('termini', Inflector::pluralize('terminus'));
-        $this->assertEquals('viruses', Inflector::pluralize('virus'));
-        $this->assertEquals('people', Inflector::pluralize('person'));
-        $this->assertEquals('people', Inflector::pluralize('people'));
-        $this->assertEquals('gloves', Inflector::pluralize('glove'));
-        $this->assertEquals('crises', Inflector::pluralize('crisis'));
-        $this->assertEquals('taxes', Inflector::pluralize('tax'));
-        $this->assertEquals('waves', Inflector::pluralize('wave'));
-        $this->assertEquals('bureaus', Inflector::pluralize('bureau'));
-        $this->assertEquals('cafes', Inflector::pluralize('cafe'));
-        $this->assertEquals('roofs', Inflector::pluralize('roof'));
-        $this->assertEquals('foes', Inflector::pluralize('foe'));
-        $this->assertEquals('cookies', Inflector::pluralize('cookie'));
-        $this->assertEquals('wolves', Inflector::pluralize('wolf'));
-        $this->assertEquals('thieves', Inflector::pluralize('thief'));
-        $this->assertEquals('potatoes', Inflector::pluralize('potato'));
-        $this->assertEquals('heroes', Inflector::pluralize('hero'));
-        $this->assertEquals('buffaloes', Inflector::pluralize('buffalo'));
-        $this->assertEquals('teeth', Inflector::pluralize('tooth'));
-        $this->assertEquals('geese', Inflector::pluralize('goose'));
-        $this->assertEquals('feet', Inflector::pluralize('foot'));
-        $this->assertEquals('objectives', Inflector::pluralize('objective'));
-        $this->assertEquals('briefs', Inflector::pluralize('brief'));
-        $this->assertEquals('quotas', Inflector::pluralize('quota'));
-        $this->assertEquals('curves', Inflector::pluralize('curve'));
-        $this->assertEquals('body_curves', Inflector::pluralize('body_curve'));
-        $this->assertEquals('metadata', Inflector::pluralize('metadata'));
-        $this->assertEquals('files_metadata', Inflector::pluralize('files_metadata'));
-        $this->assertEquals('stadia', Inflector::pluralize('stadia'));
-        $this->assertEquals('Addresses', Inflector::pluralize('Address'));
-        $this->assertEquals('sieves', Inflector::pluralize('sieve'));
-        $this->assertEquals('blue_octopuses', Inflector::pluralize('blue_octopus'));
-        $this->assertEquals('', Inflector::pluralize(''));
+        return [
+            ['axmen', 'axman'],
+            ['men', 'man'],
+            ['women', 'woman'],
+            ['humans', 'human'],
+            ['axmen', 'axman'],
+            ['men', 'man'],
+            ['women', 'woman'],
+            ['humans', 'human'],
+            ['categorias', 'categoria'],
+            ['houses', 'house'],
+            ['powerhouses', 'powerhouse'],
+            ['Buses', 'Bus'],
+            ['buses', 'bus'],
+            ['menus', 'menu'],
+            ['news', 'news'],
+            ['food_menus', 'food_menu'],
+            ['Menus', 'Menu'],
+            ['FoodMenus', 'FoodMenu'],
+            ['quizzes', 'quiz'],
+            ['matrix_rows', 'matrix_row'],
+            ['matrices', 'matrix'],
+            ['vertices', 'vertex'],
+            ['indices', 'index'],
+            ['Aliases', 'Alias'],
+            ['Aliases', 'Aliases'],
+            ['Media', 'Media'],
+            ['NodeMedia', 'NodeMedia'],
+            ['alumni', 'alumnus'],
+            ['bacilli', 'bacillus'],
+            ['cacti', 'cactus'],
+            ['foci', 'focus'],
+            ['fungi', 'fungus'],
+            ['nuclei', 'nucleus'],
+            ['octopuses', 'octopus'],
+            ['radii', 'radius'],
+            ['stimuli', 'stimulus'],
+            ['syllabi', 'syllabus'],
+            ['termini', 'terminus'],
+            ['viruses', 'virus'],
+            ['people', 'person'],
+            ['people', 'people'],
+            ['gloves', 'glove'],
+            ['crises', 'crisis'],
+            ['taxes', 'tax'],
+            ['waves', 'wave'],
+            ['bureaus', 'bureau'],
+            ['cafes', 'cafe'],
+            ['roofs', 'roof'],
+            ['foes', 'foe'],
+            ['cookies', 'cookie'],
+            ['wolves', 'wolf'],
+            ['thieves', 'thief'],
+            ['potatoes', 'potato'],
+            ['heroes', 'hero'],
+            ['buffaloes', 'buffalo'],
+            ['teeth', 'tooth'],
+            ['geese', 'goose'],
+            ['feet', 'foot'],
+            ['objectives', 'objective'],
+            ['briefs', 'brief'],
+            ['quotas', 'quota'],
+            ['curves', 'curve'],
+            ['body_curves', 'body_curve'],
+            ['metadata', 'metadata'],
+            ['files_metadata', 'files_metadata'],
+            ['stadia', 'stadia'],
+            ['Addresses', 'Address'],
+            ['sieves', 'sieve'],
+            ['blue_octopuses', 'blue_octopus'],
+            ['chefs', 'chef'],
+            ['', ''],
+        ];
     }
 
     /**

+ 15 - 3
tests/TestCase/Validation/ValidationTest.php

@@ -31,6 +31,16 @@ class ValidationTest extends TestCase
 {
 
     /**
+     * @var string
+     */
+    public $locale;
+
+    /**
+     * @var string
+     */
+    protected $_appEncoding;
+
+    /**
      * setUp method
      *
      * @return void
@@ -60,7 +70,7 @@ class ValidationTest extends TestCase
      *
      * @return void
      */
-    public function testNotEmpty()
+    public function testNotBlank()
     {
         $this->assertTrue(Validation::notBlank('abcdefg'));
         $this->assertTrue(Validation::notBlank('fasdf '));
@@ -69,6 +79,8 @@ class ValidationTest extends TestCase
         $this->assertTrue(Validation::notBlank('José'));
         $this->assertTrue(Validation::notBlank('é'));
         $this->assertTrue(Validation::notBlank('π'));
+        $this->assertTrue(Validation::notBlank('0'));
+        $this->assertTrue(Validation::notBlank(0));
         $this->assertFalse(Validation::notBlank("\t "));
         $this->assertFalse(Validation::notBlank(""));
     }
@@ -78,7 +90,7 @@ class ValidationTest extends TestCase
      *
      * @return void
      */
-    public function testNotEmptyISO88591AppEncoding()
+    public function testNotBlankIso88591AppEncoding()
     {
         Configure::write('App.encoding', 'ISO-8859-1');
         $this->assertTrue(Validation::notBlank('abcdefg'));
@@ -1862,7 +1874,7 @@ class ValidationTest extends TestCase
      */
     public function testEmailDeep()
     {
-        $this->skipIf(gethostbynamel('example.abcd'), 'Your DNS service responds for non-existant domains, skipping deep email checks.');
+        $this->skipIf((bool)gethostbynamel('example.abcd'), 'Your DNS service responds for non-existant domains, skipping deep email checks.');
 
         $this->assertTrue(Validation::email('abc.efg@cakephp.org', true));
         $this->assertFalse(Validation::email('abc.efg@caphpkeinvalid.com', true));

+ 21 - 0
tests/test_app/TestApp/Model/Table/AuthUsersTable.php

@@ -12,6 +12,7 @@
  */
 namespace TestApp\Model\Table;
 
+use Cake\Core\Exception\Exception;
 use Cake\ORM\Query;
 use Cake\ORM\Table;
 
@@ -38,4 +39,24 @@ class AuthUsersTable extends Table
 
         return $query;
     }
+
+    /**
+     * Custom finder
+     *
+     * @param \Cake\ORM\Query $query The query to find with
+     * @param array $options The options to find with
+     * @return \Cake\ORM\Query The query builder
+     */
+    public function findUsername(Query $query, array $options)
+    {
+        if (empty($options['username'])) {
+            throw new Exception(__('Username not defined'));
+        }
+
+        $query = $this->find()
+            ->where(['username' => $options['username']])
+            ->select(['id', 'username', 'password']);
+
+        return $query;
+    }
 }