chore: 前端代码风格统一并清理未使用导入;移除过时的 PR 流程规则

This commit is contained in:
2026-09-03 17:16:08 +08:00
parent 934d2c1bc5
commit de91d7a882
7 changed files with 1120 additions and 397 deletions
+170 -73
View File
@@ -1,96 +1,193 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { Refine } from '@refinedev/core'
import { MemoryRouter } from 'react-router'
import { NetworkExitList } from './NetworkExitsPage'
import { afterEach, describe, expect, it, vi } from "vitest";
import {
cleanup,
fireEvent,
render,
screen,
waitFor,
within,
} from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Refine } from "@refinedev/core";
import { MemoryRouter } from "react-router";
import { NetworkExitList } from "./NetworkExitsPage";
afterEach(() => { cleanup(); vi.restoreAllMocks() })
afterEach(() => {
cleanup();
vi.restoreAllMocks();
});
const httpError = (message, status, body) => Object.assign(new Error(message), { status, body })
const httpError = (message, status, body) =>
Object.assign(new Error(message), { status, body });
const networkExit = { id: 'exit-a', protocol: 'socks5', host: 'proxy.example', port: 1080, username: 'proxy-user', password: 'plain-password', health_status: 'healthy', observed_public_ip: '203.0.113.1' }
const networkExit = {
id: "exit-a",
protocol: "socks5",
host: "proxy.example",
port: 1080,
username: "proxy-user",
password: "plain-password",
health_status: "healthy",
observed_public_ip: "203.0.113.1",
};
function provider(exits = [], overrides = {}) {
return {
getList: vi.fn(({ resource }) => Promise.resolve(resource === 'network-exits' ? { data: exits, total: exits.length } : { data: [], total: 0 })),
getList: vi.fn(({ resource }) =>
Promise.resolve(
resource === "network-exits"
? { data: exits, total: exits.length }
: { data: [], total: 0 },
),
),
create: vi.fn().mockResolvedValue({ data: networkExit }),
networkExitAction: vi.fn().mockResolvedValue(networkExit),
getOne: vi.fn(), getMany: vi.fn(), getManyReference: vi.fn(), update: vi.fn(), updateMany: vi.fn(), delete: vi.fn(), deleteMany: vi.fn(),
getOne: vi.fn(),
getMany: vi.fn(),
getManyReference: vi.fn(),
update: vi.fn(),
updateMany: vi.fn(),
delete: vi.fn(),
deleteMany: vi.fn(),
...overrides,
}
};
}
const renderExits = dataProvider => render(
<QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { retry: false } } })}>
<Refine dataProvider={dataProvider}>
<MemoryRouter><NetworkExitList /></MemoryRouter>
</Refine>
</QueryClientProvider>,
)
const renderExits = (dataProvider) =>
render(
<QueryClientProvider
client={
new QueryClient({ defaultOptions: { queries: { retry: false } } })
}
>
<Refine dataProvider={dataProvider}>
<MemoryRouter>
<NetworkExitList />
</MemoryRouter>
</Refine>
</QueryClientProvider>,
);
describe('NetworkExitList', () => {
it('shows the ordered empty-state instruction', async () => {
renderExits(provider())
expect(await screen.findByText(/创建并检测健康后/)).toBeTruthy()
})
describe("NetworkExitList", () => {
it("shows the ordered empty-state instruction", async () => {
renderExits(provider());
expect(await screen.findByText(/创建并检测健康后/)).toBeTruthy();
});
it('shows stored credentials and runs an explicit health check', async () => {
const dataProvider = provider([networkExit])
renderExits(dataProvider)
it("shows stored credentials and runs an explicit health check", async () => {
const dataProvider = provider([networkExit]);
renderExits(dataProvider);
expect((await screen.findAllByText(/proxy-user/)).length).toBeGreaterThan(0)
expect((await screen.findAllByText(/plain-password/)).length).toBeGreaterThan(0)
fireEvent.click(screen.getAllByRole('button', { name: '检测' })[0])
await waitFor(() => expect(dataProvider.networkExitAction).toHaveBeenCalledWith('exit-a', 'check'))
})
expect((await screen.findAllByText(/proxy-user/)).length).toBeGreaterThan(
0,
);
expect(
(await screen.findAllByText(/plain-password/)).length,
).toBeGreaterThan(0);
fireEvent.click(screen.getAllByRole("button", { name: "检测" })[0]);
await waitFor(() =>
expect(dataProvider.networkExitAction).toHaveBeenCalledWith(
"exit-a",
"check",
),
);
});
it('creates with plain credentials and closes on success', async () => {
const dataProvider = provider()
renderExits(dataProvider)
it("creates with plain credentials and closes on success", async () => {
const dataProvider = provider();
renderExits(dataProvider);
fireEvent.click(await screen.findByRole('button', { name: '创建网络出口' }))
const dialog = screen.getByRole('dialog')
fireEvent.change(within(dialog).getByRole('textbox', { name: '主机' }), { target: { value: 'proxy.example' } })
fireEvent.change(within(dialog).getByRole('spinbutton', { name: '端口' }), { target: { value: '1080' } })
fireEvent.change(within(dialog).getByRole('textbox', { name: '用户名(可选)' }), { target: { value: 'proxy-user' } })
fireEvent.change(within(dialog).getByRole('textbox', { name: '密码(可选)' }), { target: { value: 'plain-password' } })
fireEvent.click(within(dialog).getByRole('button', { name: '创建网络出口' }))
fireEvent.click(
await screen.findByRole("button", { name: "创建网络出口" }),
);
const dialog = screen.getByRole("dialog");
fireEvent.change(within(dialog).getByRole("textbox", { name: "主机" }), {
target: { value: "proxy.example" },
});
fireEvent.change(within(dialog).getByRole("spinbutton", { name: "端口" }), {
target: { value: "1080" },
});
fireEvent.change(
within(dialog).getByRole("textbox", { name: "用户名(可选)" }),
{ target: { value: "proxy-user" } },
);
fireEvent.change(
within(dialog).getByRole("textbox", { name: "密码(可选)" }),
{ target: { value: "plain-password" } },
);
fireEvent.click(
within(dialog).getByRole("button", { name: "创建网络出口" }),
);
await waitFor(() => expect(dataProvider.create).toHaveBeenCalledWith({ resource: 'network-exits', variables: {
protocol: 'socks5', host: 'proxy.example', port: 1080, username: 'proxy-user', password: 'plain-password', expected_public_ip: '', expected_region: '',
} }))
await waitFor(() => expect(screen.queryByRole('dialog')).toBeNull())
})
await waitFor(() =>
expect(dataProvider.create).toHaveBeenCalledWith({
resource: "network-exits",
variables: {
protocol: "socks5",
host: "proxy.example",
port: 1080,
username: "proxy-user",
password: "plain-password",
expected_public_ip: "",
expected_region: "",
},
}),
);
await waitFor(() => expect(screen.queryByRole("dialog")).toBeNull());
});
it('keeps the create modal open after a failure', async () => {
const dataProvider = provider([], { create: vi.fn().mockRejectedValue(new Error('创建失败')) })
renderExits(dataProvider)
it("keeps the create modal open after a failure", async () => {
const dataProvider = provider([], {
create: vi.fn().mockRejectedValue(new Error("创建失败")),
});
renderExits(dataProvider);
fireEvent.click(await screen.findByRole('button', { name: '创建网络出口' }))
const dialog = screen.getByRole('dialog')
fireEvent.change(within(dialog).getByRole('textbox', { name: '主机' }), { target: { value: 'proxy.example' } })
fireEvent.change(within(dialog).getByRole('spinbutton', { name: '端口' }), { target: { value: '1080' } })
fireEvent.click(within(dialog).getByRole('button', { name: '创建网络出口' }))
fireEvent.click(
await screen.findByRole("button", { name: "创建网络出口" }),
);
const dialog = screen.getByRole("dialog");
fireEvent.change(within(dialog).getByRole("textbox", { name: "主机" }), {
target: { value: "proxy.example" },
});
fireEvent.change(within(dialog).getByRole("spinbutton", { name: "端口" }), {
target: { value: "1080" },
});
fireEvent.click(
within(dialog).getByRole("button", { name: "创建网络出口" }),
);
expect((await within(dialog).findByRole('alert')).textContent).toContain('创建失败')
expect(screen.getByRole('dialog')).toBeTruthy()
})
expect((await within(dialog).findByRole("alert")).textContent).toContain(
"创建失败",
);
expect(screen.getByRole("dialog")).toBeTruthy();
});
it('shows unknown bindings and retries when browsers return 502', async () => {
it("shows unknown bindings and retries when browsers return 502", async () => {
const dataProvider = provider([networkExit], {
getList: vi.fn(({ resource }) => resource === 'browsers'
? Promise.reject(httpError('bad gateway', 502))
: Promise.resolve({ data: [networkExit], total: 1 })),
})
renderExits(dataProvider)
getList: vi.fn(({ resource }) =>
resource === "browsers"
? Promise.reject(httpError("bad gateway", 502))
: Promise.resolve({ data: [networkExit], total: 1 }),
),
});
renderExits(dataProvider);
expect(await screen.findByText(/环境不可用/)).toBeTruthy()
expect((await screen.findAllByText(/绑定账号:状态未知|状态未知/)).length).toBeGreaterThan(0)
expect(screen.queryByText(/绑定账号:未绑定/)).toBeNull()
expect(screen.queryByText(/^未绑定$/)).toBeNull()
expect(screen.getAllByRole('button', { name: '检测' })[0].disabled).toBe(false)
fireEvent.click(screen.getByRole('button', { name: '重试环境状态' }))
await waitFor(() => expect(dataProvider.getList.mock.calls.filter(([call]) => call.resource === 'browsers').length).toBeGreaterThan(1))
})
})
expect(await screen.findByText(/环境不可用/)).toBeTruthy();
expect(
(await screen.findAllByText(/绑定账号:状态未知|状态未知/)).length,
).toBeGreaterThan(0);
expect(screen.queryByText(/绑定账号:未绑定/)).toBeNull();
expect(screen.queryByText(/^未绑定$/)).toBeNull();
expect(screen.getAllByRole("button", { name: "检测" })[0].disabled).toBe(
false,
);
fireEvent.click(screen.getByRole("button", { name: "重试环境状态" }));
await waitFor(() =>
expect(
dataProvider.getList.mock.calls.filter(
([call]) => call.resource === "browsers",
).length,
).toBeGreaterThan(1),
);
});
});