From aabb88ee45e333246f8242510bf2d415ea8e5152 Mon Sep 17 00:00:00 2001 From: Frank Noirot Date: Tue, 1 Aug 2023 13:23:17 -0400 Subject: [PATCH] Add tests for various user profile setups to sidebar (#212) * Add tests for various user profile setups to sidebar * Don't show empty user image if it isn't there * @adamchalmer review --- src/components/ActionButton.tsx | 7 +-- src/components/UserSidebarMenu.test.tsx | 66 +++++++++++++++++++++++++ src/components/UserSidebarMenu.tsx | 62 ++++++++++++++++------- src/useStore.ts | 2 +- 4 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 src/components/UserSidebarMenu.test.tsx diff --git a/src/components/ActionButton.tsx b/src/components/ActionButton.tsx index 82dde7f27..44708bf10 100644 --- a/src/components/ActionButton.tsx +++ b/src/components/ActionButton.tsx @@ -20,6 +20,7 @@ export const ActionButton = ({ to = '/', Element = 'button', children, + ...props }: ActionButtonProps) => { const classNames = `group mono text-base flex items-center gap-2 rounded-sm border border-chalkboard-40 dark:border-chalkboard-60 hover:border-liquid-40 dark:hover:bg-chalkboard-90 p-[3px] ${ icon ? 'pr-2' : 'px-2' @@ -27,21 +28,21 @@ export const ActionButton = ({ if (Element === 'button') { return ( - ) } else if (Element === 'link') { return ( - + {icon && } {children} ) } else { return ( - + {icon && } {children} diff --git a/src/components/UserSidebarMenu.test.tsx b/src/components/UserSidebarMenu.test.tsx new file mode 100644 index 000000000..176e53e18 --- /dev/null +++ b/src/components/UserSidebarMenu.test.tsx @@ -0,0 +1,66 @@ +import { fireEvent, render, screen } from '@testing-library/react' +import { User } from '../useStore' +import UserSidebarMenu from './UserSidebarMenu' +import { BrowserRouter } from 'react-router-dom' + +it("Renders user's name and email if available", () => { + const userWellFormed: User = { + id: '8675309', + name: 'Test User', + email: 'kittycad.sidebar.test@example.com', + image: 'https://placekitten.com/200/200', + created_at: 'yesteryear', + updated_at: 'today', + } + + render( + + + + ) + + fireEvent.click(screen.getByTestId('user-sidebar-toggle')) + + expect(screen.getByTestId('username')).toHaveTextContent( + userWellFormed.name || '' + ) + expect(screen.getByTestId('email')).toHaveTextContent(userWellFormed.email) +}) + +it("Renders just the user's email if no name is available", () => { + const userNoName: User = { + id: '8675309', + email: 'kittycad.sidebar.test@example.com', + image: 'https://placekitten.com/200/200', + created_at: 'yesteryear', + updated_at: 'today', + } + + render( + + + + ) + + fireEvent.click(screen.getByTestId('user-sidebar-toggle')) + + expect(screen.getByTestId('username')).toHaveTextContent(userNoName.email) +}) + +it('Renders a menu button if no user avatar is available', () => { + const userNoAvatar: User = { + id: '8675309', + name: 'Test User', + email: 'kittycad.sidebar.test@example.com', + created_at: 'yesteryear', + updated_at: 'today', + } + + render( + + + + ) + + expect(screen.getByTestId('user-sidebar-toggle')).toHaveTextContent('Menu') +}) diff --git a/src/components/UserSidebarMenu.tsx b/src/components/UserSidebarMenu.tsx index 94c3ba5b6..506f0b2df 100644 --- a/src/components/UserSidebarMenu.tsx +++ b/src/components/UserSidebarMenu.tsx @@ -3,24 +3,45 @@ import { User, useStore } from '../useStore' import { ActionButton } from './ActionButton' import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons' import { useNavigate } from 'react-router-dom' -import { A } from '@tauri-apps/api/path-c062430b' +import { useState } from 'react' const UserSidebarMenu = ({ user }: { user?: User }) => { + const displayedName = getDisplayName(user) + const [imageLoadFailed, setImageLoadFailed] = useState(false) const navigate = useNavigate() const { setToken } = useStore((s) => ({ setToken: s.setToken, })) + // Fallback logic for displaying user's "name": + // 1. user.name + // 2. user.first_name + ' ' + user.last_name + // 3. user.first_name + // 4. user.email + function getDisplayName(user?: User) { + if (!user) return null + if (user.name) return user.name + if (user.first_name) { + if (user.last_name) return user.first_name + ' ' + user.last_name + return user.first_name + } + return user.email + } + return ( - {user?.image ? ( - + {user?.image && !imageLoadFailed ? ( +
{user?.name setImageLoadFailed(true)} />
@@ -29,6 +50,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => { Element={Popover.Button} icon={{ icon: faBars }} className="border-transparent" + data-testid="user-sidebar-toggle" > Menu @@ -38,23 +60,29 @@ const UserSidebarMenu = ({ user }: { user?: User }) => { {user && (
-
- {user?.name -
+ {user.image && !imageLoadFailed && ( +
+ {user.name setImageLoadFailed(true)} + /> +
+ )}
-

- {user.name || - user.first_name + ' ' + user.last_name || - user.email} +

+ {displayedName || ''}

- {(user.name || user.first_name) && ( -

{user.email}

+ {displayedName !== user.email && ( +

+ {user.email} +

)}
diff --git a/src/useStore.ts b/src/useStore.ts index 70b3ec28b..b20ed58b1 100644 --- a/src/useStore.ts +++ b/src/useStore.ts @@ -1,4 +1,4 @@ -import create from 'zustand' +import { create } from 'zustand' import { persist } from 'zustand/middleware' import { addLineHighlight, EditorView } from './editor/highlightextension' import { abstractSyntaxTree } from './lang/abstractSyntaxTree'