fix: improve tester timeouts and telegram proxy config
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { act, create, type ReactTestInstance } from 'react-test-renderer';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { ToastProvider } from '../components/Toast.js';
|
||||
import NotificationSettings from './NotificationSettings.js';
|
||||
|
||||
const { apiMock } = vi.hoisted(() => ({
|
||||
apiMock: {
|
||||
getRuntimeSettings: vi.fn(),
|
||||
updateRuntimeSettings: vi.fn(),
|
||||
testNotification: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../api.js', () => ({
|
||||
api: apiMock,
|
||||
}));
|
||||
|
||||
function collectText(node: ReactTestInstance): string {
|
||||
return (node.children || []).map((child) => {
|
||||
if (typeof child === 'string') return child;
|
||||
return collectText(child);
|
||||
}).join('');
|
||||
}
|
||||
|
||||
async function flushMicrotasks() {
|
||||
await act(async () => {
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
describe('NotificationSettings', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
apiMock.getRuntimeSettings.mockResolvedValue({
|
||||
webhookUrl: '',
|
||||
barkUrl: '',
|
||||
webhookEnabled: true,
|
||||
barkEnabled: true,
|
||||
serverChanEnabled: false,
|
||||
telegramEnabled: true,
|
||||
telegramApiBaseUrl: 'https://tg-proxy.example.com',
|
||||
telegramChatId: '-1001234567890',
|
||||
telegramBotTokenMasked: '1234****token',
|
||||
smtpEnabled: false,
|
||||
smtpHost: '',
|
||||
smtpPort: 587,
|
||||
smtpSecure: false,
|
||||
smtpUser: '',
|
||||
smtpFrom: '',
|
||||
smtpTo: '',
|
||||
notifyCooldownSec: 300,
|
||||
});
|
||||
apiMock.updateRuntimeSettings.mockResolvedValue({
|
||||
success: true,
|
||||
telegramApiBaseUrl: 'https://proxy.example.com/custom',
|
||||
telegramBotTokenMasked: '1234****token',
|
||||
});
|
||||
apiMock.testNotification.mockResolvedValue({ success: true });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('loads and saves telegram api base url', async () => {
|
||||
let root: ReturnType<typeof create> | null = null;
|
||||
try {
|
||||
await act(async () => {
|
||||
root = create(
|
||||
<MemoryRouter>
|
||||
<ToastProvider>
|
||||
<NotificationSettings />
|
||||
</ToastProvider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
const proxyInput = root.root.find((node) => (
|
||||
node.type === 'input'
|
||||
&& node.props.placeholder === '例如: https://your-proxy.example.com'
|
||||
));
|
||||
expect(proxyInput.props.value).toBe('https://tg-proxy.example.com');
|
||||
|
||||
await act(async () => {
|
||||
proxyInput.props.onChange({ target: { value: 'https://proxy.example.com/custom/' } });
|
||||
});
|
||||
|
||||
const saveButton = root.root.find((node) => (
|
||||
node.type === 'button'
|
||||
&& typeof node.props.onClick === 'function'
|
||||
&& collectText(node).includes('保存通知设置')
|
||||
));
|
||||
await act(async () => {
|
||||
saveButton.props.onClick();
|
||||
});
|
||||
await flushMicrotasks();
|
||||
|
||||
expect(apiMock.updateRuntimeSettings).toHaveBeenCalledWith(expect.objectContaining({
|
||||
telegramApiBaseUrl: 'https://proxy.example.com/custom/',
|
||||
}));
|
||||
} finally {
|
||||
root?.unmount();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -10,6 +10,7 @@ type RuntimeSettings = {
|
||||
barkEnabled: boolean;
|
||||
serverChanEnabled: boolean;
|
||||
telegramEnabled: boolean;
|
||||
telegramApiBaseUrl: string;
|
||||
telegramChatId: string;
|
||||
smtpEnabled: boolean;
|
||||
smtpHost: string;
|
||||
@@ -32,6 +33,7 @@ export default function NotificationSettings() {
|
||||
barkEnabled: true,
|
||||
serverChanEnabled: false,
|
||||
telegramEnabled: false,
|
||||
telegramApiBaseUrl: 'https://api.telegram.org',
|
||||
telegramChatId: '',
|
||||
smtpEnabled: false,
|
||||
smtpHost: '',
|
||||
@@ -74,6 +76,7 @@ export default function NotificationSettings() {
|
||||
barkEnabled: runtimeInfo.barkEnabled ?? true,
|
||||
serverChanEnabled: !!runtimeInfo.serverChanEnabled,
|
||||
telegramEnabled: !!runtimeInfo.telegramEnabled,
|
||||
telegramApiBaseUrl: runtimeInfo.telegramApiBaseUrl || 'https://api.telegram.org',
|
||||
telegramChatId: runtimeInfo.telegramChatId || '',
|
||||
smtpEnabled: !!runtimeInfo.smtpEnabled,
|
||||
smtpHost: runtimeInfo.smtpHost || '',
|
||||
@@ -110,6 +113,7 @@ export default function NotificationSettings() {
|
||||
barkEnabled: runtime.barkEnabled,
|
||||
serverChanEnabled: runtime.serverChanEnabled,
|
||||
telegramEnabled: runtime.telegramEnabled,
|
||||
telegramApiBaseUrl: runtime.telegramApiBaseUrl,
|
||||
telegramChatId: runtime.telegramChatId,
|
||||
smtpEnabled: runtime.smtpEnabled,
|
||||
smtpHost: runtime.smtpHost,
|
||||
@@ -325,6 +329,19 @@ export default function NotificationSettings() {
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: '16px 20px', opacity: runtime.telegramEnabled ? 1 : 0.6, transition: 'opacity 0.2s' }}>
|
||||
<div style={{ gridColumn: '1 / -1' }}>
|
||||
<div style={{ fontSize: 13, fontWeight: 500, marginBottom: 8, color: 'var(--color-text-secondary)' }}>Telegram API Base URL</div>
|
||||
<input
|
||||
value={runtime.telegramApiBaseUrl}
|
||||
onChange={(e) => setRuntime((prev) => ({ ...prev, telegramApiBaseUrl: e.target.value }))}
|
||||
placeholder="例如: https://your-proxy.example.com"
|
||||
style={inputStyle}
|
||||
disabled={!runtime.telegramEnabled}
|
||||
/>
|
||||
<div style={{ marginTop: 8, fontSize: 12, color: 'var(--color-text-muted)' }}>
|
||||
留空或使用默认值时直连官方 Telegram API;如需国内反代,可填写反代前缀。
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 13, fontWeight: 500, marginBottom: 8, color: 'var(--color-text-secondary)' }}>Telegram Chat ID</div>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user