Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions app/src/features/course/components/course-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ function CourseCard({
</button>
{isOpen ? (
<ul className="divide-y divide-border border-t border-border">
{course.steps.map((step) => (
{course.steps.map((step, index) => (
<li key={step.stepOrder}>
<CourseStepRow courseId={course.courseId} step={step} />
<CourseStepRow courseId={course.courseId} displayOrder={index + 1} step={step} />
</li>
))}
</ul>
Expand Down Expand Up @@ -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);

Expand All @@ -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 ? <LockIcon aria-hidden="true" className="size-4" /> : step.stepOrder}
{isLocked ? <LockIcon aria-hidden="true" className="size-4" /> : displayOrder}
</span>
);

const body = (
<span className="min-w-0 flex-1">
<span className="block text-xs font-semibold text-ink-muted">
STEP {step.stepOrder} · {step.estimatedMinutes}분
STEP {displayOrder} · {step.estimatedMinutes}분
</span>
<span
className={`mt-0.5 block truncate text-base font-semibold ${
Expand Down
24 changes: 24 additions & 0 deletions app/src/test/course-page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ const courseCompleted: CourseItem = {
],
};

/** stepOrder는 코스 무관 전역 순번이라 두 번째 이후 코스는 1보다 큰 값에서 시작한다(이슈 290). */
const secondCourseWithGlobalStepOffset: CourseItem = {
courseId: 2,
title: "디자인 패턴",
category: "CS",
steps: [
{ stepOrder: 13, topic: "생성 패턴 개요와 싱글턴", estimatedMinutes: 10, state: "SOLVABLE" },
{ stepOrder: 14, topic: "팩토리 메서드", estimatedMinutes: 10, state: "LOCKED" },
],
};

describe("CoursePage", () => {
beforeEach(() => {
vi.mocked(getCourses).mockReset();
Expand Down Expand Up @@ -176,4 +187,17 @@ describe("CoursePage", () => {

expect(screen.queryByText("배열")).not.toBeInTheDocument();
});

it("전역 stepOrder가 아니라 코스 안 순번으로 STEP 번호를 표시한다", async () => {
vi.mocked(getCourses).mockResolvedValue({ items: [secondCourseWithGlobalStepOffset] });

render(<CoursePage />);

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();
});
});
Loading