Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //App.js:
- import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
- import LandingPage from "./components/Pages/LandingPage/LandingPage";
- import HomePage from "./components/Pages/HomePage/HomePage";
- import Contact from "./components/Pages/Support/Support";
- import RegisterPage from "./components/Pages/Register/Register";
- import Login from "./components/Pages/Login/Login";
- import BenefitDetail from "./components/Pages/BenefitDetail/BenefitDetail";
- import Verification from "./components/Pages/Verification/Verification";
- import Verified from "./components/Pages/Verified/Verified";
- import ActivityPage from "./components/Pages/Activities/ActivityPage";
- import TuristicPage from "./components/Pages/Activities/TuristicPage";
- import SocialPage from "./components/Pages/Activities/SocialPage";
- import AcademicPage from "./components/Pages/Activities/AcademicPage";
- import AcademicDetail from "./components/Pages/Activities/AcademicDetail";
- import SocialDetail from "./components/Pages/Activities/SocialDetail";
- import TuristicDetail from "./components/Pages/Activities/TuristicDetail";
- const App = () => {
- return (
- <div className="bg-pearl min-h-screen text-roboto">
- <Router>
- <Routes>
- <Route path="/" element={<LandingPage />} />
- <Route path="/Beneficios" element={<HomePage />} />
- <Route path="/Contact" element={<Contact />} />
- <Route path="/Register" element={<RegisterPage />} />
- <Route path="/Login" element={<Login />} />
- <Route path="/benefit/:benefitId" element={<BenefitDetail />} />
- <Route path="/Actividades/:id/academicDetail" element={<AcademicDetail />} />
- <Route path="/Actividades/:id/socialDetail" element={<SocialDetail />} />
- <Route path="/Actividades/:id/turisticDetail" element={<TuristicDetail />} />
- <Route path="/Verification" element={<Verification />} />
- <Route path="/Verified/:token" element={<Verified />} />
- <Route path="/Actividades" element={<ActivityPage/>}/>
- <Route path="/Actividades/:university_id/turisticPage" element={<TuristicPage/>}/>
- <Route path="/Actividades/:university_id/socialPage" element={<SocialPage/>}/>
- <Route path="/Actividades/:university_id/academicPage" element={<AcademicPage/>}/>
- </Routes>
- </Router>
- </div>
- );
- };
- export default App;
- ------------------------------------------------------------
- //HomePage.js:
- import { useState, useEffect } from 'react';
- import { useLocation } from 'react-router-dom';
- import CategoryButton from '../../CategoryButton';
- import BenefitSearch from '../../BenefitSearch';
- import NavBar from '../../NavBar';
- import Carousel from '../../Carousel';
- import BenefitCard from '../../BenefitCard';
- import { useNavigate } from "react-router-dom"; // Importa useNavigate
- import BenefitFloatingButton from '../../BenefitFloatingButton';
- function HomePage() {
- const location = useLocation();
- const queryParams = new URLSearchParams(location.search);
- const [categories, setCategories] = useState([]);
- const [activeCategory, setActiveCategory] = useState(null); // Estado para saber qué botón está subrayado
- const universityId = queryParams.get('university');
- const [images, setImages] = useState([]);
- const [selectedCategory, setSelectedCategory] = useState(null);
- const [benefits, setBenefits] = useState([]);
- const navigate = useNavigate(); //inicializa useNavigate
- useEffect(() => {
- const fetchCategories = async () => {
- try {
- const response = await fetch(
- `${process.env.REACT_APP_API_URL}/benefits/${universityId}/categories`,
- {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json',
- },
- }
- );
- if (!response.ok) {
- throw new Error('Error fetching categories');
- }
- const categories = await response.json();
- setCategories(categories);
- } catch (error) {
- console.error('Error fetching categories:', error);
- }
- };
- fetchCategories();
- }, [universityId]);
- useEffect(() => {
- const fetchImages = async () => {
- try {
- const response = await fetch(
- `${process.env.REACT_APP_API_URL}/benefits/${universityId}/featured_images`,
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- },
- }
- );
- if (!response.ok) {
- throw new Error("Error fetching categories");
- }
- const featured_images = await response.json();
- setImages(featured_images);
- } catch (error) {
- console.error("Error fetching featured images:", error);
- }
- };
- fetchImages();
- }, [universityId]);
- useEffect(() => {
- const fetchBenefitsByCategory = async () => {
- if (!selectedCategory) return; // Si no hay categoría seleccionada, no hacer nada
- try {
- const response = await fetch(
- `${process.env.REACT_APP_API_URL}/benefits/${universityId}/${selectedCategory}`,
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- },
- }
- );
- if (!response.ok) {
- throw new Error("Error fetching benefits");
- }
- const benefits = await response.json();
- // Actualizar el estado con los beneficios filtrados
- setBenefits((prevBenefits) => ({
- ...prevBenefits,
- [selectedCategory]: benefits,
- }));
- } catch (error) {
- console.error("Error fetching benefits:", error);
- }
- };
- fetchBenefitsByCategory();
- }, [selectedCategory, universityId]);
- const handleCategoryClick = (categoryName) => {
- setActiveCategory(categoryName); // Actualiza la categoría activa
- setSelectedCategory(categoryName); // Actualiza la categoría seleccionada para filtrar los beneficios
- };
- const handleCardClick = (benefitId, category) => {
- navigate(`/benefit/${benefitId}?benefitId=${benefitId}`); // Redirige con benefitId y category
- };
- return (
- <div>
- <div className="relative">
- {/* NavBar */}
- <div>
- <NavBar sections={["Beneficios", "Actividades", "Hospedajes", "Conectarse", "Chats"]} />
- </div>
- {/* Benefit Search positioned above the carousel */}
- <div className="absolute top-15 left-1/2 transform -translate-x-1/2 z-20">
- <BenefitSearch />
- </div>
- {/* Carousel */}
- <div>
- <Carousel images={images} />
- </div>
- {/* Category Buttons */}
- <div className="absolute top-1/5 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex justify-center items-center space-x-[43px] z-20">
- {categories.length > 0 ? (
- categories.map((category, index) => (
- <CategoryButton
- key={index}
- categoryName={category.name}
- icon={category.base64image}
- isActive={activeCategory === category.name} // Compara si esta categoría está activa
- onClick={() => handleCategoryClick(category.name)} // Asigna la función para manejar clics
- />
- ))
- ) : (
- <p className="col-span-3 text-center">No categories available</p>
- )}
- </div>
- </div>
- {/* Benefit Cards */}
- <div className="relative mt-40 flex flex-wrap justify-center space-x-4 z-10">
- {selectedCategory && benefits[selectedCategory] &&
- benefits[selectedCategory].map((benefit, index) => (
- <BenefitCard
- key={index}
- imageUrl={benefit.images[0]}
- alt={benefit.name}
- title={benefit.name}
- onClick={() => handleCardClick(benefit.id, selectedCategory)}
- />
- ))
- }
- </div>
- <BenefitFloatingButton/>
- </div>
- );
- }
- export default HomePage;
- HomePage.test.js:
- import React from 'react';//Es necesario importar React cuando se trabaja con componentes de React, aunque no se utilice directamente en el test.
- import { render, screen } from '@testing-library/react';//render:Función de @testing-library/react que permite renderizar un componente React en un entorno de prueba.screen: Herramienta que facilita la selección de elementos renderizados dentro del DOM de pruebas (por ejemplo, getByText, findByText).
- import HomePage from '../components/Pages/HomePage/HomePage';
- import { BrowserRouter } from 'react-router-dom';//BrowserRouter: Es necesario para envolver el componente en pruebas ya que HomePage depende del enrutamiento
- import { act } from 'react';
- test('renders HomePage with NavBar and Category buttons', async () => {
- //global.fetch: Aquí se está creando un mock para la función fetch. fetch se utiliza normalmente para hacer llamadas a la API, y este mock evita que se realicen llamadas reales en el test.
- global.fetch = jest.fn(() => //jest.fn(): Crea un mock de la función fetch, que se comporta de una manera controlada.
- Promise.resolve({ //Promise.resolve(): Simula una respuesta exitosa de la API devolviendo una promesa resuelta.
- ok: true, //ok: true: Simula una respuesta HTTP exitosa.
- //json: () => Promise.resolve([...]): Simula que la respuesta de la API tiene un método json() que devuelve una promesa con una lista de categorías, cada una con un name (nombre) y base64image (una imagen codificada en base64).
- json: () => Promise.resolve([
- { name: "Deportes", base64image: "icon_deportes" },
- { name: "Comida", base64image: "icon_comida" }
- ]),
- })
- );
- //render: Renderiza el componente HomePage dentro de un BrowserRouter. Esto es necesario porque HomePage podría usar funciones o enlaces de React Router, que necesitan un contexto de router para funcionar
- //correctamente.
- render(
- <BrowserRouter>
- <HomePage />
- </BrowserRouter>
- );
- //screen.getByText(): Busca en el DOM de prueba un elemento que contenga el texto "Beneficios". El uso de /Beneficios/i es una expresión regular que busca el texto sin importar mayúsculas o minúsculas.
- //expect(...).toBeInTheDocument(): Verifica que este elemento realmente exista en el DOM. Esto asegura que el NavBar (o algún otro componente relacionado) que contiene la palabra "Beneficios" se haya renderizado correctamente.
- expect(screen.getByText(/Beneficios/i)).toBeInTheDocument();
- // Verificar que los botones de categorías se renderizan
- const categoryButton = await screen.findByText("Deportes");
- expect(categoryButton).toBeInTheDocument();
- // Limpieza del mock
- global.fetch.mockClear();
- });
- //En resumen: El propósito de HomePage.test.js es verificar que los componentes principales de la página de inicio (HomePage.js) se rendericen correctamente y funcionen según lo esperado.
- ActivityPage.test.js:
- // ActivityPage.test.js
- import { render, screen, fireEvent } from '@testing-library/react';
- import ActivityPage from '../components/Pages/Activities/ActivityPage';
- import { BrowserRouter } from 'react-router-dom';
- import '@testing-library/jest-dom'; //Agrega funciones adicionales de jest-dom que extienden Jest para hacer más fácil verificar la presencia de elementos en el DOM, como toBeInTheDocument().
- import { useNavigate } from 'react-router-dom';
- import { act } from 'react';
- // Mueve el mock de `useNavigate` fuera de la función de prueba
- jest.mock('react-router-dom', () => ({ //jest.mock: Sobrescribe el módulo react-router-dom en el contexto del test
- ...jest.requireActual('react-router-dom'), // Mantén las funcionalidades originales de react-router-dom
- useNavigate: jest.fn(), // Crea un mock del hook useNavigate, que reemplaza la implementación real por una función simulada (jest.fn()). Esto permite controlar y verificar cuándo se llama a navigate en las pruebas.
- }));
- test('renders activity type buttons and handles navigation', () => { //Define una prueba con Jest. El nombre de la prueba es 'renders activity type buttons and handles navigation' y el contenido es una función anónima que realiza las verificaciones.
- const mockNavigate = jest.fn(); //Crea un mock manual para navigate, que simula la función de navegación en el componente.
- useNavigate.mockReturnValue(mockNavigate); // Define que cuando useNavigate sea llamado en el componente, en lugar de usar la versión real, devuelva la función mockNavigate, que es un mock y permite capturar su uso durante el test.
- // render: Renderiza el componente ActivityPage envuelto en un BrowserRouter, ya que ActivityPage necesita un router para manejar la navegación.
- //<BrowserRouter>: Proporciona el contexto necesario de enrutamiento para el componente.
- render(
- <BrowserRouter>
- <ActivityPage />
- </BrowserRouter>
- );
- // Verifica que se rendericen los botones de actividad
- const turisticButton = screen.getByText('Turísticas');
- const socialButton = screen.getByText('Sociales');
- const academicButton = screen.getByText('Académicas');
- //Verifica que los botones correspondientes efectivamente estén presentes en el DOM usando expect con el matcher toBeInTheDocument
- expect(turisticButton).toBeInTheDocument();
- expect(socialButton).toBeInTheDocument();
- expect(academicButton).toBeInTheDocument();
- // Simula clic en el botón de actividades académicas
- fireEvent.click(academicButton);
- // Verifica que, después de hacer clic en el botón, la función navigate haya sido llamada con la URL esperada
- expect(mockNavigate).toHaveBeenCalledWith('/Actividades/de61ec4a-dc96-46ec-a951-572332f10477/academicPage');
- });
- //En resumen: Este test verifica que los botones se rendericen correctamente y que, al hacer clic en el botón "Académicas", se llame a navigate con la URL correcta para la página académica.
- -----------------------------------------------------------------------------------------------------------------------------------------------------------
- ActivityPage.test.js:
- // ActivityPage.test.js
- import { render, screen, fireEvent } from '@testing-library/react';
- import ActivityPage from '../components/Pages/Activities/ActivityPage';
- import { BrowserRouter } from 'react-router-dom';
- import '@testing-library/jest-dom'; //Agrega funciones adicionales de jest-dom que extienden Jest para hacer más fácil verificar la presencia de elementos en el DOM, como toBeInTheDocument().
- import { useNavigate } from 'react-router-dom';
- import { act } from 'react';
- // Mueve el mock de `useNavigate` fuera de la función de prueba
- jest.mock('react-router-dom', () => ({ //jest.mock: Sobrescribe el módulo react-router-dom en el contexto del test
- ...jest.requireActual('react-router-dom'), // Mantén las funcionalidades originales de react-router-dom
- useNavigate: jest.fn(), // Crea un mock del hook useNavigate, que reemplaza la implementación real por una función simulada (jest.fn()). Esto permite controlar y verificar cuándo se llama a navigate en las pruebas.
- }));
- test('renders activity type buttons and handles navigation', () => { //Define una prueba con Jest. El nombre de la prueba es 'renders activity type buttons and handles navigation' y el contenido es una función anónima que realiza las verificaciones.
- const mockNavigate = jest.fn(); //Crea un mock manual para navigate, que simula la función de navegación en el componente.
- useNavigate.mockReturnValue(mockNavigate); // Define que cuando useNavigate sea llamado en el componente, en lugar de usar la versión real, devuelva la función mockNavigate, que es un mock y permite capturar su uso durante el test.
- // render: Renderiza el componente ActivityPage envuelto en un BrowserRouter, ya que ActivityPage necesita un router para manejar la navegación.
- //<BrowserRouter>: Proporciona el contexto necesario de enrutamiento para el componente.
- render(
- <BrowserRouter>
- <ActivityPage />
- </BrowserRouter>
- );
- // Verifica que se rendericen los botones de actividad
- const turisticButton = screen.getByText('Turísticas');
- const socialButton = screen.getByText('Sociales');
- const academicButton = screen.getByText('Académicas');
- //Verifica que los botones correspondientes efectivamente estén presentes en el DOM usando expect con el matcher toBeInTheDocument
- expect(turisticButton).toBeInTheDocument();
- expect(socialButton).toBeInTheDocument();
- expect(academicButton).toBeInTheDocument();
- // Simula clic en el botón de actividades académicas
- fireEvent.click(academicButton);
- // Verifica que, después de hacer clic en el botón, la función navigate haya sido llamada con la URL esperada
- expect(mockNavigate).toHaveBeenCalledWith('/Actividades/de61ec4a-dc96-46ec-a951-572332f10477/academicPage');
- });
- //En resumen: Este test verifica que los botones se rendericen correctamente y que, al hacer clic en el botón "Académicas", se llame a navigate con la URL correcta para la página académica.
- ----------------------------------------------------------------------------------------------------------------------------------------------------------
- Es entonces que me gustaría poder realizar otro test con jest donde se puedan mostrar otras funcionalidades de jest como beforeach, aftereach, describe para ponerle nombre a lo que estoy evaluando, etc.
- El archivo con el que quise realizar este otro test sería:
- AcademicDetail.js:
- import { useEffect, useState } from "react";
- import { supabase } from '../../../tests/supabaseClient';
- import NavBar from "../../NavBar";
- import { useParams } from "react-router-dom"; // Para obtener el ID de la actividad desde la URL
- import DetailCard from "../../DetailCard";
- export default function AcademicDetail() {
- const { id } = useParams(); // Obtenemos el id de la actividad desde la URL
- const [activity, setActivity] = useState(null); // Estado para la actividad
- useEffect(() => {
- const fetchActivityDetail = async () => {
- const { data, error } = await supabase
- .from('activity_academic') // Asegúrate de que el nombre de la tabla esté correcto
- .select(`name, description, image: id_image (base64image)`) // Selecciona los campos necesarios
- .eq('id', id) // Filtra por id de la actividad
- .single(); // Solo esperamos un resultado
- if (error) {
- console.error("Error fetching data: ", error);
- } else {
- // Guarda los detalles de la actividad en el estado
- setActivity({
- name: data.name,
- description: data.description,
- id_image: data.image.base64image,
- });
- }
- };
- fetchActivityDetail();
- }, [id]); // Ejecutar el efecto cuando cambie el id
- if (!activity) {
- return <div>Loading...</div>; // Mientras cargan los detalles
- }
- return (
- <div>
- {/* NavBar */}
- <NavBar sections={["Beneficios", "Actividades", "Hospedajes", "Conectarse", "Chats"]} />
- {/* Details */}
- <DetailCard title={activity.name} description={activity.description} image={activity.id_image} bgColor="bg-gray-purple"/>
- </div>
- );
- }
Add Comment
Please, Sign In to add comment