diff options
Diffstat (limited to 'tests')
31 files changed, 806 insertions, 15 deletions
diff --git a/tests/Framework/Bootstrap.php b/tests/Framework/Bootstrap.php index d18fd371b..904be7e3b 100644 --- a/tests/Framework/Bootstrap.php +++ b/tests/Framework/Bootstrap.php @@ -207,4 +207,12 @@ class Framework_Bootstrap extends PHPUnit_Framework_TestCase $this->assertFalse($result, "Invalid ASCII (UTF-8 character [2])"); } + /** + * bootstrap.php: version_parse() + */ + function test_version_parse() + { + $this->assertEquals('0.9.0', version_parse('0.9-stable')); + $this->assertEquals('0.9.99', version_parse('0.9-git')); + } } diff --git a/tests/Framework/Charset.php b/tests/Framework/Charset.php index 1fd1654dc..d3d3e88dd 100644 --- a/tests/Framework/Charset.php +++ b/tests/Framework/Charset.php @@ -159,4 +159,22 @@ class Framework_Charset extends PHPUnit_Framework_TestCase $this->assertEquals($output, rcube_charset::detect($input, $fallback)); } + /** + * Data for test_detect() + */ + function data_detect_with_lang() + { + return array( + array('顯示名稱,主要', 'zh_TW', 'BIG-5'), + ); + } + + /** + * @dataProvider data_detect_with_lang + */ + function test_detect_with_lang($input, $lang, $output) + { + $this->assertEquals($output, rcube_charset::detect($input, $output, $lang)); + } + } diff --git a/tests/Framework/Csv2vcard.php b/tests/Framework/Csv2vcard.php index 6fa3e163c..5d52efc58 100644 --- a/tests/Framework/Csv2vcard.php +++ b/tests/Framework/Csv2vcard.php @@ -31,6 +31,7 @@ class Framework_Csv2vcard extends PHPUnit_Framework_TestCase $vcf_text = trim(str_replace("\r\n", "\n", $vcf_text)); $vcard = trim(str_replace("\r\n", "\n", $vcard)); + $this->assertEquals($vcf_text, $vcard); } diff --git a/tests/Framework/Enriched.php b/tests/Framework/Enriched.php new file mode 100644 index 000000000..26bbc3b4e --- /dev/null +++ b/tests/Framework/Enriched.php @@ -0,0 +1,74 @@ +<?php + +/** + * Test class to test rcube_enriched class + * + * @package Tests + */ +class Framework_Enriched extends PHPUnit_Framework_TestCase +{ + + /** + * Class constructor + */ + function test_class() + { + $object = new rcube_enriched(); + + $this->assertInstanceOf('rcube_enriched', $object, "Class constructor"); + } + + /** + * Test to_html() + */ + function test_to_html() + { + $enriched = '<bold><italic>the-text</italic></bold>'; + $expected = '<b><i>the-text</i></b>'; + $result = rcube_enriched::to_html($enriched); + + $this->assertSame($expected, $result); + } + + /** + * Data for test_formatting() + */ + function data_formatting() + { + return array( + array('<bold>', '<b>'), + array('</bold>', '</b>'), + array('<italic>', '<i>'), + array('</italic>', '</i>'), + array('<fixed>', '<tt>'), + array('</fixed>', '</tt>'), + array('<smaller>', '<font size=-1>'), + array('</smaller>', '</font>'), + array('<bigger>', '<font size=+1>'), + array('</bigger>', '</font>'), + array('<underline>', '<span style="text-decoration: underline">'), + array('</underline>', '</span>'), + array('<flushleft>', '<span style="text-align: left">'), + array('</flushleft>', '</span>'), + array('<flushright>', '<span style="text-align: right">'), + array('</flushright>', '</span>'), + array('<flushboth>', '<span style="text-align: justified">'), + array('</flushboth>', '</span>'), + array('<indent>', '<span style="padding-left: 20px">'), + array('</indent>', '</span>'), + array('<indentright>', '<span style="padding-right: 20px">'), + array('</indentright>', '</span>'), + ); + } + + /** + * Test formatting conversion + * @dataProvider data_formatting + */ + function test_formatting($enriched, $expected) + { + $result = rcube_enriched::to_html($enriched); + + $this->assertSame($expected, $result); + } +} diff --git a/tests/HtmlToText.php b/tests/Framework/Html2text.php index b90c61adf..3e0df48d9 100644 --- a/tests/HtmlToText.php +++ b/tests/Framework/Html2text.php @@ -1,11 +1,11 @@ <?php /** - * Test class to test html2text class + * Test class to test rcube_html2text class * * @package Tests */ -class HtmlToText extends PHPUnit_Framework_TestCase +class rc_html2text extends PHPUnit_Framework_TestCase { function data_html2text() @@ -49,11 +49,30 @@ class HtmlToText extends PHPUnit_Framework_TestCase */ function test_html2text($title, $in, $out) { - $ht = new html2text(null, false, false); + $ht = new rcube_html2text(null, false, false); $ht->set_html($in); $res = $ht->get_text(); $this->assertEquals($out, $res, $title); } + + /** + * + */ + function test_multiple_blockquotes() + { + $html = <<<EOF +<br>Begin<br><blockquote>OUTER BEGIN<blockquote>INNER 1<br></blockquote><div><br></div><div>Par 1</div> +<blockquote>INNER 2</blockquote><div><br></div><div>Par 2</div> +<div><br></div><div>Par 3</div><div><br></div> +<blockquote>INNER 3</blockquote>OUTER END</blockquote> +EOF; + $ht = new rcube_html2text($html, false, false); + $res = $ht->get_text(); + + $this->assertContains('>> INNER 1', $res, 'Quote inner'); + $this->assertContains('>> INNER 3', $res, 'Quote inner'); + $this->assertContains('> OUTER END', $res, 'Quote outer'); + } } diff --git a/tests/Framework/Mime.php b/tests/Framework/Mime.php index dcd55992a..1f9a8c58f 100644 --- a/tests/Framework/Mime.php +++ b/tests/Framework/Mime.php @@ -120,4 +120,26 @@ class Framework_Mime extends PHPUnit_Framework_TestCase $this->assertEquals($item['out'], $res, "Header decoding for: " . $idx); } } + + /** + * Test format=flowed unfolding + */ + function test_format_flowed() + { + $raw = file_get_contents(TESTS_DIR . 'src/format-flowed-unfolded.txt'); + $flowed = file_get_contents(TESTS_DIR . 'src/format-flowed.txt'); + + $this->assertEquals($flowed, rcube_mime::format_flowed($raw, 80), "Test correct folding and space-stuffing"); + } + + /** + * Test format=flowed unfolding + */ + function test_unfold_flowed() + { + $flowed = file_get_contents(TESTS_DIR . 'src/format-flowed.txt'); + $unfolded = file_get_contents(TESTS_DIR . 'src/format-flowed-unfolded.txt'); + + $this->assertEquals($unfolded, rcube_mime::unfold_flowed($flowed), "Test correct unfolding of quoted lines"); + } } diff --git a/tests/Framework/StringReplacer.php b/tests/Framework/StringReplacer.php index a76ba00ee..95c59221b 100644 --- a/tests/Framework/StringReplacer.php +++ b/tests/Framework/StringReplacer.php @@ -24,11 +24,19 @@ class Framework_StringReplacer extends PHPUnit_Framework_TestCase function data_replace() { return array( - array('http://domain.tld/path*path2', '<a href="http://domain.tld/path*path2" target="_blank">http://domain.tld/path*path2</a>'), - array("Click this link:\nhttps://mail.xn--brderli-o2a.ch/rc/ EOF", "Click this link:\n<a href=\"https://mail.xn--brderli-o2a.ch/rc/\" target=\"_blank\">https://mail.xn--brderli-o2a.ch/rc/</a> EOF"), - array('Start http://localhost/?foo End', 'Start <a href="http://localhost/?foo" target="_blank">http://localhost/?foo</a> End'), - array('www.domain.tld', '<a href="http://www.domain.tld" target="_blank">www.domain.tld</a>'), - array('WWW.DOMAIN.TLD', '<a href="http://WWW.DOMAIN.TLD" target="_blank">WWW.DOMAIN.TLD</a>'), + array('http://domain.tld/path*path2', '<a href="http://domain.tld/path*path2">http://domain.tld/path*path2</a>'), + array("Click this link:\nhttps://mail.xn--brderli-o2a.ch/rc/ EOF", "Click this link:\n<a href=\"https://mail.xn--brderli-o2a.ch/rc/\">https://mail.xn--brderli-o2a.ch/rc/</a> EOF"), + array('Start http://localhost/?foo End', 'Start <a href="http://localhost/?foo">http://localhost/?foo</a> End'), + array('www.domain.tld', '<a href="http://www.domain.tld">www.domain.tld</a>'), + array('WWW.DOMAIN.TLD', '<a href="http://WWW.DOMAIN.TLD">WWW.DOMAIN.TLD</a>'), + array('[http://link.com]', '[<a href="http://link.com">http://link.com</a>]'), + array('http://link.com?a[]=1', '<a href="http://link.com?a[]=1">http://link.com?a[]=1</a>'), + array('http://link.com?a[]', '<a href="http://link.com?a[]">http://link.com?a[]</a>'), + array('(http://link.com)', '(<a href="http://link.com">http://link.com</a>)'), + array('http://link.com?a(b)c', '<a href="http://link.com?a(b)c">http://link.com?a(b)c</a>'), + array('http://link.com?(link)', '<a href="http://link.com?(link)">http://link.com?(link)</a>'), + array('http://<test>', 'http://<test>'), + array('http://', 'http://'), ); } diff --git a/tests/Framework/VCard.php b/tests/Framework/VCard.php index 79d297664..15aa5d816 100644 --- a/tests/Framework/VCard.php +++ b/tests/Framework/VCard.php @@ -50,6 +50,21 @@ class Framework_VCard extends PHPUnit_Framework_TestCase $this->assertRegExp('/TEL;TYPE=CELL:\+987654321/', $vcf, "Return CELL instead of MOBILE (set)"); } + /** + * Backslash escaping test (#1488896) + */ + function test_parse_four() + { + $vcard = "BEGIN:VCARD\nVERSION:3.0\nN:last\\;;first\\\\;middle\\\\\\;\\\\;prefix;\nFN:test\nEND:VCARD"; + $vcard = new rcube_vcard($vcard, null); + $vcard = $vcard->get_assoc(); + + $this->assertEquals("last;", $vcard['surname'], "Decode backslash character"); + $this->assertEquals("first\\", $vcard['firstname'], "Decode backslash character"); + $this->assertEquals("middle\\;\\", $vcard['middlename'], "Decode backslash character"); + $this->assertEquals("prefix", $vcard['prefix'], "Decode backslash character"); + } + function test_import() { $input = file_get_contents($this->_srcpath('apple.vcf')); diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php new file mode 100644 index 000000000..cd443266f --- /dev/null +++ b/tests/Framework/Washtml.php @@ -0,0 +1,58 @@ +<?php + +/** + * Test class to test rcube_washtml class + * + * @package Tests + */ +class Framework_Washtml extends PHPUnit_Framework_TestCase +{ + + /** + * Test the elimination of some XSS vulnerabilities + */ + function test_html_xss3() + { + // #1488850 + $html = '<p><a href="data:text/html,<script>alert(document.cookie)</script>">Firefox</a>' + .'<a href="vbscript:alert(document.cookie)">Internet Explorer</a></p>'; + + $washer = new rcube_washtml; + $washed = $washer->wash($html); + + $this->assertNotRegExp('/data:text/', $washed, "Remove data:text/html links"); + $this->assertNotRegExp('/vbscript:/', $washed, "Remove vbscript: links"); + } + + /** + * Test fixing of invalid href (#1488940) + */ + function test_href() + { + $html = "<p><a href=\"\nhttp://test.com\n\">Firefox</a>"; + + $washer = new rcube_washtml; + $washed = $washer->wash($html); + + $this->assertRegExp('|href="http://test.com">|', $washed, "Link href with newlines (#1488940)"); + } + + /** + * Test handling HTML comments + */ + function test_comments() + { + $washer = new rcube_washtml; + + $html = "<!--[if gte mso 10]><p>p1</p><!--><p>p2</p>"; + $washed = $washer->wash($html); + + $this->assertEquals('<!-- html ignored --><!-- body ignored --><p>p2</p>', $washed, "HTML conditional comments (#1489004)"); + + $html = "<!--TestCommentInvalid><p>test</p>"; + $washed = $washer->wash($html); + + $this->assertEquals('<!-- html ignored --><!-- body ignored --><p>test</p>', $washed, "HTML invalid comments (#1487759)"); + } + +} diff --git a/tests/MailFunc.php b/tests/MailFunc.php index 967277c2a..319075abd 100644 --- a/tests/MailFunc.php +++ b/tests/MailFunc.php @@ -54,7 +54,7 @@ class MailFunc extends PHPUnit_Framework_TestCase $this->assertNotRegExp('/<form [^>]+>/', $html, "No form tags allowed"); $this->assertRegExp('/Subscription form/', $html, "Include <form> contents"); $this->assertRegExp('/<!-- link ignored -->/', $html, "No external links allowed"); - $this->assertRegExp('/<a[^>]+ target="_blank">/', $html, "Set target to _blank"); + $this->assertRegExp('/<a[^>]+ target="_blank"/', $html, "Set target to _blank"); $this->assertTrue($GLOBALS['REMOTE_OBJECTS'], "Remote object detected"); // render HTML in safe mode @@ -97,6 +97,20 @@ class MailFunc extends PHPUnit_Framework_TestCase } /** + * Test the elimination of some XSS vulnerabilities + */ + function test_html_xss3() + { + // #1488850 + $html = '<p><a href="data:text/html,<script>alert(document.cookie)</script>">Firefox</a>' + .'<a href="vbscript:alert(document.cookie)">Internet Explorer</a></p>'; + $washed = rcmail_wash_html($html, array('safe' => true), array()); + + $this->assertNotRegExp('/data:text/', $washed, "Remove data:text/html links"); + $this->assertNotRegExp('/vbscript:/', $washed, "Remove vbscript: links"); + } + + /** * Test washtml class on non-unicode characters (#1487813) */ function test_washtml_utf8() @@ -119,8 +133,8 @@ class MailFunc extends PHPUnit_Framework_TestCase $html = rcmail_print_body($part, array('safe' => true)); $this->assertRegExp('/<a href="mailto:nobody@roundcube.net" onclick="return rcmail.command\(\'compose\',\'nobody@roundcube.net\',this\)">nobody@roundcube.net<\/a>/', $html, "Mailto links with onclick"); - $this->assertRegExp('#<a href="http://www.apple.com/legal/privacy" target="_blank">http://www.apple.com/legal/privacy</a>#', $html, "Links with target=_blank"); - $this->assertRegExp('#\\[<a href="http://example.com/\\?tx\\[a\\]=5" target="_blank">http://example.com/\\?tx\\[a\\]=5</a>\\]#', $html, "Links with square brackets"); + $this->assertRegExp('#<a rel="noreferrer" target="_blank" href="http://www.apple.com/legal/privacy">http://www.apple.com/legal/privacy</a>#', $html, "Links with target=_blank"); + $this->assertRegExp('#\\[<a rel="noreferrer" target="_blank" href="http://example.com/\\?tx\\[a\\]=5">http://example.com/\\?tx\\[a\\]=5</a>\\]#', $html, "Links with square brackets"); } /** @@ -134,7 +148,7 @@ class MailFunc extends PHPUnit_Framework_TestCase $html = rcmail_html4inline(rcmail_print_body($part, array('safe' => false)), 'foo'); $mailto = '<a href="mailto:me@me.com?subject=this is the subject&body=this is the body"' - .' onclick="return rcmail.command(\'compose\',\'me@me.com?subject=this is the subject&body=this is the body\',this)">e-mail</a>'; + .' onclick="return rcmail.command(\'compose\',\'me@me.com?subject=this is the subject&body=this is the body\',this)" rel="noreferrer">e-mail</a>'; $this->assertRegExp('|'.preg_quote($mailto, '|').'|', $html, "Extended mailto links"); } @@ -159,7 +173,7 @@ class MailFunc extends PHPUnit_Framework_TestCase function test_resolve_base() { $html = file_get_contents(TESTS_DIR . 'src/htmlbase.txt'); - $html = rcmail_resolve_base($html); + $html = rcube_washtml::resolve_base($html); $this->assertRegExp('|src="http://alec\.pl/dir/img1\.gif"|', $html, "URI base resolving [1]"); $this->assertRegExp('|src="http://alec\.pl/dir/img2\.gif"|', $html, "URI base resolving [2]"); diff --git a/tests/Selenium/Addressbook/Addressbook.php b/tests/Selenium/Addressbook/Addressbook.php new file mode 100644 index 000000000..9a22b6e13 --- /dev/null +++ b/tests/Selenium/Addressbook/Addressbook.php @@ -0,0 +1,21 @@ +<?php + +class Selenium_Addressbook_Addressbook extends Selenium_Test +{ + public function testAddressbook() + { + $this->go('addressbook'); + + // check task + $env = $this->get_env(); + $this->assertEquals('addressbook', $env['task']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('folderlist', $objects); + $this->assertContains('contactslist', $objects); + $this->assertContains('countdisplay', $objects); + } +} diff --git a/tests/Selenium/Addressbook/Import.php b/tests/Selenium/Addressbook/Import.php new file mode 100644 index 000000000..13d81740f --- /dev/null +++ b/tests/Selenium/Addressbook/Import.php @@ -0,0 +1,29 @@ +<?php + +class Selenium_Addressbook_Import extends Selenium_Test +{ + public function testImport() + { + $this->go('addressbook', 'import'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('addressbook', $env['task']); + $this->assertEquals('import', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('importform', $objects); + } + + public function testImport2() + { + $this->go('addressbook', 'import'); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('importform', $objects); + } +} diff --git a/tests/Selenium/Login.php b/tests/Selenium/Login.php new file mode 100644 index 000000000..a3f0ab6b4 --- /dev/null +++ b/tests/Selenium/Login.php @@ -0,0 +1,21 @@ +<?php + +class Selenium_Login extends Selenium_Test +{ + public function testLogin() + { + // first test, we're already on the login page + $this->url(TESTS_URL); + + // task should be set to 'login' + $env = $this->get_env(); + $this->assertEquals('login', $env['task']); + + // test valid login + $this->login(); + + // task should be set to 'mail' now + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + } +} diff --git a/tests/Selenium/Logout.php b/tests/Selenium/Logout.php new file mode 100644 index 000000000..95eeda57c --- /dev/null +++ b/tests/Selenium/Logout.php @@ -0,0 +1,20 @@ +<?php + +class Selenium_Logout extends Selenium_Test +{ + public function testLogout() + { + $this->go('mail'); + + $this->click_button('logout'); + + sleep(TESTS_SLEEP); + + // task should be set to 'login' + $env = $this->get_env(); + $this->assertEquals('login', $env['task']); + + // form should exist + $user_input = $this->byCssSelector('form input[name="_user"]'); + } +} diff --git a/tests/Selenium/Mail/CheckRecent.php b/tests/Selenium/Mail/CheckRecent.php new file mode 100644 index 000000000..865421c2d --- /dev/null +++ b/tests/Selenium/Mail/CheckRecent.php @@ -0,0 +1,14 @@ +<?php + +class Selenium_Mail_CheckRecent extends Selenium_Test +{ + public function testCheckRecent() + { + $this->go('mail'); + + $res = $this->ajaxResponse('check-recent', "rcmail.command('checkmail')"); + + $this->assertEquals('check-recent', $res['action']); + $this->assertRegExp('/this\.set_unread_count/', $res['exec']); + } +} diff --git a/tests/Selenium/Mail/Compose.php b/tests/Selenium/Mail/Compose.php new file mode 100644 index 000000000..e707ef17d --- /dev/null +++ b/tests/Selenium/Mail/Compose.php @@ -0,0 +1,25 @@ +<?php + +class Selenium_Mail_Compose extends Selenium_Test +{ + public function testCompose() + { + $this->go('mail', 'compose'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + $this->assertEquals('compose', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('addressbookslist', $objects); + $this->assertContains('contactslist', $objects); + $this->assertContains('messageform', $objects); + $this->assertContains('attachmentlist', $objects); + $this->assertContains('filedrop', $objects); + $this->assertContains('uploadform', $objects); + } +} diff --git a/tests/Selenium/Mail/Getunread.php b/tests/Selenium/Mail/Getunread.php new file mode 100644 index 000000000..d6362f2f4 --- /dev/null +++ b/tests/Selenium/Mail/Getunread.php @@ -0,0 +1,13 @@ +<?php + +class Selenium_Mail_Getunread extends Selenium_Test +{ + public function testGetunread() + { + $this->go('mail'); + + $res = $this->ajaxResponse('getunread', "rcmail.http_request('getunread')"); + + $this->assertEquals('getunread', $res['action']); + } +} diff --git a/tests/Selenium/Mail/List.php b/tests/Selenium/Mail/List.php new file mode 100644 index 000000000..7574c1801 --- /dev/null +++ b/tests/Selenium/Mail/List.php @@ -0,0 +1,25 @@ +<?php + +class Selenium_Mail_List extends Selenium_Test +{ + public function testCheckRecent() + { + $this->go('mail'); + + $res = $this->ajaxResponse('list', "rcmail.command('list')"); + + $this->assertEquals('list', $res['action']); + $this->assertRegExp('/this\.set_pagetitle/', $res['exec']); + $this->assertRegExp('/this\.set_unread_count/', $res['exec']); + $this->assertRegExp('/this\.set_rowcount/', $res['exec']); + $this->assertRegExp('/this\.set_message_coltypes/', $res['exec']); +// $this->assertRegExp('/this\.add_message_row/', $res['exec']); + + $this->assertContains('current_page', $res['env']); + $this->assertContains('exists', $res['env']); + $this->assertContains('pagecount', $res['env']); + $this->assertContains('pagesize', $res['env']); + $this->assertContains('messagecount', $res['env']); + $this->assertContains('mailbox', $res['env']); + } +} diff --git a/tests/Selenium/Mail/Mail.php b/tests/Selenium/Mail/Mail.php new file mode 100644 index 000000000..98413787b --- /dev/null +++ b/tests/Selenium/Mail/Mail.php @@ -0,0 +1,23 @@ +<?php + +class Selenium_Mail_Mail extends Selenium_Test +{ + public function testMail() + { + $this->go('mail'); + + // check task + $env = $this->get_env(); + $this->assertEquals('mail', $env['task']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('qsearchbox', $objects); + $this->assertContains('mailboxlist', $objects); + $this->assertContains('messagelist', $objects); + $this->assertContains('quotadisplay', $objects); + $this->assertContains('search_filter', $objects); + $this->assertContains('countdisplay', $objects); + } +} diff --git a/tests/Selenium/Settings/About.php b/tests/Selenium/Settings/About.php new file mode 100644 index 000000000..9a6c31d4b --- /dev/null +++ b/tests/Selenium/Settings/About.php @@ -0,0 +1,14 @@ +<?php + +class Selenium_Settings_About extends Selenium_Test +{ + public function testAbout() + { + $this->url(TESTS_URL . '/?_task=settings&_action=about'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('about', $env['action']); + } +} diff --git a/tests/Selenium/Settings/Folders.php b/tests/Selenium/Settings/Folders.php new file mode 100644 index 000000000..fa64e45d6 --- /dev/null +++ b/tests/Selenium/Settings/Folders.php @@ -0,0 +1,20 @@ +<?php + +class Selenium_Settings_Folders extends Selenium_Test +{ + public function testFolders() + { + $this->go('settings', 'folders'); + + // task should be set to 'settings' and action to 'folders' + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('folders', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('quotadisplay', $objects); + $this->assertContains('subscriptionlist', $objects); + } +} diff --git a/tests/Selenium/Settings/Identities.php b/tests/Selenium/Settings/Identities.php new file mode 100644 index 000000000..869018b09 --- /dev/null +++ b/tests/Selenium/Settings/Identities.php @@ -0,0 +1,19 @@ +<?php + +class Selenium_Settings_Identities extends Selenium_Test +{ + public function testIdentities() + { + $this->go('settings', 'identities'); + + // check task and action + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + $this->assertEquals('identities', $env['action']); + + $objects = $this->get_objects(); + + // these objects should be there always + $this->assertContains('identitieslist', $objects); + } +} diff --git a/tests/Selenium/Settings/Settings.php b/tests/Selenium/Settings/Settings.php new file mode 100644 index 000000000..08d8339f1 --- /dev/null +++ b/tests/Selenium/Settings/Settings.php @@ -0,0 +1,17 @@ +<?php + +class Selenium_Settings_Settings extends Selenium_Test +{ + public function testSettings() + { + $this->go('settings'); + + // task should be set to 'settings' + $env = $this->get_env(); + $this->assertEquals('settings', $env['task']); + + $objects = $this->get_objects(); + + $this->assertContains('sectionslist', $objects); + } +} diff --git a/tests/Selenium/bootstrap.php b/tests/Selenium/bootstrap.php new file mode 100644 index 000000000..6611e8feb --- /dev/null +++ b/tests/Selenium/bootstrap.php @@ -0,0 +1,185 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | tests/Selenium/bootstrap.php | + | | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2009-2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + | PURPOSE: | + | Environment initialization script for unit tests | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + | Author: Aleksander Machniak <alec@alec.pl> | + +-----------------------------------------------------------------------+ +*/ + +if (php_sapi_name() != 'cli') + die("Not in shell mode (php-cli)"); + +if (!defined('INSTALL_PATH')) define('INSTALL_PATH', realpath(dirname(__FILE__) . '/../../') . '/' ); + +define('TESTS_DIR', dirname(__FILE__) . '/'); + +if (@is_dir(TESTS_DIR . 'config')) { + define('RCMAIL_CONFIG_DIR', TESTS_DIR . 'config'); +} + +require_once(INSTALL_PATH . 'program/include/iniset.php'); + +// Extend include path so some plugin test won't fail +$include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..'; +if (set_include_path($include_path) === false) { + die("Fatal error: ini_set/set_include_path does not work."); +} + +$rcmail = rcube::get_instance(); + +define('TESTS_URL', $rcmail->config->get('tests_url')); +define('TESTS_BROWSER', $rcmail->config->get('tests_browser', 'firefox')); +define('TESTS_USER', $rcmail->config->get('tests_username')); +define('TESTS_PASS', $rcmail->config->get('tests_password')); +define('TESTS_SLEEP', $rcmail->config->get('tests_sleep', 5)); + +PHPUnit_Extensions_Selenium2TestCase::shareSession(true); + +// @TODO: remove user record from DB before running tests +// @TODO: make sure mailbox has some content (always the same) or is empty +// @TODO: plugins: enable all? + +/** + * Base class for all tests in this directory + */ +class Selenium_Test extends PHPUnit_Extensions_Selenium2TestCase +{ + protected function setUp() + { +// $this->rc = rcube::get_instance(); + $this->setBrowser(TESTS_BROWSER); + + // Set root to our index.html, for better performance + // See https://github.com/sebastianbergmann/phpunit-selenium/issues/217 + $this->setBrowserUrl(TESTS_URL . '/tests/Selenium'); + } + + protected function login() + { + $this->go('mail'); + + $user_input = $this->byCssSelector('form input[name="_user"]'); + $pass_input = $this->byCssSelector('form input[name="_pass"]'); + $submit = $this->byCssSelector('form input[type="submit"]'); + + $user_input->value(TESTS_USER); + $pass_input->value(TESTS_PASS); + + // submit login form + $submit->click(); + + // wait after successful login + sleep(TESTS_SLEEP); + } + + protected function go($task = 'mail', $action = null) + { + $this->url(TESTS_URL . '/?_task=' . $task); + + // wait for interface load (initial ajax requests, etc.) + sleep(TESTS_SLEEP); + + if ($action) { + $this->click_button($action); + + sleep(TESTS_SLEEP); + } + } + + protected function get_env() + { + return $this->execute(array( + 'script' => 'return rcmail.env;', + 'args' => array(), + )); + } + + protected function get_buttons($action) + { + $buttons = $this->execute(array( + 'script' => "return rcmail.buttons['$action'];", + 'args' => array(), + )); + + if (is_array($buttons)) { + foreach ($buttons as $idx => $button) { + $buttons[$idx] = $button['id']; + } + } + + return (array) $buttons; + } + + protected function get_objects() + { + return $this->execute(array( + 'script' => "var i,r = []; for (i in rcmail.gui_objects) r.push(i); return r;", + 'args' => array(), + )); + } + + protected function click_button($action) + { + $buttons = $this->get_buttons($action); + $id = array_shift($buttons); + + // this doesn't work for me + $this->byId($id)->click(); + } + + protected function ajaxResponse($action, $script = '', $button = false) + { + if (!$script && !$button) { + $script = "rcmail.command('$action')"; + } + + $script = + "if (!window.test_ajax_response) { + window.test_ajax_response_object = {}; + function test_ajax_response(response) + { + if (response.response && response.response.action) { + window.test_ajax_response_object[response.response.action] = response.response; + } + } + rcmail.addEventListener('responsebefore', test_ajax_response); + } + window.test_ajax_response_object['$action'] = null; + $script; + "; + + // run request + $this->execute(array( + 'script' => $script, + 'args' => array(), + )); + + if ($button) { + $this->click_button($action); + } + + // wait + sleep(TESTS_SLEEP); + + // get response + $response = $this->execute(array( + 'script' => "return window.test_ajax_response_object['$action'];", + 'args' => array(), + )); + + return $response; + } +} diff --git a/tests/Selenium/index.html b/tests/Selenium/index.html new file mode 100644 index 000000000..7aa65f829 --- /dev/null +++ b/tests/Selenium/index.html @@ -0,0 +1,8 @@ +<html> +<head> + <title>Roundcube Webmail Tests</title> +</head> +<body> +Testing... +</body> +</html> diff --git a/tests/Selenium/phpunit.xml b/tests/Selenium/phpunit.xml new file mode 100644 index 000000000..b5835cf74 --- /dev/null +++ b/tests/Selenium/phpunit.xml @@ -0,0 +1,21 @@ +<phpunit backupGlobals="false" + bootstrap="bootstrap.php" + colors="true"> + <testsuites> + <testsuite name="All Tests"> + <file>Login.php</file><!-- Login.php test must be first --> + <file>Addressbook/Addressbook.php</file> + <file>Addressbook/Import.php</file> + <file>Mail/Mail.php</file> + <file>Mail/CheckRecent.php</file> + <file>Mail/Compose.php</file> + <file>Mail/Getunread.php</file> + <file>Mail/List.php</file> + <file>Settings/About.php</file> + <file>Settings/Folders.php</file> + <file>Settings/Identities.php</file> + <file>Settings/Settings.php</file> + <file>Logout.php</file><!-- Logout.php test must be last --> + </testsuite> + </testsuites> +</phpunit> diff --git a/tests/bootstrap.php b/tests/bootstrap.php index a9e25610c..40659ebf0 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -33,3 +33,9 @@ if (@is_dir(TESTS_DIR . 'config')) { require_once(INSTALL_PATH . 'program/include/iniset.php'); rcmail::get_instance()->config->set('devel_mode', false); + +// Extend include path so some plugin test won't fail +$include_path = ini_get('include_path') . PATH_SEPARATOR . TESTS_DIR . '..'; +if (set_include_path($include_path) === false) { + die("Fatal error: ini_set/set_include_path does not work."); +} diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 36ab6d714..da0f899a9 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -10,7 +10,9 @@ <file>Framework/Charset.php</file> <file>Framework/ContentFilter.php</file> <file>Framework/Csv2vcard.php</file> + <file>Framework/Enriched.php</file> <file>Framework/Html.php</file> + <file>Framework/Html2text.php</file> <file>Framework/Imap.php</file> <file>Framework/ImapGeneric.php</file> <file>Framework/Image.php</file> @@ -27,12 +29,41 @@ <file>Framework/User.php</file> <file>Framework/Utils.php</file> <file>Framework/VCard.php</file> - <file>HtmlToText.php</file> + <file>Framework/Washtml.php</file> <file>MailFunc.php</file> </testsuite> - <testsuite name="Managesieve Tests"> + <testsuite name="Plugins Tests"> + <file>./../plugins/acl/tests/Acl.php</file> + <file>./../plugins/additional_message_headers/tests/AdditionalMessageHeaders.php</file> + <file>./../plugins/archive/tests/Archive.php</file> + <file>./../plugins/autologon/tests/Autologon.php</file> + <file>./../plugins/database_attachments/tests/DatabaseAttachments.php</file> + <file>./../plugins/debug_logger/tests/DebugLogger.php</file> + <file>./../plugins/emoticons/tests/Emoticons.php</file> + <file>./../plugins/enigma/tests/Enigma.php</file> + <file>./../plugins/example_addressbook/tests/ExampleAddressbook.php</file> + <file>./../plugins/filesystem_attachments/tests/FilesystemAttachments.php</file> + <file>./../plugins/help/tests/Help.php</file> + <file>./../plugins/hide_blockquote/tests/HideBlockquote.php</file> + <file>./../plugins/http_authentication/tests/HttpAuthentication.php</file> + <file>./../plugins/jqueryui/tests/Jqueryui.php</file> + <file>./../plugins/managesieve/tests/Managesieve.php</file> <file>./../plugins/managesieve/tests/Parser.php</file> <file>./../plugins/managesieve/tests/Tokenizer.php</file> + <file>./../plugins/markasjunk/tests/Markasjunk.php</file> + <file>./../plugins/new_user_dialog/tests/NewUserDialog.php</file> + <file>./../plugins/new_user_identity/tests/NewUserIdentity.php</file> + <file>./../plugins/newmail_notifier/tests/NewmailNotifier.php</file> + <file>./../plugins/password/tests/Password.php</file> + <file>./../plugins/redundant_attachments/tests/RedundantAttachments.php</file> + <file>./../plugins/show_additional_headers/tests/ShowAdditionalHeaders.php</file> + <file>./../plugins/squirrelmail_usercopy/tests/Squirrelmail_usercopy.php</file> + <file>./../plugins/subscriptions_option/tests/SubscriptionsOption.php</file> + <file>./../plugins/userinfo/tests/Userinfo.php</file> + <file>./../plugins/vcard_attachments/tests/VcardAttachments.php</file> + <file>./../plugins/virtuser_file/tests/VirtuserFile.php</file> + <file>./../plugins/virtuser_query/tests/VirtuserQuery.php</file> + <file>./../plugins/zipdownload/tests/Zipdownload.php</file> </testsuite> </testsuites> </phpunit> diff --git a/tests/src/Csv2vcard/tb_plain.vcf b/tests/src/Csv2vcard/tb_plain.vcf index aace259d8..b001c3924 100644 --- a/tests/src/Csv2vcard/tb_plain.vcf +++ b/tests/src/Csv2vcard/tb_plain.vcf @@ -15,4 +15,6 @@ ORG:Organization URL;TYPE=homepage:http://page.com URL;TYPE=other:http://webpage.tld BDAY;VALUE=date:1970-11-15 +ADR;TYPE=home:;;Priv address;City;region;xx-xxx;USA +ADR;TYPE=work:;;Addr work;;;33-333;Poland END:VCARD diff --git a/tests/src/format-flowed-unfolded.txt b/tests/src/format-flowed-unfolded.txt new file mode 100644 index 000000000..14e526be4 --- /dev/null +++ b/tests/src/format-flowed-unfolded.txt @@ -0,0 +1,19 @@ +I'm replying on this with a very long line which is then wrapped and space-stuffed because the draft is saved as format=flowed.
+From what's specified in RFC 2646 some lines need to be space-stuffed to avoid muning during transport.
+
+X
+
+On XX.YY.YYYY Y:YY, Somebody wrote:
+> This part is a reply wihtout any flowing lines. rcube_mime::unfold_flowed()
+> has to be careful with empty quoted lines because they might end with a
+> space but still shouldn't be considered as flowed!
+>
+> The above empty line should persist after unfolding.
+> xxxxxxxxxx. xxxx xxxxx xxxxx xxxx xx xx.xx. xxxxxx xxxxxxxxxxxx, xxxx xx
+>
+> ... and this one as well.
+
+> > text
+
+--
+Sig
diff --git a/tests/src/format-flowed.txt b/tests/src/format-flowed.txt new file mode 100644 index 000000000..359a41aec --- /dev/null +++ b/tests/src/format-flowed.txt @@ -0,0 +1,21 @@ +I'm replying on this with a very long line which is then wrapped and
+space-stuffed because the draft is saved as format=flowed.
+ From what's specified in RFC 2646 some lines need to be space-stuffed to avoid
+muning during transport.
+
+X
+
+On XX.YY.YYYY Y:YY, Somebody wrote:
+> This part is a reply wihtout any flowing lines. rcube_mime::unfold_flowed()
+> has to be careful with empty quoted lines because they might end with a
+> space but still shouldn't be considered as flowed!
+>
+> The above empty line should persist after unfolding.
+> xxxxxxxxxx. xxxx xxxxx xxxxx xxxx xx xx.xx. xxxxxx xxxxxxxxxxxx, xxxx xx
+>
+> ... and this one as well.
+
+> > text
+
+--
+Sig
|