fix(web): convert favicon.ico to RGBA format for Turbopack (#544)
All checks were successful
ci/woodpecker/push/web Pipeline was successful
All checks were successful
ci/woodpecker/push/web Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #544.
This commit is contained in:
@@ -691,4 +691,175 @@ describe("AuthContext", (): void => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("workspace ID persistence", (): void => {
|
||||
// ---------------------------------------------------------------------------
|
||||
// localStorage mock for workspace persistence tests
|
||||
// ---------------------------------------------------------------------------
|
||||
interface MockLocalStorage {
|
||||
getItem: ReturnType<typeof vi.fn>;
|
||||
setItem: ReturnType<typeof vi.fn>;
|
||||
removeItem: ReturnType<typeof vi.fn>;
|
||||
clear: ReturnType<typeof vi.fn>;
|
||||
readonly length: number;
|
||||
key: ReturnType<typeof vi.fn>;
|
||||
}
|
||||
|
||||
let localStorageMock: MockLocalStorage;
|
||||
|
||||
beforeEach((): void => {
|
||||
let store: Record<string, string> = {};
|
||||
localStorageMock = {
|
||||
getItem: vi.fn((key: string): string | null => store[key] ?? null),
|
||||
setItem: vi.fn((key: string, value: string): void => {
|
||||
store[key] = value;
|
||||
}),
|
||||
removeItem: vi.fn((key: string): void => {
|
||||
store = Object.fromEntries(Object.entries(store).filter(([k]) => k !== key));
|
||||
}),
|
||||
clear: vi.fn((): void => {
|
||||
store = {};
|
||||
}),
|
||||
get length(): number {
|
||||
return Object.keys(store).length;
|
||||
},
|
||||
key: vi.fn((_index: number): string | null => null),
|
||||
};
|
||||
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: localStorageMock,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
afterEach((): void => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should persist currentWorkspaceId to localStorage after session check", async (): Promise<void> => {
|
||||
const mockUser: AuthUser = {
|
||||
id: "user-1",
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
currentWorkspaceId: "ws-current-123",
|
||||
workspaceId: "ws-default-456",
|
||||
};
|
||||
|
||||
vi.mocked(apiGet).mockResolvedValueOnce({
|
||||
user: mockUser,
|
||||
session: { id: "session-1", token: "token123", expiresAt: futureExpiry() },
|
||||
});
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<TestComponent />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("auth-status")).toHaveTextContent("Authenticated");
|
||||
});
|
||||
|
||||
// currentWorkspaceId takes priority over workspaceId
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
"mosaic-workspace-id",
|
||||
"ws-current-123"
|
||||
);
|
||||
});
|
||||
|
||||
it("should fall back to workspaceId when currentWorkspaceId is absent", async (): Promise<void> => {
|
||||
const mockUser: AuthUser = {
|
||||
id: "user-1",
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
workspaceId: "ws-default-456",
|
||||
};
|
||||
|
||||
vi.mocked(apiGet).mockResolvedValueOnce({
|
||||
user: mockUser,
|
||||
session: { id: "session-1", token: "token123", expiresAt: futureExpiry() },
|
||||
});
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<TestComponent />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("auth-status")).toHaveTextContent("Authenticated");
|
||||
});
|
||||
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
"mosaic-workspace-id",
|
||||
"ws-default-456"
|
||||
);
|
||||
});
|
||||
|
||||
it("should not write to localStorage when no workspace ID is present on user", async (): Promise<void> => {
|
||||
const mockUser: AuthUser = {
|
||||
id: "user-1",
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
// no workspaceId or currentWorkspaceId
|
||||
};
|
||||
|
||||
vi.mocked(apiGet).mockResolvedValueOnce({
|
||||
user: mockUser,
|
||||
session: { id: "session-1", token: "token123", expiresAt: futureExpiry() },
|
||||
});
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<TestComponent />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("auth-status")).toHaveTextContent("Authenticated");
|
||||
});
|
||||
|
||||
expect(localStorageMock.setItem).not.toHaveBeenCalledWith(
|
||||
"mosaic-workspace-id",
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
|
||||
it("should remove workspace ID from localStorage on sign-out", async (): Promise<void> => {
|
||||
const mockUser: AuthUser = {
|
||||
id: "user-1",
|
||||
email: "test@example.com",
|
||||
name: "Test User",
|
||||
currentWorkspaceId: "ws-current-123",
|
||||
};
|
||||
|
||||
vi.mocked(apiGet).mockResolvedValueOnce({
|
||||
user: mockUser,
|
||||
session: { id: "session-1", token: "token123", expiresAt: futureExpiry() },
|
||||
});
|
||||
vi.mocked(apiPost).mockResolvedValueOnce({ success: true });
|
||||
|
||||
render(
|
||||
<AuthProvider>
|
||||
<TestComponent />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("auth-status")).toHaveTextContent("Authenticated");
|
||||
});
|
||||
|
||||
const signOutButton = screen.getByRole("button", { name: "Sign Out" });
|
||||
signOutButton.click();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("auth-status")).toHaveTextContent("Not Authenticated");
|
||||
});
|
||||
|
||||
expect(localStorageMock.removeItem).toHaveBeenCalledWith("mosaic-workspace-id");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user