195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''Unit tests for grit.gather.tr_html'''
701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport os
1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport sys
1101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgif __name__ == '__main__':
1298b76c0017dbdc61506f146d197d594b1ce07db7joi@chromium.org  sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport types
1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport unittest
16ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.orgimport StringIO
1701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit.gather import tr_html
1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import clique
2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import util
2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass ParserUnittest(unittest.TestCase):
248a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def testChunkingWithoutFoldWhitespace(self):
258a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunking(False)
268a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
278a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def testChunkingWithFoldWhitespace(self):
288a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunking(True)
298a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
308a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunking(self, fold_whitespace):
318a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    """Use a single function to run all chunking testing.
328a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
338a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    This makes it easier to run chunking with fold_whitespace both on and off,
348a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    to make sure the outputs are the same.
358a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
368a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    Args:
378a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org      fold_whitespace: Whether whitespace sequences should be folded into a
388a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org        single space.
398a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    """
408a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunkingBasic(fold_whitespace)
418a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunkingDescriptions(fold_whitespace)
428a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunkingReplaceables(fold_whitespace)
438a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunkingLineBreaks(fold_whitespace)
448a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.VerifyChunkingMessageBreak(fold_whitespace)
45807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    self.VerifyChunkingMessageNoBreak(fold_whitespace)
468a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
478a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunkingBasic(self, fold_whitespace):
4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    p = tr_html.HtmlChunks()
498a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<p>Hello <b>dear</b> how <i>are</i>you?<p>Fine!',
508a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
518a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<p>', ''), (True, 'Hello <b>dear</b> how <i>are</i>you?', ''),
5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<p>', ''), (True, 'Fine!', '')])
5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
558a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<p> Hello <b>dear</b> how <i>are</i>you? <p>Fine!',
568a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
578a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
5801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<p> ', ''), (True, 'Hello <b>dear</b> how <i>are</i>you?', ''),
5901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, ' <p>', ''), (True, 'Fine!', '')])
6001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
618a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<p> Hello <b>dear how <i>are you? <p> Fine!',
628a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
638a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<p> ', ''), (True, 'Hello <b>dear how <i>are you?', ''),
6501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, ' <p> ', ''), (True, 'Fine!', '')])
6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Ensure translateable sections that start with inline tags contain
6801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # the starting inline tag.
698a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<b>Hello!</b> how are you?<p><i>I am fine.</i>',
708a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
718a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
7201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<b>Hello!</b> how are you?', ''), (False, '<p>', ''),
7301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<i>I am fine.</i>', '')])
7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Ensure translateable sections that end with inline tags contain
7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # the ending inline tag.
778a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse("Hello! How are <b>you?</b><p><i>I'm fine!</i>",
788a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
798a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, 'Hello! How are <b>you?</b>', ''), (False, '<p>', ''),
8101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, "<i>I'm fine!</i>", '')])
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
838a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunkingDescriptions(self, fold_whitespace):
848a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    p = tr_html.HtmlChunks()
8501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check capitals and explicit descriptions
868a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<!-- desc=bingo! --><B>Hello!</B> how are you?<P>'
878a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<I>I am fine.</I>', fold_whitespace)
888a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
8901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<B>Hello!</B> how are you?', 'bingo!'), (False, '<P>', ''),
9001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<I>I am fine.</I>', '')])
918a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<B><!-- desc=bingo! -->Hello!</B> how are you?<P>'
928a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<I>I am fine.</I>', fold_whitespace)
938a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
9401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<B>Hello!</B> how are you?', 'bingo!'), (False, '<P>', ''),
9501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<I>I am fine.</I>', '')])
968a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    # Linebreaks get handled by the tclib message.
978a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<B>Hello!</B> <!-- desc=bi\nngo\n! -->how are you?<P>'
988a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<I>I am fine.</I>', fold_whitespace)
998a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
1008a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org      (True, '<B>Hello!</B> how are you?', 'bi\nngo\n!'), (False, '<P>', ''),
10101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<I>I am fine.</I>', '')])
10201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # In this case, because the explicit description appears after the first
10401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # translateable, it will actually apply to the second translateable.
1058a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<B>Hello!</B> how are you?<!-- desc=bingo! --><P>'
1068a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<I>I am fine.</I>', fold_whitespace)
1078a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
10801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<B>Hello!</B> how are you?', ''), (False, '<P>', ''),
10901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<I>I am fine.</I>', 'bingo!')])
11001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1118a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunkingReplaceables(self, fold_whitespace):
11201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that replaceables within block tags (where attributes would go) are
11301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # handled correctly.
1148a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    p = tr_html.HtmlChunks()
11501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    chunks = p.Parse('<b>Hello!</b> how are you?<p [BINGO] [$~BONGO~$]>'
1168a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<i>I am fine.</i>', fold_whitespace)
1178a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
11801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<b>Hello!</b> how are you?', ''),
11901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<p [BINGO] [$~BONGO~$]>', ''),
12001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, '<i>I am fine.</i>', '')])
12101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1228a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunkingLineBreaks(self, fold_whitespace):
12301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that the contents of preformatted tags preserve line breaks.
1248a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    p = tr_html.HtmlChunks()
1258a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<textarea>Hello\nthere\nhow\nare\nyou?</textarea>',
1268a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     fold_whitespace)
1278a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [(False, '<textarea>', ''),
12801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, 'Hello\nthere\nhow\nare\nyou?', ''), (False, '</textarea>', '')])
12901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # ...and that other tags' line breaks are converted to spaces
1318a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<p>Hello\nthere\nhow\nare\nyou?</p>', fold_whitespace)
1328a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [(False, '<p>', ''),
13301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (True, 'Hello there how are you?', ''), (False, '</p>', '')])
13401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1358a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def VerifyChunkingMessageBreak(self, fold_whitespace):
1368a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    p = tr_html.HtmlChunks()
1378a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    # Make sure that message-break comments work properly.
1388a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('Break<!-- message-break --> apart '
1398a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<!--message-break-->messages', fold_whitespace)
1408a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [(True, 'Break', ''),
1418a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (False, ' ', ''),
1428a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (True, 'apart', ''),
1438a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (False, ' ', ''),
1448a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (True, 'messages', '')])
1458a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
1468a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    # Make sure message-break comments work in an inline tag.
1478a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    chunks = p.Parse('<a href=\'google.com\'><!-- message-break -->Google'
1488a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<!--message-break--></a>', fold_whitespace)
1498a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [(False, '<a href=\'google.com\'>', ''),
1508a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (True, 'Google', ''),
1518a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                                  (False, '</a>', '')])
1528a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
153807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org  def VerifyChunkingMessageNoBreak(self, fold_whitespace):
154807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    p = tr_html.HtmlChunks()
155807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    # Make sure that message-no-break comments work properly.
156807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    chunks = p.Parse('Please <!-- message-no-break --> <br />don\'t break',
157807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                     fold_whitespace)
158807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    self.failUnlessEqual(chunks, [(True, 'Please <!-- message-no-break --> '
159807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                         '<br />don\'t break', '')])
160807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org
161807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    chunks = p.Parse('Please <br /> break. <!-- message-no-break --> <br /> '
162807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                     'But not this time.', fold_whitespace)
163807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    self.failUnlessEqual(chunks, [(True, 'Please', ''),
164807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                                  (False, ' <br /> ', ''),
165807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                                  (True, 'break. <!-- message-no-break --> '
166807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org                                         '<br /> But not this time.', '')])
167807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org
16801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testTranslateableAttributes(self):
16901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    p = tr_html.HtmlChunks()
17001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
17101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that the translateable attributes in <img>, <submit>, <button> and
17201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # <text> elements buttons are handled correctly.
17301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    chunks = p.Parse('<img src=bingo.jpg alt="hello there">'
17401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                     '<input type=submit value="hello">'
17501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                     '<input type="button" value="hello">'
1768a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                     '<input type=\'text\' value=\'Howdie\'>', False)
1778a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(chunks, [
17801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '<img src=bingo.jpg alt="', ''), (True, 'hello there', ''),
17901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '"><input type=submit value="', ''), (True, 'hello', ''),
18001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '"><input type="button" value="', ''), (True, 'hello', ''),
18101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '"><input type=\'text\' value=\'', ''), (True, 'Howdie', ''),
18201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      (False, '\'>', '')])
18301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testTranslateableHtmlToMessage(self):
18601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
18701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'Hello <b>[USERNAME]</b>, &lt;how&gt;&nbsp;<i>are</i> you?')
18801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
18901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
19001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'Hello BEGIN_BOLDX_USERNAME_XEND_BOLD, '
19101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    '<how>&nbsp;BEGIN_ITALICareEND_ITALIC you?')
19201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
19301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage('<b>Hello</b><I>Hello</I><b>Hello</b>')
19401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
19501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
19601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'BEGIN_BOLD_1HelloEND_BOLD_1BEGIN_ITALICHelloEND_ITALIC'
19701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'BEGIN_BOLD_2HelloEND_BOLD_2')
19801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
19901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that nesting (of the <font> tags) is handled correctly - i.e. that
20001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # the closing placeholder numbers match the opening placeholders.
20101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
20201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''<font size=-1><font color=#FF0000>Update!</font> '''
20301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''<a href='http://desktop.google.com/whatsnew.html?hl=[$~LANG~$]'>'''
20401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''New Features</a>: Now search PDFs, MP3s, Firefox web history, and '''
20501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''more</font>''')
20601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
20701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
20801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'BEGIN_FONT_1BEGIN_FONT_2Update!END_FONT_2 BEGIN_LINK'
20901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'New FeaturesEND_LINK: Now search PDFs, MP3s, Firefox '
21001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'web history, and moreEND_FONT_1')
21101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage('''<a href='[$~URL~$]'><b>[NUM][CAT]</b></a>''')
21301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
21401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres == 'BEGIN_LINKBEGIN_BOLDX_NUM_XX_CAT_XEND_BOLDEND_LINK')
21501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
21701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''<font size=-1><a class=q onClick='return window.qs?qs(this):1' '''
21801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''href='http://[WEBSERVER][SEARCH_URI]'>Desktop</a></font>&nbsp;&nbsp;'''
21901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''&nbsp;&nbsp;''')
22001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
22101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
22201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    '''BEGIN_FONTBEGIN_LINKDesktopEND_LINKEND_FONTSPACE''')
22301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
22401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
22501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''<br><br><center><font size=-2>&copy;2005 Google </font></center>''', 1)
22601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
22701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
22801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    u'BEGIN_BREAK_1BEGIN_BREAK_2BEGIN_CENTERBEGIN_FONT\xa92005'
22901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    u' Google END_FONTEND_CENTER')
23001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
23101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
23201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''&nbsp;-&nbsp;<a class=c href=[$~CACHE~$]>Cached</a>''')
23301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
23401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
23501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    '&nbsp;-&nbsp;BEGIN_LINKCachedEND_LINK')
23601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
23701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that upper-case tags are handled correctly.
23801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
23901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''You can read the <A HREF='http://desktop.google.com/privacypolicy.'''
24001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''html?hl=[LANG_CODE]'>Privacy Policy</A> and <A HREF='http://desktop'''
24101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''.google.com/privacyfaq.html?hl=[LANG_CODE]'>Privacy FAQ</A> online.''')
24201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
24301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres ==
24401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'You can read the BEGIN_LINK_1Privacy PolicyEND_LINK_1 and '
24501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'BEGIN_LINK_2Privacy FAQEND_LINK_2 online.')
24601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
24701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Check that tags with linebreaks immediately preceding them are handled
24801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # correctly.
24901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
25001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '''You can read the
25101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<A HREF='http://desktop.google.com/privacypolicy.html?hl=[LANG_CODE]'>Privacy Policy</A>
25201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.organd <A HREF='http://desktop.google.com/privacyfaq.html?hl=[LANG_CODE]'>Privacy FAQ</A> online.''')
25301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pres = msg.GetPresentableContent()
25401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(pres == '''You can read the
25501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgBEGIN_LINK_1Privacy PolicyEND_LINK_1
25601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.organd BEGIN_LINK_2Privacy FAQEND_LINK_2 online.''')
25701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
258807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    # Check that message-no-break comments are handled correctly.
259807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    msg = tr_html.HtmlToMessage('''Please <!-- message-no-break --><br /> don't break''')
260807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    pres = msg.GetPresentableContent()
261807b78b2bb3a1ada6afb52bc0301ce717c230503joi@chromium.org    self.failUnlessEqual(pres, '''Please BREAK don't break''')
26201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
26301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass TrHtmlUnittest(unittest.TestCase):
2648a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def testSetAttributes(self):
265ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO(''))
2668a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.fold_whitespace_, False)
2678a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.SetAttributes({})
2688a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.fold_whitespace_, False)
2698a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.SetAttributes({'fold_whitespace': 'false'})
2708a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.fold_whitespace_, False)
2718a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.SetAttributes({'fold_whitespace': 'true'})
2728a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.fold_whitespace_, True)
2738a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
2748a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def testFoldWhitespace(self):
2758a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    text = '<td>   Test     Message   </td>'
2768a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
277ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO(text))
2788a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.Parse()
2798a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.skeleton_[1].GetMessage().GetPresentableContent(),
2808a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                         'Test  Message')
2818a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
282ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO(text))
2838a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.fold_whitespace_ = True
2848a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.Parse()
2858a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(html.skeleton_[1].GetMessage().GetPresentableContent(),
2868a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org                         'Test Message')
2878a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
28801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testTable(self):
289ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO('''<table class="shaded-header"><tr>
29001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<td class="header-element b expand">Preferences</td>
29101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<td class="header-element s">
29201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<a href="http://desktop.google.com/preferences.html">Preferences&nbsp;Help</a>
29301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org</td>
294ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org</tr></table>'''))
29501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
29601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[3].GetMessage().GetPresentableContent() ==
29701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'BEGIN_LINKPreferences&nbsp;HelpEND_LINK')
29801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
29901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testSubmitAttribute(self):
300ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO('''</td>
30101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<td class="header-element"><input type=submit value="Save Preferences"
30201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgname=submit2></td>
303ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org</tr></table>'''))
30401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
30501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[1].GetMessage().GetPresentableContent() ==
30601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'Save Preferences')
30701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
30801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testWhitespaceAfterInlineTag(self):
30901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Test that even if there is whitespace after an inline tag at the start
31001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    of a translateable section the inline tag will be included.
31101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
312ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(
313ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org        StringIO.StringIO('''<label for=DISPLAYNONE><font size=-1> Hello</font>'''))
31401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
31501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[1].GetMessage().GetRealContent() ==
31601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    '<font size=-1> Hello</font>')
31701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
31801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testSillyHeader(self):
319ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO('''[!]
32001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgtitle\tHello
32101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgbingo
32201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgbongo
32301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgbla
32401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
325ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org<p>Other stuff</p>'''))
32601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
32701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    content = html.skeleton_[1].GetMessage().GetRealContent()
32801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(content == 'Hello')
32901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[-1] == '</p>')
33001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Right after the translateable the nontranslateable should start with
33101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # a linebreak (this catches a bug we had).
33201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[2][0] == '\n')
33301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
33401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
33501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testExplicitDescriptions(self):
336ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(
337ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org        StringIO.StringIO('Hello [USER]<br/><!-- desc=explicit -->'
338ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org                          '<input type="button">Go!</input>'))
3398a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    html.Parse()
3408a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    msg = html.GetCliques()[1].GetMessage()
3418a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(msg.GetDescription(), 'explicit')
3428a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(msg.GetRealContent(), 'Go!')
3438a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
344ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(
345ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org        StringIO.StringIO('Hello [USER]<br/><!-- desc=explicit\nmultiline -->'
346ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org                          '<input type="button">Go!</input>'))
34701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
34801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = html.GetCliques()[1].GetMessage()
3498a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(msg.GetDescription(), 'explicit multiline')
3508a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    self.failUnlessEqual(msg.GetRealContent(), 'Go!')
35101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
35201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
35301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testRegressionInToolbarAbout(self):
354ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(util.PathFromRoot(r'grit/testdata/toolbar_about.html'))
35501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
35601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    cliques = html.GetCliques()
35701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for cl in cliques:
35801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      content = cl.GetMessage().GetRealContent()
35901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if content.count('De parvis grandis acervus erit'):
36001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.failIf(content.count('$/translate'))
36101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
36201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
36301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def HtmlFromFileWithManualCheck(self, f):
364ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(f)
36501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
36601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
36701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # For manual results inspection only...
36801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    list = []
36901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for item in html.skeleton_:
37001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if isinstance(item, types.StringTypes):
37101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        list.append(item)
37201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      else:
37301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        list.append(item.GetMessage().GetPresentableContent())
37401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
37501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return html
37601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
37701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
37801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testPrivacyHtml(self):
37901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html = self.HtmlFromFileWithManualCheck(
38001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      util.PathFromRoot(r'grit/testdata/privacy.html'))
38101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
38201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[1].GetMessage().GetRealContent() ==
38301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    'Privacy and Google Desktop Search')
38401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(html.skeleton_[3].startswith('<'))
38501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(len(html.skeleton_) > 10)
38601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
38701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
38801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testPreferencesHtml(self):
38901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html = self.HtmlFromFileWithManualCheck(
39001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      util.PathFromRoot(r'grit/testdata/preferences.html'))
39101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
39201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Verify that we don't get '[STATUS-MESSAGE]' as the original content of
39301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # one of the MessageClique objects (it would be a placeholder-only message
39401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # and we're supposed to have stripped those).
39501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
396705a118ab4a1f2fe348fccdcd4786a0b5bf426ecjoi@chromium.org    for item in [x for x in html.skeleton_
397705a118ab4a1f2fe348fccdcd4786a0b5bf426ecjoi@chromium.org                 if isinstance(x, clique.MessageClique)]:
39801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if (item.GetMessage().GetRealContent() == '[STATUS-MESSAGE]' or
39901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          item.GetMessage().GetRealContent() == '[ADDIN-DO] [ADDIN-OPTIONS]'):
40001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.fail()
40101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
40201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(len(html.skeleton_) > 100)
40301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
40401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def AssertNumberOfTranslateables(self, files, num):
40501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Fails if any of the files in files don't have exactly
40601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    num translateable sections.
40701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
40801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
40901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      files: ['file1', 'file2']
41001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      num: 3
41101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
41201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for f in files:
41301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      f = util.PathFromRoot(r'grit/testdata/%s' % f)
41401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      html = self.HtmlFromFileWithManualCheck(f)
41501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      self.failUnless(len(html.GetCliques()) == num)
41601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
41701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testFewTranslateables(self):
41801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.AssertNumberOfTranslateables(['browser.html', 'email_thread.html',
41901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                                       'header.html', 'mini.html',
42001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                                       'oneclick.html', 'script.html',
42101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                                       'time_related.html', 'versions.html'], 0)
42201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.AssertNumberOfTranslateables(['footer.html', 'hover.html'], 1)
42301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
42401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testOtherHtmlFilesForManualInspection(self):
42501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    files = [
42601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'about.html', 'bad_browser.html', 'cache_prefix.html',
42701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'cache_prefix_file.html', 'chat_result.html', 'del_footer.html',
42801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'del_header.html', 'deleted.html', 'details.html', 'email_result.html',
42901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'error.html', 'explicit_web.html', 'footer.html',
43001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'homepage.html', 'indexing_speed.html',
43101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'install_prefs.html', 'install_prefs2.html',
43201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'oem_enable.html', 'oem_non_admin.html', 'onebox.html',
43301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'password.html', 'quit_apps.html', 'recrawl.html',
43401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'searchbox.html', 'sidebar_h.html', 'sidebar_v.html', 'status.html',
43501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    ]
43601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for f in files:
43701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      self.HtmlFromFileWithManualCheck(
43801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        util.PathFromRoot(r'grit/testdata/%s' % f))
43901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
44001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testTranslate(self):
44101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Note that the English translation of documents that use character
44201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # literals (e.g. &copy;) will not be the same as the original document
44301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # because the character literal will be transformed into the Unicode
44401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # character itself.  So for this test we choose some relatively complex
44501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # HTML without character entities (but with &nbsp; because that's handled
44601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # specially).
447ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO('''  <script>
44801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      <!--
44901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      function checkOffice() { var w = document.getElementById("h7");
45001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      var e = document.getElementById("h8"); var o = document.getElementById("h10");
45101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if (!(w.checked || e.checked)) { o.checked=0;o.disabled=1;} else {o.disabled=0;} }
45201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      // -->
45301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        </script>
45401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [CHECK-DOC] name=DOC id=h7 onclick='checkOffice()'>
45501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=h7> Word</label><br>
45601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [CHECK-XLS] name=XLS id=h8 onclick='checkOffice()'>
45701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=h8> Excel</label><br>
45801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [CHECK-PPT] name=PPT id=h9>
45901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=h9> PowerPoint</label><br>
46001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        </span></td><td nowrap valign=top><span class="s">
46101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [CHECK-PDF] name=PDF id=hpdf>
46201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=hpdf> PDF</label><br>
46301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [CHECK-TXT] name=TXT id=h6>
46401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=h6> Text, media, and other files</label><br>
46501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org       </tr>&nbsp;&nbsp;
46601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org       <tr><td nowrap valign=top colspan=3><span class="s"><br />
46701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org       <input type=checkbox [CHECK-SECUREOFFICE] name=SECUREOFFICE id=h10>
46801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <label for=h10> Password-protected Office documents (Word, Excel)</label><br />
46901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        <input type=checkbox [DISABLED-HTTPS] [CHECK-HTTPS] name=HTTPS id=h12><label
47001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        for=h12> Secure pages (HTTPS) in web history</label></span></td></tr>
471ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      </table>'''))
47201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
47301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    trans = html.Translate('en')
47401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if (html.GetText() != trans):
47501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      self.fail()
47601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
47701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
47801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testHtmlToMessageWithBlockTags(self):
47901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
48001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'Hello<p>Howdie<img alt="bingo" src="image.gif">', True)
48101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    result = msg.GetPresentableContent()
48201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(
48301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      result == 'HelloBEGIN_PARAGRAPHHowdieBEGIN_BLOCKbingoEND_BLOCK')
48401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
48501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(
48601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      'Hello<p>Howdie<input type="button" value="bingo">', True)
48701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    result = msg.GetPresentableContent()
48801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(
48901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      result == 'HelloBEGIN_PARAGRAPHHowdieBEGIN_BLOCKbingoEND_BLOCK')
49001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
49101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
49201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testHtmlToMessageRegressions(self):
49301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    msg = tr_html.HtmlToMessage(' - ', True)
49401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    result = msg.GetPresentableContent()
49501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(result == ' - ')
49601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
49701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
49801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testEscapeUnescaped(self):
49901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    text = '&copy;&nbsp; & &quot;&lt;hello&gt;&quot;'
50001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    unescaped = util.UnescapeHtml(text)
50101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(unescaped == u'\u00a9\u00a0 & "<hello>"')
50201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    escaped_unescaped = util.EscapeHtml(unescaped, True)
50301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.failUnless(escaped_unescaped ==
50401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                    u'\u00a9\u00a0 &amp; &quot;&lt;hello&gt;&quot;')
50501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
50601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testRegressionCjkHtmlFile(self):
50701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # TODO(joi) Fix this problem where unquoted attributes that
50801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # have a value that is CJK characters causes the regular expression
50901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # match never to return.  (culprit is the _ELEMENT regexp(
51001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if False:
51101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      html = self.HtmlFromFileWithManualCheck(util.PathFromRoot(
51201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        r'grit/testdata/ko_oem_enable_bug.html'))
51301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      self.failUnless(True)
51401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
51501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def testRegressionCpuHang(self):
51601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # If this regression occurs, the unit test will never return
517ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    html = tr_html.TrHtml(StringIO.StringIO(
518ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      '''<input type=text size=12 id=advFileTypeEntry [~SHOW-FILETYPE-BOX~] value="[EXT]" name=ext>'''))
51901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    html.Parse()
52001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
52101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgif __name__ == '__main__':
52201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  unittest.main()
523