Skip to content

Commit aa29cb0

Browse files
committed
feat: show actual overage percentage in status bar (e.g. 111%)
When overageEnabled is true and overageUsed > 0, compute the display percentage as 100 + (overageUsed / quota * 100) instead of capping at the base usedPct. This surfaces overage at a glance without requiring the user to open the tooltip. - Extract computeDisplayPct(data) as a named pure function - Export it for test-only use - Add 6 unit tests covering normal, edge, and zero-quota cases - Update README status bar states table (100%+ → 111% example)
1 parent 11dea79 commit aa29cb0

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
| `25%` | Normal usage |
2828
| `75%` (yellow) | Warning threshold reached |
2929
| `90%` (red) | Critical threshold reached |
30+
| `111%` (red) | Overage — actual usage exceeds |
3031
| `` | Unlimited plan |
3132
| `` | No premium quota data (plan has no tracked limit) |
3233
| `` | Loading |

src/extension.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,19 @@ async function refresh(promptSignIn = false, isManual = false) {
168168
// Status bar rendering
169169
// ---------------------------------------------------------------------------
170170

171+
/**
172+
* Compute the display percentage for the status bar.
173+
* When overage is active, returns the actual total (e.g. 111 when 11% over quota).
174+
* @param {import('./api').UsageData} data
175+
* @returns {number}
176+
*/
177+
function computeDisplayPct(data) {
178+
if (data.overageEnabled && data.overageUsed > 0 && data.quota > 0) {
179+
return Math.round(100 + (data.overageUsed / data.quota) * 100);
180+
}
181+
return data.usedPct;
182+
}
183+
171184
const BILLING_URL = 'https://github.com/settings/billing/premium_requests_usage';
172185

173186
/**
@@ -198,7 +211,7 @@ function updateStatusBar(data, isRateLimited = false) {
198211
return;
199212
}
200213

201-
const pct = data.usedPct;
214+
const pct = computeDisplayPct(data);
202215
let color;
203216
if (cfg.thresholdEnabled) {
204217
if (pct >= cfg.thresholdCritical) {
@@ -396,6 +409,7 @@ module.exports = {
396409
getConfig,
397410
buildTooltip,
398411
computeIsStale,
412+
computeDisplayPct,
399413
// Test-only: inspect and mutate module-level state.
400414
_setState: (s) => {
401415
if ('isOffline' in s) isOffline = s.isOffline;

tests/extension.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
getConfig,
66
buildTooltip,
77
computeIsStale,
8+
computeDisplayPct,
89
_setState,
910
_getState,
1011
_startRecoveryTimer,
@@ -301,3 +302,36 @@ describe('recovery timer', () => {
301302
expect(_getState().refreshTimerActive).toBe(true);
302303
});
303304
});
305+
306+
// ---------------------------------------------------------------------------
307+
// computeDisplayPct
308+
// ---------------------------------------------------------------------------
309+
310+
describe('computeDisplayPct', () => {
311+
const base = { usedPct: 70, quota: 100, overageEnabled: false, overageUsed: 0 };
312+
313+
it('returns usedPct when no overage', () => {
314+
expect(computeDisplayPct({ ...base, usedPct: 70 })).toBe(70);
315+
});
316+
317+
it('returns usedPct when overageEnabled but overageUsed is 0', () => {
318+
expect(computeDisplayPct({ ...base, overageEnabled: true, overageUsed: 0 })).toBe(70);
319+
});
320+
321+
it('returns usedPct when overageUsed > 0 but overageEnabled is false', () => {
322+
expect(computeDisplayPct({ ...base, overageEnabled: false, overageUsed: 10 })).toBe(70);
323+
});
324+
325+
it('returns 110 when 10 of 100 quota used as overage', () => {
326+
expect(computeDisplayPct({ ...base, usedPct: 100, overageEnabled: true, overageUsed: 10, quota: 100 })).toBe(110);
327+
});
328+
329+
it('rounds the overage percentage', () => {
330+
// 5 overage out of 300 quota = 1.667% overage → rounds to 102
331+
expect(computeDisplayPct({ ...base, usedPct: 100, overageEnabled: true, overageUsed: 5, quota: 300 })).toBe(102);
332+
});
333+
334+
it('handles quota of 0 by falling back to usedPct', () => {
335+
expect(computeDisplayPct({ ...base, usedPct: 100, overageEnabled: true, overageUsed: 10, quota: 0 })).toBe(100);
336+
});
337+
});

0 commit comments

Comments
 (0)