initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $this->assertInstanceOf(\rcmail_action::class, $action); $this->assertTrue($action->checks()); $_GET = ['_uid' => 10]; // Set expected storage function calls/results self::mockStorage() ->registerFunction('set_options') ->registerFunction('get_pagesize', 10) ->registerFunction('set_charset') ->registerFunction('is_connected', true) ->registerFunction('set_folder') ->registerFunction('get_folder', 'INBOX') ->registerFunction('get_folder', 'INBOX') ->registerFunction('get_threading', false) ->registerFunction('get_pagesize', 10) ->registerFunction('get_capability', false) ->registerFunction('get_capability', false) ->registerFunction('set_folder') ->registerFunction('set_page') ->registerFunction('set_threading'); $action->run(); $this->assertSame([], $output->headers); $this->assertNull($output->getOutput()); $this->assertSame('Inbox', $output->getProperty('pagetitle')); $this->assertSame('INBOX', $output->get_env('mailbox')); $this->assertSame(10, $output->get_env('pagesize')); $this->assertSame('/', $output->get_env('delimiter')); $this->assertSame('widescreen', $output->get_env('layout')); $this->assertSame('Drafts', $output->get_env('drafts_mailbox')); $this->assertSame('Trash', $output->get_env('trash_mailbox')); $this->assertSame('Junk', $output->get_env('junk_mailbox')); $this->assertSame(10, $output->get_env('list_uid')); } /** * Test run() method in AJAX mode */ public function test_run_ajax() { $action = new \rcmail_action_mail_index(); $output = $this->initOutput(\rcmail_action::MODE_AJAX, 'mail', 'list'); $this->assertTrue($action->checks()); // Set expected storage function calls/results self::mockStorage() ->registerFunction('set_options') ->registerFunction('get_pagesize', 10) ->registerFunction('set_charset') ->registerFunction('is_connected', true) ->registerFunction('set_folder') ->registerFunction('get_folder', 'INBOX') ->registerFunction('get_threading', false) ->registerFunction('get_pagesize') ->registerFunction('get_capability', false) ->registerFunction('get_capability', false) ->registerFunction('set_folder') ->registerFunction('set_page') ->registerFunction('set_threading'); $action->run(); $this->assertSame([], $output->headers); $this->assertNull($output->getOutput()); $this->assertSame('', $output->getProperty('pagetitle')); $this->assertSame('INBOX', $output->get_env('mailbox')); $this->assertSame(10, $output->get_env('pagesize')); $this->assertSame(1, $output->get_env('current_page')); $this->assertSame('/', $output->get_env('delimiter')); $this->assertSame('widescreen', $output->get_env('layout')); $this->assertSame('Drafts', $output->get_env('drafts_mailbox')); $this->assertSame('Trash', $output->get_env('trash_mailbox')); $this->assertSame('Junk', $output->get_env('junk_mailbox')); } /** * Test message_list_smart_column_name() method */ public function test_message_list_smart_column_name() { $action = new \rcmail_action_mail_index(); $output = $this->initOutput(\rcmail_action::MODE_AJAX, 'mail', 'list'); $output->set_env('mailbox', 'INBOX'); $this->assertSame('from', $action->message_list_smart_column_name()); $output->set_env('mailbox', 'Drafts'); $this->assertSame('to', $action->message_list_smart_column_name()); $output->set_env('mailbox', 'Drafts/Subfolder'); $this->assertSame('to', $action->message_list_smart_column_name()); $output->set_env('mailbox', 'Sent'); $this->assertSame('to', $action->message_list_smart_column_name()); $output->set_env('mailbox', 'Sent/Subfolder'); $this->assertSame('to', $action->message_list_smart_column_name()); } /** * Test message_list() method */ public function test_message_list() { $action = new \rcmail_action_mail_index(); $output = $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', 'list'); self::mockStorage()->registerFunction('get_folder', 'INBOX'); $result = $action->message_list([]); $this->assertMatchesRegularExpression('/^$/', $result); $listcols = ['threads', 'subject', 'status', 'fromto', 'date', 'size', 'flag', 'attachment']; $this->assertSame($listcols, $output->get_env('listcols')); } /** * Test js_message_list() method */ public function test_js_message_list() { $action = new \rcmail_action_mail_index(); $output = $this->initOutput(\rcmail_action::MODE_AJAX, 'mail', 'list'); self::mockStorage() ->registerFunction('get_search_set', null) ->registerFunction('get_threading', true) ->registerFunction('get_folder', 'INBOX') ->registerFunction('get_folder', 'INBOX'); $action->js_message_list([]); $this->assertFalse($output->get_env('multifolder_listing')); $commands = $output->getProperty('commands'); $this->assertCount(1, $commands); $this->assertSame('set_message_coltypes', $commands[0][0]); } /** * Test options_menu_link() method */ public function test_options_menu_link() { $action = new \rcmail_action_mail_index(); $output = $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $link = $action->options_menu_link(['icon' => 'ico.png']); $expected = '' . 'List options...'; $this->assertSame($expected, $link); } /** * Test messagecount_display() method */ public function test_messagecount_display() { $this->markTestIncomplete(); } /** * Test get_messagecount_text() method */ public function test_get_messagecount_text() { $this->markTestIncomplete(); } /** * Test send_unread_count() method */ public function test_send_unread_count() { $this->markTestIncomplete(); } /** * Test check_safe() method */ public function test_check_safe() { $this->markTestIncomplete(); } /** * Test part_image_type() method */ public function test_part_image_type() { $this->markTestIncomplete(); } /** * Test address_string() method */ public function test_address_string() { $action = new \rcmail_action_mail_index(); $this->assertNull($action->address_string('')); $result = $action->address_string('test@domain.com'); $expected = 'test@domain.com'; $this->assertSame($expected, $result); $result = $action->address_string('test@domain.com', null, true, true); $expected = '' . 'test@domain.com'; $this->assertSame($expected, $result); setProperty($action, 'PRINT_MODE', true); $result = $action->address_string('test@domain.com'); $expected = '<test@domain.com>'; $this->assertSame($expected, $result); } /** * Test attachment_name() method */ public function test_attachment_name() { $action = new \rcmail_action_mail_index(); $part = new \rcube_message_part(); $part->mime_id = '1'; $part->mimetype = 'text/html'; $this->assertSame('HTML Message', $action->attachment_name($part)); $part->mimetype = 'application/pdf'; $this->assertSame('Part 1.pdf', $action->attachment_name($part)); $part->filename = 'test.pdf'; $this->assertSame('test.pdf', $action->attachment_name($part)); } /** * Test search_filter() method */ public function test_search_filter() { $this->markTestIncomplete(); } /** * Test search_interval() method */ public function test_search_interval() { $this->markTestIncomplete(); } /** * Test message_error() method */ public function test_message_error() { $this->markTestIncomplete(); } /** * Test message_import_form() method */ public function test_message_import_form() { $this->markTestIncomplete(); } /** * Helper method to create a HTML message part object */ protected function get_html_part($body = null) { $part = new \rcube_message_part(); $part->ctype_primary = 'text'; $part->ctype_secondary = 'html'; $part->body = $body ? file_get_contents(TESTS_DIR . $body) : null; $part->replaces = []; return $part; } /** * Class constructor */ public function test_class() { $object = new \rcmail_action_mail_index(); $this->assertInstanceOf(\rcmail_action::class, $object); } /** * Test sanitization of a "normal" html message */ public function test_html() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $part = $this->get_html_part('src/htmlbody.txt'); $part->replaces = ['ex1.jpg' => 'part_1.2.jpg', 'ex2.jpg' => 'part_1.2.jpg']; $params = ['container_id' => 'foo', 'safe' => false]; // render HTML in normal mode $html = \rcmail_action_mail_index::print_body($part->body, $part, $params); $this->assertMatchesRegularExpression('/src="' . $part->replaces['ex1.jpg'] . '"/', $html, 'Replace reference to inline image'); $this->assertMatchesRegularExpression('#background="static.php/program/resources/blocked.gif"#', $html, 'Replace external background image'); $this->assertDoesNotMatchRegularExpression('/ex3.jpg/', $html, 'No references to external images'); $this->assertDoesNotMatchRegularExpression('/]+>/', $html, 'No meta tags allowed'); $this->assertDoesNotMatchRegularExpression('/]+>/', $html, 'No form tags allowed'); $this->assertMatchesRegularExpression('/Subscription form/', $html, 'Include contents'); $this->assertMatchesRegularExpression('//', $html, 'No external links allowed'); $this->assertMatchesRegularExpression('/]+ target="_blank"/', $html, 'Set target to _blank'); // $this->assertTrue($GLOBALS['REMOTE_OBJECTS'], "Remote object detected"); // render HTML in safe mode $params['safe'] = true; $html = \rcmail_action_mail_index::print_body($part->body, $part, $params); $this->assertMatchesRegularExpression('/'; $opts = ['safe' => false, 'css_prefix' => 'v1', 'add_comments' => false]; $washed = \rcmail_action_mail_index::wash_html($html, $opts); $this->assertStringContainsString('
', $washed); $this->assertStringContainsString('', $washed); } /** * Test handling of body style attributes */ public function test_wash_html_body_style() { $html = '

test

'; $params = ['container_id' => 'foo', 'add_comments' => false, 'safe' => false]; $washed = \rcmail_action_mail_index::wash_html($html, $params, []); $this->assertSame('

test

', $washed); $params['safe'] = true; $washed = \rcmail_action_mail_index::wash_html($html, $params, []); $this->assertSame('

test

', $washed); } /** * Test washtml class on non-unicode characters (#1487813) * * @group mbstring */ #[Group('mbstring')] public function test_washtml_utf8() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $part = $this->get_html_part('src/invalidchars.html'); $washed = \rcmail_action_mail_index::print_body($part->body, $part); $this->assertMatchesRegularExpression('/

(символ|симол)<\/p>/', $washed, 'Remove non-unicode characters from HTML message body'); } /** * Test inserting meta tag with required charset definition */ public function test_meta_insertion() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $meta = ''; $args = [ 'inline_html' => false, 'html_elements' => ['html', 'body', 'meta', 'head'], 'html_attribs' => ['charset'], ]; $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertStringContainsString("{$meta}Test1", $washed, 'Meta tag insertion (1)'); $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertStringContainsString("{$meta}Test1", $washed, 'Meta tag insertion (2)'); $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertTrue(strpos($washed, "{$meta}") === 0, 'Meta tag insertion (3)'); $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertTrue(strpos($washed, "{$meta}") === 0, 'Meta tag insertion (4)'); $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertTrue(strpos($washed, "{$meta}") === 0, 'Meta tag insertion (5)'); $body = 'Test1
Test2'; $washed = \rcmail_action_mail_index::wash_html($body, $args); $this->assertTrue(strpos($washed, "{$meta}") === 0, 'Meta tag insertion (6)'); $this->assertTrue(strpos($washed, 'Test2') > 0, 'Meta tag insertion (7)'); } /** * Test links pattern replacements in plaintext messages */ public function test_plaintext() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $part = new \rcube_message_part(); $part->ctype_primary = 'text'; $part->ctype_secondary = 'plain'; $part->body = quoted_printable_decode(file_get_contents(TESTS_DIR . 'src/plainbody.txt')); $html = \rcmail_action_mail_index::print_body($part->body, $part, ['safe' => true]); $this->assertMatchesRegularExpression( '/nobody@roundcube.net<\/a>/', $html, 'Mailto links with onclick' ); $this->assertMatchesRegularExpression( '#http://www.apple.com/legal/privacy#', $html, 'Links with target=_blank' ); $this->assertMatchesRegularExpression( '#\[http://example.com/\?tx\[a\]=5\]#', $html, 'Links with square brackets' ); } /** * Test mailto links in html messages */ public function test_mailto() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $part = $this->get_html_part('src/mailto.txt'); $params = ['container_id' => 'foo', 'safe' => false]; // render HTML in normal mode $html = \rcmail_action_mail_index::print_body($part->body, $part, $params); $mailto = 'e-mail'; $this->assertMatchesRegularExpression('|' . preg_quote($mailto, '|') . '|', $html, 'Extended mailto links'); } /** * Test the elimination of HTML comments */ public function test_html_comments() { $this->initOutput(\rcmail_action::MODE_HTTP, 'mail', ''); $part = $this->get_html_part('src/htmlcom.txt'); $washed = \rcmail_action_mail_index::print_body($part->body, $part, ['safe' => true]); // #1487759 $this->assertMatchesRegularExpression('|

test1

|', $washed, 'Buggy HTML comments'); // but conditional comments (