user-actions.test.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { render, screen } from "@testing-library/react";
  2. import { describe, expect, it, test, vi, afterEach } from "vitest";
  3. import userEvent from "@testing-library/user-event";
  4. import { UserActions } from "#/components/features/sidebar/user-actions";
  5. describe("UserActions", () => {
  6. const user = userEvent.setup();
  7. const onClickAccountSettingsMock = vi.fn();
  8. const onLogoutMock = vi.fn();
  9. afterEach(() => {
  10. onClickAccountSettingsMock.mockClear();
  11. onLogoutMock.mockClear();
  12. });
  13. it("should render", () => {
  14. render(
  15. <UserActions
  16. onClickAccountSettings={onClickAccountSettingsMock}
  17. onLogout={onLogoutMock}
  18. />,
  19. );
  20. expect(screen.getByTestId("user-actions")).toBeInTheDocument();
  21. expect(screen.getByTestId("user-avatar")).toBeInTheDocument();
  22. });
  23. it("should toggle the user menu when the user avatar is clicked", async () => {
  24. render(
  25. <UserActions
  26. onClickAccountSettings={onClickAccountSettingsMock}
  27. onLogout={onLogoutMock}
  28. />,
  29. );
  30. const userAvatar = screen.getByTestId("user-avatar");
  31. await user.click(userAvatar);
  32. expect(
  33. screen.getByTestId("account-settings-context-menu"),
  34. ).toBeInTheDocument();
  35. await user.click(userAvatar);
  36. expect(
  37. screen.queryByTestId("account-settings-context-menu"),
  38. ).not.toBeInTheDocument();
  39. });
  40. it("should call onClickAccountSettings and close the menu when the account settings option is clicked", async () => {
  41. render(
  42. <UserActions
  43. onClickAccountSettings={onClickAccountSettingsMock}
  44. onLogout={onLogoutMock}
  45. />,
  46. );
  47. const userAvatar = screen.getByTestId("user-avatar");
  48. await user.click(userAvatar);
  49. const accountSettingsOption = screen.getByText("Account Settings");
  50. await user.click(accountSettingsOption);
  51. expect(onClickAccountSettingsMock).toHaveBeenCalledOnce();
  52. expect(
  53. screen.queryByTestId("account-settings-context-menu"),
  54. ).not.toBeInTheDocument();
  55. });
  56. it("should call onLogout and close the menu when the logout option is clicked", async () => {
  57. render(
  58. <UserActions
  59. onClickAccountSettings={onClickAccountSettingsMock}
  60. onLogout={onLogoutMock}
  61. user={{ avatar_url: "https://example.com/avatar.png" }}
  62. />,
  63. );
  64. const userAvatar = screen.getByTestId("user-avatar");
  65. await user.click(userAvatar);
  66. const logoutOption = screen.getByText("Logout");
  67. await user.click(logoutOption);
  68. expect(onLogoutMock).toHaveBeenCalledOnce();
  69. expect(
  70. screen.queryByTestId("account-settings-context-menu"),
  71. ).not.toBeInTheDocument();
  72. });
  73. test("onLogout should not be called when the user is not logged in", async () => {
  74. render(
  75. <UserActions
  76. onClickAccountSettings={onClickAccountSettingsMock}
  77. onLogout={onLogoutMock}
  78. />,
  79. );
  80. const userAvatar = screen.getByTestId("user-avatar");
  81. await user.click(userAvatar);
  82. const logoutOption = screen.getByText("Logout");
  83. await user.click(logoutOption);
  84. expect(onLogoutMock).not.toHaveBeenCalled();
  85. });
  86. // FIXME: Spinner now provided through useQuery
  87. it.skip("should display the loading spinner", () => {
  88. render(
  89. <UserActions
  90. onClickAccountSettings={onClickAccountSettingsMock}
  91. onLogout={onLogoutMock}
  92. user={{ avatar_url: "https://example.com/avatar.png" }}
  93. />,
  94. );
  95. const userAvatar = screen.getByTestId("user-avatar");
  96. user.click(userAvatar);
  97. expect(screen.getByTestId("loading-spinner")).toBeInTheDocument();
  98. expect(screen.queryByAltText("user avatar")).not.toBeInTheDocument();
  99. });
  100. });