mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-11-10 04:46:07 -08:00
fix(stats): surface activity calendar refresh failures on Overview
- Show a retryable alert when the streak calendar refresh fails - Use a calendar-specific message while overview totals still refresh - Cover calendar failure in the Overview refresh/retry tests
This commit is contained in:
2 files changed
+18
-10
No files matched your search
@@ -196,7 +196,7 @@ for (const mode of ['session', 'day', 'anime', 'failed'] as const) {
|
||||
});
|
||||
}
|
||||
|
||||
for (const failedRead of ['overview', 'sessions'] as const) {
|
||||
for (const failedRead of ['overview', 'sessions', 'calendar'] as const) {
|
||||
test(`Overview stays available during a failed ${failedRead} refresh and can retry`, async () => {
|
||||
const uninstallDom = installDom();
|
||||
const original = { ...apiClient };
|
||||
@@ -216,7 +216,10 @@ for (const failedRead of ['overview', 'sessions'] as const) {
|
||||
if (refreshing && failRefresh && failedRead === 'sessions') return pendingRefresh;
|
||||
return sessions;
|
||||
};
|
||||
apiClient.getStreakCalendar = async () => [];
|
||||
apiClient.getStreakCalendar = async () => {
|
||||
if (refreshing && failRefresh && failedRead === 'calendar') return pendingRefresh;
|
||||
return [];
|
||||
};
|
||||
apiClient.getKnownWordsSummary = async () => ({
|
||||
totalUniqueWords: 0,
|
||||
knownWordCount: 0,
|
||||
@@ -225,6 +228,8 @@ for (const failedRead of ['overview', 'sessions'] as const) {
|
||||
sessions = [];
|
||||
refreshing = true;
|
||||
};
|
||||
// A calendar-only failure still lets the overview totals refresh.
|
||||
const staleCards = failedRead === 'calendar' ? '0' : '2';
|
||||
const container = document.createElement('div');
|
||||
document.body.append(container);
|
||||
const root = createRoot(container);
|
||||
@@ -240,12 +245,12 @@ for (const failedRead of ['overview', 'sessions'] as const) {
|
||||
assert.ok(deleteButton);
|
||||
await act(async () => deleteButton.click());
|
||||
assert.match(container.textContent ?? '', /Tracking Snapshot/);
|
||||
assert.equal(metric(container, 'Cards Mined Today'), '2');
|
||||
assert.equal(metric(container, 'Cards Mined Today'), staleCards);
|
||||
assert.match(container.textContent ?? '', /No sessions yet/);
|
||||
|
||||
await act(async () => rejectRefresh(new Error(`${failedRead} unavailable`)));
|
||||
assert.match(container.textContent ?? '', /Tracking Snapshot/);
|
||||
assert.equal(metric(container, 'Cards Mined Today'), '2');
|
||||
assert.equal(metric(container, 'Cards Mined Today'), staleCards);
|
||||
assert.match(container.querySelector('[role="alert"]')?.textContent ?? '', /unavailable/);
|
||||
|
||||
const retryButton = [...container.querySelectorAll('button')].find(
|
||||
|
||||
@@ -29,7 +29,7 @@ export function OverviewTab({
|
||||
}: OverviewTabProps) {
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
const { data, sessions, setSessions, loading, error } = useOverview(refreshKey);
|
||||
const { calendar, loading: calLoading } = useStreakCalendar(90, refreshKey);
|
||||
const { calendar, loading: calLoading, error: calendarError } = useStreakCalendar(90, refreshKey);
|
||||
const [deleteError, setDeleteError] = useState<string | null>(null);
|
||||
const [deletingIds, setDeletingIds] = useState<Set<number>>(new Set());
|
||||
const [knownWordsSummary, setKnownWordsSummary] = useState<{
|
||||
@@ -123,16 +123,19 @@ export function OverviewTab({
|
||||
}
|
||||
};
|
||||
|
||||
const errorNotice = error ? (
|
||||
const refreshError = error ?? calendarError;
|
||||
const errorNotice = refreshError ? (
|
||||
<div
|
||||
role="alert"
|
||||
className="flex items-center justify-between gap-3 rounded-lg border border-ctp-red/30 bg-ctp-red/10 p-3 text-sm text-ctp-red"
|
||||
>
|
||||
<span>
|
||||
{data
|
||||
? 'Could not refresh Overview. Displayed totals may be out of date.'
|
||||
: 'Could not load Overview.'}{' '}
|
||||
{error}
|
||||
{!data
|
||||
? 'Could not load Overview.'
|
||||
: error
|
||||
? 'Could not refresh Overview. Displayed totals may be out of date.'
|
||||
: 'Could not refresh the activity calendar. It may be out of date.'}{' '}
|
||||
{refreshError}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in new issue
Block a user