fix(FN-2404): scope onboarding first-task creation to active project
- Guard onboarding first-task creation when no project is selected - Pass projectId to createTask so onboarding tasks are created in the active project - Update AppModals wiring tests to verify projectId forwarding for selected and unselected states - Expand onboarding modal and flow regression tests to assert project-scoped task creation calls
This commit is contained in:
@@ -1197,6 +1197,10 @@ export function ModelOnboardingModal({
|
||||
}, [completeOnboarding, completedSteps, skippedSteps]);
|
||||
|
||||
const handleCreateFirstTask = useCallback(async () => {
|
||||
if (!projectId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const trimmedDescription = firstTaskDescription.trim();
|
||||
if (!trimmedDescription) {
|
||||
setTaskCreationError("Please enter a task description.");
|
||||
@@ -1209,7 +1213,7 @@ export function ModelOnboardingModal({
|
||||
let success = false;
|
||||
|
||||
try {
|
||||
const createdTask = await createTask({ description: trimmedDescription });
|
||||
const createdTask = await createTask({ description: trimmedDescription }, projectId);
|
||||
setInlineCreatedTask(createdTask);
|
||||
setShowTaskCreated(true);
|
||||
trackOnboardingEvent("onboarding:first-task-created", { taskId: createdTask?.id });
|
||||
@@ -1229,7 +1233,7 @@ export function ModelOnboardingModal({
|
||||
if (success) {
|
||||
void completeOnboarding();
|
||||
}
|
||||
}, [firstTaskDescription, addToast, completeOnboarding]);
|
||||
}, [projectId, firstTaskDescription, addToast, completeOnboarding]);
|
||||
|
||||
// Handle first task CTA - mark complete, close modal, then open new task
|
||||
const handleOpenNewTask = useCallback(async () => {
|
||||
|
||||
@@ -213,7 +213,7 @@ describe("AppModals", () => {
|
||||
});
|
||||
|
||||
describe("ModelOnboardingModal wiring", () => {
|
||||
it("passes project context and setup-wizard callback into onboarding modal", () => {
|
||||
it("passes empty project id and setup-wizard callback into onboarding modal when no project is selected", () => {
|
||||
const handleAddProject = vi.fn();
|
||||
const manager = { ...mockModalManager, modelOnboardingOpen: true };
|
||||
|
||||
@@ -240,6 +240,32 @@ describe("AppModals", () => {
|
||||
expect(props.projectId).toBe("");
|
||||
expect(props.onOpenSetupWizard).toBe(handleAddProject);
|
||||
});
|
||||
|
||||
it("passes active project id into onboarding modal when a project is selected", () => {
|
||||
const manager = { ...mockModalManager, modelOnboardingOpen: true };
|
||||
|
||||
render(
|
||||
<AppModals
|
||||
projectId="proj_123"
|
||||
tasks={[]}
|
||||
projects={[]}
|
||||
currentProject={null}
|
||||
addToast={vi.fn()}
|
||||
toasts={mockToasts}
|
||||
removeToast={vi.fn()}
|
||||
modalManager={manager}
|
||||
projectActions={{ handleAddProject: vi.fn(), handleSetupComplete: vi.fn(), handleModelOnboardingComplete: vi.fn() }}
|
||||
taskHandlers={{ handleModalCreate: vi.fn(), handlePlanningTaskCreated: vi.fn(), handlePlanningTasksCreated: vi.fn(), handleSubtaskTasksCreated: vi.fn(), handleGitHubImport: vi.fn() }}
|
||||
taskOperations={{ moveTask: vi.fn(), deleteTask: vi.fn(), mergeTask: vi.fn(), retryTask: vi.fn(), duplicateTask: vi.fn() }}
|
||||
deepLink={{ handleDetailClose: vi.fn() }}
|
||||
settings={mockSettings}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(mockModelOnboardingModalProps).toHaveBeenCalledTimes(1);
|
||||
const props = mockModelOnboardingModalProps.mock.calls[0][0];
|
||||
expect(props.projectId).toBe("proj_123");
|
||||
});
|
||||
});
|
||||
|
||||
describe("ScheduledTasksModal projectId forwarding", () => {
|
||||
|
||||
@@ -1476,6 +1476,16 @@ describe("ModelOnboardingModal", () => {
|
||||
|
||||
expect(screen.queryByTestId("onboarding-task-error")).toBeNull();
|
||||
expect(mockCreateTask).toHaveBeenCalledTimes(2);
|
||||
expect(mockCreateTask).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
{ description: "Build auth" },
|
||||
"proj_123",
|
||||
);
|
||||
expect(mockCreateTask).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
{ description: "Build auth" },
|
||||
"proj_123",
|
||||
);
|
||||
});
|
||||
|
||||
it("disables first-task submit button while creating the task", async () => {
|
||||
|
||||
@@ -762,7 +762,10 @@ describe("onboarding flow integration", () => {
|
||||
await simulateFirstTaskCreation(renderResult, "Ship onboarding telemetry");
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockCreateTask).toHaveBeenCalledWith({ description: "Ship onboarding telemetry" });
|
||||
expect(mockCreateTask).toHaveBeenCalledWith(
|
||||
{ description: "Ship onboarding telemetry" },
|
||||
"proj_123",
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockMarkOnboardingCompleted).toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user