Strengthen slice 1 localize coverage after notices and portraits drifted the shell.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,50 @@
|
|||||||
|
|
||||||
Сводка: [`../reviewed.md`](../reviewed.md). Индекс среза: [`README.md`](README.md).
|
Сводка: [`../reviewed.md`](../reviewed.md). Индекс среза: [`README.md`](README.md).
|
||||||
|
|
||||||
|
## Перепроверка среза 1 (после notices / portraits / Krea)
|
||||||
|
|
||||||
|
- **Фазы:** 0–4
|
||||||
|
- **Проверен на:** `PENDING`, 2026-08-21
|
||||||
|
- **Пути:** `src/HSchool.Client`, `src/HSchool.Protocol`, `src/HSchool.Content`,
|
||||||
|
`src/HSchool.Server/Game`, `src/HSchool.Server/Api/ModEndpoints.cs`,
|
||||||
|
`src/HSchool.Server/Api/SchoolEndpoints.cs`, `src/HSchool.Server/Net`,
|
||||||
|
`tests/HSchool.Content.Tests`, `tests/HSchool.Protocol.Tests`,
|
||||||
|
`tests/HSchool.AppHost.Tests/SchoolApiTests.cs`, `tests/HSchool.AppHost.Tests/GameSocketTests.cs`,
|
||||||
|
`tests/HSchool.AppHost.Tests/ServiceabilityTests.cs`
|
||||||
|
- **Итог:** перепроверка; `git log d087486..HEAD` по путям среза непустой (портреты, notices,
|
||||||
|
Krea, сцена). Обещания фаз 0–4 целы. Усилен тест `localize()` под два `.manager`. Код не
|
||||||
|
чинился. AppHost socket/API не гонялись (не трогали). Фазы 🔄/⬜ не закрывались.
|
||||||
|
|
||||||
|
Что подтверждено (после дрейфа):
|
||||||
|
|
||||||
|
- PixiJS нет в `package.json` и в клиентском коде. Overview: вкладки Карта/Люди, дерево,
|
||||||
|
локация с четырьмя секциями, клиентский фильтр, `localize()`. Панель общих событий по-прежнему
|
||||||
|
снята (фаза 8 / `near-term.md`); notices — модалки/тосты, не возврат ленты.
|
||||||
|
- `SchoolWorker` — `LongRunning`, `MaxCatchUpSteps = 5`. Супервизор `World` не трогает.
|
||||||
|
`SchoolContentUnavailableException` + `persist: false` + `RememberIncompatible`. Outbox
|
||||||
|
`DropOldest`; `WaitToReadAsync` переносится. `modal.ts` резолвит явно; `.dialog--screen` —
|
||||||
|
`height: fit-content`; `DefaultStartDate` UTC; меню патчит `card.update`.
|
||||||
|
- Каталог/карта: last-wins, parent/abstract, патчи, связность, пустая комната, отказ без двора
|
||||||
|
(15 зелёных в `MapValidation`/`ExamplePack`/`Inheritance`). `MapSnapshot` round-trip + size
|
||||||
|
(4 зелёных в Protocol). Кодек / `protocol.ts` / `docs/protocol.md` — один снимок (протокол v10).
|
||||||
|
- `core` в create заблокирован (`createSchoolDialog.test.ts`). Клиентский filter дерева и
|
||||||
|
пустые секции локации — `gameScreen.test.ts`.
|
||||||
|
|
||||||
|
Дописано на этом проходе:
|
||||||
|
|
||||||
|
- `gameScreen.test.ts` — `localize()` смотрит overview (не manage): вкладки + четыре секции и
|
||||||
|
empty-строки до/после смены языка
|
||||||
|
|
||||||
|
Исправлено:
|
||||||
|
|
||||||
|
- ничего в прод-коде: расхождений с дизайном среза 1, которые надо чинить, не нашлось.
|
||||||
|
|
||||||
|
Открытое:
|
||||||
|
|
||||||
|
- ветка не слита: основное дерево на `main`, но грязное (untracked срез 12 + dirty
|
||||||
|
README/AGENTS) — без stash, ждёт чистый main.
|
||||||
|
- соседний `review/slice-2-recheck` тоже ждёт чистый main — не сливать чужое.
|
||||||
|
|
||||||
## Перепроверка среза 1 (после одежды / сессии / общения)
|
## Перепроверка среза 1 (после одежды / сессии / общения)
|
||||||
|
|
||||||
- **Фазы:** 0–4
|
- **Фазы:** 0–4
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
| Срез | Проверен на | Журнал |
|
| Срез | Проверен на | Журнал |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Срез 1. Оболочка и карта | `d087486` | [01-shell](01-shell/reviewed.md) |
|
| Срез 1. Оболочка и карта | `PENDING` | [01-shell](01-shell/reviewed.md) |
|
||||||
| Срез 2. Люди | `8108508` | [02-people](02-people/reviewed.md) |
|
| Срез 2. Люди | `8108508` | [02-people](02-people/reviewed.md) |
|
||||||
| Срез 3. Штат | `cf1403e` | [03-staffing](03-staffing/reviewed.md) |
|
| Срез 3. Штат | `cf1403e` | [03-staffing](03-staffing/reviewed.md) |
|
||||||
| Срез 4. Расписание | `01ef277` | [04-schedule](04-schedule/reviewed.md) |
|
| Срез 4. Расписание | `01ef277` | [04-schedule](04-schedule/reviewed.md) |
|
||||||
|
|||||||
@@ -35,6 +35,29 @@ vi.mock('../net/api.ts', async (importOriginal) => {
|
|||||||
|
|
||||||
const initial = getLocale();
|
const initial = getLocale();
|
||||||
|
|
||||||
|
function overviewPanel(root: HTMLElement, index: number): HTMLElement {
|
||||||
|
const overview = root.querySelectorAll(':scope > .manager')[0];
|
||||||
|
const panel = overview?.querySelectorAll(':scope > .panel')[index];
|
||||||
|
if (!(panel instanceof HTMLElement)) {
|
||||||
|
throw new Error('overview panel is missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapTabs(root: HTMLElement): HTMLButtonElement[] {
|
||||||
|
return [...overviewPanel(root, 0).querySelectorAll<HTMLButtonElement>('.panel__tab')];
|
||||||
|
}
|
||||||
|
|
||||||
|
function locationBody(root: HTMLElement): HTMLElement {
|
||||||
|
const body = overviewPanel(root, 1).querySelector(':scope > .panel__body');
|
||||||
|
if (!(body instanceof HTMLElement)) {
|
||||||
|
throw new Error('location panel is missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
function school(overrides: Partial<School> = {}): School {
|
function school(overrides: Partial<School> = {}): School {
|
||||||
return {
|
return {
|
||||||
id: 1,
|
id: 1,
|
||||||
@@ -174,18 +197,31 @@ describe('GameScreen location tree', () => {
|
|||||||
document.body.append(screen.element);
|
document.body.append(screen.element);
|
||||||
screen.show(school());
|
screen.show(school());
|
||||||
|
|
||||||
expect(screen.element.querySelector('.panel__section-title')?.textContent).toBe(t('locationItems'));
|
const location = locationBody(screen.element);
|
||||||
expect([...screen.element.querySelectorAll('.panel__empty')].map((node) => node.textContent)).toContain(
|
const titles = () => [...location.querySelectorAll('.panel__section-title')].map((node) => node.textContent);
|
||||||
t('itemsEmpty'),
|
const empties = () => [...location.querySelectorAll('.panel__empty')].map((node) => node.textContent);
|
||||||
);
|
const tabs = () => [...mapTabs(screen.element)].map((node) => node.textContent);
|
||||||
|
|
||||||
|
expect(tabs()).toEqual([t('mapTitle'), t('peopleTitle')]);
|
||||||
|
expect(titles()).toEqual([
|
||||||
|
t('locationItems'),
|
||||||
|
t('locationCharacters'),
|
||||||
|
t('locationActivities'),
|
||||||
|
t('locationPositions'),
|
||||||
|
]);
|
||||||
|
expect(empties()).toEqual([t('itemsEmpty'), t('charactersEmpty'), t('activitiesEmpty'), t('positionsEmpty')]);
|
||||||
|
|
||||||
setLocale('ru');
|
setLocale('ru');
|
||||||
screen.localize();
|
screen.localize();
|
||||||
|
|
||||||
expect(screen.element.querySelector('.panel__section-title')?.textContent).toBe(t('locationItems'));
|
expect(tabs()).toEqual([t('mapTitle'), t('peopleTitle')]);
|
||||||
expect([...screen.element.querySelectorAll('.panel__empty')].map((node) => node.textContent)).toContain(
|
expect(titles()).toEqual([
|
||||||
t('itemsEmpty'),
|
t('locationItems'),
|
||||||
);
|
t('locationCharacters'),
|
||||||
|
t('locationActivities'),
|
||||||
|
t('locationPositions'),
|
||||||
|
]);
|
||||||
|
expect(empties()).toEqual([t('itemsEmpty'), t('charactersEmpty'), t('activitiesEmpty'), t('positionsEmpty')]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user