Files
tiennm99 8450b75bce feat(daily): one panorama a day, the same for everyone, with a streak
/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.
2026-09-20 23:23:02 +07:00

25 lines
1.1 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { buildShareText, buildDailyShareText } from '../src/lib/share.js';
describe('buildShareText', () => {
it('draws the score as squares and links the region page', () => {
expect(buildShareText('Ha Noi', 4, '82m', 'https://example.test/game/hn')).toBe(
'VNGeoGuessr · Ha Noi\n🟩🟩🟩🟩⬜ 4/5 · 82m away\nhttps://example.test/game/hn'
);
});
it('clamps a score outside the ladder', () => {
expect(buildShareText('Vietnam', 9, '1.20km', 'u')).toContain('🟩🟩🟩🟩🟩 5/5');
expect(buildShareText('Vietnam', -1, '1.20km', 'u')).toContain('⬜⬜⬜⬜⬜ 0/5');
});
});
describe('buildDailyShareText', () => {
it('names the challenge and shows a streak once it is worth showing', () => {
expect(buildDailyShareText(12, 3, '150m', 1, 'https://example.test/daily')).toBe(
'VNGeoGuessr Daily #12\n🟩🟩🟩⬜⬜ 3/5 · 150m away\nhttps://example.test/daily'
);
expect(buildDailyShareText(12, 0, '40.00km', 4, 'u')).toContain('⬜⬜⬜⬜⬜ 0/5 · 40.00km away · 🔥 4 days');
});
});