1# -*- coding: utf-8 -*- 2""" 3Automatic tests for module ldap0.dn 4""" 5 6# from Python's standard lib 7import sys 8import unittest 9 10import ldap0.dn 11from ldap0.dn import DNObj 12 13 14class TestDNFunctions(unittest.TestCase): 15 """ 16 test functions in ldap0.dn 17 """ 18 19 def test_is_dn(self): 20 """ 21 test function is_dn() 22 """ 23 self.assertEqual(ldap0.dn.is_dn('foobar,dc=example,dc=com'), False) 24 self.assertEqual(ldap0.dn.is_dn('-cn=foobar,dc=example,dc=com'), False) 25 self.assertEqual(ldap0.dn.is_dn(';cn=foobar,dc=example,dc=com'), False) 26 self.assertEqual(ldap0.dn.is_dn(',cn=foobar,dc=example,dc=com'), False) 27 self.assertEqual(ldap0.dn.is_dn('cn=foobar,dc=example,dc=com,'), False) 28 self.assertEqual(ldap0.dn.is_dn('uid=xkcd,cn=foobar,dc=example,dc=com'), True) 29 self.assertEqual(ldap0.dn.is_dn('cn=äöüÄÖÜß'), True) 30 self.assertEqual(ldap0.dn.is_dn('-'), False) 31 self.assertEqual(ldap0.dn.is_dn(''), True) 32 33 def test_escape_str(self): 34 """ 35 test function escape_str() 36 """ 37 self.assertEqual(ldap0.dn.escape_str(''), '') 38 self.assertEqual(ldap0.dn.escape_str('foobar'), 'foobar') 39 self.assertEqual(ldap0.dn.escape_str('foo,bar'), 'foo\\,bar') 40 self.assertEqual(ldap0.dn.escape_str('foo=bar'), 'foo\\=bar') 41 self.assertEqual(ldap0.dn.escape_str('foo#bar'), 'foo#bar') 42 self.assertEqual(ldap0.dn.escape_str('#foobar'), '\\#foobar') 43 self.assertEqual(ldap0.dn.escape_str('foo bar'), 'foo bar') 44 self.assertEqual(ldap0.dn.escape_str(' foobar'), '\\ foobar') 45 self.assertEqual(ldap0.dn.escape_str(' foobar'), '\\ foobar') 46 self.assertEqual(ldap0.dn.escape_str('foobar '), 'foobar \\ ') 47 self.assertEqual(ldap0.dn.escape_str(' '), '\\ ') 48 self.assertEqual(ldap0.dn.escape_str(' '), '\\ \\ ') 49 50 51class TestDNObj(unittest.TestCase): 52 """ 53 test class ldap0.dn.DNObj 54 """ 55 56 def test001_simple(self): 57 self.assertEqual(DNObj.from_str(''), DNObj((()))) 58 self.assertEqual(DNObj.from_str('').rdn(), DNObj((()))) 59 self.assertEqual(DNObj.from_str('').rdn_attrs(), {}) 60 self.assertEqual(len(DNObj.from_str('')), 0) 61 self.assertEqual(len(DNObj.from_str('ou=dept1 , dc=example, dc=com')), 3) 62 self.assertEqual( 63 str(DNObj.from_str('ou=dept1 , dc=example, dc=com').rdn()), 64 'ou=dept1' 65 ) 66 self.assertEqual( 67 DNObj.from_str('ou=dept1 , dc=example, dc=com').rdn_attrs(), 68 {'ou': 'dept1'} 69 ) 70 self.assertEqual( 71 DNObj.from_str('ou=dept1 + mail=test@example.com , dc=example, dc=com').rdn_attrs(), 72 {'mail': 'test@example.com', 'ou': 'dept1'} 73 ) 74 self.assertEqual( 75 str(DNObj.from_str('ou=dept1, dc=example, dc=com').parent()), 76 'dc=example,dc=com' 77 ) 78 for dn_str in ( 79 '', 80 'dc=example,dc=com', 81 'ou=dept1,dc=example,dc=com', 82 'cn=äöüÄÖÜß', 83 'cn=Michael Ströder,dc=example,dc=com', 84 ): 85 dn_obj = DNObj.from_str(dn_str, flags=0) 86 self.assertEqual(bytes(dn_obj), dn_str.encode('utf-8')) 87 self.assertEqual(dn_obj.__str__(), dn_str) 88 89 def test002_weird_whitespaces(self): 90 self.assertEqual( 91 DNObj.from_str('uid = test42 + uidNumber = 42, dc = example , dc = com'), 92 DNObj(( 93 ( 94 ('uid', 'test42'), 95 ('uidNumber', '42') 96 ), 97 (('dc', 'example'),), 98 (('dc', 'com'),) 99 )) 100 ) 101 102 def test003_repr(self): 103 if sys.version_info.major >= 3: 104 correct_repr = "DNObj(((('uid', 'test42'), ('uidNumber', '42')), (('dc', 'example'),), (('dc', 'com'),)))" 105 else: 106 correct_repr = "DNObj(((('uid', 'test42'), ('uidNumber', '42')), (('dc', 'example'),), (('dc', 'com'),)))" 107 self.assertEqual( 108 repr(DNObj(( 109 ( 110 ('uid', 'test42'), 111 ('uidNumber', '42') 112 ), 113 (('dc', 'example'),), 114 (('dc', 'com'),) 115 ))), 116 correct_repr 117 ) 118 119 def test004_hashable(self): 120 dn = DNObj(( 121 ( 122 ('uid', 'test42'), 123 ('uidNumber', '42') 124 ), 125 (('dc', 'example'),), 126 (('dc', 'com'),) 127 )) 128 data = {dn: 'foo'} 129 self.assertEqual(data[dn], 'foo') 130 self.assertEqual(set([dn]), set([dn, dn])) 131 132 def test005_slicing(self): 133 dn = DNObj.from_str('ou=dept1 , dc=example, dc=com') 134 self.assertEqual(dn[0], (('ou', 'dept1'),)) 135 self.assertEqual(dn[1], (('dc', 'example'),)) 136 self.assertEqual(dn[2], (('dc', 'com'),)) 137 self.assertEqual(DNObj(dn[:]), dn) 138 with self.assertRaises(IndexError): 139 self.assertEqual(dn[3], ()) 140 self.assertEqual( 141 reversed(DNObj.from_str('ou=dept1,dc=example,dc=com')), 142 DNObj.from_str('dc=com,dc=example,ou=dept1') 143 ) 144 self.assertEqual( 145 DNObj.from_str('ou=dept1,dc=example,dc=com')[1:], 146 DNObj.from_str('dc=example,dc=com')[:] 147 ) 148 self.assertEqual( 149 DNObj.from_str('ou=dept1,dc=example,dc=com')[:2], 150 DNObj.from_str('ou=dept1,dc=example')[:] 151 ) 152 self.assertEqual( 153 DNObj.from_str('ou=dept1,dc=example,dc=com').slice(1, None), 154 DNObj.from_str('dc=example,dc=com') 155 ) 156 self.assertEqual( 157 DNObj.from_str('ou=dept1,dc=example,dc=com').slice(None, 2), 158 DNObj.from_str('ou=dept1,dc=example') 159 ) 160 domain = 'sub3.sub2.sub1.example.com' 161 dns_labels = domain.split('.') 162 dno = DNObj.from_domain(domain) 163 for i, dn_comp in enumerate(dno): 164 self.assertEqual(dn_comp[0][0], 'dc') 165 self.assertEqual(dn_comp[0][1], dns_labels[i]) 166 self.assertEqual(dno[i], dn_comp) 167 168 def test006_domain(self): 169 self.assertEqual( 170 str(DNObj.from_domain('example.com')), 171 'dc=example,dc=com' 172 ) 173 self.assertEqual( 174 DNObj.from_domain('example.com').domain(), 175 'example.com' 176 ) 177 self.assertEqual( 178 DNObj.from_domain(u'ströder.de').domain(), 179 u'ströder.de'.encode('idna').decode('ascii') 180 ) 181 self.assertEqual( 182 DNObj.from_str('ou=dept1, dc=example, dc=com').domain(only_dc=False), 183 'example.com' 184 ) 185 with self.assertRaises(ValueError): 186 DNObj.from_str('ou=dept1,dc=example,dc=com').domain(only_dc=True) 187 with self.assertRaises(ValueError): 188 DNObj.from_str('ou=dept1,dc=example,dc=com+dc=net').domain() 189 with self.assertRaises(ValueError): 190 DNObj.from_str('ou=foo+dc=example,dc=com').domain() 191 192 193 def test007_add(self): 194 self.assertEqual( 195 DNObj.from_domain('dept1')+DNObj.from_domain('example.com'), 196 DNObj.from_domain('dept1.example.com'), 197 ) 198 self.assertEqual( 199 bytes(DNObj.from_domain('dept1')+DNObj.from_domain('example.com')), 200 b'dc=dept1,dc=example,dc=com', 201 ) 202 self.assertEqual( 203 (DNObj.from_domain('dept1')+DNObj.from_domain('example.com')).domain(), 204 'dept1.example.com', 205 ) 206 207 def test008_match(self): 208 dn_obj = DNObj.from_domain('example.com') 209 self.assertEqual( 210 dn_obj.match([DNObj.from_domain('example.com')]), 211 DNObj.from_domain('example.com') 212 ) 213 self.assertEqual( 214 dn_obj.match([DNObj.from_domain('sub1.example.com')]), 215 DNObj((())) 216 ) 217 self.assertEqual( 218 dn_obj.match([ 219 DNObj.from_domain('example.com'), 220 DNObj.from_domain('example.net'), 221 ]), 222 DNObj.from_domain('example.com') 223 ) 224 self.assertEqual( 225 dn_obj.match([ 226 DNObj.from_str('CN=Michael, dc=example, dc=com'), 227 DNObj.from_str('DC=example, DC=com'), 228 ]), 229 DNObj.from_domain('example.com'), 230 ) 231 self.assertEqual( 232 DNObj.from_str('cn=Person,dc=foo,dc=example,dc=com').match([ 233 DNObj.from_domain('foo.example.com'), 234 DNObj.from_domain('bar.example.com'), 235 ]), 236 DNObj.from_domain('foo.example.com'), 237 ) 238 # sub entry match 239 dn_obj = DNObj.from_domain('sub1.example.com') 240 self.assertEqual( 241 dn_obj.match([ 242 DNObj.from_domain('sub2.example.com'), 243 DNObj.from_domain('example.com'), 244 DNObj.from_domain('example.net'), 245 ]), 246 DNObj.from_domain('example.com') 247 ) 248 self.assertEqual( 249 dn_obj.match([ 250 DNObj.from_domain('sub1.example.com'), 251 DNObj.from_domain('example.com'), 252 ]), 253 DNObj.from_domain('sub1.example.com') 254 ) 255 # no match 256 dn_obj = DNObj.from_domain('example.net') 257 self.assertEqual( 258 dn_obj.match([ 259 DNObj.from_domain('example.com'), 260 ]), 261 DNObj((())) 262 ) 263 self.assertEqual( 264 dn_obj.match([ 265 DNObj.from_domain('sub2.example.net'), 266 DNObj.from_domain('example.com'), 267 ]), 268 DNObj((())) 269 ) 270 # empty 271 self.assertEqual( 272 DNObj((())).match([DNObj((()))]), 273 DNObj((())) 274 ) 275 276 def test009_parents(self): 277 self.assertEqual( 278 DNObj.from_domain('example.com').parents(), 279 [DNObj.from_domain('com')] 280 ) 281 self.assertEqual( 282 DNObj.from_domain('sub1.example.com').parents(), 283 [ 284 DNObj.from_domain('example.com'), 285 DNObj.from_domain('com'), 286 ] 287 ) 288 289 def test010_equals(self): 290 self.assertTrue( 291 DNObj.from_str('cn=Michael, dc=example, dc=com')==DNObj.from_str('CN=Michael, DC=example, DC=com') 292 ) 293 self.assertFalse( 294 DNObj.from_str('uid=Michael, dc=example, dc=com')==DNObj.from_str('CN=Michael, DC=example, DC=com') 295 ) 296 self.assertFalse( 297 DNObj.from_str('cn=Michael, dc=example, dc=com')==DNObj.from_str('CN=Mike, DC=example, DC=com') 298 ) 299 self.assertEqual( 300 DNObj.from_str('cn=Foo + mail= foo@example.com + sn = Bar,dc=example,dc=com'), 301 DNObj.from_str('mail=foo@example.com+sn=Bar+cn=Foo,dc=example,dc=com'), 302 ) 303 self.assertNotEqual( 304 DNObj.from_str('cn=Foo2 + mail= foo@example.com + sn = Bar,dc=example,dc=com'), 305 DNObj.from_str('mail=foo@example.com+sn=Bar+cn=Foo,dc=example,dc=com'), 306 ) 307 self.assertNotEqual( 308 DNObj.from_str('cn=Foo + mail= foo@example.com + sn = Bar,dc=example,dc=com'), 309 DNObj.from_str('mail2=foo@example.com+sn=Bar+cn=Foo,dc=example,dc=com'), 310 ) 311 312 def test010_at_sanitizer(self): 313 self.assertNotEqual( 314 str(DNObj.from_str('cn=Michael, dc=example, dc=com')), 315 str(DNObj.from_str('CN=Michael, DC=example, DC=com')) 316 ) 317 self.assertEqual( 318 str(DNObj.from_str('cn=Michael, dc=example, dc=com')), 319 str(DNObj.from_str('CN=Michael, DC=example, DC=com', at_sanitizer=str.lower)) 320 ) 321 322 323if __name__ == '__main__': 324 unittest.main() 325