merge: 최신 main을 0.1.0 사전점검에 통합
This commit is contained in:
@@ -789,6 +789,30 @@ describe('admin operation API', () => {
|
||||
).rejects.toBeDefined();
|
||||
});
|
||||
|
||||
it('stores event season zero as the next season number', async () => {
|
||||
const harness = await buildCaller(
|
||||
async () => {
|
||||
throw new Error('not used');
|
||||
},
|
||||
{ adminRoles: ['admin.profiles.settings:che:2'], firstUserIsAdmin: false }
|
||||
);
|
||||
|
||||
await harness.caller.admin.profiles.updateMeta({
|
||||
profileName: 'che:2',
|
||||
patch: { nextSeasonIdx: 0 },
|
||||
reason: 'prepare event season',
|
||||
});
|
||||
expect(harness.updatedMetas.at(-1)).toMatchObject({ nextSeasonIdx: 0 });
|
||||
|
||||
await expect(
|
||||
harness.caller.admin.profiles.updateMeta({
|
||||
profileName: 'che:2',
|
||||
patch: { nextSeasonIdx: -1 },
|
||||
reason: 'reject negative season',
|
||||
})
|
||||
).rejects.toBeDefined();
|
||||
});
|
||||
|
||||
it('does not let a scenario-only operator combine a Git update with reset', async () => {
|
||||
const harness = await buildCaller(
|
||||
async () => {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
|
||||
import { RuntimeNavigationConfigStore } from '../src/navigation/runtimeNavigationConfig.js';
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
|
||||
const createTemporaryDirectory = async (): Promise<string> => {
|
||||
const directory = await fs.mkdtemp(path.join(os.tmpdir(), 'sammo-navigation-'));
|
||||
temporaryDirectories.push(directory);
|
||||
return directory;
|
||||
};
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(temporaryDirectories.splice(0).map((directory) => fs.rm(directory, { recursive: true })));
|
||||
});
|
||||
|
||||
describe('RuntimeNavigationConfigStore', () => {
|
||||
it('운영 override가 없으면 저장소 기본 메뉴를 읽는다', async () => {
|
||||
const store = new RuntimeNavigationConfigStore(
|
||||
'/definitely-missing/navigation.json',
|
||||
path.resolve(import.meta.dirname, '../../../resources/navigation.json')
|
||||
);
|
||||
|
||||
const config = await store.get();
|
||||
|
||||
expect(config.gateway.items.map((item) => item.label)).toEqual([
|
||||
'공지사항',
|
||||
'커뮤니티',
|
||||
'건의/제안/개발',
|
||||
'신고/문의',
|
||||
'자주 묻는 질문',
|
||||
'패치 내역',
|
||||
'Git Repo.',
|
||||
'위키',
|
||||
'공식 오픈 톡',
|
||||
'잡담 오픈 톡',
|
||||
]);
|
||||
expect(config.game.items.map((item) => (item.kind === 'split' ? item.main.label : item.label))).toEqual([
|
||||
'천통국 베팅',
|
||||
'세력일람',
|
||||
'장수일람',
|
||||
'명장일람',
|
||||
'연감',
|
||||
'게임 정보',
|
||||
'커뮤니티',
|
||||
'설문조사',
|
||||
]);
|
||||
});
|
||||
|
||||
it('프로세스를 재시작하지 않아도 운영 JSON 수정이 다음 조회에 반영된다', async () => {
|
||||
const directory = await createTemporaryDirectory();
|
||||
const overridePath = path.join(directory, 'navigation.json');
|
||||
const defaultPath = path.resolve(import.meta.dirname, '../../../resources/navigation.json');
|
||||
const raw = JSON.parse(await fs.readFile(defaultPath, 'utf8')) as {
|
||||
gateway: { items: Array<{ label: string }> };
|
||||
};
|
||||
await fs.writeFile(overridePath, JSON.stringify(raw));
|
||||
const store = new RuntimeNavigationConfigStore(overridePath, defaultPath);
|
||||
|
||||
expect((await store.get()).gateway.items[0]?.label).toBe('공지사항');
|
||||
raw.gateway.items[0]!.label = '운영 공지';
|
||||
await fs.writeFile(overridePath, JSON.stringify(raw));
|
||||
expect((await store.get()).gateway.items[0]?.label).toBe('운영 공지');
|
||||
});
|
||||
|
||||
it('실행 가능한 스크립트 URL과 목적지가 없는 링크를 거부한다', async () => {
|
||||
const directory = await createTemporaryDirectory();
|
||||
const overridePath = path.join(directory, 'navigation.json');
|
||||
const invalid = {
|
||||
version: 1,
|
||||
gateway: {
|
||||
brand: { label: '삼국지 모의전투 HiDCHe', to: '/' },
|
||||
items: [{ id: 'unsafe', label: '위험', href: 'javascript:alert(1)' }],
|
||||
},
|
||||
game: { items: [{ kind: 'link', id: 'empty', label: '빈 링크' }] },
|
||||
};
|
||||
await fs.writeFile(overridePath, JSON.stringify(invalid));
|
||||
const store = new RuntimeNavigationConfigStore(overridePath, overridePath);
|
||||
|
||||
await expect(store.get()).rejects.toThrow('메뉴 설정 파일이 올바르지 않습니다');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user