Skip to content

Commit

Permalink
Fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmale committed Sep 12, 2024
2 parents 2f4134c + 8d7d1ae commit c6d7cba
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 61 deletions.
4 changes: 2 additions & 2 deletions src/components/renderer/custom-hooks-renderer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export const CustomHooksRenderer = ({
}: {
context: FormProcessorContextProps;
setContext: (context: FormProcessorContextProps) => void;
useCustomHooks: (context: FormProcessorContextProps) => {
useCustomHooks: (context: Partial<FormProcessorContextProps>) => {
data: any;
isLoading: boolean;
error: any;
updateContext: (setContext: (context: FormProcessorContextProps) => void) => void;
updateContext: (setContext: React.Dispatch<React.SetStateAction<FormProcessorContextProps>>) => void;
};
setIsLoadingCustomHooks: (isLoading: boolean) => void;
}) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React, { useEffect, useMemo, useState } from 'react';
import {
type FormField,
type RenderType,
type ValidationResult,
type FormFieldInputProps,
type FormFieldValidator,
type FormFieldValueAdapter,
type RenderType,
type SessionMode,
type ValidationResult,
type ValueAndDisplay,
} from '../../../types';
import { Controller, useWatch } from 'react-hook-form';
import { ToastNotification } from '@carbon/react';
import { useTranslation } from 'react-i18next';
import { ErrorBoundary } from 'react-error-boundary';
import { type FormFieldValueAdapter, type FormFieldInputProps } from '../../../types';
import { hasRendering } from '../../../utils/common-utils';
import { useFormProviderContext } from '../../../provider/form-provider';
import { isEmpty } from '../../../validators/form-validator';
Expand Down
64 changes: 21 additions & 43 deletions src/form-engine.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import React from 'react';
import dayjs from 'dayjs';
import userEvent from '@testing-library/user-event';
import { act, cleanup, fireEvent, render, screen, within } from '@testing-library/react';
import { act, cleanup, render, screen, within } from '@testing-library/react';
import {
createErrorHandler,
createGlobalStore,
createUseStore,
ExtensionSlot,
getAsyncLifecycle,
getGlobalStore,
OpenmrsDatePicker,
openmrsFetch,
registerExtension,
restBaseUrl,
showNotification,
showToast,
useConnectivity,
usePatient,
useSession,
} from '@openmrs/esm-framework';
Expand All @@ -37,6 +28,7 @@ import postSubmissionTestForm from '__mocks__/forms/rfe-forms/post-submission-te
import referenceByMappingForm from '__mocks__/forms/rfe-forms/reference-by-mapping-form.json';
import sampleFieldsForm from '__mocks__/forms/rfe-forms/sample_fields.json';
import testEnrolmentForm from '__mocks__/forms/rfe-forms/test-enrolment-form.json';
import historicalExpressionsForm from '__mocks__/forms/rfe-forms/historical-expressions-form.json';
import mockHxpEncounter from '__mocks__/forms/rfe-forms/mockHistoricalvisitsEncounter.json';
import requiredTestForm from '__mocks__/forms/rfe-forms/required-form.json';
import conditionalRequiredTestForm from '__mocks__/forms/rfe-forms/conditional-required-form.json';
Expand All @@ -51,25 +43,14 @@ import nextVisitForm from '__mocks__/forms/rfe-forms/next-visit-test-form.json';
import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-form.json';

import FormEngine from './form-engine.component';
import { type FormsRegistryStoreState } from './registry/registry';

const locale = 'en';
const patientUUID = '8673ee4f-e2ab-4077-ba55-4980f408773e';
const visit = mockVisit;
const formsResourcePath = when((url: string) => url.includes(`${restBaseUrl}/form/`));
const clobdataResourcePath = when((url: string) => url.includes(`${restBaseUrl}/clobdata/`));
const clobDataResourcePath = when((url: string) => url.includes(`${restBaseUrl}/clobdata/`));
global.ResizeObserver = require('resize-observer-polyfill');

const mockOpenmrsFetch = jest.mocked(openmrsFetch);
const mockUseConnectivity = jest.mocked(useConnectivity);
const mockCreateErrorHandler = jest.mocked(createErrorHandler);
const mockShowNotification = jest.mocked(showNotification);
const mockShowToast = jest.mocked(showToast);
const mockCreateGlobalStore = jest.mocked(createGlobalStore);
const mockCreateStore = jest.mocked(createUseStore);
const mockGetGlobalStore = jest.mocked(getGlobalStore<FormsRegistryStoreState>);
const mockGetAsyncLifeCycle = jest.mocked(getAsyncLifecycle);
const mockRegisterExtension = jest.mocked(registerExtension);
const mockExtensionSlot = jest.mocked(ExtensionSlot);
const mockUsePatient = jest.mocked(usePatient);
const mockUseSession = jest.mocked(useSession);
Expand All @@ -92,7 +73,7 @@ mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange, isIn
});

when(mockOpenmrsFetch).calledWith(formsResourcePath).mockReturnValue({ data: demoHtsOpenmrsForm });
when(mockOpenmrsFetch).calledWith(clobdataResourcePath).mockReturnValue({ data: demoHtsForm });
when(mockOpenmrsFetch).calledWith(clobDataResourcePath).mockReturnValue({ data: demoHtsForm });

jest.mock('../src/api', () => {
const originalModule = jest.requireActual('../src/api');
Expand Down Expand Up @@ -279,26 +260,23 @@ describe('Form engine component', () => {
});
});

// describe('historical expressions', () => {
// it('should ascertain getPreviousEncounter() returns an encounter and the historical expression displays on the UI', async () => {
// const user = userEvent.setup();
//
// renderForm(null, historicalExpressionsForm, 'COVID Assessment');
//
// //ascertain form has rendered
// await screen.findByRole('combobox', { name: /Reasons for assessment/i });
//
// //ascertain function fetching the encounter has been called
// expect(api.getPreviousEncounter).toHaveBeenCalled();
// expect(api.getPreviousEncounter).toHaveReturnedWith(Promise.resolve(mockHxpEncounter));
//
// const reuseValueButton = screen.getByRole('button', { name: /reuse value/i });
// const evaluatedHistoricalValue = screen.getByText(/Entry into a country/i);
//
// expect(reuseValueButton).toBeInTheDocument;
// expect(evaluatedHistoricalValue).toBeInTheDocument;
// });
// });
describe('historical expressions', () => {
it('should ascertain getPreviousEncounter() returns an encounter and the historical expression displays on the UI', async () => {
const user = userEvent.setup();

renderForm(null, historicalExpressionsForm, 'COVID Assessment');

//ascertain form has rendered
await screen.findByRole('combobox', { name: /Reasons for assessment/i });

//ascertain function fetching the encounter has been called
expect(api.getPreviousEncounter).toHaveBeenCalled();
expect(api.getPreviousEncounter).toHaveReturnedWith(Promise.resolve(mockHxpEncounter));

expect(screen.getByRole('button', { name: /reuse value/i })).toBeInTheDocument;
expect(screen.getByText(/Entry into a country/i));
});
});

describe('Form submission', () => {
it('should validate required field on form submission', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useProcessorDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const useProcessorDependencies = (
})
.catch((error) => {
setError(error);
reportError(error, 'Load processor dependencies failed');
reportError(error, 'Encountered error while loading dependencies');
});
}
}, [loadDependencies]);
Expand Down
3 changes: 2 additions & 1 deletion src/processors/encounter/encounter-form-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { getPreviousEncounter, saveEncounter } from '../../api';
import { useEncounterRole } from '../../hooks/useEncounterRole';
import { evaluateAsyncExpression, evaluateExpression, type FormNode } from '../../utils/expression-runner';
import { hasRendering } from '../../utils/common-utils';
import { extractObsValueAndDisplay } from '../../utils/form-helper';

function useCustomHooks(context: Partial<FormProcessorContextProps>) {
const [isLoading, setIsLoading] = useState(true);
Expand Down Expand Up @@ -311,7 +312,7 @@ export class EncounterFormProcessor extends FormProcessor {
patient: patient,
previousEncounter: previousDomainObjectValue,
});
return value;
return extractObsValueAndDisplay(field, value);
}
if (previousDomainObjectValue && field.questionOptions.enablePreviousValue) {
return await adapter.getPreviousValue(field, previousDomainObjectValue, context);
Expand Down
18 changes: 9 additions & 9 deletions src/registry/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import {
type FormSchemaTransformer,
type PostSubmissionAction,
} from '../types';
import {getGlobalStore} from '@openmrs/esm-framework';
import {FormsStore} from '../constants';
import {inbuiltControls} from './inbuilt-components/inbuiltControls';
import {inbuiltValidators} from './inbuilt-components/inbuiltValidators';
import {inbuiltDataSources} from './inbuilt-components/inbuiltDataSources';
import {getControlTemplate} from './inbuilt-components/control-templates';
import {inbuiltPostSubmissionActions} from './inbuilt-components/InbuiltPostSubmissionActions';
import {inbuiltFormTransformers} from './inbuilt-components/inbuiltTransformers';
import {inbuiltFieldValueAdapters} from './inbuilt-components/inbuiltFieldValueAdapters';
import { getGlobalStore } from '@openmrs/esm-framework';
import { FormsStore } from '../constants';
import { inbuiltControls } from './inbuilt-components/inbuiltControls';
import { inbuiltValidators } from './inbuilt-components/inbuiltValidators';
import { inbuiltDataSources } from './inbuilt-components/inbuiltDataSources';
import { getControlTemplate } from './inbuilt-components/control-templates';
import { inbuiltPostSubmissionActions } from './inbuilt-components/InbuiltPostSubmissionActions';
import { inbuiltFormTransformers } from './inbuilt-components/inbuiltTransformers';
import { inbuiltFieldValueAdapters } from './inbuilt-components/inbuiltFieldValueAdapters';

/**
* @internal
Expand Down
27 changes: 25 additions & 2 deletions src/utils/form-helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { type LayoutType } from '@openmrs/esm-framework';
import { type FormField, type FormPage, type FormSection, type SessionMode } from '../types';
import { type OpenmrsObs, type FormField, type FormPage, type FormSection, type SessionMode } from '../types';
import { isEmpty } from '../validators/form-validator';
import { getRegisteredControl } from '../registry/registry';
import { parseToLocalDateTime } from './common-utils';
import dayjs from 'dayjs';

export function shouldUseInlineLayout(
renderingType: 'single-line' | 'multiline' | 'automatic',
Expand Down Expand Up @@ -170,3 +171,25 @@ export function scrollIntoView(viewId: string, shouldFocus: boolean = false) {
currentElement?.focus();
}
}

export const extractObsValueAndDisplay = (field: FormField, obs: OpenmrsObs) => {
const rendering = field.questionOptions.rendering;

if (typeof obs.value === 'string' || typeof obs.value === 'number') {
if (rendering === 'date' || rendering === 'datetime') {
const dateObj = parseToLocalDateTime(`${obs.value}`);
return { value: dateObj, display: dayjs(dateObj).format('YYYY-MM-DD HH:mm') };
}
return { value: obs.value, display: obs.value };
} else if (['toggle', 'checkbox'].includes(rendering)) {
return {
value: obs.value?.uuid,
display: obs.value?.name?.name,
};
} else {
return {
value: obs.value?.uuid,
display: field.questionOptions.answers?.find((option) => option.concept === obs.value?.uuid)?.label,
};
}
};

0 comments on commit c6d7cba

Please sign in to comment.