diff --git a/frontend/src/__tests__/settings.test.ts b/frontend/src/__tests__/settings.test.ts index a5cd806ca..0b320eab0 100644 --- a/frontend/src/__tests__/settings.test.ts +++ b/frontend/src/__tests__/settings.test.ts @@ -965,6 +965,34 @@ describe('Settings Module', () => { expect(coverageSentFor('savings-plans-compute')).toBe(20); }); + test('a rejected global PUT leaves the coverage dirty and sends no service PUTs', async () => { + await loadWithCoverage50(); + (document.getElementById('setting-default-coverage') as HTMLInputElement).value = '70'; + (api.updateConfig as jest.Mock).mockRejectedValueOnce(new Error('boom')); + + await saveGlobalSettings({ preventDefault: jest.fn() } as unknown as Event); + + expect(api.updateServiceConfig).not.toHaveBeenCalled(); + expect(isUnsavedChanges()).toBe(true); + }); + + test('an SP card coverage whose service PUT failed stays dirty and is resent', async () => { + await loadWithCoverage50(); + (document.getElementById('aws-savings-plans-compute-coverage') as HTMLInputElement).value = '70'; + (api.updateServiceConfig as jest.Mock).mockImplementation(async (provider: string, svc: string) => { + if (provider === 'aws' && svc === 'savings-plans-compute') throw new Error('sp failed'); + }); + + await saveGlobalSettings({ preventDefault: jest.fn() } as unknown as Event); + expect(isUnsavedChanges()).toBe(true); + + (api.updateServiceConfig as jest.Mock).mockClear().mockResolvedValue(undefined); + await saveGlobalSettings({ preventDefault: jest.fn() } as unknown as Event); + + expect(coverageSentFor('savings-plans-compute')).toBe(70); + expect(isUnsavedChanges()).toBe(false); + }); + test('an empty global coverage field is rejected instead of saving 0', async () => { await loadWithCoverage50(); (document.getElementById('setting-default-coverage') as HTMLInputElement).value = ''; diff --git a/frontend/src/settings.ts b/frontend/src/settings.ts index ba9e6e88d..306426843 100644 --- a/frontend/src/settings.ts +++ b/frontend/src/settings.ts @@ -3591,9 +3591,7 @@ export async function saveGlobalSettings(e: Event): Promise { // controls. Read from the DOM when the card has the controls; fall back // to the base row value (or the global default) otherwise so RI and // Azure/GCP cards continue to inherit the global settings. - let coverage = defaultCoverageChanged - ? settings.default_coverage - : (base?.coverage ?? settings.default_coverage); + let coverage = base?.coverage ?? settings.default_coverage; let enabled = base?.enabled ?? true; if ('coverageId' in field && field.coverageId) { const rawCov = byId(field.coverageId)?.value ?? '';