Skip to content

Commit

Permalink
Merge pull request #116 from Arquisoft/groups-tests
Browse files Browse the repository at this point in the history
Hechos test de Groups, UserGroups y GroupDetails
  • Loading branch information
iyanfdezz authored Apr 14, 2024
2 parents 9c71df3 + d1ce08f commit d6e9205
Show file tree
Hide file tree
Showing 10 changed files with 457 additions and 59 deletions.
3 changes: 2 additions & 1 deletion users/userservice/user-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ app.post('/group/add', async (req, res) => {
}

const newGroup = new Group({ name: name,
members: [username] });
members: [username],
createdAt:Date.now() });
await newGroup.save();

res.json({ message: 'Group created successfully' });
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
"errorPrefix": "Error: ",
"joinable": "Groups you can join",
"join": "Join group",
"noGroups": "There are no groups available to join."
"nogroups": "There are no groups available to join."
},
"groupsTable": {
"groupName": "Group name",
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@
"errorPrefix": "Error: ",
"joinable": "Grupos a los que puedes unirte",
"join": "Unirse al grupo",
"noGroups": "No hay grupos disponibles para unirse."
"nogroups": "No hay grupos a los que puedas unirte."
},
"groupsTable": {
"groupName": "Nombre del grupo",
Expand Down
83 changes: 56 additions & 27 deletions webapp/src/pages/Social/GroupDetails.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import axios from 'axios';
import { Container, Box, Text, Heading, Table, Thead, Tbody, Tr, Th, Td, Avatar, Link } from '@chakra-ui/react';
import Nav from "../../components/Nav/Nav.js";
import Footer from "../../components/Footer/Footer.js";
Expand All @@ -9,39 +8,71 @@ import { useTranslation } from "react-i18next";
const GroupDetails = () => {
const { t } = useTranslation();
const [group, setGroup] = useState(null);
const [error, setError] = useState(null);
const { groupName } = useParams();
const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
const navigate = useNavigate();

useEffect(() => {
const fetchGroupDetails = async () => {
try {
const response = await axios.get(`${apiEndpoint}/group/${encodeURIComponent(groupName)}`);
setGroup(response.data.group);
} catch (error) {
console.error('Error fetching group details:', error);
}
};

fetchGroupDetails();
}, [groupName]);
}, []);

const fetchGroupDetails = async () => {
try {
const response = await fetch(`${apiEndpoint}/group/${encodeURIComponent(groupName)}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
setGroup(data.group);
setError(null);
} catch (error) {
setError(error);
console.error("Error al obtener los detalles del grupo:", error);
}
};


const redirectToProfile = (username) => {
navigate(`/perfil?user=${username}`);
};

if (error) {
return (
<>
<Nav />
<Box>
<Heading as="h2">Error: {error.message}</Heading>
</Box>
<Footer />
</>
);
}

if (!group) {
return (
<>
<Nav />
<Box>
<Heading as="h2">Cargando...</Heading>
</Box>
<Footer />
</>
);
}

return (
<>
<Nav/>
<Container maxW="md" mt="5">
<Heading as="h1" mb="5">{t('pages.groupdetails.details')} {groupName}</Heading>
{group ? (
group && (
<>
<Nav/>
<Container maxW="md" mt="5">
<Heading as="h1" mb="5">{t('pages.groupdetails.details')} {group.name}</Heading>
<Box>
<Text fontSize="lg" fontWeight="bold" mb="4">
{t('pages.groupdetails.createdBy')} {group.members.length > 0 ? group.members[0] : ''}
{t('pages.groupdetails.when')} {new Date(group.createdAt).toLocaleDateString()}
{t('pages.groupdetails.createdBy')} {group.members.length > 0 ? group.members[0] : ''}
{t('pages.groupdetails.when')} {new Date(group.createdAt).toLocaleDateString()}
</Text>

<Text fontSize="lg" fontWeight="bold" mb="2">{t('pages.groupdetails.participants')} ({group.members.length}) :</Text>
<Table variant="striped">
<Thead>
Expand All @@ -55,23 +86,21 @@ const GroupDetails = () => {
{group.members.map((member, index) => (
<Tr key={index}>
<Td>
<Avatar size="sm" name={member} />
<Avatar size="sm" name={member} data-testid={`user-avatar-${member}`}/>
</Td>
<Td>{member}</Td>
<Td>
<Link color="blue.500" onClick={() => redirectToProfile(member)}>{t('pages.groupdetails.viewProfile')}</Link>
<Link data-testid={`view-profile-button-${member}`} color="blue.500" onClick={() => redirectToProfile(member)}>{t('pages.groupdetails.viewProfile')}</Link>
</Td>
</Tr>
))}
</Tbody>
</Table>
</Box>
) : (
<Text>{t('pages.groupdetails.loading')}</Text>
)}
</Container>
<Footer/>
</>
</Container>
<Footer/>
</>
)
);
};

Expand Down
110 changes: 110 additions & 0 deletions webapp/src/pages/Social/GroupDetails.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React from 'react';
import { render, screen, waitFor, fireEvent } from "@testing-library/react";
import { MemoryRouter } from 'react-router-dom';
import GroupDetails from './GroupDetails';
import { I18nextProvider } from "react-i18next";
import i18n from "../../i18n.js";

const renderComponentWithRouter = async () => {
render(
<I18nextProvider i18n={i18n}>
<MemoryRouter >
<GroupDetails />
</MemoryRouter>
</I18nextProvider>
);
localStorage.setItem("username", "user1");
};

let originalFetch;

beforeEach(() => {
originalFetch = global.fetch;
global.fetch = jest.fn();
});

afterEach(() => {
global.fetch = originalFetch;
jest.restoreAllMocks();
});

const groupData = {
name: 'exampleGroup',
members: ['user1', 'user2'],
createdAt: '2024-04-11T12:00:00Z',
};

const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockNavigate,
}));

describe('GroupDetails', () => {
beforeEach(() => {
localStorage.clear();
});

afterEach(() => {
global.fetch.mockRestore();
});


it('renders loading text when group data is not yet fetched', () => {
jest.spyOn(global, "fetch").mockResolvedValue({
json: jest.fn().mockResolvedValueOnce(groupData),
});
renderComponentWithRouter();
expect(screen.getByText('Cargando...')).toBeInTheDocument();
});

it('renders group details when data is fetched', async () => {

jest.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValueOnce(groupData),
});

renderComponentWithRouter();

await waitFor(() => {
expect(screen.getByText('Detalles del grupo exampleGroup')).toBeInTheDocument();
expect(screen.getByText('Avatar')).toBeInTheDocument();
expect(screen.getByText('Nombre')).toBeInTheDocument();
const viewProfile = screen.getAllByText('Ver perfil');
expect(viewProfile).toHaveLength(3);
expect(screen.getByTestId('user-avatar-user1')).toBeInTheDocument();
expect(screen.getByTestId('user-avatar-user2')).toBeInTheDocument();
expect(screen.getByText('user1')).toBeInTheDocument();
expect(screen.getByText('user2')).toBeInTheDocument();
});
});

it('redirects to user profile when view profile link is clicked', async () => {

jest.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: jest.fn().mockResolvedValueOnce(groupData),
});

renderComponentWithRouter();

await waitFor(() => {
expect(screen.getByText('Detalles del grupo exampleGroup')).toBeInTheDocument();
expect(screen.getByText('Avatar')).toBeInTheDocument();
expect(screen.getByText('Nombre')).toBeInTheDocument();
const viewProfile = screen.getAllByText('Ver perfil');
expect(viewProfile).toHaveLength(3);
expect(screen.getByTestId('user-avatar-user1')).toBeInTheDocument();
expect(screen.getByTestId('user-avatar-user2')).toBeInTheDocument();
expect(screen.getByText('user1')).toBeInTheDocument();
expect(screen.getByText('user2')).toBeInTheDocument();
});

const viewProfileButtons = screen.getByTestId('view-profile-button-user1');

fireEvent.click(viewProfileButtons);
expect(mockNavigate).toHaveBeenCalledWith('/perfil?user=user1');
});
});

58 changes: 42 additions & 16 deletions webapp/src/pages/Social/Groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,42 @@ const Groups = () => {
}, []);

const fetchData = async () => {
try {
const response = await axios.get(`${apiEndpoint}/group/list`);
const userGroups = response.data.groups.filter(group => !group.members.includes(username));
setGroups(userGroups);
} catch (error) {
console.error('Error fetching data:', error);
}
fetch(`${apiEndpoint}/group/list`)
.then(response => response.json())
.then(data => {
const userGroups = data.groups.filter(group => !group.members.includes(username));
setGroups(userGroups);
})
.catch(error => {
console.error('Error fetching data:', error);
});
};

const addGroup = async () => {
try {
await axios.post(`${apiEndpoint}/group/add`, {
const addGroup = () => {
fetch(`${apiEndpoint}/group/add`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: name,
username: username
});
})
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to create group');
}
return response.json();
})
.then(() => {
setAlertMessage('Group created successfully');
setOpenAlert(true);
} catch (error) {
setError(error.response.data.error);
}
setName('');
})
.catch(error => {
setError(error.message);
});
};

const handleJoinGroup = (groupId) => {
Expand Down Expand Up @@ -88,10 +104,18 @@ const Groups = () => {
{`Error: ${error}`}
</Alert>
)}
{alertMessage && (
<Alert status="success" variant="subtle" mt="2">
{alertMessage}
</Alert>
)}
</Box>

<Box mt="4">
<Text fontSize="3xl" fontWeight="bold" mb="4">{t('pages.groups.joinable')}</Text>
<Text fontSize="3xl" fontWeight="bold" mb="4">{t('pages.groups.joinable')}</Text>
{groups.length === 0 ? (
<Text>{t('pages.groups.nogroups')}</Text>
) : (
<Table variant="simple">
<Thead>
<Tr>
Expand All @@ -102,6 +126,7 @@ const Groups = () => {
</Tr>
</Thead>
<Tbody>

{groups.map((group) => (
<Tr key={group._id}>
<Td>{group.name}</Td>
Expand All @@ -114,7 +139,8 @@ const Groups = () => {
))}
</Tbody>
</Table>
</Box>
)}
</Box>
</Container>
<Footer />
</>
Expand Down
Loading

0 comments on commit d6e9205

Please sign in to comment.