fix(properties): harden diagnostic visual states

This commit is contained in:
NimBold
2026-08-07 12:24:05 +03:30
parent e2654510af
commit e402603edb
10 changed files with 266 additions and 19 deletions
+36
View File
@@ -0,0 +1,36 @@
import { describe, expect, it } from 'vitest';
import {
getPropertiesAvailabilityDiagnosticState,
getPropertiesPeerDiagnosticState,
} from './propertiesDiagnostics';
const emptyPeerDiagnostics = {
totalPeers: 0,
totalSeeders: 0,
peers: [],
truncated: false,
};
describe('Properties peer diagnostics presentation state', () => {
it('keeps a genuine empty response live instead of treating it as unavailable', () => {
expect(getPropertiesPeerDiagnosticState(emptyPeerDiagnostics, false, 'idle')).toBe('live');
});
it('distinguishes loading and unavailable before a response exists', () => {
expect(getPropertiesPeerDiagnosticState(null, true, 'initial')).toBe('loading');
expect(getPropertiesPeerDiagnosticState(null, false, 'unavailable')).toBe('unavailable');
});
it('marks cached diagnostics as stale after an expected lifecycle miss', () => {
expect(getPropertiesPeerDiagnosticState(emptyPeerDiagnostics, false, 'stale')).toBe('stale');
});
it('marks cached peer diagnostics as errored after an unexpected refresh failure', () => {
expect(getPropertiesPeerDiagnosticState(emptyPeerDiagnostics, false, 'error')).toBe('error');
});
it('does not reuse peer state for unavailable availability data', () => {
expect(getPropertiesAvailabilityDiagnosticState(null, false, 'idle')).toBe('unavailable');
expect(getPropertiesAvailabilityDiagnosticState(null, false, 'error')).toBe('error');
});
});
+41
View File
@@ -0,0 +1,41 @@
import type { TorrentPeerDiagnostics } from '../bindings/TorrentPeerDiagnostics';
import type { TorrentAvailabilitySnapshot } from '../bindings/TorrentAvailabilitySnapshot';
import type { PropertiesDiagnosticPhase } from '../propertiesBridge';
export type PropertiesDiagnosticValueState = 'live' | 'loading' | 'stale' | 'error' | 'unavailable';
const getPropertiesDiagnosticValueState = (
hasValue: boolean,
diagnosticsLoading: boolean,
diagnosticPhase: PropertiesDiagnosticPhase,
): PropertiesDiagnosticValueState => {
if (hasValue) {
if (diagnosticPhase === 'error') return 'error';
if (diagnosticPhase === 'stale') return 'stale';
return 'live';
}
if (diagnosticsLoading) return 'loading';
if (diagnosticPhase === 'error') return 'error';
if (diagnosticPhase === 'stale') return 'stale';
return 'unavailable';
};
export type PropertiesPeerDiagnosticState = PropertiesDiagnosticValueState;
export const getPropertiesPeerDiagnosticState = (
peers: TorrentPeerDiagnostics | null,
diagnosticsLoading: boolean,
diagnosticPhase: PropertiesDiagnosticPhase,
): PropertiesPeerDiagnosticState => {
return getPropertiesDiagnosticValueState(peers !== null, diagnosticsLoading, diagnosticPhase);
};
export const getPropertiesAvailabilityDiagnosticState = (
availability: TorrentAvailabilitySnapshot | null,
diagnosticsLoading: boolean,
diagnosticPhase: PropertiesDiagnosticPhase,
): PropertiesDiagnosticValueState => getPropertiesDiagnosticValueState(
availability !== null,
diagnosticsLoading,
diagnosticPhase,
);