fix(quota): guard remaining usage percent (#1242)

* fix(quota): guard remaining usage percent

* test(quota): cover non-finite usage percents

* fix(ui): clean up virtual scroll frame

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Isaac Sanchez-Hawkins
2026-05-13 14:51:46 +03:00
committed by GitHub
co-authored by Isaac Sanchez Bohdan Triapitsyn
parent eb8b9ed715
commit 11e5ab93a9
3 changed files with 27 additions and 3 deletions
@@ -1355,8 +1355,9 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
// measure() defers via useAnimationFrameWithResizeObserver.
// Wait two frames then, if we were near the estimated bottom, scroll
// to the real bottom after measurements settle.
let frame2: number | null = null;
const frame1 = requestAnimationFrame(() => {
const frame2 = requestAnimationFrame(() => {
frame2 = requestAnimationFrame(() => {
if (!nearBottom) return
const el = resolveScrollContainer()
if (!el) return
@@ -1368,8 +1369,11 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
})
return () => {
cancelAnimationFrame(frame1)
if (frame2 !== null) {
cancelAnimationFrame(frame2)
}
}
}, [historyVirtualizer, shouldVirtualizeHistory]);
}, [historyVirtualizer, resolveScrollContainer, shouldVirtualizeHistory]);
const scheduleVirtualMeasure = React.useCallback(() => {
if (!shouldVirtualizeHistory) {
@@ -40,9 +40,10 @@ export const calculateResetAfterSeconds = (resetAt) => {
export const toUsageWindow = ({ usedPercent, windowSeconds, resetAt, valueLabel }) => {
const resetAfterSeconds = calculateResetAfterSeconds(resetAt);
const resetFormatted = hasResetTimestamp(resetAt) ? formatResetTime(resetAt) : null;
const hasFiniteUsedPercent = typeof usedPercent === 'number' && Number.isFinite(usedPercent);
return {
usedPercent,
remainingPercent: usedPercent !== null ? Math.max(0, 100 - usedPercent) : null,
remainingPercent: hasFiniteUsedPercent ? Math.max(0, 100 - usedPercent) : null,
windowSeconds: windowSeconds ?? null,
resetAfterSeconds,
resetAt,
@@ -32,4 +32,23 @@ describe('toUsageWindow', () => {
expect(usageWindow.resetAtFormatted).toBe(formatResetTime(0));
expect(usageWindow.resetAfterFormatted).toBe(formatResetTime(0));
});
it('does not derive remaining percent from missing usage', () => {
expect(toUsageWindow({ usedPercent: undefined }).remainingPercent).toBeNull();
});
it('does not derive remaining percent from non-finite usage', () => {
expect(toUsageWindow({ usedPercent: NaN }).remainingPercent).toBeNull();
expect(toUsageWindow({ usedPercent: Infinity }).remainingPercent).toBeNull();
expect(toUsageWindow({ usedPercent: -Infinity }).remainingPercent).toBeNull();
expect(toUsageWindow({ usedPercent: null }).remainingPercent).toBeNull();
});
it('derives remaining percent from a valid usage value', () => {
expect(toUsageWindow({ usedPercent: 60 }).remainingPercent).toBe(40);
});
it('clamps remaining percent to zero when usage exceeds 100', () => {
expect(toUsageWindow({ usedPercent: 110 }).remainingPercent).toBe(0);
});
});