fix(frontend): key geo entries by page position and clear test-suite noise

Zod 4: use the `error` param instead of the deprecated `message`.
lint:deprecated missed these because tsgolint's no-deprecated does not
resolve object-literal properties on a `string | Params` union.

Geodata: key geo entry rows by page position. antd deprecates rowKey's
index argument, and kind:value repeats within a page because the reader
drops domain attributes (22 pairs in geosite_IR.dat, 108 in geosite_RU).

Nord/PIA: the "All cities/regions" option used a null value, which antd
warns on. Map it through a sentinel at the Select boundary so form state
stays null, with tests that fail when the sentinel is not mapped back.

Tests:
- Run the oxlint guard through node; .bin/oxlint is a sh shim Windows
  cannot spawn, and the swallowed error left both guard cases vacuous.
- Start unit workers with --no-experimental-webstorage; msw's localStorage
  probe made Node 25+ warn once per forked worker.
- Set IS_REACT_ACT_ENVIRONMENT, which RTL never sets with globals: false,
  and settle the async updates it exposed inside act(). The row-cells
  memo test now fails when memo is removed.
- Disable antd's click wave in Storybook; it re-rendered inside the next
  story's act() and tripped "not configured to support act".
- Assert InboundFormModal's validation log instead of leaking it, and
  give the rule-form test a well-formed clients/list response.
This commit is contained in:
MHSanaei
2026-09-25 21:21:03 +02:00
parent a03228c455
commit 89e200ead4
25 changed files with 186 additions and 70 deletions
@@ -86,6 +86,13 @@ const EMPTY: NordFormValues = {
serverId: null,
};
// antd warns on a null option value, so "All Cities" is a sentinel mapped back to null.
const ALL_CITIES = '__all__';
const allCitiesTransform = {
input: (value: unknown) => value ?? ALL_CITIES,
output: (value: unknown) => (value === ALL_CITIES ? null : value),
};
function loadLevel(load: number): 'low' | 'medium' | 'high' {
if (load < 30) return 'low';
if (load < 70) return 'medium';
@@ -452,12 +459,16 @@ export default function NordModal({
</FormField>
{cities.length > 0 && (
<FormField name="cityId" label={t('pages.xray.outbound.city')}>
<FormField
name="cityId"
label={t('pages.xray.outbound.city')}
transform={allCitiesTransform}
>
<Select
data-testid="nord-city-select"
showSearch={{ optionFilterProp: 'label' }}
options={[
{ value: null, label: t('pages.xray.outbound.allCities') },
{ value: ALL_CITIES, label: t('pages.xray.outbound.allCities') },
...cities.map((c) => ({ value: c.id, label: c.name })),
]}
/>
+13 -2
View File
@@ -73,6 +73,13 @@ const EMPTY: PiaFormValues = {
hostname: null,
};
// antd warns on a null option value, so "All Regions" is a sentinel mapped back to null.
const ALL_REGIONS = '__all__';
const allRegionsTransform = {
input: (value: unknown) => value ?? ALL_REGIONS,
output: (value: unknown) => (value === ALL_REGIONS ? null : value),
};
function piaHostnameOf(outbound: PiaOutboundRow): string {
if (typeof outbound.piaHostname === 'string' && outbound.piaHostname.trim()) {
return outbound.piaHostname.trim();
@@ -389,12 +396,16 @@ export default function PiaModal({
</FormField>
{regions.length > 0 && (
<FormField name="regionId" label={t('pages.xray.pia.region')}>
<FormField
name="regionId"
label={t('pages.xray.pia.region')}
transform={allRegionsTransform}
>
<Select
data-testid="pia-region-select"
showSearch={{ optionFilterProp: 'label' }}
options={[
{ value: null, label: t('pages.xray.pia.allRegions') },
{ value: ALL_REGIONS, label: t('pages.xray.pia.allRegions') },
...regions.map((r) => ({ value: r.id, label: r.name })),
]}
/>