diff --git a/webview-ui/src/components/cloud/CloudView.tsx b/webview-ui/src/components/cloud/CloudView.tsx index 92ccc72564..63733ef7d2 100644 --- a/webview-ui/src/components/cloud/CloudView.tsx +++ b/webview-ui/src/components/cloud/CloudView.tsx @@ -11,6 +11,9 @@ import { ToggleSwitch } from "@/components/ui/toggle-switch" import { History, PiggyBank, SquareArrowOutUpRightIcon } from "lucide-react" +// Define the production URL constant locally to avoid importing from cloud package in tests +const PRODUCTION_ROO_CODE_API_URL = "https://app.roocode.com" + type CloudViewProps = { userInfo: CloudUserInfo | null isAuthenticated: boolean @@ -56,10 +59,16 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl // Send telemetry for cloud website visit // NOTE: Using ACCOUNT_* telemetry events for backward compatibility with analytics telemetryClient.capture(TelemetryEventName.ACCOUNT_CONNECT_CLICKED) - const cloudUrl = cloudApiUrl || "https://app.roocode.com" + const cloudUrl = cloudApiUrl || PRODUCTION_ROO_CODE_API_URL vscode.postMessage({ type: "openExternal", url: cloudUrl }) } + const handleOpenCloudUrl = () => { + if (cloudApiUrl) { + vscode.postMessage({ type: "openExternal", url: cloudApiUrl }) + } + } + const handleRemoteControlToggle = () => { const newValue = !remoteControlEnabled setRemoteControlEnabled(newValue) @@ -186,6 +195,18 @@ export const CloudView = ({ userInfo, isAuthenticated, cloudApiUrl, onDone }: Cl )} + {cloudApiUrl && cloudApiUrl !== PRODUCTION_ROO_CODE_API_URL && ( +
+
+ {t("cloud:cloudUrlPillLabel")}: + +
+
+ )} ) } diff --git a/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx b/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx index bc0acd2512..212cfbc612 100644 --- a/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx +++ b/webview-ui/src/components/cloud/__tests__/CloudView.spec.tsx @@ -21,6 +21,7 @@ vi.mock("@src/i18n/TranslationContext", () => ({ "cloud:remoteControlDescription": "Enable following and interacting with tasks in this workspace with Roo Code Cloud", "cloud:profilePicture": "Profile picture", + "cloud:cloudUrlPillLabel": "Roo Code Cloud URL: ", } return translations[key] || key }, @@ -148,4 +149,70 @@ describe("CloudView", () => { expect(screen.queryByTestId("remote-control-toggle")).not.toBeInTheDocument() expect(screen.queryByText("Roomote Control")).not.toBeInTheDocument() }) + + it("should not display cloud URL pill when pointing to production", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + } + + render( + {}} + />, + ) + + // Check that the cloud URL pill is NOT displayed for production URL + expect(screen.queryByText(/Roo Code Cloud URL:/)).not.toBeInTheDocument() + }) + + it("should display cloud URL pill when pointing to non-production environment", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + } + + render( + {}} + />, + ) + + // Check that the cloud URL pill is displayed with the staging URL + expect(screen.getByText(/Roo Code Cloud URL:/)).toBeInTheDocument() + expect(screen.getByText("https://staging.roocode.com")).toBeInTheDocument() + }) + + it("should display cloud URL pill for non-authenticated users when not pointing to production", () => { + render( + {}} + />, + ) + + // Check that the cloud URL pill is displayed even when not authenticated + expect(screen.getByText(/Roo Code Cloud URL:/)).toBeInTheDocument() + expect(screen.getByText("https://dev.roocode.com")).toBeInTheDocument() + }) + + it("should not display cloud URL pill when cloudApiUrl is undefined", () => { + const mockUserInfo = { + name: "Test User", + email: "test@example.com", + } + + render( {}} />) + + // Check that the cloud URL pill is NOT displayed when cloudApiUrl is undefined + expect(screen.queryByText(/Roo Code Cloud URL:/)).not.toBeInTheDocument() + }) })