From 91d4f8b59ba2f020dbd053d58629f0093938a2ad Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 15 Oct 2025 14:24:40 -0300 Subject: [PATCH] fix: use the selected version to check external auth (#20316) Fixes https://github.com/coder/coder/issues/20315 --- .../tasks/TaskPrompt/TaskPrompt.stories.tsx | 60 ++++++++++++++++++- .../modules/tasks/TaskPrompt/TaskPrompt.tsx | 21 ++++--- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/site/src/modules/tasks/TaskPrompt/TaskPrompt.stories.tsx b/site/src/modules/tasks/TaskPrompt/TaskPrompt.stories.tsx index 5577ff6d90..918df28d61 100644 --- a/site/src/modules/tasks/TaskPrompt/TaskPrompt.stories.tsx +++ b/site/src/modules/tasks/TaskPrompt/TaskPrompt.stories.tsx @@ -243,7 +243,6 @@ export const SelectTemplateVersion: Story = { export const OnError: Story = { decorators: [withGlobalSnackbar], beforeEach: () => { - spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); spyOn(API, "getTemplate").mockResolvedValue(MockTemplate); spyOn(API.experimental, "getTasks").mockResolvedValue(MockTasks); spyOn(API.experimental, "createTask").mockRejectedValue( @@ -349,3 +348,62 @@ export const ExternalAuthError: Story = { }); }, }; + +const tmplWithExternalAuth = { + ...MockTemplateVersion, + id: "2", + name: "With external", +}; + +export const CheckExternalAuthOnChangingVersions: Story = { + args: { + templates: [ + { + ...MockTemplate, + active_version_id: tmplWithExternalAuth.id, + }, + ], + }, + beforeEach: () => { + spyOn(API, "getTemplateVersions").mockResolvedValue([ + { + ...MockTemplateVersion, + id: "1", + name: "No external", + }, + tmplWithExternalAuth, + ]); + spyOn(API, "getTemplateVersionExternalAuth").mockImplementation( + (versionId: string) => { + return Promise.resolve( + versionId === tmplWithExternalAuth.id + ? [MockTemplateVersionExternalAuthGithub] + : [], + ); + }, + ); + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Renders external authentication", async () => { + await canvas.findByRole("button", { name: /connect to github/i }); + }); + + await step("Change into version without external auth", async () => { + const body = within(canvasElement.ownerDocument.body); + const versionSelect = await canvas.findByLabelText(/template version/i); + await userEvent.click(versionSelect); + const versionOption = await body.findByRole("option", { + name: /no external/i, + }); + await userEvent.click(versionOption); + }); + + await step("Don't render external authentication", async () => { + expect( + canvas.queryByRole("button", { name: /connect to github/i }), + ).not.toBeInTheDocument(); + }); + }, +}; diff --git a/site/src/modules/tasks/TaskPrompt/TaskPrompt.tsx b/site/src/modules/tasks/TaskPrompt/TaskPrompt.tsx index 1e9c2d2f49..643d9713a9 100644 --- a/site/src/modules/tasks/TaskPrompt/TaskPrompt.tsx +++ b/site/src/modules/tasks/TaskPrompt/TaskPrompt.tsx @@ -150,13 +150,6 @@ const CreateTaskForm: FC = ({ templates, onSuccess }) => { (t) => t.id === selectedTemplateId, ) as Template; - const { - externalAuth, - externalAuthError, - isPollingExternalAuth, - isLoadingExternalAuth, - } = useExternalAuth(selectedTemplate.active_version_id); - // Template versions const [selectedVersionId, setSelectedVersionId] = useState( selectedTemplate.active_version_id, @@ -192,6 +185,12 @@ const CreateTaskForm: FC = ({ templates, onSuccess }) => { }, [presetPrompt]); // External Auth + const { + externalAuth, + externalAuthError, + isPollingExternalAuth, + isLoadingExternalAuth, + } = useExternalAuth(selectedVersionId); const missedExternalAuth = externalAuth?.filter( (auth) => !auth.optional && !auth.authenticated, ); @@ -361,7 +360,7 @@ const CreateTaskForm: FC = ({ templates, onSuccess }) => {
{missedExternalAuth && ( )} @@ -408,19 +407,19 @@ const PromptSelectTrigger: FC = ({ }; type ExternalAuthButtonProps = { - template: Template; + versionId: string; missedExternalAuth: TemplateVersionExternalAuth[]; }; const ExternalAuthButtons: FC = ({ - template, + versionId, missedExternalAuth, }) => { const { startPollingExternalAuth, isPollingExternalAuth, externalAuthPollingState, - } = useExternalAuth(template.active_version_id); + } = useExternalAuth(versionId); const shouldRetry = externalAuthPollingState === "abandoned"; return missedExternalAuth.map((auth) => {