fix: display main turn time in server timezone
This commit is contained in:
@@ -20,6 +20,7 @@ type NavigationFixture = {
|
||||
generalMeCalls: number;
|
||||
operations: string[];
|
||||
generalName?: string;
|
||||
generalTurnTime?: string;
|
||||
cityDefence?: number;
|
||||
cityState?: number;
|
||||
nationRate?: number;
|
||||
@@ -239,7 +240,7 @@ const generalContext = (state: NavigationFixture) => ({
|
||||
dex: [350, 100_000, 500_000, 1_000_000, 1_275_975],
|
||||
},
|
||||
items: { horse: null, weapon: null, book: null, item: null },
|
||||
turnTime: '0185-01-01T00:00:00.000Z',
|
||||
turnTime: state.generalTurnTime ?? '0185-01-01T00:00:00.000Z',
|
||||
},
|
||||
city: {
|
||||
id: 1,
|
||||
@@ -666,6 +667,66 @@ test('desktop menus preserve ref columns, prefix-safe routes, and controlled dro
|
||||
await persistArtifact(page, `${basePath.slice(1)}-desktop-1200`);
|
||||
});
|
||||
|
||||
test('main general card renders the next turn in the Seoul server timezone', async ({ page }) => {
|
||||
const state: NavigationFixture = {
|
||||
officerLevel: 0,
|
||||
permission: 0,
|
||||
nationLevel: 0,
|
||||
stage: 0,
|
||||
npcMode: 1,
|
||||
generalMeCalls: 0,
|
||||
operations: [],
|
||||
generalName: 'Administrator',
|
||||
generalTurnTime: '2026-08-13T00:07:06.713Z',
|
||||
currentYear: 179,
|
||||
currentMonth: 8,
|
||||
};
|
||||
await installFixture(page, state);
|
||||
await page.setViewportSize({ width: 1200, height: 900 });
|
||||
await waitForMain(page);
|
||||
|
||||
const title = page.locator('[data-main-target="general"] .general-title').first();
|
||||
await expect(title).toContainText('Administrator');
|
||||
await expect(title).toContainText('다음 턴 09:07');
|
||||
await expect(title).not.toContainText('00:07');
|
||||
|
||||
const desktopGeometry = await title.evaluate((element) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const style = getComputedStyle(element);
|
||||
return {
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
fontSize: style.fontSize,
|
||||
lineHeight: style.lineHeight,
|
||||
overflow: style.overflow,
|
||||
};
|
||||
});
|
||||
expect(desktopGeometry.width).toBeGreaterThan(0);
|
||||
expect(desktopGeometry.height).toBeGreaterThan(0);
|
||||
if (artifactRoot) {
|
||||
const target = resolve(artifactRoot);
|
||||
await mkdir(target, { recursive: true });
|
||||
await Promise.all([
|
||||
page.screenshot({ path: resolve(target, 'main-turn-time-seoul-desktop-1200.png'), fullPage: true }),
|
||||
writeFile(
|
||||
resolve(target, 'main-turn-time-seoul-desktop-1200.json'),
|
||||
`${JSON.stringify(desktopGeometry, null, 2)}\n`
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
await page.setViewportSize({ width: 500, height: 900 });
|
||||
const mobileTitle = page.locator('[data-main-target="general"] .general-title').first();
|
||||
await expect(mobileTitle).toContainText('다음 턴 09:07');
|
||||
expect(await mobileTitle.evaluate((element) => element.scrollWidth - element.clientWidth)).toBeLessThanOrEqual(0);
|
||||
if (artifactRoot) {
|
||||
await page.screenshot({
|
||||
path: resolve(artifactRoot, 'main-turn-time-seoul-mobile-500.png'),
|
||||
fullPage: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('pure NPC message senders are not rendered as reply targets', async ({ page }) => {
|
||||
const target = (generalId: number, generalName: string) => ({
|
||||
generalId,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { computed } from 'vue';
|
||||
import SkeletonLines from '../ui/SkeletonLines.vue';
|
||||
import LegacyProgressBar from '../ui/LegacyProgressBar.vue';
|
||||
import { formatSeoulHourMinute } from '../../utils/legacyDateTime';
|
||||
import { legacyExperiencePercent, ratioPercent } from '../../utils/legacyProgress';
|
||||
|
||||
interface GeneralStats {
|
||||
@@ -80,7 +81,7 @@ const experiencePercent = computed(() =>
|
||||
<div class="general-title">
|
||||
{{ props.general.name }} · 관직 {{ props.general.officerLevel }} · {{ props.general.age ?? '-' }}세 ·
|
||||
다음 턴
|
||||
{{ props.general.turnTime?.slice(11, 16) ?? '-' }}
|
||||
{{ props.general.turnTime ? formatSeoulHourMinute(props.general.turnTime) : '-' }}
|
||||
</div>
|
||||
|
||||
<div class="stat-progress-grid">
|
||||
|
||||
@@ -20,3 +20,5 @@ export const formatSeoulDateTime = (value: string | Date): string => {
|
||||
koreaTime.getUTCSeconds()
|
||||
)}`;
|
||||
};
|
||||
|
||||
export const formatSeoulHourMinute = (value: string | Date): string => formatSeoulDateTime(value).slice(11, 16);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { formatSeoulDateTime, formatSeoulHourMinute } from '../src/utils/legacyDateTime.ts';
|
||||
|
||||
void test('formats API UTC timestamps in the server Seoul timezone', () => {
|
||||
assert.equal(formatSeoulDateTime('2026-08-13T00:07:06.713Z'), '2026-08-13 09:07:06');
|
||||
assert.equal(formatSeoulHourMinute('2026-08-13T00:07:06.713Z'), '09:07');
|
||||
});
|
||||
|
||||
void test('keeps legacy timezone-less server timestamps unchanged', () => {
|
||||
assert.equal(formatSeoulDateTime('2026-08-13 09:07:06'), '2026-08-13 09:07:06');
|
||||
assert.equal(formatSeoulHourMinute('2026-08-13 09:07:06'), '09:07');
|
||||
});
|
||||
Reference in New Issue
Block a user