Skip to content

Commit

Permalink
Merge pull request #98 from Arquisoft/96-realizar-pruebas-de-la-funci…
Browse files Browse the repository at this point in the history
…onalidad-de-amistades

Prueba
  • Loading branch information
CANCI0 authored Apr 7, 2024
2 parents c5e1804 + 9bca156 commit 430e8b6
Show file tree
Hide file tree
Showing 5 changed files with 263 additions and 22 deletions.
2 changes: 1 addition & 1 deletion users/userservice/user-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ app.post('/users/remove-friend', async (req, res) => {
// Route to get friends of the authenticated user
app.get('/friends', async (req, res) => {
try {
const username = req.query.user;
const username = req.query.user;

// Buscar al usuario por su nombre de usuario
const user = await User.findOne({ username });

Check failure

Code scanning / SonarCloud

NoSQL operations should not be vulnerable to injection attacks High

Change this code to not construct database queries directly from user-controlled data. See more on SonarCloud
Expand Down
3 changes: 1 addition & 2 deletions webapp/src/pages/Social/FriendsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ const FriendList = () => {
{t('pages.friendlist.profile')}
</Button>
<Button onClick={() => handleRemoveFriend(friend)}>
{t('pages.friendlist.delete')}
</Button>
{t('pages.friendlist.delete')}</Button>
</ListItem>
{index !== friends.length - 1 && <Divider />}
</div>
Expand Down
155 changes: 155 additions & 0 deletions webapp/src/pages/Social/FriendsList.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import React from "react";
import {
render,
screen,
waitFor,
fireEvent,
act,
} from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import FriendList from "./FriendsList.js";
import { I18nextProvider } from "react-i18next";
import i18n from "../../i18n.js";

const renderComponent = () => {
act(() => {
render(
<I18nextProvider i18n={i18n}>
<MemoryRouter>
<FriendList />
</MemoryRouter>
</I18nextProvider>
);
});
};

const checkFriends = async () => {
await waitFor(() => {
expect(screen.getByText("Friend 1")).toBeInTheDocument();
expect(screen.getByText("Friend 2")).toBeInTheDocument();
expect(screen.getByText("Friend 3")).toBeInTheDocument();
});
};

describe("FriendList Component", () => {
beforeEach(() => {
jest.clearAllMocks();
});

test("renders loading state", () => {
renderComponent();

expect(screen.getByText("Cargando ...")).toBeInTheDocument();
});

test("renders friend list", async () => {
const mockFriends = ["Friend 1", "Friend 2", "Friend 3"];
jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce({ friends: mockFriends }),
});

renderComponent();

await waitFor(() => {
expect(screen.getByText("Lista de amigos")).toBeInTheDocument();
expect(screen.getByText("Friend 1")).toBeInTheDocument();
expect(screen.getByText("Friend 2")).toBeInTheDocument();
});
});

test("renders no friends message", async () => {
jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce({ friends: [] }),
});

renderComponent();

await waitFor(() => {
expect(
screen.getByText("No tienes amigos actualmente.")
).toBeInTheDocument();
});
});

test("navigates to friend profile", async () => {
const mockFriends = ["Friend 1", "Friend 2", "Friend 3"];
jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce({ friends: mockFriends }),
});

renderComponent();

const data = {
username: "admin",
createdAt: "2024-01-30T14:59:11.576Z",
games: [
{
correctAnswers: 5,
incorrectAnswers: 4,
points: 5,
avgTime: 0,
},
{
correctAnswers: 0,
incorrectAnswers: 0,
points: 0,
avgTime: 0,
},
],
};

jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce(data),
});

checkFriends();

await waitFor(() => {
fireEvent.click(
screen.getAllByRole("button", { name: /Ver perfil/i })[0]
);
});

await waitFor(() => {
expect(screen.getByText("Perfil de usuario")).toBeInTheDocument();
});

fireEvent.click(screen.getByRole("button", { name: /Volver/i }));
});

test("fetch returns error", async () => {
global.fetch.mockRejectedValue(new Error("Failed to fetch"));
jest.spyOn(global, "fetch").mockResolvedValueOnce({ ok: false });

renderComponent();

await waitFor(() => {
expect(
screen.getByText("No tienes amigos actualmente.")
).toBeInTheDocument();
});
});

test("remove friend returns error", async () => {
const mockFriends = ["Friend 1", "Friend 2", "Friend 3"];
jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce({ friends: mockFriends }),
});

renderComponent();

checkFriends();

jest
.spyOn(global, "fetch")
.mockRejectedValueOnce(new Error("Failed to fetch"));

await waitFor(() => {
fireEvent.click(
screen.getAllByRole("button", { name: /eliminar amigo/i })[0]
);
});

expect(screen.getByText("Friend 3")).toBeInTheDocument();
});
});
34 changes: 15 additions & 19 deletions webapp/src/pages/Social/UsersPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Th,
Td,
Flex,
Text
Text,
} from "@chakra-ui/react";
import Nav from "../../components/Nav/Nav.js";
import Footer from "../../components/Footer/Footer.js";
Expand All @@ -21,29 +21,29 @@ const UserList = ({ users, handleAddFriend }) => {

return (
<div>
<Heading as="h2">{t('pages.userspage.list')}</Heading>
<Heading as="h2">{t("pages.userspage.list")}</Heading>
<Table>
<Thead>
<Tr>
<Th textAlign="center">{t('pages.userspage.user')}</Th>
<Th>{t('pages.userspage.actions')}</Th>
<Th textAlign="center">{t("pages.userspage.user")}</Th>
<Th>{t("pages.userspage.actions")}</Th>
</Tr>
</Thead>
<Tbody>
{users.map((user) => (
<Tr key={user._id}>
<Td>
<Flex flexDirection="column" alignItems="center">
<Avatar name={user.username}/>
<Avatar name={user.username} />
<Text>{user.username}</Text>
</Flex>
</Td>
<Td>
{user.isFriend ? (
<span>{t('pages.userspage.friend')}</span>
<span>{t("pages.userspage.friend")}</span>
) : (
<Button onClick={() => handleAddFriend(user)}>
{t('pages.userspage.addFriend')}
{t("pages.userspage.addFriend")}
</Button>
)}
</Td>
Expand All @@ -70,22 +70,14 @@ const UsersPage = () => {
// eslint-disable-next-line
}, []);

const fetchUsers = () => {
setIsLoading(true);
fetch(`${apiEndpoint}/users/search?username=${currentUser}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
const fetchUsers = async () => {
fetch(`${apiEndpoint}/users/search?username=${currentUser}`)
.then((response) => response.json())
.then((data) => {
console.log(data);
setUsers(data);
setIsLoading(false);
})
.catch((error) => {
console.error("Error fetching users:", error);
setError(
error.message || "Ha ocurrido un error al obtener los usuarios"
);
Expand Down Expand Up @@ -132,8 +124,12 @@ const UsersPage = () => {
<>
<Nav />
<div>
{isLoading && <p>{t('pages.userspage.loading')}</p>}
{error && <p>{t('pages.userspage.error')} {error}</p>}
{isLoading && <p>{t("pages.userspage.loading")}</p>}
{error && (
<p>
{t("pages.userspage.error")} {error}
</p>
)}
<UserList users={users} handleAddFriend={handleAddFriend} />
</div>
<Footer />
Expand Down
91 changes: 91 additions & 0 deletions webapp/src/pages/Social/UsersPage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React from "react";
import { render, screen, waitFor, fireEvent } from "@testing-library/react";
import UsersPage from "./UsersPage";
import { MemoryRouter } from "react-router-dom";
import { I18nextProvider } from "react-i18next";
import i18n from "../../i18n.js";

// Mock de la función fetch
const mockData = [
{ _id: "1", username: "user1", isFriend: false },
{ _id: "2", username: "user2", isFriend: true },
];

// Antes de cada prueba, limpiar los mocks
beforeEach(() => {
jest.clearAllMocks();
});

describe("UsersPage", () => {
beforeEach(() => {
jest.spyOn(global, "fetch").mockResolvedValueOnce({
json: jest.fn().mockResolvedValueOnce(mockData),
});

render(
<I18nextProvider i18n={i18n}>
<MemoryRouter>
<UsersPage />
</MemoryRouter>
</I18nextProvider>
);
});

test("renders loading message", () => {
expect(screen.getByText("Cargando usuarios ...")).toBeInTheDocument();
});

test("renders error message", async () => {
global.fetch.mockImplementationOnce(() =>
Promise.reject(new Error("Fetch error"))
);

await waitFor(() => {
expect(screen.getByText("Amigo")).toBeInTheDocument();
});
});

test("renders user list", async () => {
await waitFor(() => {
expect(screen.getByText("user1")).toBeInTheDocument();
expect(screen.getByText("user2")).toBeInTheDocument();
});
});

test("adds friend successfully", async () => {
await waitFor(() => {
expect(screen.getByText("user1")).toBeInTheDocument();
});

fireEvent.click(
screen.getAllByRole("button", { name: /Añadir amigo/i })[0]
);

await waitFor(() => {
expect(screen.getByText("Amigo")).toBeInTheDocument();
});
});

test("handles add friend error", async () => {
global.fetch.mockImplementationOnce(() =>
Promise.resolve({
ok: false,
json: () => Promise.resolve({ error: "Add friend error" }),
})
);

await waitFor(() => {
expect(screen.getByText("user1")).toBeInTheDocument();
});

fireEvent.click(
screen.getAllByRole("button", { name: /Añadir amigo/i })[0]
);

await waitFor(() => {
expect(screen.getByText("Amigo")).toBeInTheDocument();
});
});

});

0 comments on commit 430e8b6

Please sign in to comment.