#!/usr/bin/env python3
# coding: utf-8
from __future__ import print_function, unicode_literals
import re
import unittest
from xml.etree import ElementTree as ET
from copyparty.dxml import BadXML, mkenod, mktnod, parse_xml
ET.register_namespace("D", "DAV:")
def _parse(txt):
    try:
        parse_xml(txt)
        raise Exception("unsafe")
    except BadXML:
        pass
class TestDXML(unittest.TestCase):
    def test_qbe(self):
        # allowed by default; verify that we stopped it
        txt = r"""
]>
&a;&a;&a;&a;&a;&a;&a;&a;&a;"""
        _parse(txt)
        ET.fromstring(txt)
    def test_ent_file(self):
        # NOT allowed by default; should still be blocked
        txt = r"""
]>
ⅇ"""
        _parse(txt)
        try:
            ET.fromstring(txt)
            raise Exception("unsafe2")
        except ET.ParseError:
            pass
    def test_ent_ext(self):
        # NOT allowed by default; should still be blocked
        txt = r"""
]>
ⅇ"""
        _parse(txt)
    def test_dtd(self):
        # allowed by default; verify that we stopped it
        txt = r"""
a"""
        _parse(txt)
        ET.fromstring(txt)
    ##
    ## end of negative/security tests; the rest is functional
    ##
    def test3(self):
        txt = r"""
    
        
        
    
"""
        txt = txt.replace("\n", "\r\n")
        ET.fromstring(txt)
        el = parse_xml(txt)
        self.assertListEqual(
            [y.tag for y in el.findall(r"./{DAV:}prop/*")],
            [r"{DAV:}name", r"{DAV:}href"],
        )
    def test4(self):
        txt = r"""
    
        
            Thu, 20 Oct 2022 02:16:33 GMT
            Thu, 20 Oct 2022 02:16:35 GMT
            Thu, 20 Oct 2022 02:16:33 GMT
            00000000
        
    
"""
        ref = r"""
    
        /d1/foo.txt
        
            
                
                
                
                
            
            HTTP/1.1 403 Forbidden
        
    
"""
        txt = re.sub("\n +", "\n", txt)
        root = mkenod("a")
        root.insert(0, parse_xml(txt))
        prop = root.find(r"./{DAV:}propertyupdate/{DAV:}set/{DAV:}prop")
        assert prop is not None
        assert len(prop)
        for el in prop:
            el.clear()
        res = ET.tostring(prop).decode("utf-8")
        want = """
"""
        self.assertEqual(res, want)
    def test5(self):
        txt = r"""
    
    
    DESKTOP-FRS9AO2\ed
"""
        ref = r"""
    
    
    infinity
    DESKTOP-FRS9AO2\ed
    Second-3600
    1666199679
    /d1/foo.txt
"""
        txt = re.sub("\n +", "\n", txt)
        lk = parse_xml(txt)
        self.assertEqual(lk.tag, "{DAV:}lockinfo")
        if lk.find(r"./{DAV:}depth") is None:
            lk.append(mktnod("D:depth", "infinity"))
        lk.append(mkenod("D:timeout", mktnod("D:href", "Second-3600")))
        lk.append(mkenod("D:locktoken", mktnod("D:href", "56709")))
        lk.append(mkenod("D:lockroot", mktnod("D:href", "/foo/bar.txt")))
        lk2 = mkenod("D:activelock")
        root = mkenod("D:prop", mkenod("D:lockdiscovery", lk2))
        for a in lk:
            lk2.append(a)
        print(ET.tostring(root).decode("utf-8"))