@@ -557,64 +557,47 @@ def test_port_with_whitespace(self):
557557 with self .assertRaisesRegex (ValueError , r"Port contains whitespace character: '\\n'" ):
558558 parse_uri ("mongodb://localhost:27\n 017" )
559559
560- def test_parse_uri_options_type (self ):
561- opts = parse_uri ("mongodb://localhost:27017" )["options" ]
562- self .assertIsInstance (opts , dict )
563-
564560 def test_unquoted_percent (self ):
565- # Empty string and strings without percent signs are always safe.
566561 self .assertFalse (_unquoted_percent ("" ))
567562 self .assertFalse (_unquoted_percent ("no_percent_here" ))
568- # Valid percent-encoded sequences are not flagged.
569563 self .assertFalse (_unquoted_percent ("%25" )) # %25 decodes to literal "%"
570564 self .assertFalse (_unquoted_percent ("%40" )) # %40 decodes to "@"
571565 self .assertFalse (_unquoted_percent ("user%40domain.com" ))
572566 self .assertFalse (_unquoted_percent ("%2B" )) # %2B decodes to "+"
573567 self .assertFalse (_unquoted_percent ("%E2%85%A8" )) # multi-byte sequence
574568 self .assertFalse (_unquoted_percent ("%2525" )) # double-encoded: %25 -> %
575- # Unescaped percent signs (invalid percent encodings) are flagged.
576569 self .assertTrue (_unquoted_percent ("%foo" )) # 'o' is not a hex digit
577570 self .assertTrue (_unquoted_percent ("50%off" )) # 'o' is not a hex digit
578571 self .assertTrue (_unquoted_percent ("100%" )) # trailing bare %
579572
580573 def test_parse_ipv6_literal_host_direct (self ):
581- # IPv6 without explicit port uses default_port.
582574 self .assertEqual (("::1" , 27017 ), parse_ipv6_literal_host ("[::1]" , 27017 ))
583575 self .assertEqual (("::1" , None ), parse_ipv6_literal_host ("[::1]" , None ))
584576 # IPv6 with explicit port returns port as a string (int conversion
585577 # happens later in parse_host).
586578 host , port = parse_ipv6_literal_host ("[::1]:27018" , 27017 )
587579 self .assertEqual ("::1" , host )
588580 self .assertEqual ("27018" , port )
589- # Full-form IPv6 address without port.
590581 full_ipv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
591582 host , port = parse_ipv6_literal_host (f"[{ full_ipv6 } ]" , 27017 )
592583 self .assertEqual (full_ipv6 , host )
593584 self .assertEqual (27017 , port )
594- # Missing closing bracket must raise.
595585 self .assertRaises (ValueError , parse_ipv6_literal_host , "[::1" , 27017 )
596586
597587 def test_parse_host_case_normalization (self ):
598- # Hostnames are normalized to lowercase (RFC 4343).
599588 self .assertEqual (("localhost" , 27017 ), parse_host ("LOCALHOST:27017" ))
600589 self .assertEqual (("example.com" , 27017 ), parse_host ("Example.COM" ))
601590 self .assertEqual (("example.com" , 27017 ), parse_host ("EXAMPLE.COM:27017" ))
602- # IP addresses are unaffected but still lowercased (no-op for digits).
603591 self .assertEqual (("192.168.1.1" , 27017 ), parse_host ("192.168.1.1:27017" ))
604- # IPv6 literal addresses are lowercased.
605592 self .assertEqual (("::1" , 27017 ), parse_host ("[::1]:27017" ))
606593
607594 def test_parse_host_port_boundaries (self ):
608- # Ports 1-65535 are valid.
609595 self .assertEqual (("localhost" , 1 ), parse_host ("localhost:1" ))
610596 self .assertEqual (("localhost" , 65535 ), parse_host ("localhost:65535" ))
611- # Port 0 is invalid.
612597 self .assertRaises (ValueError , parse_host , "localhost:0" )
613- # Port 65536 is invalid.
614598 self .assertRaises (ValueError , parse_host , "localhost:65536" )
615599
616600 def test_tls_option_conflicts (self ):
617- # tlsInsecure cannot coexist with any of the options it implicitly sets.
618601 self .assertRaises (
619602 InvalidURI , split_options , "tlsInsecure=true&tlsAllowInvalidCertificates=true"
620603 )
@@ -625,104 +608,84 @@ def test_tls_option_conflicts(self):
625608 self .assertRaises (
626609 InvalidURI , split_options , "tlsInsecure=true&tlsDisableOCSPEndpointCheck=true"
627610 )
628- # tlsAllowInvalidCertificates and tlsDisableOCSPEndpointCheck are mutually exclusive.
629611 self .assertRaises (
630612 InvalidURI ,
631613 split_options ,
632614 "tlsAllowInvalidCertificates=true&tlsDisableOCSPEndpointCheck=true" ,
633615 )
634- # ssl and tls must agree when both are present.
635616 self .assertRaises (InvalidURI , split_options , "ssl=true&tls=false" )
636617 self .assertRaises (InvalidURI , split_options , "ssl=false&tls=true" )
637- # Matching ssl/tls values are allowed.
638- self .assertIsNotNone (split_options ("ssl=true&tls=true" ))
639- self .assertIsNotNone (split_options ("ssl=false&tls=false" ))
618+ self .assertTrue (split_options ("ssl=true&tls=true" ))
619+ self .assertTrue (split_options ("ssl=false&tls=false" ))
640620
641621 def test_split_options_mixed_delimiters (self ):
642- # Mixing '&' and ';' as option separators is not permitted.
643622 self .assertRaises (InvalidURI , split_options , "ssl=true&tls=true;appname=foo" )
644623 self .assertRaises (InvalidURI , split_options , "appname=foo;ssl=true&tls=true" )
645624
646625 def test_split_options_duplicate_warning (self ):
647- # Specifying the same option key more than once emits a warning.
648626 with warnings .catch_warnings (record = True ) as w :
649627 warnings .simplefilter ("always" )
650628 split_options ("appname=foo&appname=bar" )
651629 self .assertEqual (1 , len (w ))
652630 self .assertIn ("Duplicate URI option" , str (w [0 ].message ))
653631
654632 def test_split_options_empty_authsource (self ):
655- # An empty authSource value must be rejected.
656633 self .assertRaises (InvalidURI , split_options , "authSource=" )
657634
658635 def test_check_options_conflicts (self ):
659- # directConnection=true is incompatible with multiple hosts.
660636 self .assertRaises (
661637 ConfigurationError ,
662638 parse_uri ,
663639 "mongodb://host1,host2/?directConnection=true" ,
664640 )
665- # loadBalanced=true is incompatible with multiple hosts.
666641 self .assertRaises (
667642 ConfigurationError ,
668643 parse_uri ,
669644 "mongodb://host1,host2/?loadBalanced=true" ,
670645 )
671- # directConnection=true and loadBalanced=true cannot coexist.
672646 self .assertRaises (
673647 ConfigurationError ,
674648 parse_uri ,
675649 "mongodb://localhost/?directConnection=true&loadBalanced=true" ,
676650 )
677- # loadBalanced=true and replicaSet cannot coexist.
678651 self .assertRaises (
679652 ConfigurationError ,
680653 parse_uri ,
681654 "mongodb://localhost/?loadBalanced=true&replicaSet=rs0" ,
682655 )
683656
684657 def test_validate_uri_edge_cases (self ):
685- # URI with nothing after the scheme is invalid.
686658 self .assertRaises (InvalidURI , parse_uri , "mongodb://" )
687- # srvServiceName is only valid with mongodb+srv://.
688659 self .assertRaises (
689660 ConfigurationError ,
690661 parse_uri ,
691662 "mongodb://localhost/?srvServiceName=myService" ,
692663 )
693- # srvMaxHosts is only valid with mongodb+srv://.
694664 self .assertRaises (
695665 ConfigurationError ,
696666 parse_uri ,
697667 "mongodb://localhost/?srvMaxHosts=1" ,
698668 )
699- # Dollar sign is a prohibited character in database names.
700669 self .assertRaises (InvalidURI , parse_uri , "mongodb://localhost/%24db" )
701- # Space is a prohibited character in database names.
702670 self .assertRaises (InvalidURI , parse_uri , "mongodb://localhost/my%20db" )
703671
704672 def test_validate_uri_srv_structure (self ):
705- # SRV URIs require exactly one hostname with no port number.
706673 with patch ("pymongo.uri_parser_shared._have_dnspython" , return_value = True ):
707- # Multiple hosts in an SRV URI are not allowed.
708674 self .assertRaises (
709675 InvalidURI ,
710676 parse_uri ,
711677 "mongodb+srv://host1.example.com,host2.example.com" ,
712678 )
713- # A port number in a SRV URI is not allowed.
714679 self .assertRaises (
715680 InvalidURI ,
716681 parse_uri ,
717682 "mongodb+srv://host1.example.com:27017" ,
718683 )
719- # directConnection=true is incompatible with SRV URIs.
720684 self .assertRaises (
721685 ConfigurationError ,
722686 parse_uri ,
723687 "mongodb+srv://host1.example.com/?directConnection=true" ,
724688 )
725- # Without dnspython installed, SRV URIs raise ConfigurationError.
726689 with patch ("pymongo.uri_parser_shared._have_dnspython" , return_value = False ):
727690 self .assertRaises (
728691 ConfigurationError ,
0 commit comments