Kohana v3.3.5

This commit is contained in:
Deon George
2016-05-01 20:50:24 +10:00
parent 8888719653
commit 68c7f4f159
170 changed files with 4565 additions and 1176 deletions

View File

@@ -655,6 +655,22 @@ class Kohana_ArrTest extends Unittest_TestCase
'bar' => 'foobar',
),
),
array(
'strip_tags',
array(
array(
'foo' => '<p>foobar</p>',
'bar' => '<p>foobar</p>',
),
),
array('foo'),
array(
array(
'foo' => 'foobar',
'bar' => '<p>foobar</p>',
),
),
),
);
}

View File

@@ -11,13 +11,15 @@
* @category Tests
* @author Kohana Team
* @author Jeremy Bush <contractfrombelow@gmail.com>
* @copyright (c) 2008-2012 Kohana Team
* @author Andrew Coulton <andrew@ingenerator.com>
* @copyright (c) 2008-2014 Kohana Team
* @license http://kohanaframework.org/license
*/
class Kohana_CookieTest extends Unittest_TestCase
{
const UNIX_TIMESTAMP = 1411040141;
const COOKIE_EXPIRATION = 60;
protected $_default_salt = 'AdaoidadnA£ASDNadnaoiwdnawd';
/**
* Sets up the environment
*/
@@ -26,152 +28,298 @@ class Kohana_CookieTest extends Unittest_TestCase
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana_CookieTest_TestableCookie::$_mock_cookies_set = array();
Cookie::$salt = $this->_default_salt;
$this->setEnvironment(array(
'Cookie::$salt' => 'some-random-salt',
'HTTP_USER_AGENT' => 'cli'
));
}
/**
* Tears down the environment
* Tests that cookies are set with the global path, domain, etc options.
*
* @covers Cookie::set
*/
public function test_set_creates_cookie_with_configured_cookie_options()
{
$this->setEnvironment(array(
'Cookie::$path' => '/path',
'Cookie::$domain' => 'my.domain',
'Cookie::$secure' => TRUE,
'Cookie::$httponly' => FALSE,
));
Kohana_CookieTest_TestableCookie::set('cookie', 'value');
$this->assertSetCookieWith(array(
'path' => '/path',
'domain' => 'my.domain',
'secure' => TRUE,
'httponly' => FALSE
));
}
/**
* Provider for test_set_calculates_expiry_from_lifetime
*
* @return array of $lifetime, $expect_expiry
*/
public function provider_set_calculates_expiry_from_lifetime()
{
return array(
array(NULL, self::COOKIE_EXPIRATION + self::UNIX_TIMESTAMP),
array(0, 0),
array(10, 10 + self::UNIX_TIMESTAMP),
);
}
/**
* @param int $expiration
* @param int $expect_expiry
*
* @dataProvider provider_set_calculates_expiry_from_lifetime
* @covers Cookie::set
*/
public function test_set_calculates_expiry_from_lifetime($expiration, $expect_expiry)
{
$this->setEnvironment(array('Cookie::$expiration' => self::COOKIE_EXPIRATION));
Kohana_CookieTest_TestableCookie::set('foo', 'bar', $expiration);
$this->assertSetCookieWith(array('expire' => $expect_expiry));
}
/**
* @covers Cookie::get
*/
public function test_get_returns_default_if_cookie_missing()
{
unset($_COOKIE['missing_cookie']);
$this->assertEquals('default', Cookie::get('missing_cookie', 'default'));
}
/**
* @covers Cookie::get
*/
public function test_get_returns_value_if_cookie_present_and_signed()
{
Kohana_CookieTest_TestableCookie::set('cookie', 'value');
$cookie = Kohana_CookieTest_TestableCookie::$_mock_cookies_set[0];
$_COOKIE[$cookie['name']] = $cookie['value'];
$this->assertEquals('value', Cookie::get('cookie', 'default'));
}
/**
* Provider for test_get_returns_default_without_deleting_if_cookie_unsigned
*
* @return array
*/
public function provider_get_returns_default_without_deleting_if_cookie_unsigned()
{
return array(
array('unsalted'),
array('un~salted'),
);
}
/**
* Verifies that unsigned cookies are not available to the kohana application, but are not affected for other
* consumers.
*
* @param string $unsigned_value
*
* @dataProvider provider_get_returns_default_without_deleting_if_cookie_unsigned
* @covers Cookie::get
*/
public function test_get_returns_default_without_deleting_if_cookie_unsigned($unsigned_value)
{
$_COOKIE['cookie'] = $unsigned_value;
$this->assertEquals('default', Kohana_CookieTest_TestableCookie::get('cookie', 'default'));
$this->assertEquals($unsigned_value, $_COOKIE['cookie'], '$_COOKIE not affected');
$this->assertEmpty(Kohana_CookieTest_TestableCookie::$_mock_cookies_set, 'No cookies set or changed');
}
/**
* If a cookie looks like a signed cookie but the signature no longer matches, it should be deleted.
*
* @covers Cookie::get
*/
public function test_get_returns_default_and_deletes_tampered_signed_cookie()
{
$_COOKIE['cookie'] = Cookie::salt('cookie', 'value').'~tampered';
$this->assertEquals('default', Kohana_CookieTest_TestableCookie::get('cookie', 'default'));
$this->assertDeletedCookie('cookie');
}
/**
* @covers Cookie::delete
*/
public function test_delete_removes_cookie_from_globals_and_expires_cookie()
{
$_COOKIE['cookie'] = Cookie::salt('cookie', 'value').'~tampered';
$this->assertTrue(Kohana_CookieTest_TestableCookie::delete('cookie'));
$this->assertDeletedCookie('cookie');
}
/**
* @covers Cookie::delete
* @link http://dev.kohanaframework.org/issues/3501
* @link http://dev.kohanaframework.org/issues/3020
*/
public function test_delete_does_not_require_configured_salt()
{
Cookie::$salt = NULL;
$this->assertTrue(Kohana_CookieTest_TestableCookie::delete('cookie'));
$this->assertDeletedCookie('cookie');
}
/**
* @covers Cookie::salt
* @expectedException Kohana_Exception
*/
public function test_salt_throws_with_no_configured_salt()
{
Cookie::$salt = NULL;
Cookie::salt('key', 'value');
}
/**
* @covers Cookie::salt
*/
public function test_salt_creates_same_hash_for_same_values_and_state()
{
$name = 'cookie';
$value = 'value';
$this->assertEquals(Cookie::salt($name, $value), Cookie::salt($name, $value));
}
/**
* Provider for test_salt_creates_different_hash_for_different_data
*
* @return array
*/
public function provider_salt_creates_different_hash_for_different_data()
{
return array(
array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('name' => 'changed')),
array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('value' => 'changed')),
array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('salt' => 'changed-salt')),
array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('user-agent' => 'Firefox')),
array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('user-agent' => NULL)),
);
}
/**
* @param array $first_args
* @param array $changed_args
*
* @dataProvider provider_salt_creates_different_hash_for_different_data
* @covers Cookie::salt
*/
public function test_salt_creates_different_hash_for_different_data($first_args, $changed_args)
{
$second_args = array_merge($first_args, $changed_args);
$hashes = array();
foreach (array($first_args, $second_args) as $args)
{
Cookie::$salt = $args['salt'];
$this->set_or_remove_http_user_agent($args['user-agent']);
$hashes[] = Cookie::salt($args['name'], $args['value']);
}
$this->assertNotEquals($hashes[0], $hashes[1]);
}
/**
* Verify that a cookie was deleted from the global $_COOKIE array, and that a setcookie call was made to remove it
* from the client.
*
* @param string $name
*/
// @codingStandardsIgnoreStart
public function tearDown()
protected function assertDeletedCookie($name)
// @codingStandardsIgnoreEnd
{
parent::tearDown();
Cookie::$salt = NULL;
$this->assertArrayNotHasKey($name, $_COOKIE);
// To delete the client-side cookie, Cookie::delete should send a new cookie with value NULL and expiry in the past
$this->assertSetCookieWith(array(
'name' => $name,
'value' => NULL,
'expire' => -86400,
'path' => Cookie::$path,
'domain' => Cookie::$domain,
'secure' => Cookie::$secure,
'httponly' => Cookie::$httponly
));
}
/**
* Provides test data for test_set()
* Verify that there was a single call to setcookie including the provided named arguments
*
* @return array
* @param array $expected
*/
public function provider_set()
// @codingStandardsIgnoreStart
protected function assertSetCookieWith($expected)
// @codingStandardsIgnoreEnd
{
return array(
array('foo', 'bar', NULL, TRUE),
array('foo', 'bar', 10, TRUE),
);
$this->assertCount(1, Kohana_CookieTest_TestableCookie::$_mock_cookies_set);
$relevant_values = array_intersect_key(Kohana_CookieTest_TestableCookie::$_mock_cookies_set[0], $expected);
$this->assertEquals($expected, $relevant_values);
}
/**
* Tests cookie::set()
* Configure the $_SERVER[HTTP_USER_AGENT] environment variable for the test
*
* @test
* @dataProvider provider_set
* @covers cookie::set
* @param mixed $key key to use
* @param mixed $value value to set
* @param mixed $exp exp to set
* @param boolean $expected Output for cookie::set()
* @param string $user_agent
*/
public function test_set($key, $value, $exp, $expected)
protected function set_or_remove_http_user_agent($user_agent)
{
if (headers_sent()) {
$this->markTestSkipped('Cannot test setting cookies as headers have already been sent');
}
$this->assertSame($expected, cookie::set($key, $value, $exp));
}
/**
* Provides test data for test_get()
*
* @return array
*/
public function provider_get()
{
// setUp is called after the provider so we need to specify a
// salt here in order to use it in the provider
Cookie::$salt = $this->_default_salt;
return array(
array('foo', Cookie::salt('foo', 'bar').'~bar', 'bar'),
array('bar', Cookie::salt('foo', 'bar').'~bar', NULL),
array(NULL, Cookie::salt('foo', 'bar').'~bar', NULL),
);
}
/**
* Tests cookie::set()
*
* @test
* @dataProvider provider_get
* @covers cookie::get
* @param mixed $key key to use
* @param mixed $value value to set
* @param boolean $expected Output for cookie::get()
*/
public function test_get($key, $value, $expected)
{
if (headers_sent()) {
$this->markTestSkipped('Cannot test setting cookies as headers have already been sent');
}
// Force $_COOKIE
if ($key !== NULL)
if ($user_agent === NULL)
{
$_COOKIE[$key] = $value;
unset($_SERVER['HTTP_USER_AGENT']);
}
$this->assertSame($expected, cookie::get($key));
}
/**
* Provides test data for test_delete()
*
* @return array
*/
public function provider_delete()
{
return array(
array('foo', TRUE),
);
}
/**
* Tests cookie::delete()
*
* @test
* @dataProvider provider_delete
* @covers cookie::delete
* @param mixed $key key to use
* @param boolean $expected Output for cookie::delete()
*/
public function test_delete($key, $expected)
{
if (headers_sent()) {
$this->markTestSkipped('Cannot test setting cookies as headers have already been sent');
else
{
$_SERVER['HTTP_USER_AGENT'] = $user_agent;
}
$this->assertSame($expected, cookie::delete($key));
}
/**
* Provides test data for test_salt()
*
* @return array
*/
public function provider_salt()
{
return array(
array('foo', 'bar', 'b5773a6255d1deefc23f9f69bcc40fdc998e5802'),
);
}
/**
* Tests cookie::salt()
*
* @test
* @dataProvider provider_salt
* @covers cookie::salt
* @param mixed $key key to use
* @param mixed $value value to salt with
* @param boolean $expected Output for cookie::delete()
*/
public function test_salt($key, $value, $expected)
{
$this->assertSame($expected, cookie::salt($key, $value));
}
}
/**
* Class Kohana_CookieTest_TestableCookie wraps the cookie class to mock out the actual setcookie and time calls for
* unit testing.
*/
class Kohana_CookieTest_TestableCookie extends Cookie {
/**
* @var array setcookie calls that were made
*/
public static $_mock_cookies_set = array();
/**
* {@inheritdoc}
*/
protected static function _setcookie($name, $value, $expire, $path, $domain, $secure, $httponly)
{
self::$_mock_cookies_set[] = array(
'name' => $name,
'value' => $value,
'expire' => $expire,
'path' => $path,
'domain' => $domain,
'secure' => $secure,
'httponly' => $httponly
);
return TRUE;
}
/**
* @return int
*/
protected static function _time()
{
return Kohana_CookieTest::UNIX_TIMESTAMP;
}
}

View File

@@ -18,6 +18,32 @@
*/
class Kohana_CoreTest extends Unittest_TestCase
{
protected $old_modules = array();
/**
* Captures the module list as it was before this test
*
* @return null
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
$this->old_modules = Kohana::modules();
}
/**
* Restores the module list
*
* @return null
*/
// @codingStandardsIgnoreStart
public function tearDown()
// @codingStandardsIgnoreEnd
{
Kohana::modules($this->old_modules);
}
/**
* Provides test data for test_sanitize()
@@ -107,33 +133,15 @@ class Kohana_CoreTest extends Unittest_TestCase
*/
public function test_globals_removes_user_def_globals()
{
// Store the globals
$temp_globals = array(
'cookie' => $_COOKIE,
'get' => $_GET,
'files' => $_FILES,
'post' => $_POST,
'request' => $_REQUEST,
'server' => $_SERVER,
'session' => $_SESSION,
'globals' => $GLOBALS,
);
$GLOBALS = array('hackers' => 'foobar','name' => array('','',''), '_POST' => array());
$GLOBALS['hackers'] = 'foobar';
$GLOBALS['name'] = array('','','');
$GLOBALS['_POST'] = array();
Kohana::globals();
$this->assertEquals(array('_POST' => array()), $GLOBALS);
// Reset the globals for other tests
$_COOKIE = $temp_globals['cookie'];
$_GET = $temp_globals['get'];
$_FILES = $temp_globals['files'];
$_POST = $temp_globals['post'];
$_REQUEST = $temp_globals['request'];
$_SERVER = $temp_globals['server'];
$_SESSION = $temp_globals['session'];
$GLOBALS = $temp_globals['globals'];
$this->assertFalse(isset($GLOBALS['hackers']));
$this->assertFalse(isset($GLOBALS['name']));
$this->assertTrue(isset($GLOBALS['_POST']));
}
/**
@@ -175,35 +183,18 @@ class Kohana_CoreTest extends Unittest_TestCase
public function provider_message()
{
return array(
// $value, $result
array(':field must not be empty', 'validation', 'not_empty'),
array(
array('no_message_file', 'anything', 'default', 'default'),
array('no_message_file', NULL, 'anything', array()),
array('kohana_core_message_tests', 'bottom_only', 'anything', 'inherited bottom message'),
array('kohana_core_message_tests', 'cfs_replaced', 'anything', 'overriding cfs_replaced message'),
array('kohana_core_message_tests', 'top_only', 'anything', 'top only message'),
array('kohana_core_message_tests', 'missing', 'default', 'default'),
array('kohana_core_message_tests', NULL, 'anything',
array(
'alpha' => ':field must contain only letters',
'alpha_dash' => ':field must contain only numbers, letters and dashes',
'alpha_numeric' => ':field must contain only letters and numbers',
'color' => ':field must be a color',
'credit_card' => ':field must be a credit card number',
'date' => ':field must be a date',
'decimal' => ':field must be a decimal with :param2 places',
'digit' => ':field must be a digit',
'email' => ':field must be a email address',
'email_domain' => ':field must contain a valid email domain',
'equals' => ':field must equal :param2',
'exact_length' => ':field must be exactly :param2 characters long',
'in_array' => ':field must be one of the available options',
'ip' => ':field must be an ip address',
'matches' => ':field must be the same as :param2',
'min_length' => ':field must be at least :param2 characters long',
'max_length' => ':field must not exceed :param2 characters long',
'not_empty' => ':field must not be empty',
'numeric' => ':field must be numeric',
'phone' => ':field must be a phone number',
'range' => ':field must be within the range of :param2 to :param3',
'regex' => ':field does not match the required format',
'url' => ':field must be a url',
),
'validation', NULL,
'bottom_only' => 'inherited bottom message',
'cfs_replaced' => 'overriding cfs_replaced message',
'top_only' => 'top only message'
)
),
);
}
@@ -213,15 +204,18 @@ class Kohana_CoreTest extends Unittest_TestCase
*
* @test
* @dataProvider provider_message
* @covers Kohana::message
* @param boolean $expected Output for Kohana::message
* @param boolean $file File to look in for Kohana::message
* @param boolean $key Key for Kohana::message
* @covers Kohana::message
* @param string $file to pass to Kohana::message
* @param string $key to pass to Kohana::message
* @param string $default to pass to Kohana::message
* @param string $expected Output for Kohana::message
*/
public function test_message($expected, $file, $key)
public function test_message($file, $key, $default, $expected)
{
$this->markTestSkipped('This test is incredibly fragile and needs to be re-done');
$this->assertEquals($expected, Kohana::message($file, $key));
$test_path = realpath(dirname(__FILE__).'/../test_data/message_tests');
Kohana::modules(array('top' => "$test_path/top_module", 'bottom' => "$test_path/bottom_module"));
$this->assertEquals($expected, Kohana::message($file, $key, $default, $expected));
}
/**
@@ -314,7 +308,7 @@ class Kohana_CoreTest extends Unittest_TestCase
{
return array(
array(array(), array()),
array(array('unittest' => MODPATH.'unittest'), array('unittest' => $this->dirSeparator(MODPATH.'unittest/'))),
array(array('module' => __DIR__), array('module' => $this->dirSeparator(__DIR__.'/'))),
);
}

View File

@@ -0,0 +1,747 @@
<?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
/**
* Tests the encrypt class
*
* @group kohana
* @group kohana.core
* @group kohana.core.encrypt
*
* @package Kohana
* @category Tests
* @author Kohana Team
* @author Samuel Demirdjian <sam@enov.ws>
* @copyright (c) 2014 Kohana Team
* @license http://kohanaframework.org/license
*/
class Kohana_EncryptTest extends Unittest_TestCase
{
/**
* Provider for test_encode
* AES Multiblock Message Test (MMT) Sample Vectors - Known Answer Test (KAT)
* @link http://csrc.nist.gov/groups/STM/cavp/index.html NIST - Cryptographic Algorithm Validation Program
* @link http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmmt.zip file used CBCMMT128.rsp
*
* @return array of $mode, $cipher, $key, $iv, $txt_plain, $txt_encoded
*/
public function provider_encode()
{
return array(
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "1f8e4973953f3fb0bd6b16662e9a3c17"),
// IV
pack("H*", "2fe2b333ceda8f98f4a99b40d2cd34a8"),
// txt_plain
pack("H*", "45cf12964fc824ab76616ae2f4bf0822"),
// txt_encoded
pack("H*", "0f61c4d44c5147c03c195ad7e2cc12b2"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "1f8e4973953f3fb0bd6b16662e9a3c17"),
// IV
pack("H*", "2fe2b333ceda8f98f4a99b40d2cd34a8"),
// txt_plain
pack("H*", "45cf12964fc824ab76616ae2f4bf0822"),
// txt_encoded
pack("H*", "0f61c4d44c5147c03c195ad7e2cc12b2"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "0700d603a1c514e46b6191ba430a3a0c"),
// IV
pack("H*", "aad1583cd91365e3bb2f0c3430d065bb"),
// txt_plain
pack("H*", "068b25c7bfb1f8bdd4cfc908f69dffc5ddc726a197f0e5f720f730393279be91"),
// txt_encoded
pack("H*", "c4dc61d9725967a3020104a9738f23868527ce839aab1752fd8bdb95a82c4d00"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "3348aa51e9a45c2dbe33ccc47f96e8de"),
// IV
pack("H*", "19153c673160df2b1d38c28060e59b96"),
// txt_plain
pack("H*", "9b7cee827a26575afdbb7c7a329f887238052e3601a7917456ba61251c214763d5e1847a6ad5d54127a399ab07ee3599"),
// txt_encoded
pack("H*", "d5aed6c9622ec451a15db12819952b6752501cf05cdbf8cda34a457726ded97818e1f127a28d72db5652749f0c6afee5"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "b7f3c9576e12dd0db63e8f8fac2b9a39"),
// IV
pack("H*", "c80f095d8bb1a060699f7c19974a1aa0"),
// txt_plain
pack("H*", "9ac19954ce1319b354d3220460f71c1e373f1cd336240881160cfde46ebfed2e791e8d5a1a136ebd1dc469dec00c4187722b841cdabcb22c1be8a14657da200e"),
// txt_encoded
pack("H*", "19b9609772c63f338608bf6eb52ca10be65097f89c1e0905c42401fd47791ae2c5440b2d473116ca78bd9ff2fb6015cfd316524eae7dcb95ae738ebeae84a467"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "b6f9afbfe5a1562bba1368fc72ac9d9c"),
// IV
pack("H*", "3f9d5ebe250ee7ce384b0d00ee849322"),
// txt_plain
pack("H*", "db397ec22718dbffb9c9d13de0efcd4611bf792be4fce0dc5f25d4f577ed8cdbd4eb9208d593dda3d4653954ab64f05676caa3ce9bfa795b08b67ceebc923fdc89a8c431188e9e482d8553982cf304d1"),
// txt_encoded
pack("H*", "10ea27b19e16b93af169c4a88e06e35c99d8b420980b058e34b4b8f132b13766f72728202b089f428fecdb41c79f8aa0d0ef68f5786481cca29e2126f69bc14160f1ae2187878ba5c49cf3961e1b7ee9"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "bbe7b7ba07124ff1ae7c3416fe8b465e"),
// IV
pack("H*", "7f65b5ee3630bed6b84202d97fb97a1e"),
// txt_plain
pack("H*", "2aad0c2c4306568bad7447460fd3dac054346d26feddbc9abd9110914011b4794be2a9a00a519a51a5b5124014f4ed2735480db21b434e99a911bb0b60fe0253763725b628d5739a5117b7ee3aefafc5b4c1bf446467e7bf5f78f31ff7caf187"),
// txt_encoded
pack("H*", "3b8611bfc4973c5cd8e982b073b33184cd26110159172e44988eb5ff5661a1e16fad67258fcbfee55469267a12dc374893b4e3533d36f5634c3095583596f135aa8cd1138dc898bc5651ee35a92ebf89ab6aeb5366653bc60a70e0074fc11efe"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "89a553730433f7e6d67d16d373bd5360"),
// IV
pack("H*", "f724558db3433a523f4e51a5bea70497"),
// txt_plain
pack("H*", "807bc4ea684eedcfdcca30180680b0f1ae2814f35f36d053c5aea6595a386c1442770f4d7297d8b91825ee7237241da8925dd594ccf676aecd46ca2068e8d37a3a0ec8a7d5185a201e663b5ff36ae197110188a23503763b8218826d23ced74b31e9f6e2d7fbfa6cb43420c7807a8625"),
// txt_encoded
pack("H*", "406af1429a478c3d07e555c5287a60500d37fc39b68e5bbb9bafd6ddb223828561d6171a308d5b1a4551e8a5e7d572918d25c968d3871848d2f16635caa9847f38590b1df58ab5efb985f2c66cfaf86f61b3f9c0afad6c963c49cee9b8bc81a2ddb06c967f325515a4849eec37ce721a"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "c491ca31f91708458e29a925ec558d78"),
// IV
pack("H*", "9ef934946e5cd0ae97bd58532cb49381"),
// txt_plain
pack("H*", "cb6a787e0dec56f9a165957f81af336ca6b40785d9e94093c6190e5152649f882e874d79ac5e167bd2a74ce5ae088d2ee854f6539e0a94796b1e1bd4c9fcdbc79acbef4d01eeb89776d18af71ae2a4fc47dd66df6c4dbe1d1850e466549a47b636bcc7c2b3a62495b56bb67b6d455f1eebd9bfefecbca6c7f335cfce9b45cb9d"),
// txt_encoded
pack("H*", "7b2931f5855f717145e00f152a9f4794359b1ffcb3e55f594e33098b51c23a6c74a06c1d94fded7fd2ae42c7db7acaef5844cb33aeddc6852585ed0020a6699d2cb53809cefd169148ce42292afab063443978306c582c18b9ce0da3d084ce4d3c482cfd8fcf1a85084e89fb88b40a084d5e972466d07666126fb761f84078f2"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "f6e87d71b0104d6eb06a68dc6a71f498"),
// IV
pack("H*", "1c245f26195b76ebebc2edcac412a2f8"),
// txt_plain
pack("H*", "f82bef3c73a6f7f80db285726d691db6bf55eec25a859d3ba0e0445f26b9bb3b16a3161ed1866e4dd8f2e5f8ecb4e46d74a7a78c20cdfc7bcc9e479ba7a0caba9438238ad0c01651d5d98de37f03ddce6e6b4bd4ab03cf9e8ed818aedfa1cf963b932067b97d776dce1087196e7e913f7448e38244509f0caf36bd8217e15336d35c149fd4e41707893fdb84014f8729"),
// txt_encoded
pack("H*", "b09512f3eff9ed0d85890983a73dadbb7c3678d52581be64a8a8fc586f490f2521297a478a0598040ebd0f5509fafb0969f9d9e600eaef33b1b93eed99687b167f89a5065aac439ce46f3b8d22d30865e64e45ef8cd30b6984353a844a11c8cd60dba0e8866b3ee30d24b3fa8a643b328353e06010fa8273c8fd54ef0a2b6930e5520aae5cd5902f9b86a33592ca4365"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "2c14413751c31e2730570ba3361c786b"),
// IV
pack("H*", "1dbbeb2f19abb448af849796244a19d7"),
// txt_plain
pack("H*", "40d930f9a05334d9816fe204999c3f82a03f6a0457a8c475c94553d1d116693adc618049f0a769a2eed6a6cb14c0143ec5cccdbc8dec4ce560cfd206225709326d4de7948e54d603d01b12d7fed752fb23f1aa4494fbb00130e9ded4e77e37c079042d828040c325b1a5efd15fc842e44014ca4374bf38f3c3fc3ee327733b0c8aee1abcd055772f18dc04603f7b2c1ea69ff662361f2be0a171bbdcea1e5d3f"),
// txt_encoded
pack("H*", "6be8a12800455a320538853e0cba31bd2d80ea0c85164a4c5c261ae485417d93effe2ebc0d0a0b51d6ea18633d210cf63c0c4ddbc27607f2e81ed9113191ef86d56f3b99be6c415a4150299fb846ce7160b40b63baf1179d19275a2e83698376d28b92548c68e06e6d994e2c1501ed297014e702cdefee2f656447706009614d801de1caaf73f8b7fa56cf1ba94b631933bbe577624380850f117435a0355b2b"),
),
);
}
/**
* @param string $mode
* @param string $cipher
* @param string $key Encryption key
* @param string $iv Initialization vector
* @param string $txt_plain Plain text to be encrypted
* @param string $txt_encoded Known ecrypted text
*
* @dataProvider provider_encode
* @covers Encrypt::encode
*/
public function test_encode($mode, $cipher, $key, $iv, $txt_plain, $txt_encoded)
{
// initialize
$e = new Kohana_EncryptTest_IvStubbed($key, $iv, $mode, $cipher);
// prepare data
$expected = base64_encode($iv . $txt_encoded);
$actual = $e->encode($txt_plain);
// assert
$this->assertSame($expected, $actual);
}
/**
* Provider for test_decode
* AES Multiblock Message Test (MMT) Sample Vectors - Known Answer Test (KAT)
* @link http://csrc.nist.gov/groups/STM/cavp/index.html NIST - Cryptographic Algorithm Validation Program
* @link http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmmt.zip file used CBCMMT128.rsp
*
* @return array of $mode, $cipher, $key, $iv, $txt_encoded, $txt_plain
*/
public function provider_decode()
{
return array(
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "6a7082cf8cda13eff48c8158dda206ae"),
// IV
pack("H*", "bd4172934078c2011cb1f31cffaf486e"),
// txt_encoded
pack("H*", "f8eb31b31e374e960030cd1cadb0ef0c"),
// txt_plain
pack("H*", "940bc76d61e2c49dddd5df7f37fcf105"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "625eefa18a4756454e218d8bfed56e36"),
// IV
pack("H*", "73d9d0e27c2ec568fbc11f6a0998d7c8"),
// txt_encoded
pack("H*", "5d6fed86f0c4fe59a078d6361a142812514b295dc62ff5d608a42ea37614e6a1"),
// txt_plain
pack("H*", "360dc1896ce601dfb2a949250067aad96737847a4580ede2654a329b842fe81e"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "fd6e0b954ae2e3b723d6c9fcae6ab09b"),
// IV
pack("H*", "f08b65c9f4dd950039941da2e8058c4e"),
// txt_encoded
pack("H*", "e29e3114c8000eb484395b256b1b3267894f290d3999819ff35da03e6463c186c4d7ebb964941f1986a2d69572fcaba8"),
// txt_plain
pack("H*", "a206385945b21f812a9475f47fddbb7fbdda958a8d14c0dbcdaec36e8b28f1f6ececa1ceae4ce17721d162c1d42a66c1"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "7b1ab9144b0239315cd5eec6c75663bd"),
// IV
pack("H*", "0b1e74f45c17ff304d99c059ce5cde09"),
// txt_encoded
pack("H*", "d3f89b71e033070f9d7516a6cb4ea5ef51d6fb63d4f0fea089d0a60e47bbb3c2e10e9ba3b282c7cb79aefe3068ce228377c21a58fe5a0f8883d0dbd3d096beca"),
// txt_plain
pack("H*", "b968aeb199ad6b3c8e01f26c2edad444538c78bfa36ed68ca76123b8cdce615a01f6112bb80bfc3f17490578fb1f909a52e162637b062db04efee291a1f1af60"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "36466b6bd25ea3857ea42f0cac1919b1"),
// IV
pack("H*", "7186fb6bdfa98a16189544b228f3bcd3"),
// txt_encoded
pack("H*", "9ed957bd9bc52bba76f68cfbcde52157a8ca4f71ac050a3d92bdebbfd7c78316b4c9f0ba509fad0235fdafe90056ad115dfdbf08338b2acb1c807a88182dd2a882d1810d4302d598454e34ef2b23687d"),
// txt_plain
pack("H*", "999983467c47bb1d66d7327ab5c58f61ddb09b93bd2460cb78cbc12b5fa1ea0c5f759ccc5e478697687012ff4673f6e61eecaeda0ccad2d674d3098c7d17f887b62b56f56b03b4d055bf3a4460e83efa"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "89373ee6e28397640d5082eed4123239"),
// IV
pack("H*", "1a74d7c859672c804b82472f7e6d3c6b"),
// txt_encoded
pack("H*", "1bcba44ddff503db7c8c2ec4c4eea0e827957740cce125c1e11769842fa97e25f1b89269e6d77923a512a358312f4ba1cd33f2d111280cd83e1ef9e7cf7036d55048d5c273652afa611cc81b4e9dac7b5078b7c4716062e1032ead1e3329588a"),
// txt_plain
pack("H*", "45efd00daa4cdc8273ef785cae9e944a7664a2391e1e2c449f475acec0124bbc22944331678617408a1702917971f4654310ffb9229bec6173715ae512d37f93aaa6abf009f7e30d65669d1db0366b5bce4c7b00f871014f5753744a1878dc57"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "bab0cceddc0abd63e3f82e9fbff7b8aa"),
// IV
pack("H*", "68b9140f300490c5c942f66e777eb806"),
// txt_encoded
pack("H*", "c65b94b1f291fa9f0600f22c3c0432c895ad5d177bcccc9ea44e8ec339c9adf43855b326179d6d81aa36ef59462fd86127e9d81b0f286f93306bf74d4c79e47c1b3d4b74edd3a16290e3c63b742e41f20d66ceee794316bb63d3bd002712a1b136ba6185bd5c1dab81b07db90d2af5e5"),
// txt_plain
pack("H*", "c5585ff215bbb73ba5393440852fb199436de0d15e55c631f877670aa3eda9f672eb1f876f09544e63558436b8928000db2f02a5ad90f95b05ac4cf49e198e617e7678480fdf0efacc6aae691271e6cdd3541ebf719a1ccaedb24e2f80f92455dd5910cb5086b0960a3942ec182dcbd7"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "9c702898efa44557b29ed283f5bc0293"),
// IV
pack("H*", "cec6e1b82e8b2a591a9fa5ff1cf5cc51"),
// txt_encoded
pack("H*", "ba9f646755dacc22911f51d7de2f7e7cb0bc0b75257ea44fe883edb055c7c28ede04c3a0adcb10128ad4517d0093fa16bb0bcd2635e7a0ba92c7609bc8d8568002a7a983473724d256513aa7d51b477aabec1975ab5faf2872a6407e922180eff02f1ef86a4591c8bd3d143da6f0ef0e4806f94ace0d5b0151c99640fccbc843"),
// txt_plain
pack("H*", "1d1f8d81bdc3e2c7cb057f408e6450000c5aaed3260ff1e87fbb6f324df6887ffd8f78d7e2a04c9ed9deda9d64482d2b002f4a2b78d8b4f691875c8295d4a64b22257ceaf713ed2f4b92530d7ad7151d629acda882b4829577a43990b0948c1149c22fe4273656d1b08833930e8b06709a94579a78fc220f7057bbc1fa9f6563"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "5674636dbdb38f705f0b08c372ef4785"),
// IV
pack("H*", "3f20ce0509b57420d53b6be4d0b7f0a9"),
// txt_encoded
pack("H*", "198351f453103face6655666fe90bdbd9630e3733b2d66c013a634e91f2bf015bd2d975d71b26322e44defa32d4e9dce50363557046ece08ba38f258dae5fd3e5049c647476c81e73482e40c171d89f9fea29452caf995733589b0061464fbd5dabe27dc5ea463a3deeb7dcb43664ae6a65c498c143883ab8e83b51e5410b181647602443dc3cfffe86f0205398fa83c"),
// txt_plain
pack("H*", "6d40fd2f908f48ce19241b6b278b1b1676dffd4a97ce9f8a1574c33bc59237deb536bee376fd6c381e6987700e39283aa111cf1a59f26fae6fb6700bf012646a2ab80239bf5e1632329043aa87d7911978b36523a2bc0bed9a9737ccf7a00baa2f3822b4e9e742e168e7069290705fed2eb63aa044b78f97dd33a8d6b24741ec1fd8c8db79d93b884e762dba0f406961"),
),
array(
// mode
MCRYPT_MODE_CBC,
// cypher
MCRYPT_RIJNDAEL_128,
// key
pack("H*", "97a1025529b9925e25bbe78770ca2f99"),
// IV
pack("H*", "d4b4eab92aa9637e87d366384ed6915c"),
// txt_encoded
pack("H*", "22cdc3306fcd4d31ccd32720cbb61bad28d855670657c48c7b88c31f4fa1f93c01b57da90be63ead67d6a325525e6ed45083e6fb70a53529d1fa0f55653b942af59d78a2660361d63a7290155ac5c43312a25b235dacbbc863faf00940c99624076dfa44068e7c554c9038176953e571751dfc0954d41d113771b06466b1c8d13e0d4cb675ed58d1a619e1540970983781dc11d2dd8525ab5745958d615defda"),
// txt_plain
pack("H*", "e8b89150d8438bf5b17449d6ed26bd72127e10e4aa57cad85283e8359e089208e84921649f5b60ea21f7867cbc9620560c4c6238db021216db453c9943f1f1a60546173daef2557c3cdd855031b353d4bf176f28439e48785c37d38f270aa4a6faad2baabcb0c0b2d1dd5322937498ce803ba1148440a52e227ddba4872fe4d81d2d76a939d24755adb8a7b8452ceed2d179e1a5848f316f5c016300a390bfa7"),
),
);
}
/**
* @param string $mode
* @param string $cipher
* @param string $key Encryption key
* @param string $iv Initialization vector
* @param string $txt_encoded ecrypted text
* @param string $txt_plain Known plain text that is decripted
*
* @dataProvider provider_decode
* @covers Encrypt::decode
*/
public function test_decode($mode, $cipher, $key, $iv, $txt_encoded, $txt_plain)
{
// initialize
$e = new Encrypt($key, $mode, $cipher);
// prepare data
$expected = $txt_plain;
$actual = $e->decode(base64_encode($iv . $txt_encoded));
// assert
$this->assertSame($expected, $actual);
}
/**
* Provider for test_encode_decode, test_consecutive_encode_different_results
*
* @return array of $key, $mode, $cipher, $txt_plain
*/
public function provider_encode_decode()
{
return array(
array(
// key
"Some super secret key",
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_plain
"The quick brown fox jumps over the lazy dog",
),
array(
// key
"De finibus bonorum et malorum",
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_plain
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
),
);
}
/**
* @param type $key Encryption Key
* @param type $mode Encryption Mode
* @param type $cipher Encryption Cipher
* @param type $txt_plain Plain text to encode and then decode back
*
* @dataProvider provider_encode_decode
* @covers Encrypt::encode
* @covers Encrypt::decode
*/
public function test_encode_decode($key, $mode, $cipher, $txt_plain)
{
// initialize, encode
$e = new Encrypt($key, $mode, $cipher);
$txt_encoded = $e->encode($txt_plain);
// prepare data
$expected = $txt_plain;
$actual = $e->decode($txt_encoded);
// assert
$this->assertSame($expected, $actual);
}
/**
* Provider for test_decode_invalid_data
*
* @return array of $key, $mode, $cipher, $txt_invalid_encoded
*/
public function provider_decode_invalid_data()
{
return array(
array(
// key
"Some super secret key",
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_invalid_encoded
".:This data is not a valid base 64 string:.",
),
array(
// key
"Some super secret key",
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_invalid_encoded
base64_encode("too short"),
),
);
}
/**
* Tests for decode when the string is not valid base64,
* or is too short to contain a valid IV
*
* @param type $key
* @param type $mode
* @param type $cipher
* @param type $txt_encoded
*
* @dataProvider provider_decode_invalid_data
*/
public function test_decode_invalid_data($key, $mode, $cipher, $txt_invalid_encoded)
{
// initialize
$e = new Encrypt($key, $mode, $cipher);
// assert
$this->AssertFalse($e->decode($txt_invalid_encoded));
}
/**
* @param type $key Encryption Key
* @param type $mode Encryption Mode
* @param type $cipher Encryption Cipher
* @param type $txt_plain Plain text to encode and then decode back
*
* @dataProvider provider_encode_decode
* @covers Encrypt::encode
*/
public function test_consecutive_encode_produce_different_results($key, $mode, $cipher, $txt_plain)
{
// initialize, encode twice
$e = new Encrypt($key, $mode, $cipher);
$txt_encoded_first = $e->encode($txt_plain);
$txt_encoded_second = $e->encode($txt_plain);
// assert
$this->assertNotEquals($txt_encoded_first, $txt_encoded_second);
}
/**
* Provider for test_key_normalization
*
* @return array of $key, $iv, $mode, $cipher, $txt_plain
*/
public function provider_key_normalization()
{
return array(
array(
// key
"Some super secret key",
// IV
pack("H*", "2fe2b333ceda8f98f4a99b40d2cd34a8"),
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_plain
"The quick brown fox jumps over the lazy dog",
),
array(
// key
"De finibus bonorum et malorum",
// IV
pack("H*", "2fe2b333ceda8f98f4a99b40d2cd34a8"),
// mode
MCRYPT_MODE_NOFB,
// cypher
MCRYPT_RIJNDAEL_128,
// txt_plain
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
),
);
}
/**
* Test if key normalization logic behaves well
* Encrypt::_normalize_key was ment for PHP > 5.6.0
*
* We are testing our key normalization only against lower versions of PHP
* (PHP < 5.6.0) to see if it matches the internal key padding those
* PHP versions already have
*
* @param type $key Encryption Key
* @param type $mode Encryption Mode
* @param type $cipher Encryption Cipher
* @param type $txt_plain Plain text to encode and then decode back
*
* @dataProvider provider_key_normalization
* @covers Encrypt::_normalize_key
*/
public function test_key_normalization($key, $iv, $mode, $cipher, $txt_plain)
{
if (version_compare(PHP_VERSION, '5.6.0', '>='))
{
$this->markTestSkipped('Starting from PHP 5.6.0, mcrypt does not pad encryption keys with null bytes.');
}
// initialize, encode twice
$e1 = new Kohana_EncryptTest_IvStubbed($key, $iv, $mode, $cipher);
$e2 = new Kohana_EncryptTest_KeyNormalized($key, $iv, $mode, $cipher);
$txt_encoded_1 = $e1->encode($txt_plain);
$txt_encoded_2 = $e2->encode($txt_plain);
// assert
$this->assertSame($txt_encoded_1, $txt_encoded_2);
}
/**
* @expectedException Kohana_Exception
* @expectedExceptionMessage No encryption key is defined in the encryption configuration group
*/
public function test_instance_throw_exception_when_no_key_provided()
{
Encrypt::instance();
}
/**
* Provider for test_instance_returns_singleton
*
* @return array of $instance_name, $missing_config
*/
public function provider_instance_returns_singleton()
{
return array(
array(
'default',
array(
'key' => 'trwQwVXX96TIJoKxyBHB9AJkwAOHixuV1ENZmIWyanI0j1zNgSVvqywy044Agaj',
)
),
array(
'blowfish',
array(
'key' => '7bZJJkmNrelj5NaKoY6h6rMSRSmeUlJuTeOd5HHka5XknyMX4uGSfeVolTz4IYy',
'cipher' => MCRYPT_BLOWFISH,
'mode' => MCRYPT_MODE_ECB,
)
),
array(
'tripledes',
array(
'key' => 'a9hcSLRvA3LkFc7EJgxXIKQuz1ec91J7P6WNq1IaxMZp4CTj5m31gZLARLxI1jD',
'cipher' => MCRYPT_3DES,
'mode' => MCRYPT_MODE_CBC,
)
),
);
}
/**
* Test to multiple calls to the instance() method returns same instance
* also test if the instances are appropriately configured.
*
* @param string $instance_name instance name
* @param array $config_array array of config variables missing from config
*
* @dataProvider provider_instance_returns_singleton
*/
public function test_instance_returns_singleton($instance_name, array $config_array)
{
// load config
$config = Kohana::$config->load('encrypt');
// if instance name is NULL the config group should be the default
$config_group = $instance_name ? : Encrypt::$default;
// if config group does not exists, create
if (!array_key_exists($config_group, $config))
{
$config[$config_group] = array();
}
// fill in the missing config variables
$config[$config_group] = $config[$config_group] + $config_array;
// call instance twice
$e = Encrypt::instance($instance_name);
$e2 = Encrypt::instance($instance_name);
// assert instances
$this->assertInstanceOf('Encrypt', $e);
$this->assertInstanceOf('Encrypt', $e2);
$this->assertSame($e, $e2);
// test if instances are well configured
// prepare expected variables
$expected_cipher = $config[$config_group]['cipher'];
$expected_mode = $config[$config_group]['mode'];
$expected_key_size = mcrypt_get_key_size($expected_cipher, $expected_mode);
$expected_key = substr($config[$config_group]['key'], 0, $expected_key_size);
// assert
$this->assertSameProtectedProperty($expected_key, $e, '_key');
$this->assertSameProtectedProperty($expected_cipher, $e, '_cipher');
$this->assertSameProtectedProperty($expected_mode, $e, '_mode');
}
/**
* Helper method to test for private/protected properties
*
* @param mixed $expect Expected value
* @param mixed $object object that holds the private/protected property
* @param string $name the name of the private/protected property
*/
protected function assertSameProtectedProperty($expect, $object, $name)
{
$refl = new ReflectionClass($object);
$property = $refl->getProperty($name);
$property->setAccessible(TRUE);
$this->assertSame($expect, $property->getValue($object));
}
}
/**
* Class Kohana_EncryptTest_IvStubbed wraps the Encrypt class to mock out
* the actual mcrypt_create_iv calls for unit testing.
*/
class Kohana_EncryptTest_IvStubbed extends Encrypt
{
/**
* override constructor to force class use known IVs
*
* @param string $key encryption key
* @param string $iv feed a known IV
* @param string $mode mcrypt mode
* @param string $cipher mcrypt cipher
*/
public function __construct($key, $iv, $mode, $cipher)
{
parent::__construct($key, $mode, $cipher);
$this->_iv = $iv;
}
/**
* Fake a random initialization vector by returning a known one
*
* @return string a known IV
*/
protected function _create_iv()
{
return isset($this->_iv) ? $this->_iv : FALSE;
}
}
/**
* Class Kohana_EncryptTest_KeyNormalized wraps the Encrypt class to mock out
* the actual mcrypt_create_iv calls for unit testing, as well as to always
* normalize keys
*/
class Kohana_EncryptTest_KeyNormalized extends Kohana_EncryptTest_IvStubbed
{
/**
* override constructor to force key normalization
*
* @param string $key encryption key
* @param string $mode mcrypt mode
* @param string $cipher mcrypt cipher
*/
public function __construct($key, $iv, $mode, $cipher)
{
parent::__construct($key, $iv, $mode, $cipher);
$this->_key = $this->_normalize_key($this->_key, $this->_cipher, $this->_mode);
}
}

View File

@@ -16,6 +16,18 @@
*/
class Kohana_FeedTest extends Unittest_TestCase
{
/**
* Sets up the environment
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('localhost'));
}
/**
* Provides test data for test_parse()
*
@@ -25,7 +37,8 @@ class Kohana_FeedTest extends Unittest_TestCase
{
return array(
// $source, $expected
array('http://dev.kohanaframework.org/projects/kohana3/activity.atom', 15),
array(realpath(__DIR__.'/../test_data/feeds/activity.atom'), array('Proposals (Political/Workflow) #4839 (New)', 'Proposals (Political/Workflow) #4782')),
array(realpath(__DIR__.'/../test_data/feeds/example.rss20'), array('Example entry')),
);
}
@@ -38,11 +51,15 @@ class Kohana_FeedTest extends Unittest_TestCase
* @param string $source URL to test
* @param integer $expected Count of items
*/
public function test_parse($source, $expected)
public function test_parse($source, $expected_titles)
{
$this->markTestSkipped('We don\'t go to the internet for tests.');
$titles = array();
foreach (Feed::parse($source) as $item)
{
$titles[] = $item['title'];
}
$this->assertEquals($expected, count(Feed::parse($source)));
$this->assertSame($expected_titles, $titles);
}
/**

View File

@@ -5,7 +5,7 @@
*
* @group kohana
* @group kohana.core
* @group kohana.core.url
* @group kohana.core.file
*
* @package Kohana
* @category Tests
@@ -25,8 +25,7 @@ class Kohana_FileTest extends Unittest_TestCase
{
return array(
// $value, $result
array(Kohana::find_file('classes', 'File')),
array(Kohana::find_file('tests', 'test_data/github', 'png')),
array(Kohana::find_file('tests', 'test_data/github', 'png'), 'image/png'),
);
}
@@ -38,12 +37,10 @@ class Kohana_FileTest extends Unittest_TestCase
* @param boolean $input Input for File::mime
* @param boolean $expected Output for File::mime
*/
public function test_mime($input)
public function test_mime($input, $expected)
{
$this->markTestSkipped(
'This test doesn\'t do anything useful!'
);
$this->assertSame(1, preg_match('/^(?:application|audio|image|message|multipart|text|video)\/[a-z.+0-9-]+$/i', File::mime($input)));
//@todo: File::mime coverage needs significant improvement or to be dropped for a composer package - it's a "horribly unreliable" method with very little testing
$this->assertSame($expected, File::mime($input));
}
/**

View File

@@ -16,6 +16,18 @@
*/
class Kohana_HTMLTest extends Unittest_TestCase
{
/**
* Sets up the environment
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('www\.kohanaframework\.org'));
}
/**
* Defaults for this test
* @var array
@@ -117,6 +129,10 @@ class Kohana_HTMLTest extends Unittest_TestCase
'https',
FALSE
),
array(
'<script type="text/javascript" src="//google.com/script.js"></script>',
'//google.com/script.js',
),
);
}
@@ -193,6 +209,13 @@ class Kohana_HTMLTest extends Unittest_TestCase
'https',
TRUE
),
array(
'<link type="text/css" href="//google.com/style.css" rel="stylesheet" />',
'//google.com/style.css',
array(),
NULL,
FALSE
),
);
}
@@ -223,6 +246,20 @@ class Kohana_HTMLTest extends Unittest_TestCase
public function provider_anchor()
{
return array(
// a fragment-only anchor
array(
'<a href="#go-to-section-kohana">Kohana</a>',
array(),
'#go-to-section-kohana',
'Kohana',
),
// a query-only anchor
array(
'<a href="?cat=a">Category A</a>',
array(),
'?cat=a',
'Category A',
),
array(
'<a href="http://kohanaframework.org">Kohana</a>',
array(),

View File

@@ -15,6 +15,33 @@
*/
class Kohana_HTTPTest extends Unittest_TestCase {
protected $_inital_request;
/**
* Sets up the environment
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('www\.example\.com'));
$this->_initial_request = Request::$initial;
Request::$initial = new Request('/');
}
/**
* Tears down whatever is setUp
*/
// @codingStandardsIgnoreStart
public function tearDown()
// @codingStandardsIgnoreEnd
{
Request::$initial = $this->_initial_request;
parent::tearDown();
}
// @codingStandardsIgnoreStart
/**
* Defaults for this test
* @var array
@@ -84,4 +111,70 @@ class Kohana_HTTPTest extends Unittest_TestCase {
$this->fail('HTTP_Exception_Redirect not thrown');
}
/**
* Provides test data for test_request_headers
*
* @return array
*/
public function provider_request_headers()
{
return array(
array(
array(
'CONTENT_TYPE' => 'text/html; charset=utf-8',
'CONTENT_LENGTH' => '3547',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, sdch',
'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8,fr;q=0.6,hy;q=0.4',
),
array(
'content-type' => 'text/html; charset=utf-8',
'content-length' => '3547',
'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'accept-encoding'=>'gzip, deflate, sdch',
'accept-language'=>'en-US,en;q=0.8,fr;q=0.6,hy;q=0.4',
)
),
array(
array(
'HTTP_WEIRD_HTTP_HEADER' => 'A weird value for a weird header',
),
array(
'weird-http-header' => 'A weird value for a weird header',
)
),
);
}
/**
* Tests HTTP::request_headers()
*
* HTTP::request_headers relies on the $_SERVER superglobal if the function
* `apache_request_headers` or the PECL `http` extension are not available.
*
* The test feeds the $_SERVER superglobal with the test cases' datasets
* and then restores the $_SERVER superglobal so that it does not affect
* other tests.
*
* @test
* @dataProvider provider_request_headers
* @param array $server_globals globals to feed $_SERVER
* @param array $expected_headers Expected, cleaned HTTP headers
*/
public function test_request_headers(array $server_globals, array $expected_headers)
{
// save the $_SERVER super-global into temporary local var
$tmp_server = $_SERVER;
$_SERVER = array_replace_recursive($_SERVER, $server_globals);
$headers = HTTP::request_headers();
$actual_headers = array_intersect_key($headers->getArrayCopy(), $expected_headers);
$this->assertSame($expected_headers, $actual_headers);
// revert the super-global to its previous state
$_SERVER = $tmp_server;
}
}

View File

@@ -23,6 +23,7 @@ class Kohana_RequestTest extends Unittest_TestCase
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('localhost'));
$this->_initial_request = Request::$initial;
Request::$initial = new Request('/');
}
@@ -125,16 +126,15 @@ class Kohana_RequestTest extends Unittest_TestCase
{
$route = new Route('(<controller>(/<action>(/<id>)))');
$uri = 'foo/bar/id';
$uri = 'kohana_requesttest_dummy/foobar/some_id';
$request = Request::factory($uri, NULL, TRUE, array($route));
// We need to execute the request before it has matched a route
try
{
$request->execute();
}
catch (Exception $e) {}
$response = $request->execute();
$controller = new Controller_Kohana_RequestTest_Dummy($request, $response);
$this->assertSame(200, $response->status());
$this->assertSame($controller->get_expected_response(), $response->body());
$this->assertArrayHasKey('id', $request->param());
$this->assertArrayNotHasKey('foo', $request->param());
$this->assertEquals($request->uri(), $uri);
@@ -150,17 +150,16 @@ class Kohana_RequestTest extends Unittest_TestCase
$this->assertArrayNotHasKey('route', $params);
$route = new Route('(<uri>)', array('uri' => '.+'));
$route->defaults(array('controller' => 'foobar', 'action' => 'index'));
$request = Request::factory('foobar', NULL, TRUE, array($route));
$route->defaults(array('controller' => 'kohana_requesttest_dummy', 'action' => 'foobar'));
$request = Request::factory('kohana_requesttest_dummy', NULL, TRUE, array($route));
// We need to execute the request before it has matched a route
try
{
$request->execute();
}
catch (Exception $e) {}
$response = $request->execute();
$controller = new Controller_Kohana_RequestTest_Dummy($request, $response);
$this->assertSame('foobar', $request->param('uri'));
$this->assertSame(200, $response->status());
$this->assertSame($controller->get_expected_response(), $response->body());
$this->assertSame('kohana_requesttest_dummy', $request->param('uri'));
}
/**
@@ -270,6 +269,16 @@ class Kohana_RequestTest extends Unittest_TestCase
'http',
'http://localhost/kohana/foo'
),
array(
'http://www.google.com',
'http',
'http://www.google.com'
),
array(
'0',
'http',
'http://localhost/kohana/0'
)
);
}
@@ -296,7 +305,14 @@ class Kohana_RequestTest extends Unittest_TestCase
'Kohana::$index_file' => FALSE,
));
$this->assertEquals(Request::factory($uri)->url($protocol), $expected);
// issue #3967: inject the route so that we don't conflict with the application's default route
$route = new Route('(<controller>(/<action>))');
$route->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
$this->assertEquals(Request::factory($uri, array(), TRUE, array($route))->url($protocol), $expected);
}
/**
@@ -397,8 +413,15 @@ class Kohana_RequestTest extends Unittest_TestCase
*/
public function provider_uri_only_trimed_on_internal()
{
// issue #3967: inject the route so that we don't conflict with the application's default route
$route = new Route('(<controller>(/<action>))');
$route->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
$old_request = Request::$initial;
Request::$initial = new Request(TRUE);
Request::$initial = new Request(TRUE, array(), TRUE, array($route));
$result = array(
array(
@@ -417,6 +440,14 @@ class Kohana_RequestTest extends Unittest_TestCase
new Request('foo/bar'),
'foo/bar'
),
array(
new Request('/0'),
'0'
),
array(
new Request('0'),
'0'
),
array(
new Request('/'),
'/'
@@ -505,18 +536,18 @@ class Kohana_RequestTest extends Unittest_TestCase
{
$x_powered_by = 'Kohana Unit Test';
$content_type = 'application/x-www-form-urlencoded';
$request = new Request('foo/bar', array(), TRUE, array());
return array(
array(
$request = Request::factory('foo/bar')
->headers(array(
$request->headers(array(
'x-powered-by' => $x_powered_by,
'content-type' => $content_type
)
),
array(
'x-powered-by' => $x_powered_by,
'content-type' => $content_type
array(
'x-powered-by' => $x_powered_by,
'content-type' => $content_type
)
)
);
@@ -548,7 +579,6 @@ class Kohana_RequestTest extends Unittest_TestCase
{
return array(
array(
Request::factory(),
array(
'content-type' => 'application/x-www-form-urlencoded',
'x-test-header' => 'foo'
@@ -556,7 +586,6 @@ class Kohana_RequestTest extends Unittest_TestCase
"Content-Type: application/x-www-form-urlencoded\r\nX-Test-Header: foo\r\n\r\n"
),
array(
Request::factory(),
array(
'content-type' => 'application/json',
'x-powered-by' => 'kohana'
@@ -571,13 +600,13 @@ class Kohana_RequestTest extends Unittest_TestCase
*
* @dataProvider provider_headers_set
*
* @param Request request object
* @param array header(s) to set to the request object
* @param string expected http header
* @return void
*/
public function test_headers_set(Request $request, $headers, $expected)
public function test_headers_set($headers, $expected)
{
$request = new Request(TRUE, array(), TRUE, array());
$request->headers($headers);
$this->assertSame($expected, (string) $request->headers());
}
@@ -707,14 +736,83 @@ class Kohana_RequestTest extends Unittest_TestCase
$this->assertEquals($client->strict_redirect(), FALSE);
}
/**
* Tests correctness request content-length header after calling render
*/
public function test_content_length_after_render()
{
$request = Request::factory('https://example.org/post')
->client(new Kohana_RequestTest_Header_Spying_Request_Client_External)
->method(Request::POST)
->post(array('aaa' => 'bbb'));
$request->render();
$request->execute();
$headers = $request->client()->get_received_request_headers();
$this->assertEquals(strlen($request->body()), $headers['content-length']);
}
/**
* Tests correctness request content-length header after calling render
* and changing post
*/
public function test_content_length_after_changing_post()
{
$request = Request::factory('https://example.org/post')
->client(new Kohana_RequestTest_Header_Spying_Request_Client_External)
->method(Request::POST)
->post(array('aaa' => 'bbb'));
$request->render();
$request->post(array('one' => 'one', 'two' => 'two', 'three' => 'three'));
$request->execute();
$headers = $request->client()->get_received_request_headers();
$this->assertEquals(strlen($request->body()), $headers['content-length']);
}
} // End Kohana_RequestTest
/**
* A dummy Request_Client_External implementation, that spies on the headers
* of the request
*/
class Kohana_RequestTest_Header_Spying_Request_Client_External extends Request_Client_External
{
private $headers;
protected function _send_message(\Request $request, \Response $response)
{
$this->headers = $request->headers();
return $response;
}
public function get_received_request_headers()
{
return $this->headers;
}
}
class Controller_Kohana_RequestTest_Dummy extends Controller
{
public function action_index()
// hard coded dummy response
protected $dummy_response = "this is a dummy response";
public function action_foobar()
{
$this->response->body($this->dummy_response);
}
public function get_expected_response()
{
return $this->dummy_response;
}
} // End Kohana_RequestTest

View File

@@ -171,27 +171,6 @@ class Kohana_ResponseTest extends Unittest_TestCase
$this->assertSame(Cookie::$expiration, $cookie['expiration']);
}
/**
* Tests that the headers are not sent by PHP in CLI mode
*
* @return void
*/
public function test_send_headers_cli()
{
if (headers_sent())
{
$this->markTestSkipped('Cannot test this feature as headers have already been sent!');
}
$content_type = 'application/json';
$response = new Response;
$response->headers('content-type', $content_type)
->send_headers();
$this->assertFalse(headers_sent());
}
/**
* Test the content type is sent when set
*
@@ -205,4 +184,4 @@ class Kohana_ResponseTest extends Unittest_TestCase
$headers = $response->send_headers()->headers();
$this->assertSame($content_type, (string) $headers['content-type']);
}
}
}

View File

@@ -28,6 +28,8 @@ class Kohana_RouteTest extends Unittest_TestCase
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('kohanaframework\.org'));
$this->cleanCacheDir();
}
@@ -268,11 +270,7 @@ class Kohana_RouteTest extends Unittest_TestCase
$route = new Route($uri);
// Mock a request class with the $match uri
$stub = $this->getMock('Request', array('uri'), array($match));
$stub->expects($this->any())
->method('uri')
// Request::uri() called by Route::matches() will return $match
->will($this->returnValue($match));
$stub = $this->get_request_mock($match);
$this->assertSame(FALSE, $route->matches($stub));
}
@@ -308,11 +306,7 @@ class Kohana_RouteTest extends Unittest_TestCase
$route = new Route($uri);
// Mock a request class with the $m uri
$request = $this->getMock('Request', array('uri'), array($m));
$request->expects($this->any())
->method('uri')
// Request::uri() called by Route::matches() will return $m
->will($this->returnValue($m));
$request = $this->get_request_mock($m);
$matches = $route->matches($request);
@@ -381,10 +375,7 @@ class Kohana_RouteTest extends Unittest_TestCase
$this->assertSame($defaults, $route->defaults());
// Mock a request class
$request = $this->getMock('Request', array('uri'), array($default_uri));
$request->expects($this->any())
->method('uri')
->will($this->returnValue($default_uri));
$request = $this->get_request_mock($default_uri);
$matches = $route->matches($request);
@@ -550,28 +541,19 @@ class Kohana_RouteTest extends Unittest_TestCase
$route = new Route($uri);
// Mock a request class that will return empty uri
$request = $this->getMock('Request', array('uri'), array(''));
$request->expects($this->any())
->method('uri')
->will($this->returnValue(''));
$request = $this->get_request_mock('');
$this->assertFalse($route->matches($request));
// Mock a request class that will return route1
$request = $this->getMock('Request', array('uri'), array($matches_route1));
$request->expects($this->any())
->method('uri')
->will($this->returnValue($matches_route1));
$request = $this->get_request_mock($matches_route1);
$matches = $route->matches($request);
$this->assertInternalType('array', $matches);
// Mock a request class that will return route2 uri
$request = $this->getMock('Request', array('uri'), array($matches_route2));
$request->expects($this->any())
->method('uri')
->will($this->returnValue($matches_route2));
$request = $this->get_request_mock($matches_route2);
$matches = $route->matches($request);
@@ -899,14 +881,78 @@ class Kohana_RouteTest extends Unittest_TestCase
$route = new Route($route);
// Mock a request class
$request = $this->getMock('Request', array('uri'), array($uri));
$request->expects($this->any())
->method('uri')
->will($this->returnValue($uri));
$request = $this->get_request_mock($uri);
$params = $route->defaults($defaults)->filter($filter)->matches($request);
$this->assertSame($expected_params, $params);
}
/**
* Provides test data for test_route_uri_encode_parameters
*
* @return array
*/
public function provider_route_uri_encode_parameters()
{
return array(
array(
'article',
'blog/article/<article_name>',
array(
'controller' => 'home',
'action' => 'index'
),
'article_name',
'Article name with special chars \\ ##',
'blog/article/Article%20name%20with%20special%20chars%20\\%20%23%23'
)
);
}
/**
* http://dev.kohanaframework.org/issues/4079
*
* @test
* @covers Route::get
* @ticket 4079
* @dataProvider provider_route_uri_encode_parameters
*/
public function test_route_uri_encode_parameters($name, $uri_callback, $defaults, $uri_key, $uri_value, $expected)
{
Route::set($name, $uri_callback)->defaults($defaults);
$get_route_uri = Route::get($name)->uri(array($uri_key => $uri_value));
$this->assertSame($expected, $get_route_uri);
}
/**
* Get a mock of the Request class with a mocked `uri` method
*
* We are also mocking `method` method as it conflicts with newer PHPUnit,
* in order to avoid the fatal errors
*
* @param string $uri
* @return type
*/
public function get_request_mock($uri)
{
// Mock a request class with the $uri uri
$request = $this->getMock('Request', array('uri', 'method'), array($uri));
// mock `uri` method
$request->expects($this->any())
->method('uri')
// Request::uri() called by Route::matches() in the tests will return $uri
->will($this->returnValue($uri));
// also mock `method` method
$request->expects($this->any())
->method('method')
->withAnyParameters();
return $request;
}
}

View File

@@ -67,17 +67,6 @@ class Kohana_SecurityTest extends Unittest_TestCase
*/
public function provider_csrf_token()
{
// Unfortunately this data provider has to use the session in order to
// generate its data. If headers have already been sent then this method
// throws an error, even if the test is does not run. If we return an
// empty array then this also causes an error, so the only way to get
// around it is to return an array of misc data and have the test skip
// if headers have been sent. It's annoying this hack has to be
// implemented, but the security code isn't exactly brilliantly
// implemented. Ideally we'd be able to inject a session instance
if (headers_sent())
return array(array('', '', 0));
$array = array();
for ($i = 0; $i <= 4; $i++)
{
@@ -96,10 +85,7 @@ class Kohana_SecurityTest extends Unittest_TestCase
*/
public function test_csrf_token($expected, $input, $iteration)
{
if (headers_sent()) {
$this->markTestSkipped('Headers have already been sent, session not available');
}
//@todo: the Security::token tests need to be reviewed to check how much of the logic they're actually covering
Security::$token_name = 'token_'.$iteration;
$this->assertSame(TRUE, $input);
$this->assertSame($expected, Security::token(FALSE));

View File

@@ -95,20 +95,14 @@ class Kohana_SessionTest extends Unittest_TestCase
*/
public function test_constructor_loads_session_with_session_id()
{
$this->markTestIncomplete(
'Need to work out why constructor is not being called'
);
$config = array();
$session_id = 'lolums';
// Don't auto-call constructor, we need to setup the mock first
$session = $this->getMockForAbstractClass(
'Session',
array(),
'',
FALSE
);
$session = $this->getMockBuilder('Session')
->disableOriginalConstructor()
->setMethods(array('read'))
->getMockForAbstractClass();
$session
->expects($this->once())

View File

@@ -196,6 +196,30 @@ class Kohana_TextTest extends Unittest_TestCase
$this->assertSame('yes', Text::alternate($val_a, $val_b, $val_c));
}
/**
* Provides test data for test_ucfirst
*
* @return array Test data
*/
public function provider_ucfirst()
{
return array(
array('Content-Type', 'content-type', '-'),
array('Բարեւ|Ձեզ', 'բարեւ|ձեզ', '|'),
);
}
/**
* Covers Text::ucfirst()
*
* @test
* @dataProvider provider_ucfirst
*/
public function test_ucfirst($expected, $string, $delimiter)
{
$this->assertSame($expected, Text::ucfirst($string, $delimiter));
}
/**
* Provides test data for test_reducde_slashes()
*
@@ -386,9 +410,90 @@ class Kohana_TextTest extends Unittest_TestCase
{
return array
(
array('No gain, no&nbsp;pain', 'No gain, no pain'),
array("spaces?what'rethey?", "spaces?what'rethey?"),
array('', ''),
// A very simple widont test
array(
'A very simple&nbsp;test',
'A very simple test',
),
// Single word items shouldn't be changed
array(
'Test',
'Test',
),
// Single word after single space shouldn't be changed either
array(
' Test',
' Test',
),
// Single word with HTML all around
array(
'<ul><li><p>Test</p></li><ul>',
'<ul><li><p>Test</p></li><ul>',
),
// Single word after single space with HTML all around
array(
'<ul><li><p> Test</p></li><ul>',
'<ul><li><p> Test</p></li><ul>',
),
// Widont with more than one paragraph
array(
'<p>In a couple of&nbsp;paragraphs</p><p>paragraph&nbsp;two</p>',
'<p>In a couple of paragraphs</p><p>paragraph two</p>',
),
// a link inside a heading
array(
'<h1><a href="#">In a link inside a&nbsp;heading </a></h1>',
'<h1><a href="#">In a link inside a heading </a></h1>',
),
// a link followed by text
array(
'<h1><a href="#">In a link</a> followed by other&nbsp;text</h1>',
'<h1><a href="#">In a link</a> followed by other text</h1>',
),
// empty html, with no text inside
array(
'<h1><a href="#"></a></h1>',
'<h1><a href="#"></a></h1>',
),
// apparently, we don't love DIVs
array(
'<div>Divs get no love!</div>',
'<div>Divs get no love!</div>',
),
// we don't love PREs, either
array(
'<pre>Neither do PREs</pre>',
'<pre>Neither do PREs</pre>',
),
// but we love DIVs with paragraphs
array(
'<div><p>But divs with paragraphs&nbsp;do!</p></div>',
'<div><p>But divs with paragraphs do!</p></div>',
),
array(
'No gain, no&nbsp;pain',
'No gain, no pain',
),
array(
"spaces?what'rethey?",
"spaces?what'rethey?",
),
/*
* // @issue 3499, with HTML at the end
* array(
* 'with HTML at the end &nbsp;<strong>Kohana</strong>',
* 'with HTML at the end <strong>Kohana</strong>',
* ),
* // @issue 3499, with HTML with attributes at the end
* array(
* 'with HTML at the end:&nbsp;<a href="#" title="Kohana">Kohana</a>',
* 'with HTML at the end: <a href="#" title="Kohana">Kohana</a>',
* ),
*/
array(
'',
'',
),
);
}
@@ -639,4 +744,111 @@ class Kohana_TextTest extends Unittest_TestCase
}
public function provider_user_agents()
{
return array(
array(
"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
array(
'browser' => 'Chrome',
'version' => '37.0.2049.0',
'platform' => "Windows 8.1"
)
),
array(
"Mozilla/5.0 (Macintosh; U; Mac OS X 10_6_1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/ Safari/530.5",
array(
'browser' => 'Chrome',
'version' => '530.5',
'platform' => "Mac OS X"
)
),
array(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
array(
'browser' => 'Safari',
'version' => '534.57.2',
'platform' => 'Mac OS X'
)
),
array(
"Lynx/2.8.8dev.3 libwww-FM/2.14 SSL-MM/1.4.1",
array(
'browser' => 'Lynx',
'version' => '2.8.8dev.3',
'platform' => false
)
)
);
}
/**
* Tests Text::user_agent
*
* @dataProvider provider_user_agents
* @group current
*/
public function test_user_agent_returns_correct_browser($userAgent, $expectedData)
{
$browser = Text::user_agent($userAgent, 'browser');
$this->assertEquals($expectedData['browser'], $browser);
}
/**
* Tests Text::user_agent
*
* @dataProvider provider_user_agents
* @test
*/
public function test_user_agent_returns_correct_version($userAgent, $expectedData)
{
$version = Text::user_agent($userAgent, 'version');
$this->assertEquals($expectedData['version'], $version);
}
/**
* Tests Text::user_agent
* @test
*/
public function test_user_agent_recognizes_robots()
{
$bot = Text::user_agent('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', 'robot');
$this->assertEquals('Googlebot', $bot);
}
/**
* Tests Text::user_agent
*
* @dataProvider provider_user_agents
* @test
*/
public function test_user_agent_returns_correct_platform($userAgent, $expectedData)
{
$platform = Text::user_agent($userAgent, 'platform');
$this->assertEquals($expectedData['platform'], $platform);
}
/**
* Tests Text::user_agent
* @test
*/
public function test_user_agent_accepts_array()
{
$agent_info = Text::user_agent(
'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 '.
'(KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36',
array('browser', 'version', 'platform'));
$this->assertArrayHasKey('browser', $agent_info);
$this->assertArrayHasKey('version', $agent_info);
$this->assertArrayHasKey('platform', $agent_info);
}
}

View File

@@ -16,6 +16,18 @@
*/
class Kohana_URLTest extends Unittest_TestCase
{
/**
* Sets up the environment
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana::$config->load('url')->set('trusted_hosts', array('example\.com', 'example\.org'));
}
/**
* Default values for the environment, see setEnvironment
* @var array
@@ -276,4 +288,95 @@ class Kohana_URLTest extends Unittest_TestCase
URL::query($params, $use_get)
);
}
/**
* Provides test data for URL::is_trusted_host()
* @return array
*/
public function provider_is_trusted_host()
{
return array(
// data set #0
array(
'givenhost',
array(
'list-of-trusted-hosts',
),
FALSE
),
// data set #1
array(
'givenhost',
array(
'givenhost',
'example\.com',
),
TRUE
),
// data set #2
array(
'www.kohanaframework.org',
array(
'.*\.kohanaframework\.org',
),
TRUE
),
// data set #3
array(
'kohanaframework.org',
array(
'.*\.kohanaframework\.org',
),
FALSE // because we are requesting a subdomain
),
);
}
/**
* Tests URL::is_trusted_hosts()
*
* @test
* @dataProvider provider_is_trusted_host
* @param string $host the given host
* @param array $trusted_hosts list of trusted hosts
* @param boolean $expected TRUE if host is trusted, FALSE otherwise
*/
public function test_is_trusted_host($host, $trusted_hosts, $expected)
{
$this->assertSame(
$expected,
URL::is_trusted_host($host, $trusted_hosts)
);
}
/**
* Tests if invalid host throws "Invalid host" exception
*
* @test
* @expectedException Kohana_Exception
* @expectedExceptionMessage Invalid host <invalid>
*/
public function test_if_invalid_host_throws_exception()
{
// set the global HTTP_HOST to <invalid>
$_SERVER['HTTP_HOST'] = '<invalid>';
// trigger exception
URL::base('https');
}
/**
* Tests if untrusted host throws "Untrusted host" exception
*
* @test
* @expectedException Kohana_Exception
* @expectedExceptionMessage Untrusted host untrusted.com
*/
public function test_if_untrusted_host_throws_exception()
{
// set the global HTTP_HOST to a valid but untrusted host
$_SERVER['HTTP_HOST'] = 'untrusted.com';
// trigger exception
URL::base('https');
}
}

View File

@@ -673,4 +673,48 @@ class Kohana_ValidationTest extends Unittest_TestCase
$this->assertSame($errors, $validation->errors('validation'));
}
/**
* Provides test data for test_rule_label_regex
*
* @return array
*/
public function provider_rule_label_regex()
{
// $data, $field, $rules, $expected
return array(
array(
array(
'email1' => '',
),
'email1',
array(
array(
'not_empty'
)
),
array(
'email1' => 'email1 must not be empty'
),
)
);
}
/**
* http://dev.kohanaframework.org/issues/4201
*
* @test
* @ticket 4201
* @covers Validation::rule
* @dataProvider provider_rule_label_regex
*/
public function test_rule_label_regex($data, $field, $rules, $expected)
{
$validation = Validation::factory($data)->rules($field, $rules);
$validation->check();
$errors = $validation->errors('');
$this->assertSame($errors, $expected);
}
}

View File

@@ -60,9 +60,23 @@ class Kohana_ViewTest extends Unittest_TestCase
);
}
/**
* Provider to test_set
*
* @return array
*/
public function provider_set()
{
return array(
array('foo', 'bar', 'foo', 'bar'),
array(array('foo' => 'bar'), NULL, 'foo', 'bar'),
array(new ArrayIterator(array('foo' => 'bar')), NULL, 'foo', 'bar'),
);
}
/**
* Tests that we can instantiate a view file
*
*
* @test
* @dataProvider provider_instantiate
*
@@ -80,4 +94,33 @@ class Kohana_ViewTest extends Unittest_TestCase
$this->assertSame(TRUE, $expects_exception);
}
}
/**
* Tests that we can set using string, array or Traversable object
*
* @test
* @dataProvider provider_set
*
* @return null
*/
public function test_set($data_key, $value, $test_key, $expected)
{
$view = View::factory()->set($data_key, $value);
$this->assertSame($expected, $view->$test_key);
}
/**
* Tests that we can set global using string, array or Traversable object
*
* @test
* @dataProvider provider_set
*
* @return null
*/
public function test_set_global($data_key, $value, $test_key, $expected)
{
$view = View::factory();
$view::set_global($data_key, $value);
$this->assertSame($expected, $view->$test_key);
}
}

View File

@@ -17,6 +17,30 @@
*/
class Kohana_Request_Client_InternalTest extends Unittest_TestCase
{
protected $_log_object;
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
// temporarily save $log object
$this->_log_object = Kohana::$log;
Kohana::$log = NULL;
}
// @codingStandardsIgnoreStart
public function tearDown()
// @codingStandardsIgnoreEnd
{
// re-assign log object
Kohana::$log = $this->_log_object;
parent::tearDown();
}
public function provider_response_failure_status()
{
return array(
@@ -37,7 +61,7 @@ class Kohana_Request_Client_InternalTest extends Unittest_TestCase
public function test_response_failure_status($directory, $controller, $action, $uri, $expected)
{
// Mock for request object
$request = $this->getMock('Request', array('directory', 'controller', 'action', 'uri', 'response'), array($uri));
$request = $this->getMock('Request', array('directory', 'controller', 'action', 'uri', 'response', 'method'), array($uri));
$request->expects($this->any())
->method('directory')
@@ -59,10 +83,15 @@ class Kohana_Request_Client_InternalTest extends Unittest_TestCase
->method('response')
->will($this->returnValue($this->getMock('Response')));
// mock `method` method to avoid fatals in newer versions of PHPUnit
$request->expects($this->any())
->method('method')
->withAnyParameters();
$internal_client = new Request_Client_Internal;
$response = $internal_client->execute($request);
$this->assertSame($expected, $response->status());
}
}
}

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Kohana v3.x: Activity</title>
<link href="http://dev.kohanaframework.org/projects/kohana3/activity.atom" rel="self"/>
<link href="http://dev.kohanaframework.org/projects/kohana3/activity" rel="alternate"/>
<id>http://dev.kohanaframework.org/</id>
<icon>http://dev.kohanaframework.org/favicon.ico?1392677580</icon>
<updated>2014-08-28T01:52:12Z</updated>
<author>
<name>Kohana Development</name>
</author>
<generator uri="http://www.redmine.org/">
Redmine </generator>
<entry>
<title>Proposals (Political/Workflow) #4839 (New)</title>
<link href="http://dev.kohanaframework.org/issues/4839" rel="alternate"/>
<id>http://dev.kohanaframework.org/issues/4839</id>
<updated>2014-08-28T01:52:12Z</updated>
<author>
<name>Guillaume Poirier-Morency</name>
<email>guillaumepoiriermorency@gmail.com</email>
</author>
<content type="html">
&lt;p&gt;I have a prototype here &lt;a class="external" href="https://github.com/arteymix/kohana-makefile"&gt;https://github.com/arteymix/kohana-makefile&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The tool is very useful for settings permissions and running tests.&lt;/p&gt;
&lt;p&gt;I think we should consider having a good make tool in the sample application for the 3.4.*.&lt;/p&gt; </content>
</entry>
<entry>
<title>Proposals (Political/Workflow) #4782</title>
<link href="http://dev.kohanaframework.org/issues/4782#change-17279" rel="alternate"/>
<id>http://dev.kohanaframework.org/issues/4782#change-17279</id>
<updated>2014-08-28T01:44:26Z</updated>
<author>
<name>Guillaume Poirier-Morency</name>
<email>guillaumepoiriermorency@gmail.com</email>
</author>
<content type="html">
&lt;p&gt;Moving to composer is a nice idea. This will allow Kohana modules to define a wide range of dependencies.&lt;/p&gt;
&lt;p&gt;Although, I think that modules designed specifically for Kohana should end in modules and external libraries in application/vendor. This makes a clear dinsinction between what gets autoloaded by the CFS and what gets loaded by composer. Technically, we add "vendor-dir": "application/vendor" in "config" in composer.json.&lt;/p&gt;
&lt;p&gt;Then, only add a line after the modules loading in bootstrap.php&lt;/p&gt;
&lt;pre&gt;
// Autoloading composer packages
require Kohana::find_file('vendor', 'autoload');
&lt;/pre&gt;
&lt;p&gt;This is pretty much what I do right now. This doesn't break anything and allow a full access to composer.&lt;/p&gt; </content>
</entry>
</feed>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>RSS Title</title>
<description>This is an example of an RSS feed</description>
<link>http://www.example.com/main.html</link>
<lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000 </lastBuildDate>
<pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
<ttl>1800</ttl>
<item>
<title>Example entry</title>
<description>Here is some text containing an interesting description.</description>
<link>http://www.example.com/blog/post/1</link>
<guid>7bd204c6-1655-4c27-aeee-53f933c5395f</guid>
<pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
</item>
</channel>
</rss>

View File

@@ -0,0 +1,6 @@
<?php
// See the Kohana_CoreTest tests for Kohana::message
return array(
'bottom_only' => 'inherited bottom message',
'cfs_replaced' => 'inherited cfs_replaced message',
);

View File

@@ -0,0 +1,6 @@
<?php
// See the Kohana_CoreTest tests for Kohana::message
return array(
'top_only' => 'top only message',
'cfs_replaced' => 'overriding cfs_replaced message',
);