[\s\r\n]*/';
/**
* Helper to be tested
*
* @var \Cake\View\Helper\HtmlHelper
*/
public $Html;
/**
* Mocked view
*
* @var \Cake\View\View|\PHPUnit_Framework_MockObject_MockObject
*/
public $View;
/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$request = new ServerRequest([
'webroot' => '',
]);
$this->View = $this->getMockBuilder('Cake\View\View')
->setMethods(['append'])
->setConstructorArgs([$request])
->getMock();
$this->Html = new HtmlHelper($this->View);
$this->loadPlugins(['TestTheme']);
static::setAppNamespace();
Configure::write('Asset.timestamp', false);
}
/**
* tearDown method
*
* @return void
*/
public function tearDown()
{
parent::tearDown();
$this->clearPlugins();
unset($this->Html, $this->View);
}
/**
* testDocType method
*
* @return void
*/
public function testDocType()
{
$result = $this->Html->docType();
$expected = '';
$this->assertEquals($expected, $result);
$result = $this->Html->docType('html4-strict');
$expected = '';
$this->assertEquals($expected, $result);
$this->assertNull($this->Html->docType('non-existing-doctype'));
}
/**
* testLink method
*
* @return void
*/
public function testLink()
{
Router::reload();
Router::connect('/:controller/:action/*');
$this->View->setRequest($this->View->getRequest()->withAttribute('webroot', ''));
$result = $this->Html->link('/home');
$expected = ['a' => ['href' => '/home'], 'preg:/\/home/', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link(['action' => 'login', '<[You]>']);
$expected = [
'a' => ['href' => '/login/%3C%5BYou%5D%3E'],
'preg:/\/login\/<\[You\]>/',
'/a',
];
$this->assertHtml($expected, $result);
Router::reload();
Router::connect('/:controller', ['action' => 'index']);
Router::connect('/:controller/:action/*');
$result = $this->Html->link('Posts', ['controller' => 'posts', 'action' => 'index', '_full' => true]);
$expected = ['a' => ['href' => Router::fullBaseUrl() . '/posts'], 'Posts', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Home', '/home', ['confirm' => 'Are you sure you want to do this?']);
$expected = [
'a' => ['href' => '/home', 'onclick' => 'if (confirm("Are you sure you want to do this?")) { return true; } return false;'],
'Home',
'/a',
];
$this->assertHtml($expected, $result);
$this->Html->setTemplates(['confirmJs' => 'if (confirm({{confirmMessage}})) { window.location="/";};']);
$result = $this->Html->link('Home', '/home', ['confirm' => 'Are you sure you want to do this?']);
$expected = [
'a' => ['href' => '/home', 'onclick' => 'preg:/if \(confirm\("Are you sure you want to do this\?"\)\) \{ window\.location="\/";\};/'],
'Home',
'/a',
];
$this->assertHtml($expected, $result);
$this->Html->setTemplates(['confirmJs' => '{{confirm}}']);
$result = $this->Html->link('Home', '/home', ['escape' => false, 'confirm' => 'Confirm\'s "nightmares"']);
$expected = [
'a' => ['href' => '/home', 'onclick' => 'if (confirm("Confirm's \"nightmares\"")) { return true; } return false;'],
'Home',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Home', '/home', ['onclick' => 'someFunction();']);
$expected = [
'a' => ['href' => '/home', 'onclick' => 'someFunction();'],
'Home',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#');
$expected = [
'a' => ['href' => '#'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', ['escape' => true]);
$expected = [
'a' => ['href' => '#'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', ['escape' => 'utf-8']);
$expected = [
'a' => ['href' => '#'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', ['escape' => false]);
$expected = [
'a' => ['href' => '#'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', [
'title' => 'to escape … or not escape?',
'escape' => false,
]);
$expected = [
'a' => ['href' => '#', 'title' => 'to escape … or not escape?'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', [
'title' => 'to escape … or not escape?',
'escape' => true,
]);
$expected = [
'a' => ['href' => '#', 'title' => 'to escape … or not escape?'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Next >', '#', [
'title' => 'Next >',
'escapeTitle' => false,
]);
$expected = [
'a' => ['href' => '#', 'title' => 'Next >'],
'Next >',
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Original size', [
'controller' => 'images', 'action' => 'view', 3, '?' => ['height' => 100, 'width' => 200],
]);
$expected = [
'a' => ['href' => '/images/view/3?height=100&width=200'],
'Original size',
'/a',
];
$this->assertHtml($expected, $result);
Configure::write('Asset.timestamp', false);
$result = $this->Html->link($this->Html->image('test.gif'), '#', ['escape' => false]);
$expected = [
'a' => ['href' => '#'],
'img' => ['src' => 'img/test.gif', 'alt' => ''],
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link($this->Html->image('test.gif'), '#', [
'title' => 'hey "howdy"',
'escapeTitle' => false,
]);
$expected = [
'a' => ['href' => '#', 'title' => 'hey "howdy"'],
'img' => ['src' => 'img/test.gif', 'alt' => ''],
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->image('test.gif', ['url' => '#']);
$expected = [
'a' => ['href' => '#'],
'img' => ['src' => 'img/test.gif', 'alt' => ''],
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link($this->Html->image('../favicon.ico'), '#', ['escape' => false]);
$expected = [
'a' => ['href' => '#'],
'img' => ['src' => 'img/../favicon.ico', 'alt' => ''],
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->image('../favicon.ico', ['url' => '#']);
$expected = [
'a' => ['href' => '#'],
'img' => ['src' => 'img/../favicon.ico', 'alt' => ''],
'/a',
];
$this->assertHtml($expected, $result);
$result = $this->Html->link('http://www.example.org?param1=value1¶m2=value2');
$expected = ['a' => ['href' => 'http://www.example.org?param1=value1¶m2=value2'], 'http://www.example.org?param1=value1¶m2=value2', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('alert', 'javascript:alert(\'cakephp\');');
$expected = ['a' => ['href' => 'javascript:alert('cakephp');'], 'alert', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('write me', 'mailto:example@cakephp.org');
$expected = ['a' => ['href' => 'mailto:example@cakephp.org'], 'write me', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('call me on 0123465-798', 'tel:0123465-798');
$expected = ['a' => ['href' => 'tel:0123465-798'], 'call me on 0123465-798', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('text me on 0123465-798', 'sms:0123465-798');
$expected = ['a' => ['href' => 'sms:0123465-798'], 'text me on 0123465-798', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('say hello to 0123465-798', 'sms:0123465-798?body=hello there');
$expected = ['a' => ['href' => 'sms:0123465-798?body=hello there'], 'say hello to 0123465-798', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('say hello to 0123465-798', 'sms:0123465-798?body=hello "cakephp"');
$expected = ['a' => ['href' => 'sms:0123465-798?body=hello "cakephp"'], 'say hello to 0123465-798', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Home', '/', ['fullBase' => true]);
$expected = ['a' => ['href' => 'http://localhost/'], 'Home', '/a'];
$this->assertHtml($expected, $result);
$result = $this->Html->link('Home', '/', ['fullBase' => false]);
$expected = ['a' => ['href' => '/'], 'Home', '/a'];
$this->assertHtml($expected, $result);
}
/**
* testImageTag method
*
* @return void
*/
public function testImageTag()
{
Router::connect('/:controller', ['action' => 'index']);
Router::connect('/:controller/:action/*');
$result = $this->Html->image('test.gif');
$expected = ['img' => ['src' => 'img/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('http://google.com/logo.gif');
$expected = ['img' => ['src' => 'http://google.com/logo.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('//google.com/logo.gif');
$expected = ['img' => ['src' => '//google.com/logo.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image(['controller' => 'test', 'action' => 'view', 1, '_ext' => 'gif']);
$expected = ['img' => ['src' => '/test/view/1.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('/test/view/1.gif');
$expected = ['img' => ['src' => '/test/view/1.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('cid:cakephp_logo');
$expected = ['img' => ['src' => 'cid:cakephp_logo', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('x:">');
$expected = ['img' => ['src' => 'x:"><script>alert(1)</script>', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('//google.com/">');
$expected = ['img' => ['src' => '//google.com/"><script>alert(1)</script>', 'alt' => '']];
$this->assertHtml($expected, $result);
}
/**
* Ensure that data URIs don't get base paths set.
*
* @return void
*/
public function testImageDataUriBaseDir()
{
$request = $this->View->getRequest()
->withAttribute('base', 'subdir')
->withAttribute('webroot', 'subdir/');
$this->View->setRequest($request);
Router::pushRequest($request);
$data = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4' .
'/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
$result = $this->Html->image($data);
$expected = ['img' => ['src' => $data, 'alt' => '']];
$this->assertHtml($expected, $result);
$data = 'data:image/png;base64,';
$result = $this->Html->image($data);
$expected = ['img' => ['src' => h($data), 'alt' => '']];
$this->assertHtml($expected, $result);
}
/**
* Test image() with query strings.
*
* @return void
*/
public function testImageQueryString()
{
$result = $this->Html->image('test.gif?one=two&three=four');
$expected = ['img' => ['src' => 'img/test.gif?one=two&three=four', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image([
'controller' => 'images',
'action' => 'display',
'test',
'?' => ['one' => 'two', 'three' => 'four'],
]);
$expected = ['img' => ['src' => '/images/display/test?one=two&three=four', 'alt' => '']];
$this->assertHtml($expected, $result);
}
/**
* Test that image works with pathPrefix.
*
* @return void
*/
public function testImagePathPrefix()
{
$result = $this->Html->image('test.gif', ['pathPrefix' => '/my/custom/path/']);
$expected = ['img' => ['src' => '/my/custom/path/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('test.gif', ['pathPrefix' => 'http://cakephp.org/assets/img/']);
$expected = ['img' => ['src' => 'http://cakephp.org/assets/img/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('test.gif', ['pathPrefix' => '//cakephp.org/assets/img/']);
$expected = ['img' => ['src' => '//cakephp.org/assets/img/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$previousConfig = Configure::read('App.imageBaseUrl');
Configure::write('App.imageBaseUrl', '//cdn.cakephp.org/img/');
$result = $this->Html->image('test.gif');
$expected = ['img' => ['src' => '//cdn.cakephp.org/img/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
Configure::write('App.imageBaseUrl', $previousConfig);
}
/**
* Test that image() works with fullBase and a webroot not equal to /
*
* @return void
*/
public function testImageWithFullBase()
{
$result = $this->Html->image('test.gif', ['fullBase' => true]);
$here = $this->Html->Url->build('/', true);
$expected = ['img' => ['src' => $here . 'img/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$result = $this->Html->image('sub/test.gif', ['fullBase' => true]);
$here = $this->Html->Url->build('/', true);
$expected = ['img' => ['src' => $here . 'img/sub/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
$this->View->setRequest($this->View->getRequest()
->withAttribute('webroot', '/myproject/')
->withAttribute('base', '/myproject'));
$result = $this->Html->image('sub/test.gif', ['fullBase' => true]);
$here = $this->Html->Url->build('/', true);
$expected = ['img' => ['src' => $here . 'myproject/img/sub/test.gif', 'alt' => '']];
$this->assertHtml($expected, $result);
}
/**
* test image() with Asset.timestamp
*
* @return void
*/
public function testImageWithTimestampping()
{
Configure::write('Asset.timestamp', 'force');
$this->View->setRequest($this->View->getRequest()->withAttribute('webroot', '/'));
$result = $this->Html->image('cake.icon.png');
$expected = ['img' => ['src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '']];
$this->assertHtml($expected, $result);
Configure::write('debug', false);
Configure::write('Asset.timestamp', 'force');
$result = $this->Html->image('cake.icon.png');
$expected = ['img' => ['src' => 'preg:/\/img\/cake\.icon\.png\?\d+/', 'alt' => '']];
$this->assertHtml($expected, $result);
$this->View->setRequest($this->View->getRequest()->withAttribute('webroot', '/testing/longer/'));
$result = $this->Html->image('cake.icon.png');
$expected = [
'img' => ['src' => 'preg:/\/testing\/longer\/img\/cake\.icon\.png\?[0-9]+/', 'alt' => ''],
];
$this->assertHtml($expected, $result);
}
/**
* Tests creation of an image tag using a theme and asset timestamping
*
* @return void
*/
public function testImageTagWithTheme()
{
$this->skipIf(!is_writable(WWW_ROOT), 'Cannot write to webroot.');
$testfile = WWW_ROOT . 'test_theme/img/__cake_test_image.gif';
$File = new File($testfile, true);
Configure::write('Asset.timestamp', true);
Configure::write('debug', true);
$this->View->setRequest($this->View->getRequest()->withAttribute('webroot', '/'));
$this->Html->Url->getView()->setTheme('TestTheme');
$result = $this->Html->image('__cake_test_image.gif');
$expected = [
'img' => [
'src' => 'preg:/\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
'alt' => '',
],
];
$this->assertHtml($expected, $result);
$this->View->setRequest($this->View->getRequest()->withAttribute('webroot', '/testing/'));
$result = $this->Html->image('__cake_test_image.gif');
$expected = [
'img' => [
'src' => 'preg:/\/testing\/test_theme\/img\/__cake_test_image\.gif\?\d+/',
'alt' => '',
]];
$this->assertHtml($expected, $result);
$File->delete();
}
/**
* test theme assets in main webroot path
*
* @return void
*/
public function testThemeAssetsInMainWebrootPath()
{
Configure::write('App.wwwRoot', TEST_APP . 'webroot/');
$this->Html->Url->getView()->setTheme('TestTheme');
$result = $this->Html->css('webroot_test');
$expected = [
'link' => ['rel' => 'stylesheet', 'href' => 'preg:/.*test_theme\/css\/webroot_test\.css/'],
];
$this->assertHtml($expected, $result);
$this->Html->getView()->setTheme('TestTheme');
$result = $this->Html->css('theme_webroot');
$expected = [
'link' => ['rel' => 'stylesheet', 'href' => 'preg:/.*test_theme\/css\/theme_webroot\.css/'],
];
$this->assertHtml($expected, $result);
}
/**
* testStyle method
*
* @return void
*/
public function testStyle()
{
$result = $this->Html->style(['display' => 'none', 'margin' => '10px']);
$this->assertEquals('display:none; margin:10px;', $result);
$result = $this->Html->style(['display' => 'none', 'margin' => '10px'], false);
$this->assertEquals("display:none;\nmargin:10px;", $result);
}
/**
* testCssLink method
*
* @return void
*/
public function testCssLink()
{
$result = $this->Html->css('screen');
$expected = [
'link' => ['rel' => 'stylesheet', 'href' => 'preg:/.*css\/screen\.css/'],
];
$this->assertHtml($expected, $result);
$result = $this->Html->css('screen.css', ['once' => false]);
$this->assertHtml($expected, $result);
$this->loadPlugins(['TestPlugin']);
$result = $this->Html->css('TestPlugin.style', ['plugin' => false]);
$expected['link']['href'] = 'preg:/.*css\/TestPlugin\.style\.css/';
$this->assertHtml($expected, $result);
$this->removePlugins(['TestPlugin']);
$result = $this->Html->css('my.css.library');
$expected['link']['href'] = 'preg:/.*css\/my\.css\.library\.css/';
$this->assertHtml($expected, $result);
$result = $this->Html->css('screen.css?1234');
$expected['link']['href'] = 'preg:/.*css\/screen\.css\?1234/';
$this->assertHtml($expected, $result);
$result = $this->Html->css('screen.css?with=param&other=param');
$expected['link']['href'] = 'css/screen.css?with=param&other=param';
$this->assertHtml($expected, $result);
$result = $this->Html->css('x:">');
$expected['link']['href'] = 'x:"><script>alert(1)</script>';
$this->assertHtml($expected, $result);
$result = $this->Html->css('http://whatever.com/screen.css?1234');
$expected['link']['href'] = 'preg:/http:\/\/.*\/screen\.css\?1234/';
$this->assertHtml($expected, $result);
Configure::write('App.cssBaseUrl', '//cdn.cakephp.org/css/');
$result = $this->Html->css('cake.generic');
$expected['link']['href'] = '//cdn.cakephp.org/css/cake.generic.css';
$this->assertHtml($expected, $result);
$result = $this->Html->css('//example.com/css/cake.generic.css');
$expected['link']['href'] = 'preg:/.*example\.com\/css\/cake\.generic\.css/';
$this->assertHtml($expected, $result);
$result = explode("\n", trim($this->Html->css(['cake', 'vendor.generic'])));
$expected['link']['href'] = 'preg:/.*css\/cake\.css/';
$this->assertHtml($expected, $result[0]);
$expected['link']['href'] = 'preg:/.*css\/vendor\.generic\.css/';
$this->assertHtml($expected, $result[1]);
$this->assertCount(2, $result);
$this->View->expects($this->at(0))
->method('append')
->with('css', $this->matchesRegularExpression('/css_in_head.css/'));
$this->View->expects($this->at(1))
->method('append')
->with('css', $this->matchesRegularExpression('/more_css_in_head.css/'));
$result = $this->Html->css('css_in_head', ['block' => true]);
$this->assertNull($result);
$result = $this->Html->css('more_css_in_head', ['block' => true]);
$this->assertNull($result);
$result = $this->Html->css('import-screen', ['rel' => 'import']);
$expected = [
'