Fix secrets dialog provider fallback loop

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-02 02:00:12 +00:00
1 parent 8e7ac6c69e
commit f5d7a13aba
2 files changed
+50 -6

No files matched your search

+36
View File
@@ -703,6 +703,42 @@ describe("Secrets page layout", () => {
});
});
it("opens the New secret dialog when provider queries fail", async () => {
mockSecretsApi.providers.mockRejectedValueOnce(new ApiError(403, "Providers unavailable"));
mockSecretsApi.providerConfigs.mockRejectedValueOnce(new ApiError(403, "Provider vaults unavailable"));
const root = createRoot(container);
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
await act(async () => {
root.render(
<MemoryRouter>
<QueryClientProvider client={queryClient}>
<Secrets />
</QueryClientProvider>
</MemoryRouter>,
);
});
await flushReact();
await flushReact();
const newSecretButton = Array.from(container.querySelectorAll("button")).find(
(button) => button.textContent?.includes("New secret"),
) as HTMLButtonElement | undefined;
await act(async () => {
newSecretButton?.click();
});
await flushReact();
expect(document.body.textContent).toContain("Create secret");
expect(document.body.textContent).toContain("Select a provider.");
await act(async () => {
root.unmount();
});
});
it("opens the each-user detail sheet with coverage and set-my-value actions", async () => {
const definition = makeUserSecretDefinition();
mockSecretsApi.listUserSecretDefinitions.mockResolvedValue([definition]);
+14 -6
View File
@@ -143,6 +143,12 @@ type SafeProviderErrorDetails = {
safeAlternative?: string;
};
const EMPTY_SECRETS: CompanySecret[] = [];
const EMPTY_USER_SECRET_DEFINITIONS: UserSecretDefinition[] = [];
const EMPTY_MY_USER_SECRETS: MyUserSecretEntry[] = [];
const EMPTY_SECRET_PROVIDERS: SecretProviderDescriptor[] = [];
const EMPTY_PROVIDER_CONFIGS: CompanySecretProviderConfig[] = [];
const PROVIDER_ORDER: SecretProvider[] = [
"local_encrypted",
"aws_secrets_manager",
@@ -693,11 +699,11 @@ export function Secrets() {
retry: false,
});
const secrets = secretsQuery.data ?? [];
const userDefinitions = userDefinitionsQuery.data ?? [];
const myUserSecrets = myUserSecretsQuery.data ?? [];
const providers = providersQuery.data ?? [];
const providerConfigs = providerConfigsQuery.data ?? [];
const secrets = secretsQuery.data ?? EMPTY_SECRETS;
const userDefinitions = userDefinitionsQuery.data ?? EMPTY_USER_SECRET_DEFINITIONS;
const myUserSecrets = myUserSecretsQuery.data ?? EMPTY_MY_USER_SECRETS;
const providers = providersQuery.data ?? EMPTY_SECRET_PROVIDERS;
const providerConfigs = providerConfigsQuery.data ?? EMPTY_PROVIDER_CONFIGS;
const selectedSecret = useMemo(
() => secrets.find((secret) => secret.id === selectedSecretId) ?? null,
[secrets, selectedSecretId],
@@ -1199,9 +1205,11 @@ export function Secrets() {
if (!createOpen) return;
const current = providerConfigs.find((config) => config.id === createForm.providerConfigId);
if (current?.provider === createForm.provider) return;
const nextProviderConfigId = getDefaultProviderConfigId(providerConfigs, createForm.provider);
if (nextProviderConfigId === createForm.providerConfigId) return;
setCreateForm((form) => ({
...form,
providerConfigId: getDefaultProviderConfigId(providerConfigs, form.provider),
providerConfigId: nextProviderConfigId,
}));
}, [createForm.provider, createForm.providerConfigId, createOpen, providerConfigs]);