Skip to content

Commit

Permalink
OHRI-2318: Infant's name to display on the Mother banner (#1929)
Browse files Browse the repository at this point in the history
* Infant's name to display on the Mother banner

* change display of childern names

* faillling test and remove redundant code
  • Loading branch information
lucyjemutai authored Oct 17, 2024
1 parent 3cf5e33 commit cb86c63
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,91 +1,123 @@
import React from 'react';
import { render, act, screen } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { PatientStatusBannerTag } from './patient-status-tag.component';
import { usePatientHivStatus } from './patientHivStatus';
import { usePatientFamilyNames } from './usePatientFamilyNames';

jest.mock('./patientHivStatus');
jest.mock('./patientHivStatus', () => ({
usePatientHivStatus: jest.fn(),
}));

const mockusePatientHivStatus = usePatientHivStatus as jest.Mock;
jest.mock('./usePatientFamilyNames', () => ({
usePatientFamilyNames: jest.fn(),
}));

describe('PatientStatusBannerTag', () => {
const hivPositiveSampleUuid = '138571AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';

beforeEach(() => {
jest.clearAllMocks();
});

const hivPositiveSampleUuid = '138571AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';

it('renders red tag when patient is HIV positive', async () => {
mockusePatientHivStatus.mockReturnValue({
hivStatus: 'positive',
isLoading: false,
it('should not render anything while loading', () => {
(usePatientHivStatus as jest.Mock).mockReturnValue({
hivStatus: null,
isLoading: true,
isError: false,
});

await act(async () => {
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
patientAge: null,
patientGender: null,
isLoading: true,
isError: false,
});

expect(screen.getByText(/HIV Positive/i)).toBeInTheDocument();
const { container } = render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);

expect(container.firstChild).toBeNull();
});

it('renders green tag when patient is HIV negative', async () => {
mockusePatientHivStatus.mockReturnValue({
hivStatus: 'negative',
it('should display the correct tag for HIV positive status', () => {
(usePatientHivStatus as jest.Mock).mockReturnValue({
hivStatus: 'positive',
isLoading: false,
isError: false,
});

await act(async () => {
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
patientAge: null,
patientGender: null,
isLoading: false,
isError: false,
});

expect(screen.getByText(/HIV Negative/i)).toBeInTheDocument();
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
expect(screen.getByText('HIV Positive')).toBeInTheDocument();
});

it('does not render any tag when patient HIV status is not positive or negative', async () => {
mockusePatientHivStatus.mockReturnValue({
hivStatus: 'other',
it('should display the correct tag for HIV negative status', () => {
(usePatientHivStatus as jest.Mock).mockReturnValue({
hivStatus: 'negative',
isLoading: false,
isError: false,
});

await act(async () => {
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
patientAge: null,
patientGender: null,
isLoading: false,
isError: false,
});

expect(screen.queryByText(/HIV Positive/i)).not.toBeInTheDocument();
expect(screen.queryByText(/HIV Negative/i)).not.toBeInTheDocument();
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
expect(screen.getByText('HIV Negative')).toBeInTheDocument();
});

it('shows loading state initially', async () => {
mockusePatientHivStatus.mockReturnValue({
hivStatus: null,
isLoading: true,
it('should display mother’s name on the Infant banner', () => {
(usePatientHivStatus as jest.Mock).mockReturnValue({
hivStatus: 'negative',
isLoading: false,
isError: false,
});

await act(async () => {
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: 'Jane Doe',
patientAge: 10,
patientGender: 'M',
isLoading: false,
isError: false,
});

expect(screen.queryByText(/HIV Positive/i)).not.toBeInTheDocument();
expect(screen.queryByText(/HIV Negative/i)).not.toBeInTheDocument();
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
expect(screen.getByText('Mother: Jane Doe')).toBeInTheDocument();
});

it('handles error state', async () => {
mockusePatientHivStatus.mockReturnValue({
it('should show an error message when there is an error fetching data', () => {
(usePatientHivStatus as jest.Mock).mockReturnValue({
hivStatus: null,
isLoading: false,
isError: true,
isError: false,
});

await act(async () => {
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
(usePatientFamilyNames as jest.Mock).mockReturnValue({
childrenNames: [],
motherName: null,
patientAge: null,
patientGender: null,
isLoading: false,
isError: true,
});

expect(screen.queryByText(/HIV Positive/i)).not.toBeInTheDocument();
expect(screen.queryByText(/HIV Negative/i)).not.toBeInTheDocument();
// Optionally check for an error message if your component shows one
render(<PatientStatusBannerTag patientUuid={hivPositiveSampleUuid} />);
expect(screen.getByText('Error fetching family information')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { Tag } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { usePatientHivStatus } from './patientHivStatus';
import { usePatientFamilyNames } from './usePatientFamilyNames';

export function PatientStatusBannerTag({ patientUuid }) {
const { t } = useTranslation();
const { hivStatus } = usePatientHivStatus(patientUuid);
const { childrenNames, motherName, patientAge, patientGender, isLoading, isError } =
usePatientFamilyNames(patientUuid);

if (isLoading) {
return null;
}

if (isError) {
return <div>Error fetching family information</div>;
}

return (
<>
{/* HIV Status Display */}
{hivStatus === 'positive' && <Tag type="red">{t('hivPositive', 'HIV Positive')}</Tag>}
{hivStatus === 'negative' && <Tag type="green">{t('hivNegative', 'HIV Negative')}</Tag>}

{/* Mother Name Display (if patient is under 10) */}
{patientAge !== null && patientAge <= 14 && motherName && <Tag type="purple">Mother: {motherName}</Tag>}

{/* Children Names Display (if patient is female and over 10) */}
{patientAge !== null && patientAge > 14 && patientGender === 'F' && childrenNames.length > 0 && (
<Tag type="purple">Children: {childrenNames.join(' || ')}</Tag>
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useState, useEffect, useCallback } from 'react';
import { fetchPatientRelationships } from '@ohri/openmrs-esm-ohri-commons-lib';

export const usePatientFamilyNames = (patientUuid: string) => {
const [childrenNames, setChildrenNames] = useState<string[]>([]);
const [motherName, setMotherName] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(false);
const [patientAge, setPatientAge] = useState<number | null>(null);
const [patientGender, setPatientGender] = useState<string | null>(null);

const fetchFamilyData = useCallback(async () => {
try {
// Fetch patient demographics (age and gender)
const response = await fetch(`/openmrs/ws/rest/v1/patient/${patientUuid}?v=full`);
const patient = await response.json();
setPatientAge(patient.person.age);
setPatientGender(patient.person.gender);

// Fetch relationships
const relationships = await fetchPatientRelationships(patientUuid);

if (!relationships || !Array.isArray(relationships)) {
console.warn('No valid relationships data:', relationships);
setChildrenNames([]);
setMotherName(null);
setIsLoading(false);
return;
}

const childRelationships = relationships
.filter((relationship) => relationship.relationshipType?.displayBIsToA === 'Child')
.map((relationship) => relationship.personB?.display);

setChildrenNames(childRelationships);

const motherRelationship = relationships.find(
(relationship) =>
relationship.relationshipType?.displayAIsToB === 'Mother' ||
relationship.relationshipType?.displayBIsToA === 'Child',
);

setMotherName(motherRelationship?.personA?.display || 'Mother not found');

setIsLoading(false);
} catch (error) {
console.error('Error fetching family names:', error);
setIsError(true);
setIsLoading(false);
}
}, [patientUuid]);

useEffect(() => {
if (patientUuid) {
fetchFamilyData();
}
}, [fetchFamilyData, patientUuid]);

return { childrenNames, motherName, patientAge, patientGender, isLoading, isError };
};

0 comments on commit cb86c63

Please sign in to comment.