fix(admin-ui): patch site config updates instead of replacing
Some checks failed
CI / Banner Lint & Typecheck (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / API Lint (push) Has been cancelled
CI / API Tests (push) Has been cancelled
CI / Scanner Lint (push) Has been cancelled
CI / Scanner Tests (push) Has been cancelled
CI / Banner Tests (push) Has been cancelled
CI / Banner Build (push) Has been cancelled
CI / Admin UI Typecheck (push) Has been cancelled
CI / Admin UI Tests (push) Has been cancelled
CI / Admin UI Build (push) Has been cancelled
Some checks failed
CI / Banner Lint & Typecheck (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / API Lint (push) Has been cancelled
CI / API Tests (push) Has been cancelled
CI / Scanner Lint (push) Has been cancelled
CI / Scanner Tests (push) Has been cancelled
CI / Banner Tests (push) Has been cancelled
CI / Banner Build (push) Has been cancelled
CI / Admin UI Typecheck (push) Has been cancelled
CI / Admin UI Tests (push) Has been cancelled
CI / Admin UI Build (push) Has been cancelled
The admin UI sends partial SiteConfig bodies from Configuration and Banner Builder tabs. Using PUT replaced omitted fields with backend defaults, which reset default_language to null whenever banner_config was saved. Switch updateSiteConfig() to PATCH so omitted fields are preserved, make the new default_language field optional for older config shapes, and add a regression test that ensures partial updates do not use PUT.
This commit is contained in:
@@ -38,7 +38,7 @@ export async function updateSiteConfig(
|
||||
siteId: string,
|
||||
body: Partial<SiteConfig>,
|
||||
): Promise<SiteConfig> {
|
||||
const { data } = await apiClient.put<SiteConfig>(`/sites/${siteId}/config`, body);
|
||||
const { data } = await apiClient.patch<SiteConfig>(`/sites/${siteId}/config`, body);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
31
apps/admin-ui/src/test/sites-api.test.ts
Normal file
31
apps/admin-ui/src/test/sites-api.test.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
const apiClient = {
|
||||
get: vi.fn(),
|
||||
post: vi.fn(),
|
||||
patch: vi.fn(),
|
||||
put: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
};
|
||||
|
||||
vi.mock('../api/client', () => ({
|
||||
default: apiClient,
|
||||
}));
|
||||
|
||||
describe('sites API client', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('partially updates site config with PATCH so omitted fields are preserved', async () => {
|
||||
apiClient.patch.mockResolvedValue({ data: { id: 'cfg-1' } });
|
||||
|
||||
const { updateSiteConfig } = await import('../api/sites');
|
||||
await updateSiteConfig('site-1', { banner_config: { displayMode: 'corner_popup' } });
|
||||
|
||||
expect(apiClient.patch).toHaveBeenCalledWith('/sites/site-1/config', {
|
||||
banner_config: { displayMode: 'corner_popup' },
|
||||
});
|
||||
expect(apiClient.put).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -125,7 +125,7 @@ export interface SiteConfig {
|
||||
banner_config: BannerConfig | null;
|
||||
privacy_policy_url: string | null;
|
||||
terms_url: string | null;
|
||||
default_language: string | null;
|
||||
default_language?: string | null;
|
||||
consent_expiry_days: number;
|
||||
scan_enabled: boolean;
|
||||
scan_frequency_hours: number;
|
||||
|
||||
Reference in New Issue
Block a user