- workshop-app: 메모 탭과 동일 구조의 "개요" 탭(textarea) 추가 — project.description 직접 편집, 채팅 set_description으로 쓴 내용은 응답 후 softRefresh로 갱신 - readme.md 자동생성(syncProjectReadmes) 철회 — 파일탭이 산만해져서 사용자 지정으로 탭 방식으로 전환, 생성된 개요 폴더들도 삭제. description/set_description은 유지 - server.ts IMAGE_TYPES: 텍스트 계열(.md/.txt/.csv 등) charset=utf-8 명시 — charset 없이 text/plain으로 뱉으면 브라우저가 latin1로 해석해 한글이 전부 깨짐(실측) Co-Authored-By: Claude Code <noreply@anthropic.com>
39 lines
1.9 KiB
TypeScript
39 lines
1.9 KiB
TypeScript
// workshop-storage.ts 프로젝트 개요 문서(projectToReadme) 단위 테스트 (2026-09-23)
|
||
// 대시보드 데이터 → 마크다운 'get' 출력. readme 파일 생성은 철회됨(개요 탭으로 이동).
|
||
import test from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import { projectToReadme, WorkshopProject } from '../src/gateway/routes/workshop-storage.js';
|
||
|
||
function sampleProject(over: Partial<WorkshopProject> = {}): WorkshopProject {
|
||
return {
|
||
id: 'proj_test',
|
||
name: 'SO-101 로봇팔',
|
||
parts: [
|
||
{ id: 'p1', name: 'STS3215 서보', qty: 12, unitPrice: 20000, status: '검토중', memo: 'Leader 6 + Follower 6', links: [{ id: 'lk1', label: '구매처', url: 'https://example.com' }] },
|
||
{ id: 'p2', name: '나사 세트', qty: 1, unitPrice: 0, status: '보유', memo: '', links: [] },
|
||
],
|
||
phases: [
|
||
{ id: 'ph1', name: '준비', tasks: [{ id: 't1', text: 'STL 다운로드', done: true }, { id: 't2', text: '출력', done: false }] },
|
||
],
|
||
notes: 'K2로 출력한다',
|
||
...over,
|
||
};
|
||
}
|
||
|
||
test('projectToReadme: 개요 섹션은 description이 있을 때만', () => {
|
||
const withDesc = projectToReadme(sampleProject({ description: 'LeRobot SO-101 오픈소스 로봇팔 조립 프로젝트' }));
|
||
assert.ok(withDesc.includes('# SO-101 로봇팔'));
|
||
assert.ok(withDesc.includes('## 개요\nLeRobot SO-101 오픈소스 로봇팔 조립 프로젝트'));
|
||
|
||
const withoutDesc = projectToReadme(sampleProject());
|
||
assert.ok(!withoutDesc.includes('## 개요'));
|
||
// 부품/작업/메모는 항상 실린다
|
||
assert.ok(withoutDesc.includes('- [검토중] STS3215 서보 × 12 = 240,000원'));
|
||
assert.ok(withoutDesc.includes('- [x] STL 다운로드'));
|
||
assert.ok(withoutDesc.includes('## 메모'));
|
||
});
|
||
|
||
test('projectToReadme: 부품 링크를 들여쓰기로 실음', () => {
|
||
const md = projectToReadme(sampleProject());
|
||
assert.ok(md.includes(' - 구매처: https://example.com'));
|
||
}); |