mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-06 12:52:19 +00:00
Extract alert webhook destinations runtime owner
This commit is contained in:
@@ -250,13 +250,16 @@ serialization,
|
||||
override normalization plus resource-backed override projection, and
|
||||
`frontend-modern/src/features/alerts/useAlertDestinationsState.ts` for
|
||||
notification destination reload and persistence.
|
||||
`frontend-modern/src/features/alerts/useAlertWebhookDestinationsState.ts` now
|
||||
owns webhook load/mutate/test flow,
|
||||
`frontend-modern/src/features/alerts/useAlertDestinationsTabState.ts` now owns
|
||||
webhook load/mutate/test flow plus destination test actions, while
|
||||
destination test actions plus retry orchestration around that webhook runtime,
|
||||
while
|
||||
`frontend-modern/src/features/alerts/tabs/DestinationsTab.tsx` stays the
|
||||
destinations render shell. Future config cleanup should extend the config
|
||||
transport hook, the config model, the override-projection hook, or the
|
||||
destinations runtime hook based on which subsystem actually owns the behavior
|
||||
instead of letting the broader configuration hook absorb all three concerns
|
||||
instead of letting the broader configuration hook absorb all four concerns
|
||||
again.
|
||||
The email destination provider picker now follows that same split:
|
||||
`frontend-modern/src/components/Alerts/useEmailProviderSelectState.ts` owns
|
||||
|
||||
@@ -451,8 +451,10 @@ serialization, `frontend-modern/src/features/alerts/useAlertOverridesState.ts`
|
||||
for override projection and thresholds-facing resource selectors, and
|
||||
`frontend-modern/src/features/alerts/useAlertDestinationsState.ts` for
|
||||
notification destination reload and persistence.
|
||||
`frontend-modern/src/features/alerts/useAlertWebhookDestinationsState.ts` now
|
||||
owns webhook runtime, and
|
||||
`frontend-modern/src/features/alerts/useAlertDestinationsTabState.ts` now owns
|
||||
webhook runtime and destination test actions while
|
||||
destination test actions plus retry orchestration while
|
||||
`frontend-modern/src/features/alerts/tabs/DestinationsTab.tsx` stays the
|
||||
render shell. Future cleanup should extend the transport hook, config model,
|
||||
override hook, or destinations runtime hook based on the true owner, not move
|
||||
|
||||
+4
-51
@@ -100,25 +100,6 @@ describe('useAlertDestinationsTabState', () => {
|
||||
] as never);
|
||||
vi.mocked(NotificationsAPI.testNotification).mockResolvedValue({ success: true } as never);
|
||||
vi.mocked(NotificationsAPI.testWebhook).mockResolvedValue({ success: true } as never);
|
||||
vi.mocked(NotificationsAPI.createWebhook).mockResolvedValue({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
} as never);
|
||||
vi.mocked(NotificationsAPI.updateWebhook).mockResolvedValue({
|
||||
enabled: false,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager Updated',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
} as never);
|
||||
vi.mocked(NotificationsAPI.deleteWebhook).mockResolvedValue({ success: true } as never);
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useAlertDestinationsTabState({
|
||||
@@ -153,37 +134,9 @@ describe('useAlertDestinationsTabState', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
await result.addWebhook({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
});
|
||||
expect(result.webhooks().map((hook) => hook.id)).toEqual(['hook-1', 'hook-2']);
|
||||
|
||||
await result.updateWebhook({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
});
|
||||
expect(result.webhooks().find((hook) => hook.id === 'hook-2')).toEqual(
|
||||
expect.objectContaining({ enabled: false, name: 'Pager Updated' }),
|
||||
);
|
||||
|
||||
await result.testWebhook('hook-2');
|
||||
expect(NotificationsAPI.testNotification).toHaveBeenCalledWith({
|
||||
type: 'webhook',
|
||||
webhookId: 'hook-2',
|
||||
});
|
||||
|
||||
await result.deleteWebhook('hook-1');
|
||||
expect(result.webhooks().map((hook) => hook.id)).toEqual(['hook-2']);
|
||||
expect(result.webhooks()).toEqual([
|
||||
expect.objectContaining({ id: 'hook-1', service: 'generic' }),
|
||||
]);
|
||||
|
||||
result.updateApprise({ mode: 'http', serverUrl: 'https://apprise.internal' });
|
||||
expect(result.appriseState()).toEqual(
|
||||
@@ -193,7 +146,7 @@ describe('useAlertDestinationsTabState', () => {
|
||||
result.handleRetry();
|
||||
expect(onRetryLoad).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => expect(NotificationsAPI.getWebhooks).toHaveBeenCalledTimes(2));
|
||||
expect(notificationStore.success).toHaveBeenCalled();
|
||||
expect(notificationStore.success).toHaveBeenCalledTimes(2);
|
||||
expect(showErrorWithDetail).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import { renderHook, waitFor } from '@solidjs/testing-library';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { NotificationsAPI } from '@/api/notifications';
|
||||
import { notificationStore } from '@/stores/notifications';
|
||||
import { showErrorWithDetail } from '@/utils/toast';
|
||||
|
||||
import { useAlertWebhookDestinationsState } from '../useAlertWebhookDestinationsState';
|
||||
|
||||
vi.mock('@/api/notifications', () => ({
|
||||
NotificationsAPI: {
|
||||
createWebhook: vi.fn(),
|
||||
deleteWebhook: vi.fn(),
|
||||
getWebhooks: vi.fn(),
|
||||
testNotification: vi.fn(),
|
||||
testWebhook: vi.fn(),
|
||||
updateWebhook: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/stores/notifications', () => ({
|
||||
notificationStore: {
|
||||
error: vi.fn(),
|
||||
success: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/logger', () => ({
|
||||
logger: {
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/toast', () => ({
|
||||
showErrorWithDetail: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('useAlertWebhookDestinationsState', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(NotificationsAPI.createWebhook).mockReset();
|
||||
vi.mocked(NotificationsAPI.deleteWebhook).mockReset();
|
||||
vi.mocked(NotificationsAPI.getWebhooks).mockReset();
|
||||
vi.mocked(NotificationsAPI.testNotification).mockReset();
|
||||
vi.mocked(NotificationsAPI.testWebhook).mockReset();
|
||||
vi.mocked(NotificationsAPI.updateWebhook).mockReset();
|
||||
vi.mocked(notificationStore.error).mockReset();
|
||||
vi.mocked(notificationStore.success).mockReset();
|
||||
vi.mocked(showErrorWithDetail).mockReset();
|
||||
});
|
||||
|
||||
it('owns webhook load, mutation, and test runtime for alert destinations', async () => {
|
||||
vi.mocked(NotificationsAPI.getWebhooks).mockResolvedValue([
|
||||
{
|
||||
enabled: true,
|
||||
headers: {},
|
||||
id: 'hook-1',
|
||||
method: 'POST',
|
||||
name: 'Ops',
|
||||
url: 'https://hooks.example.test/ops',
|
||||
},
|
||||
] as never);
|
||||
vi.mocked(NotificationsAPI.testNotification).mockResolvedValue({ success: true } as never);
|
||||
vi.mocked(NotificationsAPI.createWebhook).mockResolvedValue({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
} as never);
|
||||
vi.mocked(NotificationsAPI.updateWebhook).mockResolvedValue({
|
||||
enabled: false,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager Updated',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
} as never);
|
||||
vi.mocked(NotificationsAPI.deleteWebhook).mockResolvedValue({ success: true } as never);
|
||||
|
||||
const { result } = renderHook(() => useAlertWebhookDestinationsState());
|
||||
|
||||
await waitFor(() => expect(NotificationsAPI.getWebhooks).toHaveBeenCalledTimes(1));
|
||||
expect(result.webhooks()).toEqual([
|
||||
expect.objectContaining({ id: 'hook-1', service: 'generic' }),
|
||||
]);
|
||||
|
||||
await result.addWebhook({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
});
|
||||
expect(result.webhooks().map((hook) => hook.id)).toEqual(['hook-1', 'hook-2']);
|
||||
|
||||
await result.updateWebhook({
|
||||
enabled: true,
|
||||
headers: {},
|
||||
id: 'hook-2',
|
||||
method: 'POST',
|
||||
name: 'Pager',
|
||||
service: 'slack',
|
||||
url: 'https://hooks.example.test/pager',
|
||||
});
|
||||
expect(result.webhooks().find((hook) => hook.id === 'hook-2')).toEqual(
|
||||
expect.objectContaining({ enabled: false, name: 'Pager Updated' }),
|
||||
);
|
||||
|
||||
await result.testWebhook('hook-2');
|
||||
expect(NotificationsAPI.testNotification).toHaveBeenCalledWith({
|
||||
type: 'webhook',
|
||||
webhookId: 'hook-2',
|
||||
});
|
||||
|
||||
await result.deleteWebhook('hook-1');
|
||||
expect(result.webhooks().map((hook) => hook.id)).toEqual(['hook-2']);
|
||||
|
||||
await result.loadWebhooks();
|
||||
expect(NotificationsAPI.getWebhooks).toHaveBeenCalledTimes(2);
|
||||
expect(notificationStore.success).toHaveBeenCalled();
|
||||
expect(showErrorWithDetail).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createMemo, createSignal, onMount, type Accessor } from 'solid-js';
|
||||
import { createMemo, createSignal, type Accessor } from 'solid-js';
|
||||
|
||||
import { NotificationsAPI, type AppriseConfig, type Webhook } from '@/api/notifications';
|
||||
import { NotificationsAPI, type AppriseConfig } from '@/api/notifications';
|
||||
import { notificationStore } from '@/stores/notifications';
|
||||
import { logger } from '@/utils/logger';
|
||||
import { showErrorWithDetail } from '@/utils/toast';
|
||||
@@ -10,17 +10,11 @@ import {
|
||||
getAlertDestinationsAppriseValidationError,
|
||||
getAlertDestinationsEmailTestFailure,
|
||||
getAlertDestinationsEmailTestSuccess,
|
||||
getAlertDestinationsWebhookLoadError,
|
||||
} from '@/utils/alertDestinationsPresentation';
|
||||
import {
|
||||
getAlertWebhookMutationFailure,
|
||||
getAlertWebhookMutationSuccess,
|
||||
getAlertWebhookTestFailure,
|
||||
getAlertWebhookTestSuccess,
|
||||
} from '@/utils/alertWebhookPresentation';
|
||||
|
||||
import { parseAppriseTargets } from './helpers';
|
||||
import type { UIAppriseConfig, UIEmailConfig } from './types';
|
||||
import { useAlertWebhookDestinationsState } from './useAlertWebhookDestinationsState';
|
||||
|
||||
export interface AlertDestinationsTabStateProps {
|
||||
emailConfig: Accessor<UIEmailConfig>;
|
||||
@@ -32,23 +26,15 @@ export interface AlertDestinationsTabStateProps {
|
||||
onRetryLoad: () => void;
|
||||
}
|
||||
|
||||
const normalizeWebhook = (webhook: Webhook): Webhook => ({
|
||||
...webhook,
|
||||
service: webhook.service || 'generic',
|
||||
});
|
||||
|
||||
export function useAlertDestinationsTabState(props: AlertDestinationsTabStateProps) {
|
||||
const [webhooks, setWebhooks] = createSignal<Webhook[]>([]);
|
||||
const [webhookLoadError, setWebhookLoadError] = createSignal<string | null>(null);
|
||||
const [isLoadingWebhooks, setIsLoadingWebhooks] = createSignal(true);
|
||||
const [testingEmail, setTestingEmail] = createSignal(false);
|
||||
const [testingApprise, setTestingApprise] = createSignal(false);
|
||||
const [testingWebhook, setTestingWebhook] = createSignal<string | null>(null);
|
||||
const webhookState = useAlertWebhookDestinationsState();
|
||||
|
||||
const isLoading = createMemo(
|
||||
() => props.isLoadingDestinations() || isLoadingWebhooks() || props.isRetrying(),
|
||||
() => props.isLoadingDestinations() || webhookState.isLoadingWebhooks() || props.isRetrying(),
|
||||
);
|
||||
const hasLoadError = createMemo(() => props.configLoadError() || webhookLoadError());
|
||||
const hasLoadError = createMemo(() => props.configLoadError() || webhookState.webhookLoadError());
|
||||
const appriseState = createMemo(() => props.appriseConfig());
|
||||
|
||||
const updateApprise = (partial: Partial<UIAppriseConfig>) => {
|
||||
@@ -73,24 +59,6 @@ export function useAlertDestinationsTabState(props: AlertDestinationsTabStatePro
|
||||
};
|
||||
};
|
||||
|
||||
const loadWebhooks = async () => {
|
||||
setWebhookLoadError(null);
|
||||
setIsLoadingWebhooks(true);
|
||||
try {
|
||||
const hooks = await NotificationsAPI.getWebhooks();
|
||||
setWebhooks(hooks.map(normalizeWebhook));
|
||||
} catch (error) {
|
||||
logger.error('Failed to load webhooks:', error);
|
||||
setWebhookLoadError(getAlertDestinationsWebhookLoadError());
|
||||
} finally {
|
||||
setIsLoadingWebhooks(false);
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
void loadWebhooks();
|
||||
});
|
||||
|
||||
const testEmailConfig = async () => {
|
||||
setTestingEmail(true);
|
||||
try {
|
||||
@@ -143,88 +111,21 @@ export function useAlertDestinationsTabState(props: AlertDestinationsTabStatePro
|
||||
}
|
||||
};
|
||||
|
||||
const testWebhook = async (webhookId: string, webhookData?: Omit<Webhook, 'id'>) => {
|
||||
setTestingWebhook(webhookId);
|
||||
try {
|
||||
if (webhookData) {
|
||||
await NotificationsAPI.testWebhook(webhookData);
|
||||
} else {
|
||||
await NotificationsAPI.testNotification({ type: 'webhook', webhookId });
|
||||
}
|
||||
notificationStore.success(getAlertWebhookTestSuccess());
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : getAlertWebhookTestFailure();
|
||||
const detail = (error as Error & { detail?: string })?.detail;
|
||||
showErrorWithDetail(message, detail);
|
||||
} finally {
|
||||
setTestingWebhook(null);
|
||||
}
|
||||
};
|
||||
|
||||
const addWebhook = async (webhook: Omit<Webhook, 'id'>) => {
|
||||
try {
|
||||
const created = await NotificationsAPI.createWebhook(webhook);
|
||||
setWebhooks((current) => [...current, normalizeWebhook(created)]);
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('add'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to add webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('add'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateWebhook = async (webhook: Webhook) => {
|
||||
try {
|
||||
const updated = await NotificationsAPI.updateWebhook(webhook.id, webhook);
|
||||
setWebhooks((current) =>
|
||||
current.map((entry) => (entry.id === webhook.id ? normalizeWebhook(updated) : entry)),
|
||||
);
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('update'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to update webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('update'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteWebhook = async (id: string) => {
|
||||
try {
|
||||
await NotificationsAPI.deleteWebhook(id);
|
||||
setWebhooks((current) => current.filter((entry) => entry.id !== id));
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('delete'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('delete'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRetry = () => {
|
||||
props.onRetryLoad();
|
||||
void loadWebhooks();
|
||||
void webhookState.loadWebhooks();
|
||||
};
|
||||
|
||||
return {
|
||||
addWebhook,
|
||||
appriseState,
|
||||
deleteWebhook,
|
||||
handleRetry,
|
||||
hasLoadError,
|
||||
isLoading,
|
||||
isLoadingWebhooks,
|
||||
loadWebhooks,
|
||||
testApprise,
|
||||
testEmailConfig,
|
||||
testWebhook,
|
||||
testingApprise,
|
||||
testingEmail,
|
||||
testingWebhook,
|
||||
updateApprise,
|
||||
updateWebhook,
|
||||
webhookLoadError,
|
||||
webhooks,
|
||||
...webhookState,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
import { createSignal, onMount } from 'solid-js';
|
||||
|
||||
import { NotificationsAPI, type Webhook } from '@/api/notifications';
|
||||
import { notificationStore } from '@/stores/notifications';
|
||||
import { logger } from '@/utils/logger';
|
||||
import { showErrorWithDetail } from '@/utils/toast';
|
||||
import { getAlertDestinationsWebhookLoadError } from '@/utils/alertDestinationsPresentation';
|
||||
import {
|
||||
getAlertWebhookMutationFailure,
|
||||
getAlertWebhookMutationSuccess,
|
||||
getAlertWebhookTestFailure,
|
||||
getAlertWebhookTestSuccess,
|
||||
} from '@/utils/alertWebhookPresentation';
|
||||
|
||||
const normalizeWebhook = (webhook: Webhook): Webhook => ({
|
||||
...webhook,
|
||||
service: webhook.service || 'generic',
|
||||
});
|
||||
|
||||
export function useAlertWebhookDestinationsState() {
|
||||
const [webhooks, setWebhooks] = createSignal<Webhook[]>([]);
|
||||
const [webhookLoadError, setWebhookLoadError] = createSignal<string | null>(null);
|
||||
const [isLoadingWebhooks, setIsLoadingWebhooks] = createSignal(true);
|
||||
const [testingWebhook, setTestingWebhook] = createSignal<string | null>(null);
|
||||
|
||||
const loadWebhooks = async () => {
|
||||
setWebhookLoadError(null);
|
||||
setIsLoadingWebhooks(true);
|
||||
try {
|
||||
const hooks = await NotificationsAPI.getWebhooks();
|
||||
setWebhooks(hooks.map(normalizeWebhook));
|
||||
} catch (error) {
|
||||
logger.error('Failed to load webhooks:', error);
|
||||
setWebhookLoadError(getAlertDestinationsWebhookLoadError());
|
||||
} finally {
|
||||
setIsLoadingWebhooks(false);
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
void loadWebhooks();
|
||||
});
|
||||
|
||||
const testWebhook = async (webhookId: string, webhookData?: Omit<Webhook, 'id'>) => {
|
||||
setTestingWebhook(webhookId);
|
||||
try {
|
||||
if (webhookData) {
|
||||
await NotificationsAPI.testWebhook(webhookData);
|
||||
} else {
|
||||
await NotificationsAPI.testNotification({ type: 'webhook', webhookId });
|
||||
}
|
||||
notificationStore.success(getAlertWebhookTestSuccess());
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : getAlertWebhookTestFailure();
|
||||
const detail = (error as Error & { detail?: string })?.detail;
|
||||
showErrorWithDetail(message, detail);
|
||||
} finally {
|
||||
setTestingWebhook(null);
|
||||
}
|
||||
};
|
||||
|
||||
const addWebhook = async (webhook: Omit<Webhook, 'id'>) => {
|
||||
try {
|
||||
const created = await NotificationsAPI.createWebhook(webhook);
|
||||
setWebhooks((current) => [...current, normalizeWebhook(created)]);
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('add'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to add webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('add'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateWebhook = async (webhook: Webhook) => {
|
||||
try {
|
||||
const updated = await NotificationsAPI.updateWebhook(webhook.id, webhook);
|
||||
setWebhooks((current) =>
|
||||
current.map((entry) => (entry.id === webhook.id ? normalizeWebhook(updated) : entry)),
|
||||
);
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('update'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to update webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('update'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteWebhook = async (id: string) => {
|
||||
try {
|
||||
await NotificationsAPI.deleteWebhook(id);
|
||||
setWebhooks((current) => current.filter((entry) => entry.id !== id));
|
||||
notificationStore.success(getAlertWebhookMutationSuccess('delete'));
|
||||
} catch (error) {
|
||||
logger.error('Failed to delete webhook:', error);
|
||||
notificationStore.error(
|
||||
error instanceof Error ? error.message : getAlertWebhookMutationFailure('delete'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
addWebhook,
|
||||
deleteWebhook,
|
||||
isLoadingWebhooks,
|
||||
loadWebhooks,
|
||||
testWebhook,
|
||||
testingWebhook,
|
||||
updateWebhook,
|
||||
webhookLoadError,
|
||||
webhooks,
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import alertsConfigurationModelSource from '@/features/alerts/alertsConfiguratio
|
||||
import alertOverridesStateSource from '@/features/alerts/useAlertOverridesState.ts?raw';
|
||||
import alertDestinationsStateSource from '@/features/alerts/useAlertDestinationsState.ts?raw';
|
||||
import alertDestinationsTabStateSource from '@/features/alerts/useAlertDestinationsTabState.ts?raw';
|
||||
import alertWebhookDestinationsStateSource from '@/features/alerts/useAlertWebhookDestinationsState.ts?raw';
|
||||
import alertAcknowledgementStateSource from '@/features/alerts/useAlertAcknowledgementState.ts?raw';
|
||||
import alertHistoryStateSource from '@/features/alerts/useAlertHistoryState.ts?raw';
|
||||
import alertIncidentTimelineStateSource from '@/features/alerts/useAlertIncidentTimelineState.ts?raw';
|
||||
@@ -231,9 +232,16 @@ describe('tab path helpers', () => {
|
||||
expect(alertDestinationsStateSource).toContain('NotificationsAPI.getEmailConfig');
|
||||
expect(alertDestinationsStateSource).toContain('NotificationsAPI.updateEmailConfig');
|
||||
expect(alertDestinationsTabStateSource).toContain('export function useAlertDestinationsTabState');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.testNotification');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertDestinationsTabStateSource).toContain('useAlertWebhookDestinationsState');
|
||||
expect(alertDestinationsTabStateSource).not.toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertDestinationsTabStateSource).not.toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertWebhookDestinationsStateSource).toContain(
|
||||
'export function useAlertWebhookDestinationsState',
|
||||
);
|
||||
expect(alertWebhookDestinationsStateSource).toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertWebhookDestinationsStateSource).toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertWebhookDestinationsStateSource).toContain('NotificationsAPI.testNotification');
|
||||
expect(alertsPageSource).toContain(
|
||||
"import { HistoryTab } from '@/features/alerts/tabs/HistoryTab';",
|
||||
);
|
||||
|
||||
@@ -330,6 +330,7 @@ import alertsConfigurationModelSource from '@/features/alerts/alertsConfiguratio
|
||||
import alertOverridesStateSource from '@/features/alerts/useAlertOverridesState.ts?raw';
|
||||
import alertDestinationsStateSource from '@/features/alerts/useAlertDestinationsState.ts?raw';
|
||||
import alertDestinationsTabStateSource from '@/features/alerts/useAlertDestinationsTabState.ts?raw';
|
||||
import alertWebhookDestinationsStateSource from '@/features/alerts/useAlertWebhookDestinationsState.ts?raw';
|
||||
import alertAcknowledgementStateSource from '@/features/alerts/useAlertAcknowledgementState.ts?raw';
|
||||
import alertHistoryStateSource from '@/features/alerts/useAlertHistoryState.ts?raw';
|
||||
import alertIncidentTimelineStateSource from '@/features/alerts/useAlertIncidentTimelineState.ts?raw';
|
||||
@@ -2810,10 +2811,18 @@ describe('frontend resource type boundaries', () => {
|
||||
expect(alertDestinationsStateSource).toContain('NotificationsAPI.getEmailConfig');
|
||||
expect(alertDestinationsStateSource).toContain('NotificationsAPI.updateEmailConfig');
|
||||
expect(alertDestinationsTabStateSource).toContain('export function useAlertDestinationsTabState');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.testNotification');
|
||||
expect(alertDestinationsTabStateSource).toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertDestinationsTabStateSource).toContain('getAlertDestinationsWebhookLoadError');
|
||||
expect(alertDestinationsTabStateSource).toContain('useAlertWebhookDestinationsState');
|
||||
expect(alertDestinationsTabStateSource).not.toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertDestinationsTabStateSource).not.toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertWebhookDestinationsStateSource).toContain(
|
||||
'export function useAlertWebhookDestinationsState',
|
||||
);
|
||||
expect(alertWebhookDestinationsStateSource).toContain('NotificationsAPI.getWebhooks');
|
||||
expect(alertWebhookDestinationsStateSource).toContain('NotificationsAPI.createWebhook');
|
||||
expect(alertWebhookDestinationsStateSource).toContain(
|
||||
'getAlertDestinationsWebhookLoadError',
|
||||
);
|
||||
expect(alertDestinationsTabSource).toContain('getAlertDestinationsLoadErrorBanner');
|
||||
expect(alertDestinationsTabSource).toContain('getAlertDestinationsAppriseTargetsHelp');
|
||||
expect(alertDestinationsTabSource).toContain('getAlertDestinationsAppriseTestLabel');
|
||||
|
||||
Reference in New Issue
Block a user