fix: expose host editing through the plugin shell bridge (#1778)

This commit is contained in:
ZacharyZcR authored and GitHub committed 2026-11-06 20:46:28 -06:00
1 parent 1173f3f576
commit 3630d6c157
2 files changed
+74 -1

No files matched your search

+5
View File
@@ -114,6 +114,11 @@ export const shell: TabShellCallbacks = {
openRailView: (...args) => callbacks?.openRailView(...args), openRailView: (...args) => callbacks?.openRailView(...args),
closeRailView: (...args) => callbacks?.closeRailView(...args), closeRailView: (...args) => callbacks?.closeRailView(...args),
openHostEditor: (...args) => callbacks?.openHostEditor?.(...args), openHostEditor: (...args) => callbacks?.openHostEditor?.(...args),
get editHost() {
return callbacks?.editHost
? (hostId: number) => callbacks?.editHost?.(hostId)
: undefined;
},
saveQuickConnect: (...args) => saveQuickConnect: (...args) =>
callbacks?.saveQuickConnect?.(...args) ?? Promise.resolve(), callbacks?.saveQuickConnect?.(...args) ?? Promise.resolve(),
confirm: (options) => confirm: (options) =>
+69 -1
View File
@@ -1,4 +1,7 @@
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import { createElement } from "react";
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { withPluginScope } from "@/plugin-host/scope";
import { import {
resetShellBridge, resetShellBridge,
setShellCallbacks, setShellCallbacks,
@@ -18,7 +21,10 @@ const saved = {
socks5Host: "proxy", socks5Host: "proxy",
} as unknown as Host; } as unknown as Host;
afterEach(() => resetShellBridge()); afterEach(() => {
cleanup();
resetShellBridge();
});
describe("withShellHost", () => { describe("withShellHost", () => {
it("fills a typed record back in from the shell's own host", () => { it("fills a typed record back in from the shell's own host", () => {
@@ -50,3 +56,65 @@ describe("withShellHost", () => {
expect(openTab.mock.calls[0][0]).toMatchObject({ socks5Host: "proxy" }); expect(openTab.mock.calls[0][0]).toMatchObject({ socks5Host: "proxy" });
}); });
}); });
describe("shell.editHost", () => {
it("forwards saved host editing to the current shell", () => {
const editHost = vi.fn();
const openHostEditor = vi.fn();
setShellCallbacks({ editHost, openHostEditor } as never);
expect(shell.editHost).toBeTypeOf("function");
const edit = shell.editHost!;
edit(5);
expect(editHost).toHaveBeenCalledWith(5);
expect(openHostEditor).not.toHaveBeenCalled();
const next = vi.fn();
setShellCallbacks({ editHost: next } as never);
edit(7);
expect(next).toHaveBeenCalledWith(7);
resetShellBridge();
expect(() => edit(5)).not.toThrow();
expect(next).toHaveBeenCalledTimes(1);
});
it("preserves editing through the scoped plugin view without exposing other settings", () => {
const editHost = vi.fn();
setShellCallbacks({ editHost } as never);
let seen: Host | undefined;
const View = withPluginScope(
"fixture",
({ host, shell: bridge }: { host: Host; shell: typeof shell }) => {
seen = host;
return bridge.editHost
? createElement(
"button",
{
onClick: () => bridge.editHost?.(Number(host.id)),
},
"Edit host",
)
: null;
},
);
render(
createElement(View, {
host: {
...saved,
pluginSettings: {
fixture: { enabled: true },
other: { enabled: false },
},
},
shell,
}),
);
fireEvent.click(screen.getByText("Edit host"));
expect(editHost).toHaveBeenCalledWith(5);
expect(seen?.id).toBe("5");
expect(seen?.pluginSettings).toEqual({ fixture: { enabled: true } });
});
it("does not advertise editing when the mounted shell cannot edit hosts", () => {
setShellCallbacks({ openHostEditor: vi.fn() } as never);
expect(shell.editHost).toBeUndefined();
});
});