Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

Feature/89 fe integrate the students list filters hf #108

Merged
merged 58 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b7957cc
filter students roles
Dar-ya218 Apr 2, 2024
22bcf41
filter
Dar-ya218 Apr 3, 2024
980fba3
filter done
Dar-ya218 Apr 7, 2024
bf063e4
Merge branch 'hotfix-filtering' into feature/89-fe-integrate-the-stud…
Dar-ya218 Apr 7, 2024
3df2c29
add rules
Dar-ya218 Apr 9, 2024
e48f74d
role filtering
Dar-ya218 Apr 9, 2024
8790354
fix FetchStudentsList
Dar-ya218 Apr 15, 2024
2bd6194
change
Dar-ya218 Apr 17, 2024
cd58a5f
Merge branch 'main' of https://github.com/IT-Academy-BCN/ita-profiles…
Dar-ya218 Apr 17, 2024
38a8953
fix eslint
Dar-ya218 Apr 17, 2024
24a4730
hot fix
Dar-ya218 Apr 17, 2024
25a2780
fix checkbox
Dar-ya218 Apr 17, 2024
3c81469
test
Dar-ya218 Apr 17, 2024
9b49975
fix test TS
Dar-ya218 Apr 17, 2024
99c5ed6
test
Dar-ya218 Apr 22, 2024
04213ed
update
llopFilms Apr 24, 2024
0285189
Merge branch 'main' of https://github.com/IT-Academy-BCN/ita-profiles…
Dar-ya218 Apr 24, 2024
1997f40
Merge branch 'feature/89-fe-integrate-the-students-list-filters-hf' o…
Dar-ya218 Apr 24, 2024
105f387
add context filters
Dar-ya218 Apr 24, 2024
53a930e
Student Interface Layout
Dar-ya218 Apr 24, 2024
956f95c
Implement Student Filters Context
Dar-ya218 Apr 24, 2024
6def488
fillters role done
Dar-ya218 Apr 27, 2024
1cdacc7
fix
Dar-ya218 Apr 27, 2024
2c4b8b4
small fix
Dar-ya218 Apr 27, 2024
8dc5918
test
Dar-ya218 Apr 27, 2024
8897ef9
Implement Error Handling
Dar-ya218 Apr 27, 2024
e4d2408
fix test
Dar-ya218 Apr 27, 2024
e718986
fix test
Dar-ya218 Apr 28, 2024
f77febf
test
Dar-ya218 Apr 28, 2024
b1562ea
fix checks
Dar-ya218 Apr 28, 2024
2110e9c
fix
Dar-ya218 Apr 28, 2024
5ee6dad
Refactor StudentFilters dependency
Dar-ya218 Apr 28, 2024
ace9652
layout children
Dar-ya218 Apr 28, 2024
d631ba5
chang
Dar-ya218 Apr 30, 2024
aa73045
fix
Dar-ya218 May 1, 2024
5bc1006
Merge branch 'main' into feature/89-fe-integrate-the-students-list-fi…
Dar-ya218 May 1, 2024
c9dba83
test
Dar-ya218 May 1, 2024
6ae1efe
test
Dar-ya218 May 1, 2024
af3d6f3
test 3
Dar-ya218 May 1, 2024
6520b78
test
Dar-ya218 May 1, 2024
afb21bb
test 2.1
Dar-ya218 May 2, 2024
efc2bc2
test
Dar-ya218 May 2, 2024
e3372c6
test
Dar-ya218 May 6, 2024
0c98c69
Merge branch 'main' into feature/89-fe-integrate-the-students-list-fi…
Dar-ya218 May 6, 2024
14b9719
Merge branch 'main' into feature/89-fe-integrate-the-students-list-fi…
Dar-ya218 May 8, 2024
ca78dcd
hf
Dar-ya218 May 9, 2024
d525e4e
test
Dar-ya218 May 10, 2024
9cdb04f
StudentFiltersContent test 1
monica-mp May 10, 2024
7be4619
StudentFiltersContent test 2
monica-mp May 10, 2024
bed9c18
test1
Dar-ya218 May 10, 2024
654b240
Merge branch 'feature/89-fe-integrate-the-students-list-filters-hf' o…
Dar-ya218 May 10, 2024
f058903
tests
May 10, 2024
dd52971
Merge branch 'feature/89-fe-integrate-the-students-list-filters-hf' o…
May 10, 2024
c9ae361
tests 2
May 10, 2024
708e029
test 2
May 10, 2024
0bbf4e5
test 13.46
Dar-ya218 May 10, 2024
abd9ba5
fin
Dar-ya218 May 10, 2024
6055d32
unistall jest
Dar-ya218 May 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"@hookform/resolvers": "3.3.2",
"@reduxjs/toolkit": "1.9.7",
"axios": "1.6.2",
"axios-mock-adapter": "^1.22.0",
"classnames": "2.5.1",
"i18next": "23.6.0",
"i18next-browser-languagedetector": "7.1.0",
Expand All @@ -30,8 +29,8 @@
},
"devDependencies": {
"@tailwindcss/typography": "0.5.10",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "14.2.2",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.2.2",
"@types/js-cookie": "3.0.6",
"@types/react": "18.2.15",
"@types/react-dom": "18.2.7",
Expand Down
95 changes: 95 additions & 0 deletions src/__tests__/components/studentFilters/ApiGetUserDetail.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { useContext } from 'react'
import axios from 'axios'
import { fireEvent, render } from '@testing-library/react'
// eslint-disable-next-line import/no-extraneous-dependencies
import MockAdapter from 'axios-mock-adapter'
import { FetchStudentsListHome } from '../../../api/FetchStudentsList'
import {
StudentFiltersProvider,
StudentFiltersContext,
} from '../../../context/StudentFiltersContext'
import StudentFiltersContent from '../../../components/studentFilters/StudentFiltersContent'

const mockAxios = new MockAdapter(axios)

describe('FetchStudentsListHome function', () => {
afterEach(() => {
mockAxios.reset()
})

it('should fetch student list for home', async () => {
const selectedRoles = ['role1', 'role2']

const expectedUrl =
'https://itaperfils.eurecatacademy.org/api/v1/student/list/for-home?specialization=role1,role2'

const mockData = [
{ id: 1, name: 'Student 1' },
{ id: 2, name: 'Student 2' },
]

mockAxios.onGet(expectedUrl).reply(200, mockData)

const result = await FetchStudentsListHome(selectedRoles)

expect(result).toEqual(mockData)
})

it('should handle errors', async () => {
const selectedRoles: string[] = []

const expectedUrl =
'https://itaperfils.eurecatacademy.org/api/v1/student/list/for-home'

mockAxios.onGet(expectedUrl).reply(500)

await expect(FetchStudentsListHome(selectedRoles)).rejects.toThrow()
})
})

describe('StudentFiltersContent component', () => {
it('renders StudentFiltersContent and handles user events', () => {
const { getByTestId } = render(
<StudentFiltersProvider>
<StudentFiltersContent />
</StudentFiltersProvider>,
)

// Verifies that the component renders correctly
expect(getByTestId('student-filters-content')).toBeDefined()
})

it('should add and remove role', () => {
const TestComponent = () => {
const { selectedRoles, addRole, removeRole } =
useContext(StudentFiltersContext) || {}

if (!selectedRoles || !addRole || !removeRole) {
throw new Error('Context is undefined')
}
return (
<div data-testid="student-filters-content">
<button type="button" onClick={() => addRole('test')}>
Add role
</button>
<button type="button" onClick={() => removeRole('test')}>
Remove role
</button>
<div>{selectedRoles.join(',')}</div>
</div>
)
}

const { getByText, queryByText } = render(
<StudentFiltersProvider>
<TestComponent />
</StudentFiltersProvider>,
)

fireEvent.click(getByText('Add role'))
expect(getByText('test')).toBeInTheDocument()

fireEvent.click(getByText('Remove role'))
expect(queryByText('test')).not.toBeInTheDocument()
})
})
24 changes: 24 additions & 0 deletions src/__tests__/components/studentFilters/Landing.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { render, screen } from '@testing-library/react'
import { Provider } from 'react-redux' // Import Provider from react-redux
import Landing from '../../../components/landing/Landing'

import { store } from '../../../store/store'

describe('StudentDetailsLayout', () => {
it('should render the studentDetailsLayout component correctly', () => {
const { container } = render(
<Provider store={store}>
<Landing />
</Provider>,
)
expect(container).toBeInTheDocument()
})

test('renders all the different cards', () => {
expect(screen.queryByTestId('MenuNavbar')).toBeDefined()
expect(screen.queryByTestId('UserNavbar')).toBeDefined()
expect(screen.queryByTestId('StudentFiltersLayout')).toBeDefined()
expect(screen.queryByTestId('StudentLayout')).toBeDefined()
expect(screen.queryByTestId('StudentDetailsLayout')).toBeDefined()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { renderHook, act } from '@testing-library/react'
import { describe, expect, it } from 'vitest'
import { ReactNode, useContext } from 'react'
import {
StudentFiltersProvider,
StudentFiltersContext,
} from '../../../context/StudentFiltersContext'

describe('StudentFiltersProvider', () => {
it('should add role to selectedRoles', () => {
const wrapper = (
{ children }: { children: ReactNode }, // Explicitly type children prop
) => <StudentFiltersProvider>{children}</StudentFiltersProvider>

const { result } = renderHook(() => useContext(StudentFiltersContext), {
wrapper,
})

act(() => {
result.current?.addRole('Role1') // Guard against result.current being undefined
})

expect(result.current?.selectedRoles).toEqual(['Role1']) // Guard against result.current being undefined
})

it('should remove role from selectedRoles', () => {
const wrapper = (
{ children }: { children: ReactNode }, // Explicitly type children prop
) => <StudentFiltersProvider>{children}</StudentFiltersProvider>

const { result } = renderHook(() => useContext(StudentFiltersContext), {
wrapper,
})

act(() => {
result.current?.addRole('Role1') // Guard against result.current being undefined
result.current?.addRole('Role2') // Guard against result.current being undefined
result.current?.removeRole('Role1') // Guard against result.current being undefined
})

expect(result.current?.selectedRoles).toEqual(['Role2']) // Guard against result.current being undefined
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { render, RenderResult, waitFor } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import StudentFiltersProvider from '../../../components/studentFilters/StudentFiltersContent';
import { StudentFiltersContext } from '../../../context/StudentFiltersContext';

describe('StudentFiltersProvider', () => {
let mock: MockAdapter;

beforeAll(() => {
mock = new MockAdapter(axios);
});

afterEach(() => {
mock.reset();
});

afterAll(() => {
mock.restore();
});

const selectedRoles: string[] = [];
const addRole = () => { };
const removeRole = () => { };

const value = {
selectedRoles,
addRole,
removeRole,
};

const rolesData: string[] | undefined = [];
const developmentData: string[] | undefined = [];

test('renders student filters correctly', async () => {
// Mock API responses
mock
.onGet('https://itaperfils.eurecatacademy.org/api/v1/specialization/list')
.reply(200, rolesData);

mock
.onGet('https://itaperfils.eurecatacademy.org/api/v1/development/list')
.reply(200, developmentData);

let getByText: RenderResult['getByText'];

// Render the component
await act(async () => {
const renderResult = render(
<StudentFiltersContext.Provider value={value}>
<StudentFiltersProvider />
</StudentFiltersContext.Provider>
);
getByText = renderResult.getByText;

// Wait for data to be fetched and rendered
await waitFor(() => {
rolesData.forEach((role) => {
expect(getByText(role)).toBeInTheDocument();
});

developmentData.forEach((development) => {
expect(getByText(development)).toBeInTheDocument();
});
});
});
});
});
31 changes: 21 additions & 10 deletions src/api/FetchStudentsList.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import axios from 'axios'
import { IStudentList } from '../interfaces/interfaces'
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
import axios, { AxiosError } from 'axios';
import { IStudentList } from '../interfaces/interfaces';

// eslint-disable-next-line consistent-return
export const FetchStudentsListHome = async () => {
export const FetchStudentsListHome = async (selectedRoles:Array<string>= []) => {

try {
const response = await axios.get<IStudentList[]>(
'https://itaperfils.eurecatacademy.org/api/v1/student/list/for-home',
)
return response.data
} catch (e) {
let queryParams = '';

// Construir la cadena de consulta para roles seleccionados
if (selectedRoles.length > 0) {
queryParams += `specialization=${selectedRoles.join(',')}`;
}

// Construir la URL completa con la cadena de consulta
const url = `https://itaperfils.eurecatacademy.org/api/v1/student/list/for-home${queryParams ? `?${queryParams}` : ''}`;

const response = await axios.get<IStudentList[]>(url);
return response.data;
// @ts-expect-error throws AxiosError exception
} catch (e: AxiosError) {
// eslint-disable-next-line no-console
console.error(e)
throw new DOMException(e.message, 'ConnectionFailed');
}
}
};
22 changes: 14 additions & 8 deletions src/components/landing/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@ import UserNavbar from '../userNavBar/UserNavbar'
import StudentDetailsLayout from '../studentDetail/StudentDetailsLayout'
import StudentsLayout from '../students/StudentsLayout'
import StudentFiltersLayout from '../studentFilters/StudentFiltersLayout'
import { StudentFiltersProvider } from '../../context/StudentFiltersContext'

const Landing = () => (
<div className="flex h-screen">
<MenuNavbar />
<MenuNavbar data-testid="MenuNavbar" /> {/* Added data-testid */}
<div className="flex w-full md:w-[calc(100%-176px)] flex-col gap-3 p-2.5 md:p-2 md:pb-8 md:pr-14">
<UserNavbar />
<div className="flex h-[90vh] gap-10">
<div className="flex flex-1 w-auto h-full rounded-xl bg-white p-10">
<StudentFiltersLayout />
<StudentsLayout />
<UserNavbar data-testid="UserNavbar" /> {/* Added data-testid */}
<StudentFiltersProvider>
<div className="flex h-[90vh] gap-10">
<div className="flex flex-1 w-auto h-full rounded-xl bg-white p-10">
<StudentFiltersLayout data-testid="StudentFiltersLayout" />{' '}
{/* Added data-testid */}
<StudentsLayout data-testid="StudentLayout" />{' '}
{/* Added data-testid */}
</div>
<StudentDetailsLayout data-testid="StudentDetailsLayout" />{' '}
{/* Added data-testid */}
</div>
<StudentDetailsLayout />
</div>
</StudentFiltersProvider>
</div>
</div>
)
Expand Down
Loading
Loading