Skip to content

Commit ca48b87

Browse files
authored
fix: update template with noop returned undefined template (#11688)
* fix: doing a noop patch to templates resulted in 404 The patch response did not include the template. The UI required the template to be returned to form the new page path null is more explicit, and harder to make occur by mistake.
1 parent 75d70a9 commit ca48b87

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

enterprise/coderd/templates_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,44 @@ func TestTemplates(t *testing.T) {
687687
require.Empty(t, template.DeprecationMessage)
688688
require.False(t, template.Deprecated)
689689
})
690+
691+
// Create a template, remove the group, see if an owner can
692+
// still fetch the template.
693+
t.Run("GetOnEveryoneRemove", func(t *testing.T) {
694+
t.Parallel()
695+
owner, first := coderdenttest.New(t, &coderdenttest.Options{
696+
Options: &coderdtest.Options{
697+
IncludeProvisionerDaemon: true,
698+
TemplateScheduleStore: schedule.NewEnterpriseTemplateScheduleStore(agplUserQuietHoursScheduleStore()),
699+
},
700+
LicenseOptions: &coderdenttest.LicenseOptions{
701+
Features: license.Features{
702+
codersdk.FeatureAccessControl: 1,
703+
codersdk.FeatureTemplateRBAC: 1,
704+
},
705+
},
706+
})
707+
708+
client, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, rbac.RoleTemplateAdmin())
709+
version := coderdtest.CreateTemplateVersion(t, client, first.OrganizationID, nil)
710+
template := coderdtest.CreateTemplate(t, client, first.OrganizationID, version.ID)
711+
712+
ctx := testutil.Context(t, testutil.WaitMedium)
713+
err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
714+
UserPerms: nil,
715+
GroupPerms: map[string]codersdk.TemplateRole{
716+
// OrgID is the everyone ID
717+
first.OrganizationID.String(): codersdk.TemplateRoleDeleted,
718+
},
719+
})
720+
require.NoError(t, err)
721+
722+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
723+
defer cancel()
724+
725+
_, err = owner.Template(ctx, template.ID)
726+
require.NoError(t, err)
727+
})
690728
}
691729

692730
func TestTemplateACL(t *testing.T) {

site/src/api/api.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,16 @@ export const unarchiveTemplateVersion = async (templateVersionId: string) => {
414414
export const updateTemplateMeta = async (
415415
templateId: string,
416416
data: TypesGen.UpdateTemplateMeta,
417-
): Promise<TypesGen.Template> => {
417+
): Promise<TypesGen.Template | null> => {
418418
const response = await axios.patch<TypesGen.Template>(
419419
`/api/v2/templates/${templateId}`,
420420
data,
421421
);
422+
// On 304 response there is no data payload.
423+
if (response.status === 304) {
424+
return null;
425+
}
426+
422427
return response.data;
423428
};
424429

site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.tsx

+13-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,19 @@ export const TemplateSettingsPage: FC = () => {
2929
(data: UpdateTemplateMeta) => updateTemplateMeta(template.id, data),
3030
{
3131
onSuccess: async (data) => {
32-
// we use data.name because an admin may have updated templateName to something new
33-
await queryClient.invalidateQueries(
34-
templateByNameKey(orgId, data.name),
35-
);
32+
// This update has a chance to return a 304 which means nothing was updated.
33+
// In this case, the return payload will be empty and we should use the
34+
// original template data.
35+
if (!data) {
36+
data = template;
37+
} else {
38+
// Only invalid the query if data is returned, indicating at least one field was updated.
39+
//
40+
// we use data.name because an admin may have updated templateName to something new
41+
await queryClient.invalidateQueries(
42+
templateByNameKey(orgId, data.name),
43+
);
44+
}
3645
displaySuccess("Template updated successfully");
3746
navigate(`/templates/${data.name}`);
3847
},

0 commit comments

Comments
 (0)