Skip to content

Commit

Permalink
Merge pull request #112 from NCAR/prettier-patches
Browse files Browse the repository at this point in the history
Fixes by prettier action
  • Loading branch information
LucientZ authored Feb 24, 2025
2 parents 16affbf + 611a321 commit 976a4ad
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 98 deletions.
7 changes: 4 additions & 3 deletions frontend/src/API/API_GetMethods.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,11 @@ export async function getUserById(id: string): Promise<User> {
*/
export async function getGoogleAuthUser(): Promise<UserClaims | null> {
try {
const response = await axios.get<UserClaims>(`${AUTH_URL}/google/whoami`, { withCredentials: true, });
const response = await axios.get<UserClaims>(`${AUTH_URL}/google/whoami`, {
withCredentials: true,
});
return response.data;
}
catch (error: any) {
} catch (error: any) {
console.error(`Error fetching current user: ${error}`);
return null;
}
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/components/HeaderFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,14 @@ export const Footer = () => {
</Typography>
<br />
<Typography variant="inherit">
Britt Schiller, Ore Ogunleye, Nishka Mittal, Josh Hare, Sydney Ferris <br />
Britt Schiller, Ore Ogunleye, Nishka Mittal, Josh Hare, Sydney
Ferris <br />
Fall 2024 Capstone Team
</Typography>
<br />
<Typography variant="inherit">
Jackson Stewart, Kaili Fogle, Robbie Cook, Donato Curvino, James Fontenot <br />
Jackson Stewart, Kaili Fogle, Robbie Cook, Donato Curvino, James
Fontenot <br />
Spring 2025 Capstone Team
</Typography>
<br />
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/pages/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
let userInfo: User | null = storedUser ? JSON.parse(storedUser) : null;

const authInfo = await getGoogleAuthUser();
if (authInfo?.email && (!userInfo || userInfo?.email != authInfo?.email)) {
if (
authInfo?.email &&
(!userInfo || userInfo?.email != authInfo?.email)
) {
userInfo = await getUserByEmail(authInfo?.email);
setUser(userInfo);
localStorage.setItem("user", JSON.stringify(userInfo));
}
else if (!authInfo?.nameId) {
} else if (!authInfo?.nameId) {
setUser(null);
localStorage.removeItem("user");
}
else {
} else {
setUser(userInfo);
}
};
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/pages/logIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ const LogIn: React.FC = () => {
`${AUTH_URL}/google/logout?returnUrl=${returnUrl}`,
);
window.location.assign(loginUrl);
}
else {
} else {
navigate("loggedIn");
}
};
Expand Down
181 changes: 95 additions & 86 deletions frontend/test/logIn.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import axios, { AxiosHeaders, AxiosResponse } from "axios";
vi.mock("axios");

const mockUserInfo: User = {
"role": "admin",
"email": "test@email.com",
"username": "Test Account",
}
role: "admin",
email: "test@email.com",
username: "Test Account",
};

describe("Unauthenticated LogIn Component", () => {
const originalLocation = window.location;
Expand All @@ -41,15 +41,18 @@ describe("Unauthenticated LogIn Component", () => {
}

beforeEach(() => {
window.location = { ...originalLocation, assign: vi.fn((_: string | URL) => { }) };
window.location = {
...originalLocation,
assign: vi.fn((_: string | URL) => {}),
};
vi.spyOn(axios, "get").mockResolvedValue(createMockUserData());

render(
<AuthProvider>
<MemoryRouter initialEntries={['/', '/loggedIn']}>
<MemoryRouter initialEntries={["/", "/loggedIn"]}>
<LogIn />
</MemoryRouter>
</AuthProvider>
</AuthProvider>,
);
});

Expand All @@ -60,12 +63,11 @@ describe("Unauthenticated LogIn Component", () => {
});

it("should render the login button and the guest button", () => {
expect(screen.getByText("Sign in")).toBeTruthy(); // Check presence of the login button
expect(screen.getByText("Continue as Guest")).toBeTruthy(); // Check presence of the guest button
expect(screen.getByText("Sign in")).toBeTruthy(); // Check presence of the login button
expect(screen.getByText("Continue as Guest")).toBeTruthy(); // Check presence of the guest button
});

it("should open and close the About modal", async () => {

const aboutButton = screen.getAllByRole("button", { name: "About" })[0];
fireEvent.click(aboutButton);

Expand Down Expand Up @@ -98,91 +100,98 @@ describe("Unauthenticated LogIn Component", () => {
describe.each([
["", mockUserInfo],
["with uncached user", null],
["with other cached user", {
email: "wronguser@gmail.co.uk",
role: "unauthenticated",
username: "John Doe"
}],
])
("Authenticated LogIn Component %s", (_, cachedUserInfo) => {
const originalLocation = window.location;

function createMockUserData(): AxiosResponse {
return {
data: {
nameId: "1234567890",
email: mockUserInfo.email,
id: "1234",
username: mockUserInfo.username,
role: mockUserInfo.role,
} as UserClaims & User,
status: 200,
statusText: "OK",
headers: {},
config: {
headers: new AxiosHeaders({ "Content-Type": "text/plain" }),
},
} as AxiosResponse;
}

beforeEach(async () => {
vi.spyOn(axios, "get").mockResolvedValue(createMockUserData());
window.location = { ...originalLocation, assign: vi.fn((_: string | URL) => { }) };
localStorage.setItem("user", JSON.stringify(cachedUserInfo));
render(
<AuthProvider>
<MemoryRouter initialEntries={['/', '/loggedIn']}>
<LogIn />
</MemoryRouter>
</AuthProvider>
);

await act(() => axios.get); // Allows the initial useLayoutEffect to fire
});

afterEach(() => {
cleanup();
window.location = originalLocation;
localStorage.clear();
});
[
"with other cached user",
{
email: "wronguser@gmail.co.uk",
role: "unauthenticated",
username: "John Doe",
},
],
])("Authenticated LogIn Component %s", (_, cachedUserInfo) => {
const originalLocation = window.location;

it("shows different buttons when logged in", () => {
expect(screen.getByText(`Continue as ${mockUserInfo.username}`)).toBeTruthy();
expect(screen.getByText("Switch Account")).toBeTruthy();
expect(screen.getByText("Continue as Guest")).toBeTruthy();
});
function createMockUserData(): AxiosResponse {
return {
data: {
nameId: "1234567890",
email: mockUserInfo.email,
id: "1234",
username: mockUserInfo.username,
role: mockUserInfo.role,
} as UserClaims & User,
status: 200,
statusText: "OK",
headers: {},
config: {
headers: new AxiosHeaders({ "Content-Type": "text/plain" }),
},
} as AxiosResponse;
}

it("navigates to the backend when switching accounts", () => {
const loginButton = screen.getByText("Switch Account");
expect(loginButton).toBeTruthy();
fireEvent.click(loginButton);
expect(window.location.assign).toHaveBeenCalledOnce(); // Redirect to backend auth/google/login endpoint
});
beforeEach(async () => {
vi.spyOn(axios, "get").mockResolvedValue(createMockUserData());
window.location = {
...originalLocation,
assign: vi.fn((_: string | URL) => {}),
};
localStorage.setItem("user", JSON.stringify(cachedUserInfo));
render(
<AuthProvider>
<MemoryRouter initialEntries={["/", "/loggedIn"]}>
<LogIn />
</MemoryRouter>
</AuthProvider>,
);

it("navigates to the backend when continuing as a guest", () => {
const guestButton = screen.getByText("Continue as Guest");
expect(guestButton).toBeTruthy();
fireEvent.click(guestButton);
expect(window.location.assign).toHaveBeenCalledOnce();
});
await act(() => axios.get); // Allows the initial useLayoutEffect to fire
});

it("removes user from local storage when logging out", () => {
expect(document.getElementById("side-nav-button")).toBeTruthy();
expect(localStorage.getItem("user")).toBeTruthy();
afterEach(() => {
cleanup();
window.location = originalLocation;
localStorage.clear();
});

// Open side nav
const hamburgerMenu: HTMLElement = document.getElementById("side-nav-button")!;
fireEvent.click(hamburgerMenu);
it("shows different buttons when logged in", () => {
expect(
screen.getByText(`Continue as ${mockUserInfo.username}`),
).toBeTruthy();
expect(screen.getByText("Switch Account")).toBeTruthy();
expect(screen.getByText("Continue as Guest")).toBeTruthy();
});

// Click logout button
const logoutButton = screen.getByText("Log Out");
fireEvent.click(logoutButton);
it("navigates to the backend when switching accounts", () => {
const loginButton = screen.getByText("Switch Account");
expect(loginButton).toBeTruthy();
fireEvent.click(loginButton);
expect(window.location.assign).toHaveBeenCalledOnce(); // Redirect to backend auth/google/login endpoint
});

expect(window.location.assign).toHaveBeenCalledOnce(); // Redirect to backend auth/google/logout endpoint
expect(localStorage.getItem("user")).toBeFalsy();
});
it("navigates to the backend when continuing as a guest", () => {
const guestButton = screen.getByText("Continue as Guest");
expect(guestButton).toBeTruthy();
fireEvent.click(guestButton);
expect(window.location.assign).toHaveBeenCalledOnce();
});

it("removes user from local storage when logging out", () => {
expect(document.getElementById("side-nav-button")).toBeTruthy();
expect(localStorage.getItem("user")).toBeTruthy();

// Open side nav
const hamburgerMenu: HTMLElement =
document.getElementById("side-nav-button")!;
fireEvent.click(hamburgerMenu);

// Click logout button
const logoutButton = screen.getByText("Log Out");
fireEvent.click(logoutButton);

expect(window.location.assign).toHaveBeenCalledOnce(); // Redirect to backend auth/google/logout endpoint
expect(localStorage.getItem("user")).toBeFalsy();
});
});

describe("Sanity Check Tests", () => {
it("should always pass test 1", () => {
Expand Down

0 comments on commit 976a4ad

Please sign in to comment.