mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-09 04:19:27 -07:00
feat(stats): support 365d range in trends query
This commit is contained in:
@@ -835,6 +835,65 @@ test('getTrendsDashboard keeps local-midnight session buckets separate', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getTrendsDashboard supports 365d range and caps day buckets at 365', () => {
|
||||||
|
const dbPath = makeDbPath();
|
||||||
|
const db = new Database(dbPath);
|
||||||
|
withMockNowMs('1772395200000', () => {
|
||||||
|
try {
|
||||||
|
ensureSchema(db);
|
||||||
|
|
||||||
|
const videoId = getOrCreateVideoRecord(db, 'local:/tmp/365d-trends.mkv', {
|
||||||
|
canonicalTitle: '365d Trends',
|
||||||
|
sourcePath: '/tmp/365d-trends.mkv',
|
||||||
|
sourceUrl: null,
|
||||||
|
sourceType: SOURCE_TYPE_LOCAL,
|
||||||
|
});
|
||||||
|
const animeId = getOrCreateAnimeRecord(db, {
|
||||||
|
parsedTitle: '365d Trends',
|
||||||
|
canonicalTitle: '365d Trends',
|
||||||
|
anilistId: null,
|
||||||
|
titleRomaji: null,
|
||||||
|
titleEnglish: null,
|
||||||
|
titleNative: null,
|
||||||
|
metadataJson: null,
|
||||||
|
});
|
||||||
|
linkVideoToAnimeRecord(db, videoId, {
|
||||||
|
animeId,
|
||||||
|
parsedBasename: '365d-trends.mkv',
|
||||||
|
parsedTitle: '365d Trends',
|
||||||
|
parsedSeason: 1,
|
||||||
|
parsedEpisode: 1,
|
||||||
|
parserSource: 'test',
|
||||||
|
parserConfidence: 1,
|
||||||
|
parseMetadataJson: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const insertDailyRollup = db.prepare(
|
||||||
|
`
|
||||||
|
INSERT INTO imm_daily_rollups (
|
||||||
|
rollup_day, video_id, total_sessions, total_active_min, total_lines_seen,
|
||||||
|
total_tokens_seen, total_cards, CREATED_DATE, LAST_UPDATE_DATE
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
`,
|
||||||
|
);
|
||||||
|
// Seed 400 distinct rollup days so we can prove the 365d range caps at 365.
|
||||||
|
const latestRollupDay = 20513;
|
||||||
|
const createdAtMs = '1772395200000';
|
||||||
|
for (let offset = 0; offset < 400; offset += 1) {
|
||||||
|
const rollupDay = latestRollupDay - offset;
|
||||||
|
insertDailyRollup.run(rollupDay, videoId, 1, 30, 4, 100, 2, createdAtMs, createdAtMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dashboard = getTrendsDashboard(db, '365d', 'day');
|
||||||
|
|
||||||
|
assert.equal(dashboard.activity.watchTime.length, 365);
|
||||||
|
} finally {
|
||||||
|
db.close();
|
||||||
|
cleanupDbPath(dbPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('getTrendsDashboard month grouping spans every touched calendar month and keeps progress monthly', () => {
|
test('getTrendsDashboard month grouping spans every touched calendar month and keeps progress monthly', () => {
|
||||||
const dbPath = makeDbPath();
|
const dbPath = makeDbPath();
|
||||||
const db = new Database(dbPath);
|
const db = new Database(dbPath);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from './query-shared';
|
} from './query-shared';
|
||||||
import { getDailyRollups, getMonthlyRollups } from './query-sessions';
|
import { getDailyRollups, getMonthlyRollups } from './query-sessions';
|
||||||
|
|
||||||
type TrendRange = '7d' | '30d' | '90d' | 'all';
|
type TrendRange = '7d' | '30d' | '90d' | '365d' | 'all';
|
||||||
type TrendGroupBy = 'day' | 'month';
|
type TrendGroupBy = 'day' | 'month';
|
||||||
|
|
||||||
interface TrendChartPoint {
|
interface TrendChartPoint {
|
||||||
@@ -85,6 +85,7 @@ const TREND_DAY_LIMITS: Record<Exclude<TrendRange, 'all'>, number> = {
|
|||||||
'7d': 7,
|
'7d': 7,
|
||||||
'30d': 30,
|
'30d': 30,
|
||||||
'90d': 90,
|
'90d': 90,
|
||||||
|
'365d': 365,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MONTH_NAMES = [
|
const MONTH_NAMES = [
|
||||||
|
|||||||
Reference in New Issue
Block a user