MailJD nbsp;·nbsp; Test Dashboard nbsp;·nbsp; Coverage
LCOV - code coverage report
Current view: top level - service - DavXmlHelper.h (source / functions) Coverage Total Hit
Test: MailJD Coverage (Unit + E2E) Lines: 97.9 % 48 47
Test Date: 2026-06-21 21:10:19 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 67.0 % 88 59

             Branch data     Line data    Source code
       1                 :             : #pragma once
       2                 :             : 
       3                 :             : #include <QDomDocument>
       4                 :             : #include <QDomElement>
       5                 :             : #include <QDomNodeList>
       6                 :             : #include <QString>
       7                 :             : 
       8                 :             : // ═══════════════════════════════════════════════════════
       9                 :             : // Shared DAV XML helpers (Sprint 32 – T-331)
      10                 :             : // Extracted from CardDavClient.cpp for reuse in CalDavClient.
      11                 :             : // ═══════════════════════════════════════════════════════
      12                 :             : 
      13                 :             : namespace DavXmlHelper {
      14                 :             : 
      15                 :             : /// Find child elements by local name, ignoring namespace prefix.
      16                 :             : /// Uses localName() comparison which is namespace-prefix-agnostic.
      17                 :         206 : inline QDomNodeList findElementsByLocalName(const QDomElement &parent,
      18                 :             :                                             const QString &localName) {
      19                 :             :   // Fast path: try unprefixed tag name
      20         [ +  - ]:         206 :   QDomNodeList nodes = parent.elementsByTagName(localName);
      21   [ +  -  +  + ]:         206 :   if (!nodes.isEmpty())
      22                 :           6 :     return nodes;
      23                 :             : 
      24                 :             :   // Namespace-agnostic: walk all descendants, match by localName()
      25         [ +  - ]:         200 :   QDomNodeList all = parent.elementsByTagName(QStringLiteral("*"));
      26                 :             :   // Qt doesn't let us build a QDomNodeList, so we use the fast path with
      27                 :             :   // known prefixes as well, then fall back to manual iteration
      28                 :             :   static const QString prefixes[] = {
      29                 :           8 :       QStringLiteral("d:"),    QStringLiteral("D:"),
      30                 :           8 :       QStringLiteral("card:"), QStringLiteral("C:"),
      31                 :           8 :       QStringLiteral("cs:"),   QStringLiteral("cr:"),
      32                 :           8 :       QStringLiteral("cal:"),  QStringLiteral("c:"),
      33                 :           8 :       QStringLiteral("apple:"),
      34   [ +  +  +  - ]:         307 :   };
      35         [ +  + ]:         784 :   for (const auto &prefix : prefixes) {
      36   [ +  -  +  -  :         753 :     nodes = parent.elementsByTagName(prefix + localName);
                   +  - ]
      37   [ +  -  +  + ]:         753 :     if (!nodes.isEmpty())
      38                 :         169 :       return nodes;
      39                 :             :   }
      40                 :          31 :   return nodes; // empty
      41                 :         200 : }
      42                 :             : 
      43                 :             : /// Find the first element by local name using namespace-agnostic traversal.
      44                 :             : /// This handles any arbitrary namespace prefix (x1:, ns0:, etc.).
      45                 :             : /// Note: the documents here are parsed WITHOUT namespace processing, so
      46                 :             : /// QDomElement::localName() is always empty — the local name must be
      47                 :             : /// derived from tagName() by stripping the prefix. QDom also does not
      48                 :             : /// support the DOM "*" wildcard, so the fallback walks children manually.
      49                 :          69 : inline QDomElement findFirstElementByLocalName(const QDomElement &parent,
      50                 :             :                                                 const QString &localName) {
      51                 :             :   // Fast path: unprefixed
      52         [ +  - ]:          69 :   QDomNodeList nodes = parent.elementsByTagName(localName);
      53   [ +  -  +  + ]:          69 :   if (!nodes.isEmpty())
      54   [ +  -  +  - ]:           4 :     return nodes.at(0).toElement();
      55                 :             : 
      56                 :             :   // Depth-first walk comparing the tag name after the prefix
      57   [ +  -  +  -  :         109 :   for (QDomElement el = parent.firstChildElement(); !el.isNull();
                   +  + ]
      58   [ +  -  +  - ]:          44 :        el = el.nextSiblingElement()) {
      59         [ +  - ]:          60 :     const QString tag = el.tagName();
      60   [ +  -  +  + ]:          60 :     if (tag.mid(tag.indexOf(QLatin1Char(':')) + 1) == localName)
      61         [ +  - ]:           6 :       return el;
      62         [ +  - ]:          54 :     QDomElement deep = findFirstElementByLocalName(el, localName);
      63   [ +  -  +  + ]:          54 :     if (!deep.isNull())
      64         [ +  - ]:          10 :       return deep;
      65   [ +  +  +  +  :         135 :   }
                   +  + ]
      66         [ +  - ]:          49 :   return {};
      67                 :          69 : }
      68                 :             : 
      69                 :             : /// Same but for QDomDocument root level.
      70                 :          72 : inline QDomNodeList findElementsByLocalNameDoc(QDomDocument &doc,
      71                 :             :                                                const QString &localName) {
      72                 :          72 :   QDomNodeList nodes = doc.elementsByTagName(localName);
      73   [ +  -  +  + ]:          72 :   if (!nodes.isEmpty())
      74                 :           5 :     return nodes;
      75                 :             : 
      76                 :             :   static const QString prefixes[] = {
      77                 :           7 :       QStringLiteral("d:"),    QStringLiteral("D:"),
      78                 :           7 :       QStringLiteral("card:"), QStringLiteral("C:"),
      79                 :           7 :       QStringLiteral("cs:"),   QStringLiteral("cr:"),
      80                 :           7 :       QStringLiteral("cal:"),  QStringLiteral("c:"),
      81                 :           7 :       QStringLiteral("apple:"),
      82   [ +  +  +  - ]:         130 :   };
      83         [ +  + ]:         241 :   for (const auto &prefix : prefixes) {
      84   [ +  -  +  -  :         224 :     nodes = doc.elementsByTagName(prefix + localName);
                   +  - ]
      85   [ +  -  +  + ]:         224 :     if (!nodes.isEmpty())
      86                 :          50 :       return nodes;
      87                 :             :   }
      88                 :          17 :   return nodes;
      89                 :           0 : }
      90                 :             : 
      91                 :             : } // namespace DavXmlHelper
        

Generated by: LCOV version 2.0-1