mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-05 17:35:33 -03:00
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:
@@ -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()
|
||||
|
||||
@@ -2950,10 +2950,11 @@ def _price_alerts_adapter(update_service, scanners=None):
|
||||
|
||||
|
||||
class _FakeUpdateService:
|
||||
def __init__(self, alerts, *, unavailable_count=0):
|
||||
def __init__(self, alerts, *, unavailable_count=0, priced_count=0):
|
||||
self.alerts = alerts
|
||||
self.calls = []
|
||||
self.unavailable_count = unavailable_count
|
||||
self.priced_count = priced_count
|
||||
|
||||
async def get_price_alerts(self, model_type=None, *, threshold_buzz=None, limit=200):
|
||||
self.calls.append((model_type, threshold_buzz, limit))
|
||||
@@ -2965,6 +2966,9 @@ class _FakeUpdateService:
|
||||
def count_unavailable_prices(self, model_type=None):
|
||||
return self.unavailable_count
|
||||
|
||||
def count_priced_versions(self, model_type=None):
|
||||
return self.priced_count
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_price_alerts_handler_returns_the_global_list():
|
||||
@@ -3002,6 +3006,7 @@ async def test_price_alerts_handler_returns_the_global_list():
|
||||
assert payload["thresholdBuzz"] == 300
|
||||
assert payload["newestCheckedAt"] == 1791039694.5
|
||||
assert payload["unavailableCount"] == 0
|
||||
assert payload["pricedCount"] == 0
|
||||
assert payload["alerts"][0]["civitaiUrl"] == (
|
||||
"https://civitai.com/models/2981320?modelVersionId=3379626"
|
||||
)
|
||||
|
||||
@@ -2023,6 +2023,20 @@ async def test_failed_price_attempt_is_not_retried_within_the_ttl(tmp_path):
|
||||
assert service.count_unavailable_prices("lora") == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_priced_count_reports_known_prices(tmp_path):
|
||||
service = _price_service(tmp_path, price_tracking_enabled=True)
|
||||
scanner = DummyScanner(LOCAL_RAW_DATA)
|
||||
provider = PriceProvider(GATED_RESPONSE, prices=PRICE_PAYLOAD)
|
||||
|
||||
assert service.count_priced_versions("lora") == 0
|
||||
|
||||
await service.refresh_for_model_type("lora", scanner, provider)
|
||||
|
||||
assert service.count_priced_versions("lora") == 1
|
||||
assert service.count_priced_versions("checkpoint") == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_forced_refresh_reprices_within_the_ttl(tmp_path):
|
||||
service = _long_ttl_service(tmp_path, price_tracking_enabled=True)
|
||||
|
||||
Reference in New Issue
Block a user