ae3ab5feb5
- os/ 67 文件(DesktopOS/Dock/Launcher/MenuBar/MissionControl/NotificationCenter/AppStore/Window 系统 + os*Store/hooks) - pages/Hub + api/modules/hub.ts + ImportHubModal(已有) - Inbox 采用上游 Mailbox(approvals/messages 双 Tab + MailAccessControlDrawer/useMailPendingCount/mailDetail),保留云超服 Harvest 组件 - App.tsx 引入 OS Shell 分支(isOsPath→DesktopOSPage, Router 外)+ /hub/admin 路由 + BackendModeRouter + RuntimeAvailabilityGuard,保留云超服 AuthGuard/chatSocket/OPC 主题/vi-th-my-lo - 双改合并:usePluginLoader(loadPawApp)/pluginMarket(isMarketPluginApp)/registry store(removeBySource)/hostExternals(removePlugin)/LanguageSwitcher(persistRemotely+ja-ru-pt-id)/BackendLoadingPage(override props)/ApprovalCard(reasoning)/auth.ts(mode)/auth/gate.ts - SidebarSettingsPanel 加 Desktop Mode 入口(OS Shell 切换) - locales 合并 os/hub/projectDirectory/inbox/account(zh/en/vi 用上游,lo/my/th 用 en 占位) - 验证:tsc 0 错误、build 通过(1m23s)、阶段5 新增 35 文件 271 测试全过;全量回归 30 失败均预存在(stash 验证)
40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
import { useState } from "react";
|
|
import { Dropdown } from "antd";
|
|
import { fireEvent, screen } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { renderWithProviders } from "@/test/common_setup";
|
|
|
|
function Harness({ onAction }: { onAction: () => void }) {
|
|
const [open, setOpen] = useState(true);
|
|
return (
|
|
<div onPointerDown={() => setOpen(false)}>
|
|
{open && (
|
|
<Dropdown
|
|
open
|
|
trigger={[]}
|
|
menu={{
|
|
items: [{ key: "action", label: "Arrange", onClick: onAction }],
|
|
}}
|
|
popupRender={(menu) => (
|
|
<div onPointerDown={(event) => event.stopPropagation()}>{menu}</div>
|
|
)}
|
|
>
|
|
<span>anchor</span>
|
|
</Dropdown>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
describe("Desktop context menu", () => {
|
|
it("runs portal menu actions before the desktop closes the menu", () => {
|
|
const onAction = vi.fn();
|
|
renderWithProviders(<Harness onAction={onAction} />);
|
|
|
|
fireEvent.pointerDown(screen.getByText("Arrange"));
|
|
fireEvent.click(screen.getByText("Arrange"));
|
|
|
|
expect(onAction).toHaveBeenCalledOnce();
|
|
});
|
|
});
|