121 lines
4.7 KiB
Python
121 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Gezielte Tests: roter Nachrichten-Badge scrollt zur ersten ungelesenen Nachricht."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import inspect
|
|
import re
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
HTML = (ROOT / "web" / "empfang.html").read_text(encoding="utf-8-sig")
|
|
|
|
|
|
def _func_body(src: str, name: str) -> str:
|
|
marker = f"function {name}"
|
|
idx = src.find(marker)
|
|
if idx < 0:
|
|
return ""
|
|
rest = src[idx + len(marker) :]
|
|
nxt = rest.find("\nfunction ")
|
|
return rest[:nxt] if nxt >= 0 else rest
|
|
|
|
|
|
class MessageBadgeScrollTests(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.html = HTML
|
|
cls.nav = _func_body(cls.html, "navigateFromMessagesBadgeClick")
|
|
cls.render = _func_body(cls.html, "renderMessengerConversation")
|
|
cls.task_nav = _func_body(cls.html, "navigateFromTaskBadgeClick")
|
|
|
|
def test_badge_has_click_handler(self):
|
|
self.assertIn("navigateFromMessagesBadgeClick()", self.html)
|
|
self.assertIn("sb-me-pill-msgs", self.html)
|
|
|
|
def test_uses_peer_user_id(self):
|
|
self.assertIn("findFirstPeerWithPendingAck", self.nav)
|
|
self.assertIn("hit.uid", self.nav)
|
|
self.assertIn("selectDmPeer", self.nav)
|
|
|
|
def test_first_unread_message_id(self):
|
|
self.assertIn("findFirstUnreadMessageIdForPeer", self.html)
|
|
self.assertIn("messageNeedsAlarmAck", _func_body(self.html, "findFirstUnreadMessageIdForPeer"))
|
|
|
|
def test_dm_open_msg_id_in_kontakt_panel(self):
|
|
kp = _func_body(self.html, "kontaktPanelOpenMessagesBadgeInHuelle")
|
|
self.assertIn("dm_open_msg_id", kp)
|
|
self.assertIn("/shell/dm-open", kp)
|
|
self.assertIn("focus_empfang_chat_shell", kp)
|
|
self.assertIn("kontaktPanelOpenMessagesBadgeInHuelle", self.nav)
|
|
|
|
def test_arm_pending_scroll(self):
|
|
self.assertIn("armEmpfangBadgeScrollToUnread", self.nav)
|
|
self.assertIn("consumeEmpfangBadgeScrollForActivePeer", self.render)
|
|
|
|
def test_scroll_after_render_not_blind_timeout(self):
|
|
self.assertIn("scrollMessengerToMessageIdWithRetry", self.html)
|
|
self.assertNotIn("setTimeout(function() { scrollMessengerToMessageId(dmMid); }, 720)", self.html)
|
|
body = _func_body(self.html, "scrollMessengerToMessageIdWithRetry")
|
|
self.assertIn("maxTries", body)
|
|
self.assertIn("messengerMessageElementForId", body)
|
|
|
|
def test_scroll_into_view(self):
|
|
body = _func_body(self.html, "scrollMessengerToMessageIdWithRetry")
|
|
self.assertIn("scrollIntoView", body)
|
|
|
|
def test_fallback_bottom(self):
|
|
body = _func_body(self.html, "scrollMessengerToMessageIdWithRetry")
|
|
self.assertIn("fallbackBottom", body)
|
|
self.assertIn("scrollMessengerToBottom", body)
|
|
|
|
def test_no_infinite_loop(self):
|
|
body = _func_body(self.html, "scrollMessengerToMessageIdWithRetry")
|
|
self.assertIn("tries >= maxTries", body)
|
|
self.assertNotIn("setInterval", body)
|
|
|
|
def test_stable_message_id_selector(self):
|
|
self.assertIn("data-msg-id", _func_body(self.html, "messengerMessageElementForId"))
|
|
|
|
def test_message_involves_peer_by_uid(self):
|
|
body = _func_body(self.html, "messageInvolvesPeerUid")
|
|
self.assertIn("direct_conv_key", body)
|
|
self.assertIn("sender_user_id", body)
|
|
|
|
def test_kontakt_and_chat_same_nav_function(self):
|
|
self.assertIn("isKontaktPanelMode()", self.nav)
|
|
self.assertIn("selectDmPeer", self.nav)
|
|
|
|
def test_task_badge_unchanged(self):
|
|
self.assertIn("kontaktPanelNavigateFromBadge", self.task_nav)
|
|
self.assertNotIn("findFirstUnreadMessageIdForPeer", self.task_nav)
|
|
|
|
def test_ack_helpers_unchanged(self):
|
|
self.assertIn("function messageHasChatAckEffective", self.html)
|
|
self.assertIn("function messageNeedsAlarmAck", self.html)
|
|
|
|
def test_chronological_first_unread(self):
|
|
body = _func_body(self.html, "findFirstUnreadMessageIdForPeer")
|
|
self.assertIn("messengerChronoSorted", body)
|
|
|
|
def test_shell_context_uses_arm_not_timeout(self):
|
|
ctx = _func_body(self.html, "refreshDesktopShellContextFromServer")
|
|
self.assertIn("armEmpfangBadgeScrollToUnread", ctx)
|
|
|
|
|
|
class EmpfangHtmlSyntaxSmoke(unittest.TestCase):
|
|
def test_no_obvious_script_tag_break(self):
|
|
scripts = re.findall(r"<script[^>]*>([\s\S]*?)</script>", HTML, flags=re.I)
|
|
self.assertGreater(len(scripts), 0)
|
|
for block in scripts:
|
|
if "navigateFromMessagesBadgeClick" in block:
|
|
self.assertIn("function navigateFromMessagesBadgeClick", block)
|
|
break
|
|
else:
|
|
self.fail("navigateFromMessagesBadgeClick script block missing")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|