mirror of
https://github.com/tiennm99/vngeoguessr.git
synced 2026-10-14 18:19:30 +00:00
/api/daily opens an ordinary session on a panorama picked deterministically from the day and cached in Redis for two days, so the Postgres draw and the Mapillary lookup happen once a day. Days roll over at midnight Vietnam time. The round is scored by /api/guess like any other and counted under its own level in the statistics. There is no daily leaderboard: the only identity is a cookie and a localStorage name, so a dated board would be won by whoever opened the most private windows. The browser keeps the finished round and replays it on a revisit, and tracks the streak of consecutive days. The home page carries the challenge card and the result dialog shares the outcome as a squares line.
29 lines
1.1 KiB
JavaScript
29 lines
1.1 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { nextStreak, currentStreak } from '../src/lib/daily-progress.js';
|
|
|
|
// The streak rule, without a browser: the day after the last play extends it,
|
|
// the same day keeps it, any gap restarts it.
|
|
describe('daily streak', () => {
|
|
const played = (day, streak) => ({ day, streak });
|
|
|
|
it('starts at one with no history', () => {
|
|
expect(nextStreak(null, '2026-09-21')).toBe(1);
|
|
});
|
|
|
|
it('extends across consecutive days and keeps within a day', () => {
|
|
expect(nextStreak(played('2026-09-20', 3), '2026-09-21')).toBe(4);
|
|
expect(nextStreak(played('2026-09-21', 4), '2026-09-21')).toBe(4);
|
|
});
|
|
|
|
it('restarts after a missed day', () => {
|
|
expect(nextStreak(played('2026-09-19', 7), '2026-09-21')).toBe(1);
|
|
});
|
|
|
|
it('shows a streak only while it is still alive', () => {
|
|
expect(currentStreak(null, '2026-09-21')).toBe(0);
|
|
expect(currentStreak(played('2026-09-21', 2), '2026-09-21')).toBe(2);
|
|
expect(currentStreak(played('2026-09-20', 2), '2026-09-21')).toBe(2);
|
|
expect(currentStreak(played('2026-09-18', 9), '2026-09-21')).toBe(0);
|
|
});
|
|
});
|