mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-29 06:28:23 +02:00
The four landing "Dashboard" CTAs used href="/" and relied on the proxy bouncing logged-in visitors from the root path to their workspace. Once #5363 kept "/" public on the official marketing host so logged-in users could browse the site (#5326), that bounce stopped — and the CTAs began resolving to the page the visitor was already on, so clicking them did nothing at all. Resolve the destination in the CTA instead of leaning on a redirect side effect elsewhere: useDashboardCtaHref() runs the same resolvePostAuthDestination() that RedirectIfAuthenticated already uses, so "where the dashboard lives" has one source of truth. This also collapses the same `user ? "/" : "/login"` line that had been copy-pasted across four files. proxy.ts and redirect-if-authenticated.tsx are untouched — #5363's behavior is correct and proxy.test.ts still passes unchanged. Closes MUL-4794 Co-authored-by: Walt <walt@multica.ai> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { paths } from "@multica/core/paths";
|
|
import type { Workspace } from "@multica/core/types";
|
|
import { resolveDashboardCtaHref } from "./use-dashboard-cta";
|
|
|
|
function makeWs(slug: string): Workspace {
|
|
return {
|
|
id: `id-${slug}`,
|
|
name: slug,
|
|
slug,
|
|
description: null,
|
|
context: null,
|
|
settings: {},
|
|
repos: [],
|
|
issue_prefix: slug.toUpperCase(),
|
|
avatar_url: null,
|
|
created_at: "",
|
|
updated_at: "",
|
|
};
|
|
}
|
|
|
|
const fetched = (workspaces: Workspace[], hasOnboarded = true) => ({
|
|
isAuthenticated: true,
|
|
isWorkspaceListFetched: true,
|
|
workspaces,
|
|
hasOnboarded,
|
|
});
|
|
|
|
describe("resolveDashboardCtaHref", () => {
|
|
it("sends logged-out visitors to /login", () => {
|
|
expect(
|
|
resolveDashboardCtaHref({
|
|
isAuthenticated: false,
|
|
isWorkspaceListFetched: false,
|
|
workspaces: undefined,
|
|
hasOnboarded: false,
|
|
}),
|
|
).toBe(paths.login());
|
|
});
|
|
|
|
// The bug this hook exists to fix: the CTA used to be `/`, which on the
|
|
// public marketing host resolves to the page the visitor is already on, so
|
|
// the click did nothing. It must resolve to a real workspace route.
|
|
it("sends an onboarded visitor to their workspace, never back to the landing page", () => {
|
|
const href = resolveDashboardCtaHref(fetched([makeWs("acme")]));
|
|
expect(href).toBe(paths.workspace("acme").issues());
|
|
expect(href).not.toBe("/");
|
|
});
|
|
|
|
it("sends an un-onboarded visitor to /onboarding", () => {
|
|
expect(resolveDashboardCtaHref(fetched([makeWs("acme")], false))).toBe(
|
|
paths.onboarding(),
|
|
);
|
|
});
|
|
|
|
it("sends an onboarded visitor with no workspace to /workspaces/new", () => {
|
|
expect(resolveDashboardCtaHref(fetched([]))).toBe(paths.newWorkspace());
|
|
});
|
|
|
|
it.each([
|
|
["the list has not resolved yet", false, undefined],
|
|
["the list resolved as undefined", true, undefined],
|
|
])("falls back to /issues while %s", (_label, isWorkspaceListFetched, workspaces) => {
|
|
// /issues is a legacy route the proxy rewrites to the last workspace, so
|
|
// the button still works during hydration. It must not fall back to `/`,
|
|
// which is what made the CTA dead in the first place.
|
|
const href = resolveDashboardCtaHref({
|
|
isAuthenticated: true,
|
|
isWorkspaceListFetched,
|
|
workspaces,
|
|
hasOnboarded: true,
|
|
});
|
|
expect(href).toBe("/issues");
|
|
expect(href).not.toBe("/");
|
|
});
|
|
});
|