| 
1 |  | -"use strict";  | 
2 |  | - | 
 | 1 | +import { describe, it, expect, vi, beforeEach } from "vitest";  | 
 | 2 | +import { render, screen, fireEvent } from "@testing-library/react";  | 
 | 3 | +import "@testing-library/jest-dom";  | 
3 | 4 | import React from "react";  | 
 | 5 | +import UserRow from "../../../src/components/user/UserRow.jsx";  | 
4 | 6 | import { IntlProvider } from "react-intl";  | 
5 |  | -import TestUtils from "react-dom/test-utils";  | 
6 |  | -import UserRow from "../../../src/components/user/UserRow";  | 
7 |  | -import enLang from "../../../src/i18n/en";  | 
8 |  | -import { describe, expect, it, vi } from "vitest";  | 
 | 7 | +import enLang from "../../../src/i18n/en.js";  | 
 | 8 | +import { isUsingOidcAuth } from "../../../src/utils/OidcUtils.js";  | 
 | 9 | + | 
 | 10 | +vi.mock("../../../src/utils/OidcUtils", () => ({  | 
 | 11 | +  isUsingOidcAuth: vi.fn(() => false),  | 
 | 12 | +}));  | 
9 | 13 | 
 
  | 
10 |  | -describe("UserRow", function () {  | 
 | 14 | +const renderWithIntl = (ui) => {  | 
11 | 15 |   const intlData = enLang;  | 
12 |  | -  let user,  | 
13 |  | -    deletionLoading = false,  | 
14 |  | -    onEdit = vi.fn(),  | 
15 |  | -    onDelete = vi.fn();  | 
16 |  | - | 
17 |  | -  user = {  | 
18 |  | -    uri: "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch",  | 
19 |  | -    firstName: "Test1",  | 
20 |  | -    lastName: "Man",  | 
21 |  | -    username: "testman1",  | 
22 |  | -    emailAddress:  "[email protected]",  | 
23 |  | -    institution: {  | 
24 |  | -      uri: "http://test.io",  | 
25 |  | -      key: "823372507340798303",  | 
26 |  | -      name: "Test Institution",  | 
27 |  | -      emailAddress:  "[email protected]",  | 
28 |  | -    },  | 
29 |  | -    types: [  | 
30 |  | -      "http://onto.fel.cvut.cz/ontologies/record-manager/administrator",  | 
31 |  | -      "http://onto.fel.cvut.cz/ontologies/record-manager/doctor",  | 
32 |  | -    ],  | 
 | 16 | +  return render(  | 
 | 17 | +    <IntlProvider locale="en" {...intlData}>  | 
 | 18 | +      {ui}  | 
 | 19 | +    </IntlProvider>,  | 
 | 20 | +  );  | 
 | 21 | +};  | 
 | 22 | + | 
 | 23 | +const mockUser = {  | 
 | 24 | +  uri: "http://onto.fel.cvut.cz/ontologies/record-manager/Admin-Administratorowitch",  | 
 | 25 | +  firstName: "Test1",  | 
 | 26 | +  lastName: "Man",  | 
 | 27 | +  username: "testman1",  | 
 | 28 | +  emailAddress:  "[email protected]",  | 
 | 29 | +  institution: {  | 
 | 30 | +    uri: "http://test.io",  | 
 | 31 | +    key: "823372507340798303",  | 
 | 32 | +    name: "Test Institution",  | 
 | 33 | +    emailAddress:  "[email protected]",  | 
 | 34 | +  },  | 
 | 35 | +  types: [  | 
 | 36 | +    "http://onto.fel.cvut.cz/ontologies/record-manager/administrator",  | 
 | 37 | +    "http://onto.fel.cvut.cz/ontologies/record-manager/doctor",  | 
 | 38 | +  ],  | 
 | 39 | +};  | 
 | 40 | + | 
 | 41 | +describe("UserRow", () => {  | 
 | 42 | +  const renderComponent = (user = mockUser, overrides = {}) => {  | 
 | 43 | +    return renderWithIntl(<UserRow user={user} onEdit={vi.fn()} onDelete={vi.fn()} {...overrides} />);  | 
33 | 44 |   };  | 
34 | 45 | 
 
  | 
35 |  | -  it("renders one row of table with 5 columns and 2 buttons and 1 link button", function () {  | 
36 |  | -    const tree = TestUtils.renderIntoDocument(  | 
37 |  | -      <IntlProvider locale="en" {...intlData}>  | 
38 |  | -        <table>  | 
39 |  | -          <tbody>  | 
40 |  | -            <UserRow user={user} onEdit={onEdit} onDelete={onDelete} deletionLoading={deletionLoading} />  | 
41 |  | -          </tbody>  | 
42 |  | -        </table>  | 
43 |  | -      </IntlProvider>,  | 
44 |  | -    );  | 
45 |  | -    const td = TestUtils.scryRenderedDOMComponentsWithTag(tree, "td");  | 
46 |  | -    expect(td.length).toEqual(5);  | 
47 |  | -    const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button");  | 
48 |  | -    expect(buttons.length).toEqual(3);  | 
 | 46 | +  beforeEach(() => {  | 
 | 47 | +    vi.clearAllMocks();  | 
 | 48 | +  });  | 
 | 49 | + | 
 | 50 | +  it("renders user full name as a link button with correct tooltip", () => {  | 
 | 51 | +    const { getByRole } = renderComponent();  | 
 | 52 | +    const fullName = `${mockUser.firstName} ${mockUser.lastName}`;  | 
 | 53 | +    const nameButton = getByRole("button", { name: new RegExp(fullName, "i") });  | 
 | 54 | +    expect(nameButton).toBeInTheDocument();  | 
 | 55 | +    expect(nameButton).toHaveAttribute("title", "View and edit details of this user");  | 
 | 56 | +  });  | 
 | 57 | + | 
 | 58 | +  it("renders username correctly", () => {  | 
 | 59 | +    renderComponent();  | 
 | 60 | +    expect(screen.getByText(mockUser.username)).toBeInTheDocument();  | 
 | 61 | +  });  | 
 | 62 | + | 
 | 63 | +  it("renders institution name when present", () => {  | 
 | 64 | +    renderComponent();  | 
 | 65 | +    expect(screen.getByText(mockUser.institution.name)).toBeInTheDocument();  | 
 | 66 | +  });  | 
 | 67 | + | 
 | 68 | +  it("renders email address correctly", () => {  | 
 | 69 | +    renderComponent();  | 
 | 70 | +    expect(screen.getByText(mockUser.emailAddress)).toBeInTheDocument();  | 
 | 71 | +  });  | 
 | 72 | + | 
 | 73 | +  it("renders Open button with correct text and tooltip", () => {  | 
 | 74 | +    const { getByRole } = renderComponent();  | 
 | 75 | +    const openButton = getByRole("button", { name: /Open/i });  | 
 | 76 | +    expect(openButton).toBeInTheDocument();  | 
 | 77 | +    expect(openButton).toHaveAttribute("title", "View and edit details of this user");  | 
 | 78 | +  });  | 
 | 79 | + | 
 | 80 | +  it("renders Delete button with correct text and tooltip when not using OIDC", () => {  | 
 | 81 | +    const { getByRole } = renderComponent();  | 
 | 82 | +    const deleteButton = getByRole("button", { name: /Delete/i });  | 
 | 83 | +    expect(deleteButton).toBeInTheDocument();  | 
 | 84 | +    expect(deleteButton).toHaveAttribute("title", "Delete this user");  | 
 | 85 | +  });  | 
 | 86 | + | 
 | 87 | +  it("calls onEdit when name link button is clicked", () => {  | 
 | 88 | +    const onEdit = vi.fn();  | 
 | 89 | +    const fullName = `${mockUser.firstName} ${mockUser.lastName}`;  | 
 | 90 | +    const { getByRole } = renderComponent(mockUser, { onEdit });  | 
 | 91 | +    const nameButton = getByRole("button", { name: new RegExp(fullName, "i") });  | 
 | 92 | +    fireEvent.click(nameButton);  | 
 | 93 | +    expect(onEdit).toHaveBeenCalledTimes(1);  | 
 | 94 | +    expect(onEdit).toHaveBeenCalledWith(mockUser);  | 
 | 95 | +  });  | 
 | 96 | + | 
 | 97 | +  it("calls onEdit when Open button is clicked", () => {  | 
 | 98 | +    const onEdit = vi.fn();  | 
 | 99 | +    const { getByRole } = renderComponent(mockUser, { onEdit });  | 
 | 100 | +    const openButton = getByRole("button", { name: /Open/i });  | 
 | 101 | +    fireEvent.click(openButton);  | 
 | 102 | +    expect(onEdit).toHaveBeenCalledTimes(1);  | 
 | 103 | +    expect(onEdit).toHaveBeenCalledWith(mockUser);  | 
49 | 104 |   });  | 
50 | 105 | 
 
  | 
51 |  | -  it('renders "Open" button and click on it', function () {  | 
52 |  | -    const tree = TestUtils.renderIntoDocument(  | 
53 |  | -      <IntlProvider locale="en" {...intlData}>  | 
54 |  | -        <table>  | 
55 |  | -          <tbody>  | 
56 |  | -            <UserRow user={user} onEdit={onEdit} onDelete={onDelete} deletionLoading={deletionLoading} />  | 
57 |  | -          </tbody>  | 
58 |  | -        </table>  | 
59 |  | -      </IntlProvider>,  | 
60 |  | -    );  | 
61 |  | -    const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button");  | 
62 |  | -    expect(buttons.length).toEqual(3);  | 
63 |  | - | 
64 |  | -    TestUtils.Simulate.click(buttons[0]); // Open User  | 
65 |  | -    expect(onEdit).toHaveBeenCalled();  | 
 | 106 | +  it("calls onDelete when Delete button is clicked", () => {  | 
 | 107 | +    const onDelete = vi.fn();  | 
 | 108 | +    const { getByRole } = renderComponent(mockUser, { onDelete });  | 
 | 109 | +    const deleteButton = getByRole("button", { name: /Delete/i });  | 
 | 110 | +    fireEvent.click(deleteButton);  | 
 | 111 | +    expect(onDelete).toHaveBeenCalledTimes(1);  | 
 | 112 | +    expect(onDelete).toHaveBeenCalledWith(mockUser);  | 
66 | 113 |   });  | 
67 | 114 | 
 
  | 
68 |  | -  it("renders name with link and click on it", function () {  | 
69 |  | -    const tree = TestUtils.renderIntoDocument(  | 
70 |  | -      <IntlProvider locale="en" {...intlData}>  | 
71 |  | -        <table>  | 
72 |  | -          <tbody>  | 
73 |  | -            <UserRow user={user} onEdit={onEdit} onDelete={onDelete} deletionLoading={deletionLoading} />  | 
74 |  | -          </tbody>  | 
75 |  | -        </table>  | 
76 |  | -      </IntlProvider>,  | 
77 |  | -    );  | 
78 |  | - | 
79 |  | -    const buttons = TestUtils.scryRenderedDOMComponentsWithClass(tree, "btn-link");  | 
80 |  | -    expect(buttons.length).toBe(1);  | 
81 |  | - | 
82 |  | -    TestUtils.Simulate.click(buttons[0]);  | 
83 |  | -    expect(onEdit).toHaveBeenCalled();  | 
 | 115 | +  it("does not render institution name when user has no institution", () => {  | 
 | 116 | +    const userWithoutInstitution = { ...mockUser, institution: undefined };  | 
 | 117 | +    renderComponent(userWithoutInstitution);  | 
 | 118 | +    expect(screen.queryByText(mockUser.institution.name)).not.toBeInTheDocument();  | 
84 | 119 |   });  | 
85 | 120 | 
 
  | 
86 |  | -  it('renders "Delete" button and click on it', function () {  | 
87 |  | -    const tree = TestUtils.renderIntoDocument(  | 
88 |  | -      <IntlProvider locale="en" {...intlData}>  | 
89 |  | -        <table>  | 
90 |  | -          <tbody>  | 
91 |  | -            <UserRow user={user} onEdit={onEdit} onDelete={onDelete} deletionLoading={deletionLoading} />  | 
92 |  | -          </tbody>  | 
93 |  | -        </table>  | 
94 |  | -      </IntlProvider>,  | 
95 |  | -    );  | 
96 |  | -    const buttons = TestUtils.scryRenderedDOMComponentsWithTag(tree, "Button");  | 
97 |  | -    expect(buttons.length).toEqual(3);  | 
98 |  | - | 
99 |  | -    TestUtils.Simulate.click(buttons[2]); // Delete User  | 
100 |  | -    expect(onDelete).toHaveBeenCalled();  | 
 | 121 | +  it("hides Delete button when using OIDC auth", () => {  | 
 | 122 | +    vi.mocked(isUsingOidcAuth).mockReturnValue(true);  | 
 | 123 | +    renderComponent();  | 
 | 124 | +    expect(screen.queryByRole("button", { name: /Delete/i })).not.toBeInTheDocument();  | 
101 | 125 |   });  | 
102 | 126 | });  | 
0 commit comments