This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
lnkohana/system/tests/kohana/CookieTest.php
2016-05-01 20:50:24 +10:00

326 lines
9.0 KiB
PHP

<?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
/**
* Tests the cookie class
*
* @group kohana
* @group kohana.core
* @group kohana.core.cookie
*
* @package Kohana
* @category Tests
* @author Kohana Team
* @author Jeremy Bush <contractfrombelow@gmail.com>
* @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;
/**
* Sets up the environment
*/
// @codingStandardsIgnoreStart
public function setUp()
// @codingStandardsIgnoreEnd
{
parent::setUp();
Kohana_CookieTest_TestableCookie::$_mock_cookies_set = array();
$this->setEnvironment(array(
'Cookie::$salt' => 'some-random-salt',
'HTTP_USER_AGENT' => 'cli'
));
}
/**
* 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
protected function assertDeletedCookie($name)
// @codingStandardsIgnoreEnd
{
$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
));
}
/**
* Verify that there was a single call to setcookie including the provided named arguments
*
* @param array $expected
*/
// @codingStandardsIgnoreStart
protected function assertSetCookieWith($expected)
// @codingStandardsIgnoreEnd
{
$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);
}
/**
* Configure the $_SERVER[HTTP_USER_AGENT] environment variable for the test
*
* @param string $user_agent
*/
protected function set_or_remove_http_user_agent($user_agent)
{
if ($user_agent === NULL)
{
unset($_SERVER['HTTP_USER_AGENT']);
}
else
{
$_SERVER['HTTP_USER_AGENT'] = $user_agent;
}
}
}
/**
* 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;
}
}