@@ -1787,3 +1787,37 @@ def test_get_sqlalchemy_engine_with_proxy(self):
17871787 # Check that the URI doesn't contain proxy params
17881788 called_uri = mock_create_engine .call_args [0 ][0 ]
17891789 assert "proxy_host" not in str (called_uri )
1790+
1791+ def test_get_connection_form_widgets_proxy_port_is_optional (self ):
1792+ """Proxy Port is an IntegerField and must remain optional.
1793+
1794+ Regression test for the Snowflake connection form silently rejecting
1795+ save when `Proxy Port` is left blank. `IntegerField` fails WTForms
1796+ validation on empty input by default, so `Optional()` is required to
1797+ preserve the documented optional semantics.
1798+ """
1799+ pytest .importorskip ("flask_appbuilder" )
1800+ pytest .importorskip ("flask_babel" )
1801+ Form = pytest .importorskip ("wtforms" ).Form
1802+ Optional = pytest .importorskip ("wtforms.validators" ).Optional
1803+ MultiDict = pytest .importorskip ("werkzeug.datastructures" ).MultiDict
1804+
1805+ widgets = SnowflakeHook .get_connection_form_widgets ()
1806+ assert "proxy_port" in widgets
1807+
1808+ proxy_port_field = widgets ["proxy_port" ]
1809+ assert any (isinstance (v , Optional ) for v in proxy_port_field .kwargs .get ("validators" , []))
1810+
1811+ form_cls = type ("_SnowflakeConnForm" , (Form ,), dict (widgets ))
1812+
1813+ empty_form = form_cls (MultiDict ([("proxy_port" , "" )]))
1814+ assert empty_form .validate () is True , empty_form .errors
1815+ assert empty_form .proxy_port .data is None
1816+
1817+ populated_form = form_cls (MultiDict ([("proxy_port" , "8080" )]))
1818+ assert populated_form .validate () is True , populated_form .errors
1819+ assert populated_form .proxy_port .data == 8080
1820+
1821+ invalid_form = form_cls (MultiDict ([("proxy_port" , "not-an-int" )]))
1822+ assert invalid_form .validate () is False
1823+ assert "proxy_port" in invalid_form .errors
0 commit comments