diff --git a/__tests__/Unit/Components/Tasks/TaskDates.test.tsx b/__tests__/Unit/Components/Tasks/TaskDates.test.tsx
new file mode 100644
index 000000000..2c507b7c6
--- /dev/null
+++ b/__tests__/Unit/Components/Tasks/TaskDates.test.tsx
@@ -0,0 +1,28 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { TaskDates } from '@/components/taskDetails/TaskDates';
+
+const mockSetNewEndOnDate = jest.fn();
+const mockHandleBlurOfEndsOn = jest.fn();
+
+describe('TaskDates Component', () => {
+ it('should render input field for End On date when in editing mode', () => {
+ render(
+
+ );
+
+ const input = screen.getByTestId('endsOnTaskDetails');
+ expect(input).toBeInTheDocument();
+ fireEvent.blur(input);
+ expect(mockHandleBlurOfEndsOn).toHaveBeenCalled();
+ });
+});
diff --git a/__tests__/Unit/Components/Tasks/TaskDependency.test.tsx b/__tests__/Unit/Components/Tasks/TaskDependency.test.tsx
deleted file mode 100644
index a1a300776..000000000
--- a/__tests__/Unit/Components/Tasks/TaskDependency.test.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react';
-import { fireEvent, waitFor } from '@testing-library/react';
-import { renderWithRouter } from '@/test_utils/createMockRouter';
-import TaskDependency from '@/components/taskDetails/taskDependency';
-import { taskDetailsHandler } from '../../../../__mocks__/handlers/task-details.handler';
-import { filterTaskHandler } from '../../../../__mocks__/handlers/tasks.handler';
-import { setupServer } from 'msw/node';
-import { Provider } from 'react-redux';
-import { store } from '@/app/store';
-import { TaskDependencyIds } from '../../../../__mocks__/db/tasks';
-import { useGetAllTasksQuery } from '@/app/services/tasksApi';
-
-const setEditedTaskDetails = jest.fn();
-const mockNavigateToTask = jest.fn();
-
-jest.mock('@/app/services/tasksApi');
-const mockedUseGetAllTasksQuery = useGetAllTasksQuery as jest.MockedFunction<
- typeof useGetAllTasksQuery
->;
-
-describe('TaskDependency', () => {
- const server = setupServer(...taskDetailsHandler);
- beforeAll(() => server.listen());
- afterEach(() => server.resetHandlers());
- afterAll(() => server.close());
-
- it('should select/unselect a task when checkbox is clicked', async () => {
- mockedUseGetAllTasksQuery.mockReturnValue({
- data: {
- tasks: [
- { id: 'task1', title: 'Test Task 1' },
- { id: 'task2', title: 'Test Task 2' },
- ],
- },
- isLoading: false,
- isError: false,
- refetch: jest.fn(),
- });
- const { container } = renderWithRouter(
-
-
-
- );
- const checkboxes = container.querySelectorAll('input[type="checkbox"]');
- const firstCheckbox = checkboxes[0] as HTMLInputElement;
- expect(firstCheckbox.checked).toBe(false);
- fireEvent.click(firstCheckbox);
- await waitFor(() => {
- expect(firstCheckbox.checked).toBe(true);
- });
- fireEvent.click(firstCheckbox);
- await waitFor(() => {
- expect(firstCheckbox.checked).toBe(false);
- });
- });
-
- it('should render loading state when searching for tasks', async () => {
- server.use(filterTaskHandler);
- const { getByText } = renderWithRouter(
-
-
-
- );
- const loadingText = await waitFor(() => getByText('Loading...'));
- expect(loadingText).toBeInTheDocument();
- });
-
- it('should render DependencyList when isEditing is false', async () => {
- const { queryByRole, getByTestId } = renderWithRouter(
-
-
- ,
- { push: mockNavigateToTask }
- );
-
- const textarea = queryByRole('textbox');
- expect(textarea).toBeNull();
-
- await waitFor(() => {
- const dependencyList = getByTestId('dependency-list');
- expect(dependencyList).toBeInTheDocument();
- });
- });
-});
diff --git a/__tests__/Unit/Components/Tasks/TaskDescription.test.tsx b/__tests__/Unit/Components/Tasks/TaskDescription.test.tsx
new file mode 100644
index 000000000..c2b8363a3
--- /dev/null
+++ b/__tests__/Unit/Components/Tasks/TaskDescription.test.tsx
@@ -0,0 +1,55 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { TaskDescription } from '@/components/taskDetails/TaskDescription';
+
+const mockHandleChange = jest.fn();
+
+describe('TaskDescription Component', () => {
+ it('should renders the task description when not editing', () => {
+ render(
+
+ );
+ expect(screen.getByText('Test Purpose')).toBeInTheDocument();
+ });
+
+ it('should renders "No description available" when purpose is empty', () => {
+ render(
+
+ );
+ expect(
+ screen.getByText('No description available')
+ ).toBeInTheDocument();
+ });
+
+ it('should renders textarea when in editing mode', () => {
+ render(
+
+ );
+ expect(screen.getByTestId('purpose-textarea')).toBeInTheDocument();
+ });
+
+ it('should calls handleChange when textarea value changes', () => {
+ render(
+
+ );
+ fireEvent.change(screen.getByTestId('purpose-textarea'), {
+ target: { value: 'New Purpose' },
+ });
+ expect(mockHandleChange).toHaveBeenCalled();
+ });
+});
diff --git a/__tests__/Unit/Components/Tasks/TaskDetailsSection.test.tsx b/__tests__/Unit/Components/Tasks/TaskDetailsSection.test.tsx
new file mode 100644
index 000000000..fb79a3caa
--- /dev/null
+++ b/__tests__/Unit/Components/Tasks/TaskDetailsSection.test.tsx
@@ -0,0 +1,97 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { Provider } from 'react-redux';
+import { configureStore } from '@reduxjs/toolkit';
+import { TaskDetailsSection } from '@/components/taskDetails/TaskDetailsSection';
+import '@testing-library/jest-dom/extend-expect';
+import { TASK } from '../../../../__mocks__/db/tasks';
+import { useRouter } from 'next/router';
+import { api } from '@/app/services/api';
+
+jest.mock('next/router', () => ({
+ useRouter: jest.fn(),
+}));
+
+const createMockStore = () => {
+ return configureStore({
+ reducer: {
+ user: (state = { roles: {} }) => state,
+ [api.reducerPath]: api.reducer,
+ },
+ middleware: (getDefaultMiddleware) =>
+ getDefaultMiddleware().concat(api.middleware),
+ });
+};
+
+describe('TaskDetailsSection Component', () => {
+ const mockHandleTaskStatusUpdate = jest.fn();
+ const mockRouter = {
+ query: { dev: true },
+ };
+
+ beforeEach(() => {
+ (useRouter as jest.Mock).mockReturnValue(mockRouter);
+ });
+
+ const defaultProps = {
+ isEditing: false,
+ type: TASK.type,
+ priority: TASK.priority,
+ status: TASK.status,
+ link: TASK.featureUrl,
+ percentCompleted: TASK.percentCompleted,
+ handleTaskStatusUpdate: mockHandleTaskStatusUpdate,
+ taskDetailsData: TASK,
+ };
+
+ it('should render task details correctly when not in editing mode', () => {
+ render(
+
+
+
+ );
+
+ expect(screen.getByText(TASK.type)).toBeInTheDocument();
+ expect(screen.getByText(TASK.priority)).toBeInTheDocument();
+ expect(screen.getByText(TASK.status)).toBeInTheDocument();
+
+ const linkElement = screen.getByRole('link', {
+ name: /open github issue/i,
+ });
+ expect(linkElement).toHaveAttribute('href', TASK.featureUrl);
+ });
+
+ it('should render task status dropdown when in editing mode', () => {
+ render(
+
+
+
+ );
+ expect(screen.getByRole('combobox')).toBeInTheDocument();
+ expect(screen.queryByText(TASK.status)).toBeNull();
+ });
+
+ it('should call handleTaskStatusUpdate when task status is changed', () => {
+ render(
+
+
+
+ );
+ const dropdown = screen.getByRole('combobox');
+ fireEvent.change(dropdown, { target: { value: 'DONE' } });
+
+ expect(mockHandleTaskStatusUpdate).toHaveBeenCalledWith({
+ newStatus: 'DONE',
+ });
+ });
+
+ it('should render progress container correctly', () => {
+ render(
+
+
+
+ );
+ expect(
+ screen.getByText(`${TASK.percentCompleted}%`)
+ ).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/Unit/Components/Tasks/TaskHeader.test.tsx b/__tests__/Unit/Components/Tasks/TaskHeader.test.tsx
new file mode 100644
index 000000000..bda23da68
--- /dev/null
+++ b/__tests__/Unit/Components/Tasks/TaskHeader.test.tsx
@@ -0,0 +1,61 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { TaskHeader } from '@/components/taskDetails/TaskHeader';
+import { ButtonProps } from '@/interfaces/taskDetails.type';
+
+const mockSetIsEditing = jest.fn();
+const mockOnSave = jest.fn();
+const mockOnCancel = jest.fn();
+const mockHandleChange = jest.fn();
+
+const renderTaskHeader = (isEditing = false) => {
+ return render(
+
+ );
+};
+
+describe('TaskHeader Component', () => {
+ it('should renders the task title correctly when not editing', () => {
+ renderTaskHeader(false);
+ expect(screen.getByText('Test Title')).toBeInTheDocument();
+ expect(
+ screen.getByRole('button', { name: 'Edit' })
+ ).toBeInTheDocument();
+ });
+
+ it('should renders textarea for title when in editing mode', () => {
+ renderTaskHeader(true);
+ expect(screen.getByTestId('title-textarea')).toBeInTheDocument();
+ expect(
+ screen.getByRole('button', { name: 'Save' })
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole('button', { name: 'Cancel' })
+ ).toBeInTheDocument();
+ });
+
+ it('should calls setIsEditing with true when Edit button is clicked', () => {
+ renderTaskHeader(false);
+ fireEvent.click(screen.getByRole('button', { name: 'Edit' }));
+ expect(mockSetIsEditing).toHaveBeenCalledWith(true);
+ });
+
+ it('should calls onSave when Save button is clicked', () => {
+ renderTaskHeader(true);
+ fireEvent.click(screen.getByRole('button', { name: 'Save' }));
+ expect(mockOnSave).toHaveBeenCalled();
+ });
+
+ it('should calls onCancel when Cancel button is clicked', () => {
+ renderTaskHeader(true);
+ fireEvent.click(screen.getByRole('button', { name: 'Cancel' }));
+ expect(mockOnCancel).toHaveBeenCalled();
+ });
+});
diff --git a/__tests__/Unit/Components/Tasks/TaskParticipants.test.tsx b/__tests__/Unit/Components/Tasks/TaskParticipants.test.tsx
new file mode 100644
index 000000000..d0e9c6fc9
--- /dev/null
+++ b/__tests__/Unit/Components/Tasks/TaskParticipants.test.tsx
@@ -0,0 +1,49 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import { TaskParticipants } from '@/components/taskDetails/TaskParticipants';
+import { Provider } from 'react-redux';
+import { store } from '@/app/store';
+
+const mockHandleAssignment = jest.fn();
+const mockHandleAssigneSelect = jest.fn();
+const mockSetShowSuggestion = jest.fn();
+
+const renderWithProvider = (ui: React.ReactElement) => {
+ return render({ui});
+};
+
+describe('TaskParticipants Component', () => {
+ it('should render the assignee name correctly when not editing', () => {
+ renderWithProvider(
+
+ );
+
+ expect(screen.getByText('John Doe')).toBeInTheDocument();
+ });
+
+ it('should render the Suggestions component when editing', () => {
+ renderWithProvider(
+
+ );
+
+ const input = screen.getByRole('textbox');
+ expect(input).toBeInTheDocument();
+ fireEvent.change(input, { target: { value: 'Jane Doe' } });
+ expect(mockHandleAssignment).toHaveBeenCalled();
+ });
+});