Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions src/browser/components/ChatPane/WorkspaceFooterBar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ const repoMetadata: FrontendWorkspaceMetadata = {
createdAt: "2026-01-01T00:00:00.000Z",
};

function mockDetectedPR() {
spyOn(PRStatusStoreModule, "useWorkspacePR").mockImplementation(
() =>
({
type: "github-pr",
url: "https://github.com/acme/widgets/pull/7",
owner: "acme",
repo: "widgets",
number: 7,
detectedAt: 0,
occurrenceCount: 1,
}) as unknown as ReturnType<typeof PRStatusStoreModule.useWorkspacePR>
);
}

function renderFooter(overrides?: Partial<ComponentProps<typeof WorkspaceFooterBarComponent>>) {
return render(
<TooltipProvider delayDuration={0}>
Expand Down Expand Up @@ -200,25 +215,25 @@ describe("WorkspaceFooterBar repository controls", () => {

it("shows the GitHub slug instead of the project label once a PR is detected", () => {
workspaceMetadata.set(workspaceId, repoMetadata);
spyOn(PRStatusStoreModule, "useWorkspacePR").mockImplementation(
() =>
({
type: "github-pr",
url: "https://github.com/acme/widgets/pull/7",
owner: "acme",
repo: "widgets",
number: 7,
detectedAt: 0,
occurrenceCount: 1,
}) as unknown as ReturnType<typeof PRStatusStoreModule.useWorkspacePR>
);
mockDetectedPR();

const { container } = renderFooter();

expect(container.textContent).toContain("acme/widgets");
expect(container.textContent).not.toContain("demo");
});

it("links the GitHub slug to the repository page", () => {
workspaceMetadata.set(workspaceId, repoMetadata);
mockDetectedPR();

const { getByTestId } = renderFooter();

expect(getByTestId("workspace-footer-repository").getAttribute("href")).toBe(
"https://github.com/acme/widgets"
);
});

it("falls back to the project label when no PR is detected", () => {
workspaceMetadata.set(workspaceId, repoMetadata);

Expand Down
24 changes: 18 additions & 6 deletions src/browser/components/ChatPane/WorkspaceFooterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,25 @@ function FooterRepositoryLabel(props: { workspaceId: string; projectLabel: strin
return <FooterProjectLabel projectLabel={props.projectLabel} />;
}

// The slug comes from a parsed github.com PR URL, so the repo page is always this host.
const slug = `${workspacePR.owner}/${workspacePR.repo}`;

return (
<span className="text-muted flex shrink-0 items-center gap-1">
<Github className="h-3 w-3 shrink-0" aria-hidden="true" />
<span className="font-mono">
{workspacePR.owner}/{workspacePR.repo}
</span>
</span>
<Tooltip>
<TooltipTrigger asChild>
<a
href={`https://github.com/${slug}`}
target="_blank"
rel="noopener noreferrer"
data-testid="workspace-footer-repository"
className="text-muted hover:bg-hover hover:text-foreground focus-visible:ring-accent flex h-5 shrink-0 items-center gap-1 rounded-md px-1.5 transition-colors focus-visible:ring-1"
>
<Github className="h-3 w-3 shrink-0" aria-hidden="true" />
<span className="font-mono">{slug}</span>
</a>
</TooltipTrigger>
<TooltipContent side="top">Open on GitHub</TooltipContent>
</Tooltip>
);
}

Expand Down
Loading