Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add stories for header and footer #368

Merged
merged 3 commits into from
Nov 15, 2024
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
11 changes: 0 additions & 11 deletions apps/nextjs/.storybook/MockClerkProvider.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion apps/nextjs/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { Preview, Decorator } from "@storybook/react";

import { TooltipProvider } from "../src/components/AppComponents/Chat/ui/tooltip";
import { AnalyticsProvider } from "../src/mocks/analytics/provider";
import { ClerkDecorator } from "../src/mocks/clerk/ClerkDecorator";
import { TRPCReactProvider } from "../src/utils/trpc";
import { RadixThemeDecorator } from "./decorators/RadixThemeDecorator";
import "./preview.css";
Expand All @@ -28,7 +29,6 @@ const preview: Preview = {
};

// Providers not currently used
// - MockClerkProvider
// - CookieConsentProvider
// - DemoProvider
// - LessonPlanTrackingProvider
Expand All @@ -38,6 +38,7 @@ const preview: Preview = {

export const decorators: Decorator[] = [
RadixThemeDecorator,
ClerkDecorator,
(Story) => (
<>
{/* TODO: Mock tRPC calls with MSW */}
Expand Down
17 changes: 17 additions & 0 deletions apps/nextjs/src/components/Footer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";

import Footer from "./Footer";

const meta: Meta<typeof Footer> = {
title: "Components/Layout/Footer",
component: Footer,
tags: ["autodocs"],
};

export default meta;

type Story = StoryObj<typeof Footer>;

export const Default: Story = {
args: {},
};
27 changes: 27 additions & 0 deletions apps/nextjs/src/components/Header.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from "@storybook/react";

import Header from "./Header";

const meta: Meta<typeof Header> = {
title: "Components/Layout/Header",
component: Header,
tags: ["autodocs"],
};

export default meta;

type Story = StoryObj<typeof Header>;

export const SignedIn: Story = {
args: {},
parameters: {
auth: "signedIn",
},
};

export const SignedOut: Story = {
args: {},
parameters: {
auth: "signedOut",
},
};
11 changes: 11 additions & 0 deletions apps/nextjs/src/mocks/clerk/ClerkDecorator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Decorator } from "@storybook/react/*";

import { ClerkProvider } from "./nextjsComponents";

export const ClerkDecorator: Decorator = (Story, { parameters }) => {
return (
<ClerkProvider state={parameters.auth ?? "signedIn"}>
<Story />
</ClerkProvider>
);
};
5 changes: 3 additions & 2 deletions apps/nextjs/src/mocks/clerk/nextjs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
/*
Mocks the Clerk authentication library for use in Story book.
See the readme for more context on why this is needed.
See the readme for more context on why this is needed.
*/

export {
Expand All @@ -10,4 +10,5 @@ export {
SignedIn,
SignedOut,
ClerkProvider,
UserButton,
} from "./nextjsComponents";
116 changes: 94 additions & 22 deletions apps/nextjs/src/mocks/clerk/nextjsComponents.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,115 @@
import React from "react";

type Context = {
isLoaded: boolean;
isSignedIn: boolean | undefined;
user:
| Record<
"id" | "firstName" | "lastName" | "emailAddresses" | "publicMetadata",
unknown
>
| undefined;
};

const mockUser = {
id: "user_123",
firstName: "John",
lastName: "Doe",
emailAddresses: [{ emailAddress: "[email protected]" }],
publicMetadata: { labs: { isDemoUser: true } },
publicMetadata: { labs: { isDemoUser: false } },
// Add other user properties as needed
};

export const useUser = () => ({
isLoaded: true,
isSignedIn: true,
user: mockUser,
});
const states: Record<ClerkProviderProps["state"], Context> = {
loading: {
isLoaded: false,
isSignedIn: undefined,
user: undefined,
},
signedOut: {
isLoaded: true,
isSignedIn: false,
user: undefined,
},
signedIn: {
isLoaded: true,
isSignedIn: true,
user: mockUser,
},
signedInDemo: {
isLoaded: true,
isSignedIn: true,
user: {
...mockUser,
publicMetadata: { ...mockUser.publicMetadata, isDemoUser: true },
},
},
};

const ClerkContext = React.createContext<Context>(states.signedIn);

type ClerkProviderProps = {
state: "loading" | "signedIn" | "signedInDemo" | "signedOut";
children: React.ReactNode;
};
export const ClerkProvider = ({ state, children }: ClerkProviderProps) => (
<ClerkContext.Provider value={states[state]}>
{children}
</ClerkContext.Provider>
);

export const useUser = () => {
const context = React.useContext(ClerkContext);
return {
isLoaded: context.isLoaded,
isSignedIn: context.isSignedIn,
user: context.user,
};
};

export const useClerk = () => ({
signOut: () => Promise.resolve(),
signIn: () => Promise.resolve(),
// Add other Clerk methods as needed
});

export const useAuth = () => ({
isLoaded: true,
isSignedIn: true,
userId: mockUser.id,
sessionId: "session_123",
getToken: () => Promise.resolve("mock_token"),
});
export const useAuth = () => {
const context = React.useContext(ClerkContext);
return {
isLoaded: context.isLoaded,
isSignedIn: context.isSignedIn,
userId: mockUser?.id,
sessionId: "session_123",
getToken: () => Promise.resolve("mock_token"),
};
};

export const SignedIn = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const SignedOut = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const SignedIn = ({ children }: { children: React.ReactNode }) => {
const context = React.useContext(ClerkContext);
return context.isSignedIn ? children : null;
};

export const ClerkProvider = ({ children }: { children: React.ReactNode }) => (
<>{children}</>
);
export const SignedOut = ({ children }: { children: React.ReactNode }) => {
const context = React.useContext(ClerkContext);
return context.isSignedIn ? null : children;
};

export const UserButton = () => {
const context = React.useContext(ClerkContext);

return context.isSignedIn ? (
<div
style={{
display: "block",
height: "28px",
width: "28px",
background: "yellowgreen",
borderRadius: "50%",
}}
/>
) : (
"Sign in"
);
};

// Mock other Clerk components and hooks as needed
Loading