-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3242 from OpenNeuroOrg/user-routes
User routes
- Loading branch information
Showing
29 changed files
with
1,265 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
packages/openneuro-app/src/scripts/users/__tests__/user-account-view.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import React from 'react'; | ||
import { render, screen, fireEvent, within, waitFor} from '@testing-library/react'; | ||
import { UserAccountView } from '../user-account-view'; | ||
|
||
const baseUser = { | ||
name: "John Doe", | ||
email: "[email protected]", | ||
orcid: "0000-0001-2345-6789", | ||
location: "San Francisco, CA", | ||
institution: "University of California", | ||
links: ["https://example.com", "https://example.org"], | ||
github: "johndoe", | ||
}; | ||
|
||
describe('<UserAccountView />', () => { | ||
it('should render the user details correctly', () => { | ||
render(<UserAccountView user={baseUser} />); | ||
|
||
// Check if user details are rendered | ||
expect(screen.getByText('Name:')).toBeInTheDocument(); | ||
expect(screen.getByText('John Doe')).toBeInTheDocument(); | ||
expect(screen.getByText('Email:')).toBeInTheDocument(); | ||
expect(screen.getByText('[email protected]')).toBeInTheDocument(); | ||
expect(screen.getByText('ORCID:')).toBeInTheDocument(); | ||
expect(screen.getByText('0000-0001-2345-6789')).toBeInTheDocument(); | ||
expect(screen.getByText('johndoe')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render links with EditableContent', async () => { | ||
render(<UserAccountView user={baseUser} />); | ||
const institutionSection = within(screen.getByText('Institution').closest('.user-meta-block')); | ||
expect(screen.getByText('Institution')).toBeInTheDocument(); | ||
const editButton = institutionSection.getByText('Edit'); | ||
fireEvent.click(editButton); | ||
const textbox = institutionSection.getByRole('textbox'); | ||
fireEvent.change(textbox, { target: { value: 'New University' } }); | ||
const saveButton = institutionSection.getByText('Save'); | ||
const closeButton = institutionSection.getByText('Close'); | ||
fireEvent.click(saveButton); | ||
fireEvent.click(closeButton); | ||
// Add debug step | ||
await waitFor(() => screen.debug()); | ||
// Use a flexible matcher to check for text | ||
await waitFor(() => | ||
expect(institutionSection.getByText('New University')).toBeInTheDocument() | ||
); | ||
}); | ||
|
||
|
||
it('should render location with EditableContent', async () => { | ||
render(<UserAccountView user={baseUser} />); | ||
const locationSection = within(screen.getByText('Location').closest('.user-meta-block')); | ||
expect(screen.getByText('Location')).toBeInTheDocument(); | ||
const editButton = locationSection.getByText('Edit'); | ||
fireEvent.click(editButton); | ||
const textbox = locationSection.getByRole('textbox'); | ||
fireEvent.change(textbox, { target: { value: 'Marin, CA' } }); | ||
const saveButton = locationSection.getByText('Save'); | ||
const closeButton = locationSection.getByText('Close'); | ||
fireEvent.click(saveButton); | ||
fireEvent.click(closeButton); | ||
// Add debug step | ||
await waitFor(() => screen.debug()); | ||
// Use a flexible matcher to check for text | ||
await waitFor(() => | ||
expect(locationSection.getByText('Marin, CA')).toBeInTheDocument() | ||
); | ||
}); | ||
}); |
95 changes: 95 additions & 0 deletions
95
packages/openneuro-app/src/scripts/users/__tests__/user-card.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import React from "react"; | ||
import { render, screen } from "@testing-library/react"; | ||
import type { User } from "../user-card"; | ||
import { UserCard } from "../user-card"; | ||
|
||
describe("UserCard Component", () => { | ||
const baseUser: User = { | ||
name: "John Doe", | ||
email: "[email protected]", | ||
orcid: "0000-0001-2345-6789", | ||
location: "San Francisco, CA", | ||
institution: "University of California", | ||
links: ["https://example.com", "https://example.org"], | ||
github: "johndoe", | ||
}; | ||
|
||
it("renders all user details when all data is provided", () => { | ||
|
||
render(<UserCard user={baseUser} />); | ||
|
||
const orcidLink = screen.getByRole("link", { | ||
name: "ORCID profile of John Doe", | ||
}); | ||
expect(orcidLink).toHaveAttribute("href", "https://orcid.org/0000-0001-2345-6789"); | ||
expect(screen.getByText("University of California")).toBeInTheDocument(); | ||
expect(screen.getByText("San Francisco, CA")).toBeInTheDocument(); | ||
|
||
const emailLink = screen.getByRole("link", { name: "[email protected]" }); | ||
expect(emailLink).toHaveAttribute("href", "mailto:[email protected]"); | ||
|
||
const githubLink = screen.getByRole("link", { name: "Github profile of John Doe", }); | ||
expect(githubLink).toHaveAttribute("href", "https://github.com/johndoe"); | ||
expect( | ||
screen.getByRole("link", { name: "https://example.com" }) | ||
).toHaveAttribute("href", "https://example.com"); | ||
expect( | ||
screen.getByRole("link", { name: "https://example.org" }) | ||
).toHaveAttribute("href", "https://example.org"); | ||
}); | ||
|
||
it("renders without optional fields", () => { | ||
const minimalUser: User = { | ||
name: "Jane Doe", | ||
email: "[email protected]", | ||
orcid: "0000-0002-3456-7890", | ||
links: [], | ||
}; | ||
|
||
render(<UserCard user={minimalUser} />); | ||
|
||
const orcidLink = screen.getByRole("link", { | ||
name: "ORCID profile of Jane Doe", | ||
}); | ||
expect(orcidLink).toHaveAttribute("href", "https://orcid.org/0000-0002-3456-7890"); | ||
const emailLink = screen.getByRole("link", { name: "[email protected]" }); | ||
expect(emailLink).toHaveAttribute("href", "mailto:[email protected]"); | ||
expect(screen.queryByText("University of California")).not.toBeInTheDocument(); | ||
expect(screen.queryByText("San Francisco, CA")).not.toBeInTheDocument(); | ||
expect(screen.queryByRole("link", { name: "Github profile of Jane Doe" })).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("renders correctly when links are empty", () => { | ||
const userWithEmptyLinks: User = { | ||
...baseUser, | ||
links: [], | ||
}; | ||
|
||
render(<UserCard user={userWithEmptyLinks} />); | ||
|
||
expect(screen.queryByRole("link", { name: "https://example.com" })).not.toBeInTheDocument(); | ||
expect(screen.queryByRole("link", { name: "https://example.org" })).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("renders correctly when location and institution are missing", () => { | ||
const userWithoutLocationAndInstitution: User = { | ||
name: "Emily Doe", | ||
email: "[email protected]", | ||
orcid: "0000-0003-4567-8901", | ||
links: ["https://example.com"], | ||
}; | ||
|
||
render(<UserCard user={userWithoutLocationAndInstitution} />); | ||
|
||
const orcidLink = screen.getByRole("link", { | ||
name: "ORCID profile of Emily Doe", | ||
}); | ||
expect(orcidLink).toHaveAttribute("href", "https://orcid.org/0000-0003-4567-8901"); | ||
const emailLink = screen.getByRole("link", { name: "[email protected]" }); | ||
expect(emailLink).toHaveAttribute("href", "mailto:[email protected]"); | ||
const link = screen.getByRole("link", { name: "https://example.com" }); | ||
expect(link).toHaveAttribute("href", "https://example.com"); | ||
expect(screen.queryByText("San Francisco, CA")).not.toBeInTheDocument(); | ||
expect(screen.queryByText("University of California")).not.toBeInTheDocument(); | ||
}); | ||
}); |
60 changes: 60 additions & 0 deletions
60
packages/openneuro-app/src/scripts/users/__tests__/user-query.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React from "react"; | ||
import { render, screen } from "@testing-library/react"; | ||
import { MemoryRouter, Route, Routes } from "react-router-dom"; | ||
import { UserQuery } from "../user-query"; | ||
import FourOFourPage from "../../errors/404page"; | ||
|
||
|
||
// TODO update these once the correct query is in place and dummy data is not used. | ||
// maybe there is a better way to do this | ||
const VALID_ORCID = "0000-0001-6755-0259"; | ||
const INVALID_ORCID = "0000-000X-1234-5678"; | ||
const UNKNOWN_ORCID = "0000-0000-0000-0000"; | ||
|
||
const renderWithRouter = (orcid: string) => { | ||
return render( | ||
<MemoryRouter initialEntries={[`/user/${orcid}`]}> | ||
<Routes> | ||
<Route path="/user/:orcid" element={<UserQuery />} /> | ||
<Route path="*" element={<FourOFourPage />} /> | ||
</Routes> | ||
</MemoryRouter> | ||
); | ||
}; | ||
|
||
describe("UserQuery Component", () => { | ||
// TODO update these once the correct query is in place and dummy data is not used. | ||
// maybe there is a better way to do this | ||
it("renders UserRoutes for a valid ORCID", async () => { | ||
renderWithRouter(VALID_ORCID); | ||
const userName = await screen.findByText("Gregory Noack"); | ||
expect(userName).toBeInTheDocument(); | ||
|
||
const userLocation = screen.getByText("Stanford, CA"); | ||
expect(userLocation).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders FourOFourPage for an invalid ORCID", async () => { | ||
renderWithRouter(INVALID_ORCID); | ||
const errorMessage = await screen.findByText( | ||
/404: The page you are looking for does not exist./i | ||
); | ||
expect(errorMessage).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders FourOFourPage for a missing ORCID", async () => { | ||
renderWithRouter(""); | ||
const errorMessage = await screen.findByText( | ||
/404: The page you are looking for does not exist./i | ||
); | ||
expect(errorMessage).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders FourOFourPage for an unknown ORCID", async () => { | ||
renderWithRouter(UNKNOWN_ORCID); | ||
const errorMessage = await screen.findByText( | ||
/404: The page you are looking for does not exist./i | ||
); | ||
expect(errorMessage).toBeInTheDocument(); | ||
}); | ||
}); |
71 changes: 71 additions & 0 deletions
71
packages/openneuro-app/src/scripts/users/__tests__/user-routes.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React from "react"; | ||
import { render, screen, cleanup } from "@testing-library/react"; | ||
import { MemoryRouter } from "react-router-dom"; | ||
import { UserRoutes } from "../user-routes"; | ||
import type { User } from "../user-routes"; | ||
|
||
const defaultUser: User = { | ||
id: "1", | ||
name: "John Doe", | ||
location: "Unknown", | ||
github: "", | ||
institution: "Unknown Institution", | ||
email: "[email protected]", | ||
avatar: "https://dummyimage.com/200x200/000/fff", | ||
orcid: "0000-0000-0000-0000", | ||
links: [], | ||
}; | ||
|
||
const renderWithRouter = (user: User, route: string, hasEdit: boolean) => { | ||
return render( | ||
<MemoryRouter initialEntries={[route]}> | ||
<UserRoutes user={user} hasEdit={hasEdit} /> | ||
</MemoryRouter> | ||
); | ||
}; | ||
|
||
describe("UserRoutes Component", () => { | ||
const user: User = defaultUser; | ||
|
||
it("renders UserDatasetsView for the default route", async () => { | ||
renderWithRouter(user, "/", true); | ||
expect(screen.getByText(`${user.name}'s Datasets`)).toBeInTheDocument(); | ||
const datasetsView = await screen.findByTestId("user-datasets-view"); | ||
expect(datasetsView).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders FourOFourPage for an invalid route", async () => { | ||
renderWithRouter(user, "/nonexistent-route", true); | ||
const errorMessage = await screen.findByText( | ||
/404: The page you are looking for does not exist./i | ||
); | ||
expect(errorMessage).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders UserAccountView when hasEdit is true", async () => { | ||
renderWithRouter(user, "/account", true); | ||
const accountView = await screen.findByTestId("user-account-view"); | ||
expect(accountView).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders UserNotificationsView when hasEdit is true", async () => { | ||
renderWithRouter(user, "/notifications", true); | ||
const notificationsView = await screen.findByTestId( | ||
"user-notifications-view" | ||
); | ||
expect(notificationsView).toBeInTheDocument(); | ||
}); | ||
|
||
it("renders FourOThreePage when hasEdit is false for restricted routes", async () => { | ||
const restrictedRoutes = ["/account", "/notifications"]; | ||
|
||
for (const route of restrictedRoutes) { | ||
cleanup(); | ||
renderWithRouter(user, route, false); | ||
const errorMessage = await screen.findByText( | ||
/403: You do not have access to this page, you may need to sign in./i | ||
); | ||
expect(errorMessage).toBeInTheDocument(); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.