@@ -73,5 +73,63 @@ async def _scenario(self):
7373 await close_db ()
7474
7575
76+ class LegacyBackgroundUpgradeTests (SettingsOverrideMixin , unittest .TestCase ):
77+ """存量部署升级:旧版本合法、新校验不接受的值,不得阻塞设置保存。"""
78+
79+ def test_unchanged_legacy_background_does_not_block_unrelated_save (self ):
80+ asyncio .run (self ._unchanged_legacy_allows_save ())
81+
82+ async def _unchanged_legacy_allows_save (self ):
83+ await init_memory_db ()
84+ try :
85+ from apps .base .config import refresh_settings
86+ from apps .base .models import KeyValue
87+
88+ # 旧版本合法(相对路径 + 空格),新的 http(s) 校验会拒绝
89+ legacy = "/static/bg image.png"
90+ await KeyValue .create (
91+ key = "settings" , value = {"background" : legacy , "name" : "old" }
92+ )
93+ await refresh_settings (force = True )
94+
95+ service = ConfigService ()
96+ # 修复前这里会 400,导致存量部署连无关设置项都保存不了
97+ await service .update_config ({"name" : "new" })
98+
99+ record = await KeyValue .filter (key = "settings" ).first ()
100+ self .assertEqual (record .value .get ("background" ), legacy , "旧值应原样保留" )
101+ self .assertEqual (record .value .get ("name" ), "new" )
102+ finally :
103+ await close_db ()
104+
105+ def test_changing_background_is_still_validated (self ):
106+ asyncio .run (self ._change_still_validated ())
107+
108+ async def _change_still_validated (self ):
109+ await init_memory_db ()
110+ try :
111+ from fastapi import HTTPException
112+
113+ from apps .base .config import refresh_settings
114+ from apps .base .models import KeyValue
115+
116+ await KeyValue .create (key = "settings" , value = {"background" : "/legacy/bg.png" })
117+ await refresh_settings (force = True )
118+
119+ service = ConfigService ()
120+ # 修改为恶意值仍然被拒
121+ with self .assertRaises (HTTPException ) as ctx :
122+ await service .update_config (
123+ {"background" : "x') ;background:url(https://evil.com/)" }
124+ )
125+ self .assertEqual (ctx .exception .status_code , 400 )
126+ # 修改为合法值可以通过
127+ await service .update_config ({"background" : "https://ok.example/bg.png" })
128+ record = await KeyValue .filter (key = "settings" ).first ()
129+ self .assertEqual (record .value .get ("background" ), "https://ok.example/bg.png" )
130+ finally :
131+ await close_db ()
132+
133+
76134if __name__ == "__main__" :
77135 unittest .main ()
0 commit comments