fix(ui): explain a 0 Buzz threshold in the price alerts panel

The default threshold is 0 ("only tell me when a version becomes free") and the
settings copy says so, but the panel did not: a real instance with 52 priced paid
versions and an untouched threshold showed "Nothing is under your price threshold
right now" with only a small "Alert threshold: 0 Buzz" in the corner, which reads
as a broken feature.

- the payload now carries pricedCount, so the empty state can say how many paid
  versions already have a known price
- when the threshold is 0 and prices are known, the empty state says so and
  points at Settings - Library instead of implying there is nothing to show
- the read-time threshold comparison means setting one takes effect immediately;
  measured on a copy of that instance: 0 Buzz -> 0 alerts, 100 -> 44,
  500 -> 48, 5000 -> 51
This commit is contained in:
Will Miao
2026-10-04 20:28:57 +08:00
parent 425d90a912
commit 156d2e5eb9
17 changed files with 148 additions and 23 deletions
@@ -218,6 +218,36 @@ describe('UpdateService price alerts panel', () => {
expect(note.textContent).toContain('3 paid version(s) have no readable price');
});
it('explains a 0 Buzz threshold instead of claiming there is nothing', async () => {
// The exact confusion a real user hit: 52 priced versions, threshold 0,
// and an empty panel saying "nothing is under your threshold".
global.fetch = vi.fn().mockResolvedValue(
createFetchResponse(
alertPayload([], { thresholdBuzz: 0, pricedCount: 52 })
)
);
await service.loadPriceAlerts({ force: true });
const empty = document.getElementById('priceAlertsEmpty');
expect(empty.classList.contains('hidden')).toBe(false);
expect(empty.textContent).toContain('52 paid version(s) have a known price');
expect(empty.textContent).toContain('threshold is 0 Buzz');
});
it('keeps the plain empty message when a real threshold is set', async () => {
global.fetch = vi.fn().mockResolvedValue(
createFetchResponse(
alertPayload([], { thresholdBuzz: 500, pricedCount: 52 })
)
);
await service.loadPriceAlerts({ force: true });
const empty = document.getElementById('priceAlertsEmpty');
expect(empty.textContent).toBe('Nothing is under your price threshold right now.');
});
it('keeps the last known list when the request fails', async () => {
global.fetch = vi
.fn()