diff --git a/app/src/features/course/components/course-page.tsx b/app/src/features/course/components/course-page.tsx
index e6105c9..ef276da 100644
--- a/app/src/features/course/components/course-page.tsx
+++ b/app/src/features/course/components/course-page.tsx
@@ -176,9 +176,9 @@ function CourseCard({
{isOpen ? (
- {course.steps.map((step) => (
+ {course.steps.map((step, index) => (
-
-
+
))}
@@ -210,7 +210,15 @@ function isCourseCompleted(course: CourseItem): boolean {
return course.steps.length > 0 && course.steps.every((step) => step.state === "COMPLETED");
}
-function CourseStepRow({ courseId, step }: { courseId: number; step: CourseStep }) {
+function CourseStepRow({
+ courseId,
+ displayOrder,
+ step,
+}: {
+ courseId: number;
+ displayOrder: number;
+ step: CourseStep;
+}) {
const isLocked = step.state === "LOCKED";
const href = getStepHref(courseId, step);
@@ -220,14 +228,14 @@ function CourseStepRow({ courseId, step }: { courseId: number; step: CourseStep
isLocked ? "bg-surface-muted text-ink-muted" : "bg-primary text-primary-fg"
}`}
>
- {isLocked ? : step.stepOrder}
+ {isLocked ? : displayOrder}
);
const body = (
- STEP {step.stepOrder} · {step.estimatedMinutes}분
+ STEP {displayOrder} · {step.estimatedMinutes}분
{
beforeEach(() => {
vi.mocked(getCourses).mockReset();
@@ -176,4 +187,17 @@ describe("CoursePage", () => {
expect(screen.queryByText("배열")).not.toBeInTheDocument();
});
+
+ it("전역 stepOrder가 아니라 코스 안 순번으로 STEP 번호를 표시한다", async () => {
+ vi.mocked(getCourses).mockResolvedValue({ items: [secondCourseWithGlobalStepOffset] });
+
+ render();
+
+ await screen.findByText("생성 패턴 개요와 싱글턴");
+
+ expect(screen.getByText(/STEP 1 ·/)).toBeInTheDocument();
+ expect(screen.getByText(/STEP 2 ·/)).toBeInTheDocument();
+ expect(screen.queryByText(/STEP 13/)).not.toBeInTheDocument();
+ expect(screen.queryByText(/STEP 14/)).not.toBeInTheDocument();
+ });
});