mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-20 12:11:28 -07:00
fix(stats): load full session timelines by default
This commit is contained in:
@@ -439,6 +439,51 @@ test('registerIpcHandlers validates and clamps stats request limits', async () =
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('registerIpcHandlers requests the full timeline when no limit is provided', async () => {
|
||||||
|
const { registrar, handlers } = createFakeIpcRegistrar();
|
||||||
|
const calls: Array<[string, number | undefined, number]> = [];
|
||||||
|
|
||||||
|
registerIpcHandlers(
|
||||||
|
createRegisterIpcDeps({
|
||||||
|
immersionTracker: {
|
||||||
|
recordYomitanLookup: () => {},
|
||||||
|
getSessionSummaries: async () => [],
|
||||||
|
getDailyRollups: async () => [],
|
||||||
|
getMonthlyRollups: async () => [],
|
||||||
|
getQueryHints: async () => ({
|
||||||
|
totalSessions: 0,
|
||||||
|
activeSessions: 0,
|
||||||
|
episodesToday: 0,
|
||||||
|
activeAnimeCount: 0,
|
||||||
|
totalCards: 0,
|
||||||
|
totalActiveMin: 0,
|
||||||
|
activeDays: 0,
|
||||||
|
totalEpisodesWatched: 0,
|
||||||
|
totalAnimeCompleted: 0,
|
||||||
|
}),
|
||||||
|
getSessionTimeline: async (sessionId: number, limit?: number) => {
|
||||||
|
calls.push(['timeline', limit, sessionId]);
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
getSessionEvents: async () => [],
|
||||||
|
getVocabularyStats: async () => [],
|
||||||
|
getKanjiStats: async () => [],
|
||||||
|
getMediaLibrary: async () => [],
|
||||||
|
getMediaDetail: async () => null,
|
||||||
|
getMediaSessions: async () => [],
|
||||||
|
getMediaDailyRollups: async () => [],
|
||||||
|
getCoverArt: async () => null,
|
||||||
|
markActiveVideoWatched: async () => false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
registrar,
|
||||||
|
);
|
||||||
|
|
||||||
|
await handlers.handle.get(IPC_CHANNELS.request.statsGetSessionTimeline)!({}, 7, undefined);
|
||||||
|
|
||||||
|
assert.deepEqual(calls, [['timeline', undefined, 7]]);
|
||||||
|
});
|
||||||
|
|
||||||
test('registerIpcHandlers ignores malformed fire-and-forget payloads', () => {
|
test('registerIpcHandlers ignores malformed fire-and-forget payloads', () => {
|
||||||
const { registrar, handlers } = createFakeIpcRegistrar();
|
const { registrar, handlers } = createFakeIpcRegistrar();
|
||||||
const saves: unknown[] = [];
|
const saves: unknown[] = [];
|
||||||
|
|||||||
@@ -517,7 +517,7 @@ export function registerIpcHandlers(deps: IpcServiceDeps, ipc: IpcMainRegistrar
|
|||||||
async (_event, sessionId: unknown, limit: unknown) => {
|
async (_event, sessionId: unknown, limit: unknown) => {
|
||||||
const parsedSessionId = parsePositiveInteger(sessionId);
|
const parsedSessionId = parsePositiveInteger(sessionId);
|
||||||
if (parsedSessionId === null) return [];
|
if (parsedSessionId === null) return [];
|
||||||
const parsedLimit = parsePositiveIntLimit(limit, 200, 1000);
|
const parsedLimit = limit === undefined ? undefined : parsePositiveIntLimit(limit, 200, 1000);
|
||||||
return deps.immersionTracker?.getSessionTimeline(parsedSessionId, parsedLimit) ?? [];
|
return deps.immersionTracker?.getSessionTimeline(parsedSessionId, parsedLimit) ?? [];
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -189,7 +189,8 @@ export function createStatsApp(
|
|||||||
app.get('/api/stats/sessions/:id/timeline', async (c) => {
|
app.get('/api/stats/sessions/:id/timeline', async (c) => {
|
||||||
const id = parseIntQuery(c.req.param('id'), 0);
|
const id = parseIntQuery(c.req.param('id'), 0);
|
||||||
if (id <= 0) return c.json([], 400);
|
if (id <= 0) return c.json([], 400);
|
||||||
const limit = parseIntQuery(c.req.query('limit'), 200, 1000);
|
const rawLimit = c.req.query('limit');
|
||||||
|
const limit = rawLimit === undefined ? undefined : parseIntQuery(rawLimit, 200, 1000);
|
||||||
const timeline = await tracker.getSessionTimeline(id, limit);
|
const timeline = await tracker.getSessionTimeline(id, limit);
|
||||||
return c.json(timeline);
|
return c.json(timeline);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -70,8 +70,12 @@ export const apiClient = {
|
|||||||
getMonthlyRollups: (limit = 24) =>
|
getMonthlyRollups: (limit = 24) =>
|
||||||
fetchJson<MonthlyRollup[]>(`/api/stats/monthly-rollups?limit=${limit}`),
|
fetchJson<MonthlyRollup[]>(`/api/stats/monthly-rollups?limit=${limit}`),
|
||||||
getSessions: (limit = 50) => fetchJson<SessionSummary[]>(`/api/stats/sessions?limit=${limit}`),
|
getSessions: (limit = 50) => fetchJson<SessionSummary[]>(`/api/stats/sessions?limit=${limit}`),
|
||||||
getSessionTimeline: (id: number, limit = 200) =>
|
getSessionTimeline: (id: number, limit?: number) =>
|
||||||
fetchJson<SessionTimelinePoint[]>(`/api/stats/sessions/${id}/timeline?limit=${limit}`),
|
fetchJson<SessionTimelinePoint[]>(
|
||||||
|
limit === undefined
|
||||||
|
? `/api/stats/sessions/${id}/timeline`
|
||||||
|
: `/api/stats/sessions/${id}/timeline?limit=${limit}`,
|
||||||
|
),
|
||||||
getSessionEvents: (id: number, limit = 500) =>
|
getSessionEvents: (id: number, limit = 500) =>
|
||||||
fetchJson<SessionEvent[]>(`/api/stats/sessions/${id}/events?limit=${limit}`),
|
fetchJson<SessionEvent[]>(`/api/stats/sessions/${id}/events?limit=${limit}`),
|
||||||
getSessionKnownWordsTimeline: (id: number) =>
|
getSessionKnownWordsTimeline: (id: number) =>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const ipcClient = {
|
|||||||
getDailyRollups: (limit = 60) => getIpc().getDailyRollups(limit),
|
getDailyRollups: (limit = 60) => getIpc().getDailyRollups(limit),
|
||||||
getMonthlyRollups: (limit = 24) => getIpc().getMonthlyRollups(limit),
|
getMonthlyRollups: (limit = 24) => getIpc().getMonthlyRollups(limit),
|
||||||
getSessions: (limit = 50) => getIpc().getSessions(limit),
|
getSessions: (limit = 50) => getIpc().getSessions(limit),
|
||||||
getSessionTimeline: (id: number, limit = 200) => getIpc().getSessionTimeline(id, limit),
|
getSessionTimeline: (id: number, limit?: number) => getIpc().getSessionTimeline(id, limit),
|
||||||
getSessionEvents: (id: number, limit = 500) => getIpc().getSessionEvents(id, limit),
|
getSessionEvents: (id: number, limit = 500) => getIpc().getSessionEvents(id, limit),
|
||||||
getVocabulary: (limit = 100) => getIpc().getVocabulary(limit),
|
getVocabulary: (limit = 100) => getIpc().getVocabulary(limit),
|
||||||
getWordOccurrences: (headword: string, word: string, reading: string, limit = 50, offset = 0) =>
|
getWordOccurrences: (headword: string, word: string, reading: string, limit = 50, offset = 0) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user