* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); require_once($_test_dir.'/unit/sfContextMock.class.php'); $t = new lime_test(41); function get_cache_manager($context) { myCache::clear(); $m = new myViewCacheManager($context, new myCache()); return $m; } function get_cache_config($contextual = false) { return array( 'withLayout' => false, 'lifeTime' => 86400, 'clientLifeTime' => 86400, 'contextual' => $contextual, 'vary' => array(), ); } class myViewCacheManager extends sfViewCacheManager { public function registerConfiguration($moduleName) { } } class myController extends sfWebController { } class myRequest { public $getParameters = array('page' => 5, 'sort' => 'asc'); public function getHost() { return 'localhost'; } public function getScriptName() { return 'index.php'; } public function getHttpHeader($headerName) { return '/foo#|#/bar/'; } public function getGetParameters() { return $this->getParameters; } } class myCache extends sfCache { static public $cache = array(); public function initialize($parameters = array()) { } public function get($key, $default = null) { return isset(self::$cache[$key]) ? self::$cache[$key] : $default; } public function has($key) { return isset(self::$cache[$key]); } public function set($key, $data, $lifetime = null) { self::$cache[$key] = $data; } public function remove($key) { unset(self::$cache[$key]); } public function removePattern($pattern, $delimiter = ':') { $pattern = '#^' . str_replace('*', '.*', $pattern) . '$#'; foreach(self::$cache as $key => $value) { if(preg_match($pattern, $key)) { unset(self::$cache[$key]); } } } public function clean($mode = sfCache::ALL) { self::$cache = array(); } public function getTimeout($key) { return time() - 60; } public function getLastModified($key) { return time() - 600; } static public function clear() { self::$cache = array(); } } class myRouting extends sfPatternRouting { public $currentInternalUri = 'currentModule/currentAction?currentKey=currentValue'; public function getCurrentInternalUri($with_route_name = false) { return $this->currentInternalUri; } } $context = sfContext::getInstance(array('controller' => 'myController', 'routing' => 'myRouting', 'request' => 'myRequest')); $r = $context->routing; $r->connect('default', new sfRoute('/:module/:action/*')); // ->initialize() $t->diag('->initialize()'); $m = new myViewCacheManager($context, $cache = new myCache()); $t->is($m->getCache(), $cache, '->initialize() takes a sfCache object as its second argument'); // ->generateCacheKey() $t->diag('->generateCacheKey'); $t->is($m->generateCacheKey('mymodule/myaction'), '/localhost/all/mymodule/myaction', '->generateCacheKey() creates a simple cache key from an internal URI'); $t->is($m->generateCacheKey('mymodule/myaction', 'foo'), '/foo/all/mymodule/myaction', '->generateCacheKey() can take a hostName as second parameter'); $t->is($m->generateCacheKey('mymodule/myaction', null, 'bar'), '/localhost/bar/mymodule/myaction', '->generateCacheKey() can take a serialized set of vary headers as third parameter'); $t->is($m->generateCacheKey('mymodule/myaction?key1=value1&key2=value2'), '/localhost/all/mymodule/myaction/key1/value1/key2/value2', '->generateCacheKey() includes request parameters as key/value pairs'); $t->is($m->generateCacheKey('mymodule/myaction?akey=value1&ckey=value2&bkey=value3'), '/localhost/all/mymodule/myaction/akey/value1/bkey/value3/ckey/value2', '->generateCacheKey() reorders request parameters alphabetically'); try { $m->generateCacheKey('@rule?key=value'); $t->fail('->generateCacheKey() throws an sfException when passed an internal URI with a rule'); } catch(sfException $e) { $t->pass('->generateCacheKey() throws an sfException when passed an internal URI with a rule'); } try { $m->generateCacheKey('@sf_cache_partial?module=mymodule&action=myaction'); $t->pass('->generateCacheKey() does not throw an sfException when passed an internal URI with a @sf_cache_partial rule'); } catch(sfException $e) { $t->fail('->generateCacheKey() does not throw an sfException when passed an internal URI with a @sf_cache_partial rule'); } try { $m->generateCacheKey('@sf_cache_partial?key=value'); $t->fail('->generateCacheKey() throws an sfException when passed an internal URI with a @sf_cache_partial rule with no module or action param'); } catch(sfException $e) { $t->pass('->generateCacheKey() throws an sfException when passed an internal URI with a @sf_cache_partial rule with no module or action param'); } $t->is($m->generateCacheKey('@sf_cache_partial?module=foo&action=bar&sf_cache_key=value'), '/localhost/all/sf_cache_partial/foo/bar/sf_cache_key/value', '->generateCacheKey() can deal with internal URIs to partials'); $m = get_cache_manager($context); $m->addCache('foo', 'bar', get_cache_config(true)); $t->is($m->generateCacheKey('@sf_cache_partial?module=foo&action=bar&sf_cache_key=value'), '/localhost/all/currentModule/currentAction/currentKey/currentValue/foo/bar/value', '->generateCacheKey() can deal with internal URIs to contextual partials'); $t->is($m->generateCacheKey('@sf_cache_partial?module=foo&action=bar&sf_cache_key=value', null, null, 'baz'), '/localhost/all/baz/foo/bar/value', '->generateCacheKey() can take a prefix for contextual partials as fourth parameter'); $m = get_cache_manager($context); $m->addCache('module', 'action', array('vary' => array('myheader', 'secondheader'))); $t->is($m->generateCacheKey('module/action'), '/localhost/myheader-_foo_bar_-secondheader-_foo_bar_/module/action', '->generateCacheKey() creates a directory friendly vary cache key'); // ->generateNamespace() $t->diag('->generateNamespace()'); $m = get_cache_manager($context); // ->addCache() $t->diag('->addCache()'); $m = get_cache_manager($context); $m->set('test', 'module/action'); $t->is($m->has('module/action'), false, '->addCache() register a cache configuration for an action'); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action'); $t->is($m->get('module/action'), 'test', '->addCache() register a cache configuration for an action'); // ->set() $t->diag('->set()'); $m = get_cache_manager($context); $t->is($m->set('test', 'module/action'), false, '->set() returns false if the action is not cacheable'); $m->addCache('module', 'action', get_cache_config()); $t->is($m->set('test', 'module/action'), true, '->set() returns true if the action is cacheable'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action'); $t->is($m->get('module/action'), 'test', '->set() stores the first parameter in a key computed from the second parameter'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action?key1=value1'); $t->is($m->get('module/action?key1=value1'), 'test', '->set() works with URIs with parameters'); $t->is($m->get('module/action?key2=value2'), null, '->set() stores a different version for each set of parameters'); $t->is($m->get('module/action'), null, '->set() stores a different version for each set of parameters'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config()); $m->set('test', '@sf_cache_partial?module=module&action=action'); $t->is($m->get('@sf_cache_partial?module=module&action=action'), 'test', '->set() accepts keys to partials'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config(true)); $m->set('test', '@sf_cache_partial?module=module&action=action'); $t->is($m->get('@sf_cache_partial?module=module&action=action'), 'test', '->set() accepts keys to contextual partials'); // ->get() $t->diag('->get()'); $m = get_cache_manager($context); $t->is($m->get('module/action'), null, '->get() returns null if the action is not cacheable'); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action'); $t->is($m->get('module/action'), 'test', '->get() returns the saved content if the action is cacheable'); // ->has() $t->diag('->has()'); $m = get_cache_manager($context); $t->is($m->has('module/action'), false, '->has() returns false if the action is not cacheable'); $m->addCache('module', 'action', get_cache_config()); $t->is($m->has('module/action'), false, '->has() returns the cache does not exist for the action'); $m->set('test', 'module/action'); $t->is($m->has('module/action'), true, '->get() returns true if the action is in cache'); // ->remove() $t->diag('->remove()'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action'); $m->remove('module/action'); $t->is($m->has('module/action'), false, '->remove() removes cache content for an action'); $m->set('test', 'module/action?key1=value1'); $m->set('test', 'module/action?key2=value2'); $m->remove('module/action?key1=value1'); $t->is($m->has('module/action?key1=value1'), false, '->remove() removes accepts an internal URI as first parameter'); $t->is($m->has('module/action?key2=value2'), true, '->remove() does not remove cache content for keys not matching the internal URI'); $m = get_cache_manager($context); $m->addCache('module', 'action', get_cache_config()); $m->set('test', 'module/action?key1=value1'); $m->set('test', 'module/action?key1=value2'); $m->set('test', 'module/action?key2=value1'); $m->remove('module/action?key1=*'); $t->is($m->has('module/action?key1=value1'), false, '->remove() accepts wildcards in URIs and then removes all keys matching the pattern'); $t->is($m->has('module/action?key1=value2'), false, '->remove() accepts wildcards in URIs and then removes all keys matching the pattern'); $t->is($m->has('module/action?key2=value1'), true, '->remove() accepts wildcards in URIs and lets keys not matching the pattern unchanged'); $t->diag('Cache key generation options'); $m = new myViewCacheManager($context, $cache = new myCache(), array('cache_key_use_vary_headers' => false)); $t->is($m->generateCacheKey('mymodule/myaction'), '/localhost/mymodule/myaction', '->generateCacheKey() uses "cache_key_use_vary_headers" option to know if vary headers changes cache key.'); $m = new myViewCacheManager($context, $cache = new myCache(), array('cache_key_use_host_name' => false)); $t->is($m->generateCacheKey('mymodule/myaction'), '/all/mymodule/myaction', '->generateCacheKey() uses "cache_key_use_host_name" option to know if vary headers changes cache key.'); $m = new myViewCacheManager($context, $cache = new myCache(), array('cache_key_use_host_name' => false, 'cache_key_use_vary_headers' => false)); $t->is($m->generateCacheKey('mymodule/myaction'), '/mymodule/myaction', '->generateCacheKey() allows the use of both "cache_key_use_host_name" and "cache_key_use_vary_headers" options.'); $m = new myViewCacheManager($context, new myCache()); $t->is($m->generateCacheKey('mymodule/myaction?foo=../_bar'), '/localhost/all/mymodule/myaction/foo/_../__bar', '->generateCacheKey() prevents directory traversal'); $t->is($m->generateCacheKey('mymodule/myaction?foo=..\\_bar'), '/localhost/all/mymodule/myaction/foo/_..\\__bar', '->generateCacheKey() prevents directory traversal'); // ->getCurrentCacheKey() $t->diag('->getCurrentCacheKey()'); $m = get_cache_manager($context); $t->is($m->getCurrentCacheKey(), 'currentModule/currentAction?currentKey=currentValue&page=5&sort=asc', '->getCurrentCacheKey() appends GET parameters to an existing query string'); $context->getRouting()->currentInternalUri = 'currentModule/currentAction'; $t->is($m->getCurrentCacheKey(), 'currentModule/currentAction?page=5&sort=asc', '->getCurrentCacheKey() adds a query string of GET parameters if none is there');