Skip to content

Commit

Permalink
test: add stories for header and footer (#368)
Browse files Browse the repository at this point in the history
  • Loading branch information
codeincontext authored Nov 15, 2024
1 parent 33df453 commit 72d381f
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 36 deletions.
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

0 comments on commit 72d381f

Please sign in to comment.