mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-11 01:45:58 +00:00
Align IM connections with local channels
This commit is contained in:
@@ -106,12 +106,20 @@ export function WorkspaceChannelsList() {
|
||||
disabled={!canConnect || isPending}
|
||||
title={getProviderDisabledReason(provider, t)}
|
||||
onClick={() => {
|
||||
const connectWindow = prepareConnectWindow();
|
||||
const connectWindow =
|
||||
provider.auth_mode === "deep_link"
|
||||
? prepareConnectWindow()
|
||||
: null;
|
||||
void connectMutation
|
||||
.mutateAsync(provider.provider)
|
||||
.then((result) =>
|
||||
openConnectUrl(result.url, connectWindow),
|
||||
)
|
||||
.then((result) => {
|
||||
if (result.url) {
|
||||
openConnectUrl(result.url, connectWindow);
|
||||
return;
|
||||
}
|
||||
closeConnectWindow(connectWindow);
|
||||
toast.success(result.instruction);
|
||||
})
|
||||
.catch((error) => {
|
||||
closeConnectWindow(connectWindow);
|
||||
toast.error(
|
||||
|
||||
@@ -165,10 +165,20 @@ function ChannelProviderItem({
|
||||
disabled={!canConnect || isConnecting}
|
||||
title={unavailableReason}
|
||||
onClick={() => {
|
||||
const connectWindow = prepareConnectWindow();
|
||||
const connectWindow =
|
||||
provider.auth_mode === "deep_link"
|
||||
? prepareConnectWindow()
|
||||
: null;
|
||||
void connectMutation
|
||||
.mutateAsync(provider.provider)
|
||||
.then((result) => openConnectUrl(result.url, connectWindow))
|
||||
.then((result) => {
|
||||
if (result.url) {
|
||||
openConnectUrl(result.url, connectWindow);
|
||||
return;
|
||||
}
|
||||
closeConnectWindow(connectWindow);
|
||||
toast.success(result.instruction);
|
||||
})
|
||||
.catch((error) => {
|
||||
closeConnectWindow(connectWindow);
|
||||
toast.error(
|
||||
|
||||
@@ -35,6 +35,8 @@ export interface ChannelConnectionsResponse {
|
||||
export interface ChannelConnectResponse {
|
||||
provider: ChannelProviderId;
|
||||
mode: string;
|
||||
url: string;
|
||||
url?: string | null;
|
||||
code: string;
|
||||
instruction: string;
|
||||
expires_in: number;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ function mockChannelsAPI(page: Page) {
|
||||
display_name: "Slack",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
auth_mode: "oauth",
|
||||
auth_mode: "binding_code",
|
||||
connection_status: "not_connected",
|
||||
},
|
||||
{
|
||||
@@ -31,7 +31,7 @@ function mockChannelsAPI(page: Page) {
|
||||
display_name: "Discord",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
auth_mode: "oauth_and_bot_install",
|
||||
auth_mode: "binding_code",
|
||||
connection_status: "not_connected",
|
||||
},
|
||||
],
|
||||
@@ -53,8 +53,10 @@ function mockChannelsAPI(page: Page) {
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
provider: "slack",
|
||||
mode: "oauth",
|
||||
url: "http://localhost:3000/mock-slack-oauth?client_id=dev&state=test",
|
||||
mode: "binding_code",
|
||||
url: null,
|
||||
code: "abc123",
|
||||
instruction: "Send /connect abc123 to the DeerFlow Slack bot.",
|
||||
expires_in: 600,
|
||||
}),
|
||||
});
|
||||
@@ -91,11 +93,10 @@ test.describe("IM channels", () => {
|
||||
const connectButtons = dialog.getByRole("button", { name: "Connect" });
|
||||
await expect(connectButtons).toHaveCount(3);
|
||||
|
||||
const popupPromise = page.waitForEvent("popup");
|
||||
await connectButtons.nth(1).click();
|
||||
const popup = await popupPromise;
|
||||
await expect(page).toHaveURL(/\/workspace\/chats\/new/);
|
||||
await expect(popup).toHaveURL(/\/mock-slack-oauth/);
|
||||
await popup.close();
|
||||
await expect(
|
||||
page.getByText("Send /connect abc123 to the DeerFlow Slack bot."),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -85,6 +85,8 @@ describe("channels api", () => {
|
||||
provider: "telegram",
|
||||
mode: "deep_link",
|
||||
url: "https://t.me/deerflow_bot?start=state",
|
||||
code: "state",
|
||||
instruction: "Send /start state to the DeerFlow Telegram bot.",
|
||||
expires_in: 600,
|
||||
}),
|
||||
);
|
||||
@@ -92,6 +94,7 @@ describe("channels api", () => {
|
||||
await expect(connectChannelProvider("telegram")).resolves.toMatchObject({
|
||||
provider: "telegram",
|
||||
url: "https://t.me/deerflow_bot?start=state",
|
||||
instruction: "Send /start state to the DeerFlow Telegram bot.",
|
||||
});
|
||||
expect(mockedFetch).toHaveBeenCalledWith(
|
||||
"/backend/api/channels/telegram/connect",
|
||||
@@ -99,6 +102,26 @@ describe("channels api", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("starts a binding-code connection flow", async () => {
|
||||
mockedFetch.mockResolvedValueOnce(
|
||||
jsonResponse(200, {
|
||||
provider: "slack",
|
||||
mode: "binding_code",
|
||||
url: null,
|
||||
code: "abc123",
|
||||
instruction: "Send /connect abc123 to the DeerFlow Slack bot.",
|
||||
expires_in: 600,
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(connectChannelProvider("slack")).resolves.toMatchObject({
|
||||
provider: "slack",
|
||||
url: null,
|
||||
code: "abc123",
|
||||
instruction: "Send /connect abc123 to the DeerFlow Slack bot.",
|
||||
});
|
||||
});
|
||||
|
||||
test("disconnects a channel connection", async () => {
|
||||
mockedFetch.mockResolvedValueOnce(new Response(null, { status: 204 }));
|
||||
|
||||
|
||||
@@ -69,9 +69,11 @@ describe("channel connect window helpers", () => {
|
||||
test("falls back to current-window navigation when no popup is available", () => {
|
||||
const { assign } = stubWindow(null);
|
||||
|
||||
openConnectUrl("https://slack.com/oauth/v2/authorize");
|
||||
openConnectUrl("https://t.me/deerflow_bot?start=state");
|
||||
|
||||
expect(assign).toHaveBeenCalledWith("https://slack.com/oauth/v2/authorize");
|
||||
expect(assign).toHaveBeenCalledWith(
|
||||
"https://t.me/deerflow_bot?start=state",
|
||||
);
|
||||
});
|
||||
|
||||
test("closes a prepared popup on connect failure", () => {
|
||||
|
||||
Reference in New Issue
Block a user