From 8e3667f602495bcb043e8a4c56a86dc148106524 Mon Sep 17 00:00:00 2001
From: wurstsalat <mailtrash@posteo.de>
Date: Fri, 2 Apr 2021 12:09:17 +0200
Subject: [PATCH] GTK Tests: Use ConversationView for XHTML test

---
 gajim/gtk/conversation/view.py     | 24 +++++++++---
 gajim/gtk/conversation_textview.py | 32 +++++++++------
 gajim/gtk/htmltextview.py          | 16 ++++----
 test/gtk/htmltextview.py           | 62 +++++++++++++-----------------
 4 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/gajim/gtk/conversation/view.py b/gajim/gtk/conversation/view.py
index 6ca4d31872..c63cc24be5 100644
--- a/gajim/gtk/conversation/view.py
+++ b/gajim/gtk/conversation/view.py
@@ -52,7 +52,9 @@ def __init__(self, account, contact, history_mode=False):
         self.set_selection_mode(Gtk.SelectionMode.NONE)
         self.set_sort_func(self._sort_func)
         self._account = account
-        self._client = app.get_client(account)
+        self._client = None
+        if account is not None:
+            self._client = app.get_client(account)
         self._contact = contact
         self._history_mode = history_mode
 
@@ -70,8 +72,9 @@ def __init__(self, account, contact, history_mode=False):
         # message_id -> row mapping
         self._message_id_row_map = {}
 
-        self._read_marker_row = ReadMarkerRow(self._account, self._contact)
-        self.add(self._read_marker_row)
+        if self._contact is not None:
+            self._read_marker_row = ReadMarkerRow(self._account, self._contact)
+            self.add(self._read_marker_row)
 
         self._scroll_hint_row = ScrollHintRow(self._account,
                                               history_mode=self._history_mode)
@@ -133,8 +136,9 @@ def add_message(self,
         if other_text_tags is None:
             other_text_tags = []
 
-        if (kind in ('status', 'info') or
-                (subject and self._contact.is_groupchat)):
+        muc_subject = bool(subject and self._contact is not None and
+                           self._contact.is_groupchat)
+        if kind in ('status', 'info') or muc_subject:
             message = InfoMessageRow(
                 self._account,
                 timestamp,
@@ -157,6 +161,11 @@ def add_message(self,
                 return
 
             avatar = self._get_avatar(kind, name)
+
+            is_groupchat = False
+            if self._contact is not None:
+                is_groupchat = self._contact.is_groupchat
+
             message = MessageRow(
                 self._account,
                 message_id,
@@ -166,7 +175,7 @@ def add_message(self,
                 text,
                 other_text_tags,
                 avatar,
-                self._contact.is_groupchat,
+                is_groupchat,
                 additional_data=additional_data,
                 display_marking=display_marking,
                 marker=marker,
@@ -181,6 +190,9 @@ def add_message(self,
         self._insert_message(message)
 
     def _get_avatar(self, kind, name):
+        if self._contact is None:
+            return None
+
         scale = self.get_scale_factor()
         if self._contact.is_groupchat:
             contact = self._contact.get_resource(name)
diff --git a/gajim/gtk/conversation_textview.py b/gajim/gtk/conversation_textview.py
index 9534fc7d67..d3ad8e9df8 100644
--- a/gajim/gtk/conversation_textview.py
+++ b/gajim/gtk/conversation_textview.py
@@ -184,8 +184,7 @@ def print_text(self, text, other_text_tags=None, kind=None, graphics=True,
                 if (name and (text.startswith('/me ') or
                               text.startswith('/me\n'))):
                     xhtml = xhtml.replace('/me', '<i>* %s</i>' % (name,), 1)
-                self.display_html(
-                    xhtml, self, self)
+                self.display_html(xhtml, self)
                 return
             except Exception as err:
                 log.debug('Error processing xhtml: %s', err)
@@ -217,7 +216,7 @@ def print_text(self, text, other_text_tags=None, kind=None, graphics=True,
         GLib.idle_add(self.queue_resize)
 
     def parse_formatting(self, text, text_tags, graphics=True,
-                         additional_data=None):
+                         additional_data=None, iter_=None):
         '''
         Parses message formatting (Emojis, URIs, Styles).
         A regex is used for text matching. Each text fragment gets
@@ -237,10 +236,8 @@ def parse_formatting(self, text, text_tags, graphics=True,
         else:
             insert_tags_func = buffer_.insert
 
-        # TODO: Adapt HtmlHandler.handle_specials()
-        # detect_and_print_special_text() is used by
-        # HtmlHandler.handle_specials() and uses Gtk.TextTag objects,
-        # not strings
+        # parse_formatting() is used by HtmlHandler.handle_specials()
+        # and uses Gtk.TextTag objects, not strings
         if text_tags and isinstance(text_tags[0], Gtk.TextTag):
             insert_tags_func = buffer_.insert_with_tags
 
@@ -273,7 +270,11 @@ def parse_formatting(self, text, text_tags, graphics=True,
                 regex = LINK_REGEX
 
         iterator = regex.finditer(text)
-        end_iter = buffer_.get_end_iter()
+        if iter_:
+            end_iter = iter_
+        else:
+            end_iter = buffer_.get_end_iter()
+
         # TODO: Evaluate limit
         # Too many fragments (emoticons, LaTeX formulas, etc)
         # may cause Gajim to freeze (see #5129).
@@ -285,7 +286,8 @@ def parse_formatting(self, text, text_tags, graphics=True,
             fragment = text[start:end]
             if start > index:
                 text_before_fragment = text[index:start]
-                end_iter = buffer_.get_end_iter()
+                if not iter_:
+                    end_iter = buffer_.get_end_iter()
                 if text_tags:
                     insert_tags_func(
                         end_iter, text_before_fragment, *text_tags)
@@ -296,7 +298,8 @@ def parse_formatting(self, text, text_tags, graphics=True,
             self.apply_formatting(fragment,
                                   text_tags,
                                   graphics=graphics,
-                                  additional_data=additional_data)
+                                  additional_data=additional_data,
+                                  iter_=end_iter)
             fragment_limit += 1
             if fragment_limit <= 0:
                 break
@@ -304,8 +307,10 @@ def parse_formatting(self, text, text_tags, graphics=True,
         # Add remaining text after last match
         insert_tags_func(buffer_.get_end_iter(), text[index:], *text_tags)
 
+        return end_iter
+
     def apply_formatting(self, fragment, text_tags, graphics=True,
-                         additional_data=None):
+                         additional_data=None, iter_=None):
         # TODO: Plugin system GUI extension point
         # self.plugin_modified = False
         # app.plugin_manager.extension_point('print_special_text', self,
@@ -329,7 +334,10 @@ def apply_formatting(self, fragment, text_tags, graphics=True,
         # Check if we accept this as an uri
         is_valid_uri = fragment.startswith(tuple(URI_SCHEMES))
 
-        end_iter = buffer_.get_end_iter()
+        if iter_:
+            end_iter = iter_
+        else:
+            end_iter = buffer_.get_end_iter()
 
         theme = app.settings.get('emoticons_theme')
         show_emojis = theme and theme != 'font'
diff --git a/gajim/gtk/htmltextview.py b/gajim/gtk/htmltextview.py
index d876c116ba..65cfe2d4f2 100644
--- a/gajim/gtk/htmltextview.py
+++ b/gajim/gtk/htmltextview.py
@@ -208,12 +208,11 @@ class HtmlHandler(xml.sax.handler.ContentHandler):
     It keeps a stack of "style spans" (start/end element pairs) and a stack of
     list counters, for nested lists.
     """
-    def __init__(self, textview, conv_textview, startiter):
+    def __init__(self, textview, startiter):
         xml.sax.handler.ContentHandler.__init__(self)
         self.textbuf = textview.get_buffer()
         self.textview = textview
         self.iter = startiter
-        self.conv_textview = conv_textview
         self.text = ''
         self.starting = True
         self.preserve = False
@@ -561,11 +560,10 @@ def _anchor_event(self, _tag, _textview, event, _iter, href, type_):
         return False
 
     def handle_specials(self, text):
-        if self.conv_textview:
-            self.iter = self.conv_textview.detect_and_print_special_text(
-                text, self._get_style_tags(), iter_=self.iter)
-        else:
-            self._insert_text(text)
+        # TODO: Parse formatting
+        # self.iter = self.textview.parse_formatting(
+        #    text, self._get_style_tags(), iter_=self.iter)
+        self._insert_text(text)
 
     def characters(self, content):
         if self.preserve:
@@ -830,14 +828,14 @@ def hyperlink_handler(self, texttag, _widget, event, iter_, _kind):
         open_uri(uri, account=self.account)
         return Gdk.EVENT_STOP
 
-    def display_html(self, html, textview, conv_textview, iter_=None):
+    def display_html(self, html, textview, iter_=None):
         buffer_ = self.get_buffer()
         if iter_:
             eob = iter_
         else:
             eob = buffer_.get_end_iter()
         parser = xml.sax.make_parser()
-        parser.setContentHandler(HtmlHandler(textview, conv_textview, eob))
+        parser.setContentHandler(HtmlHandler(textview, eob))
         parser.parse(StringIO(html))
         # If the xhtml ends with a BLOCK element we have to remove
         # the \n we add after BLOCK elements
diff --git a/test/gtk/htmltextview.py b/test/gtk/htmltextview.py
index 8e850795c0..036edbdd37 100644
--- a/test/gtk/htmltextview.py
+++ b/test/gtk/htmltextview.py
@@ -8,17 +8,29 @@
 from gajim.common import configpaths
 configpaths.init()
 
+from gajim.common.const import KindConstant
 
 from gajim import gui
 gui.init('gtk')
 
 from gajim.common.helpers import AdditionalDataDict
 
-from gajim.conversation_textview import ConversationTextview
+from gajim.gui.conversation.view import ConversationView
 from gajim.gui_interface import Interface
 
 
+def setting_side_effect(*args, **kwargs):
+    if args[0] == 'chat_timestamp_format':
+        return '%H:%M'
+    if args[0] in ('autoawaytime', 'autoxatime'):
+        return 5
+    if args[0] == 'show_xhtml':
+        return True
+
+
 app.settings = MagicMock()
+app.settings.get.side_effect = setting_side_effect
+
 app.plugin_manager = MagicMock()
 app.logger = MagicMock()
 app.cert_store = MagicMock()
@@ -50,10 +62,6 @@
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <p style='font-size:large'>
@@ -65,10 +73,6 @@
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <p>
@@ -82,10 +86,6 @@
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <p style='text-align:center'>
@@ -98,10 +98,6 @@
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <ul style='background-color:rgb(120,140,100)'>
@@ -119,10 +115,6 @@ def faciter(n,acc):
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <ol style='background-color:rgb(120,140,100)'>
@@ -141,10 +133,6 @@ def faciter(n,acc):
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <p>
@@ -168,10 +156,6 @@ def faciter(n,acc):
     </body>
     ''',
 
-    '''
-    <hr />
-    ''',
-
     '''
     <body xmlns='http://www.w3.org/1999/xhtml'>
         <img src='data:image/png;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw\
@@ -183,32 +167,38 @@ def faciter(n,acc):
             hhx4dbgYKAAA7' alt='Larry'/>
     </body>
     ''',
-
 ]
 
 
 class TextviewWindow(Gtk.Window):
     def __init__(self):
-        Gtk.Window.__init__(self, title="Textview Test")
+        Gtk.Window.__init__(self, title='Textview Test')
         self.set_default_size(600, 600)
 
-        self._textview = ConversationTextview(None)
+        self._conversation_view = ConversationView(None, None)
 
         scrolled = Gtk.ScrolledWindow()
         scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
-        scrolled.add(self._textview.tv)
+        scrolled.add(self._conversation_view)
         self.add(scrolled)
         self.show()
         self._print_xhtml()
 
     def _print_xhtml(self):
+        timestamp = 1
         for xhtml in XHTML:
             additional_data = AdditionalDataDict()
             additional_data.set_value('gajim', 'xhtml', xhtml)
-            self._textview.print_real_text(None, additional_data=additional_data)
-            self._textview.print_real_text('\n')
+            self._conversation_view.add_message(
+                '',
+                KindConstant.SINGLE_MSG_RECV,
+                'Test Row',
+                timestamp,
+                additional_data=additional_data)
+        timestamp += 1
+
 
 win = TextviewWindow()
-win.connect("destroy", Gtk.main_quit)
+win.connect('destroy', Gtk.main_quit)
 win.show_all()
 Gtk.main()
-- 
GitLab