vibe-proxy/frontend/tests/timezoneLabel.test.ts
2026-08-24 00:10:41 +02:00

71 lines
2.7 KiB
TypeScript

/**
* Timezone labelling, and the guard against the Asia/Shanghai hardcode
* returning.
*
* Codex reset-credit expiry was rendered in a fixed GMT+8 while every other
* timestamp on the same page used the browser's timezone — so one credit
* appeared twice, in two timezones, on one screen.
*/
import { describe, expect, test } from 'vitest';
import i18n from '@/i18n';
import * as resetCredits from '@/utils/quota/resetCredits';
import { formatUtcOffsetLabel, resolveTimeZoneLabel } from '@/utils/time/timezone';
describe('formatUtcOffsetLabel', () => {
test('renders whole-hour offsets east and west of UTC', () => {
expect(formatUtcOffsetLabel(480)).toBe('GMT+8');
expect(formatUtcOffsetLabel(-300)).toBe('GMT-5');
expect(formatUtcOffsetLabel(720)).toBe('GMT+12');
expect(formatUtcOffsetLabel(-720)).toBe('GMT-12');
});
test('renders half- and quarter-hour offsets', () => {
expect(formatUtcOffsetLabel(330)).toBe('GMT+5:30');
expect(formatUtcOffsetLabel(-570)).toBe('GMT-9:30');
expect(formatUtcOffsetLabel(345)).toBe('GMT+5:45');
});
test('UTC itself carries no sign', () => {
expect(formatUtcOffsetLabel(0)).toBe('GMT');
expect(formatUtcOffsetLabel(-0)).toBe('GMT');
});
test('a non-finite offset degrades to a bare GMT rather than "GMT+NaN"', () => {
expect(formatUtcOffsetLabel(Number.NaN)).toBe('GMT');
});
});
describe('resolveTimeZoneLabel', () => {
test('produces a well-formed label whatever timezone the runner is in', () => {
expect(resolveTimeZoneLabel()).toMatch(/^GMT([+-]\d{1,2}(:\d{2})?)?$/);
});
test('reflects the offset of the instant it is given, not of "now"', () => {
// A DST-observing zone answers differently in January than in July, so the
// label has to follow the date the timestamps are being rendered for.
const january = new Date(2026, 0, 15, 12);
const july = new Date(2026, 6, 15, 12);
expect(resolveTimeZoneLabel(january)).toBe(
formatUtcOffsetLabel(-january.getTimezoneOffset())
);
expect(resolveTimeZoneLabel(july)).toBe(formatUtcOffsetLabel(-july.getTimezoneOffset()));
});
});
describe('Asia/Shanghai hardcode', () => {
test('is gone from the reset-credit module', () => {
expect('formatShanghaiDateTime' in resetCredits).toBe(false);
expect(resetCredits.normalizeCodexResetCreditsPayload).toBeDefined();
});
test('the expiry heading interpolates a timezone in all four locales', async () => {
for (const locale of ['en', 'zh-CN', 'zh-TW', 'ru']) {
await i18n.changeLanguage(locale);
const label = i18n.t('codex_quota.reset_credits_expiry_label', { timezone: 'GMT+8' });
expect(label).toContain('GMT+8');
expect(label).not.toContain('{{');
}
await i18n.changeLanguage('en');
});
});