Skip to content

Commit

Permalink
Merge branch 'main' into ft-add-support-of-location-attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
usamaidrsk authored Jul 10, 2024
2 parents 81e2a0d + 20499f9 commit 294d56b
Show file tree
Hide file tree
Showing 82 changed files with 1,074 additions and 465 deletions.
14 changes: 12 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
"env": {
"node": true
},
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest-dom/recommended",
"plugin:testing-library/react"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "react-hooks"],
"plugins": ["@typescript-eslint", "jest-dom", "react-hooks", "testing-library"],
"rules": {
"react-hooks/rules-of-hooks": "error",
// Disabling these rules for now just to keep the diff small. I'll enable them one by one as we go.
Expand All @@ -14,6 +19,11 @@
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/triple-slash-reference": "off",
// The following rules need `noImplicitAny` to be set to `true` in our tsconfig. They are too restrictive for now, but should be reconsidered in future
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/unbound-method": "off",
// Use `import type` instead of `import` for type imports https://typescript-eslint.io/blog/consistent-type-imports-and-exports-why-and-how
"@typescript-eslint/consistent-type-imports": [
"error",
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
branches:
- main

env:
TURBO_API: 'http://127.0.0.1:9080'
TURBO_TOKEN: ${{ secrets.TURBO_SERVER_TOKEN }}
TURBO_TEAM: ${{ github.repository_owner }}

jobs:
main:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -35,11 +40,18 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: yarn install --immutable

- name: Setup local cache server for Turborepo
uses: felixmosh/turborepo-gh-artifacts@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
server-token: ${{ env.TURBO_TOKEN }}


- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps

- name: Build apps
run: yarn turbo run build --concurrency=5
run: yarn turbo run build --color --concurrency=5

- name: Run dev server
run: bash e2e/support/github/run-e2e-docker-env.sh
Expand All @@ -51,7 +63,7 @@ jobs:
run: yarn playwright test

- name: Stop dev server
if: "!cancelled()"
if: '!cancelled()'
run: docker stop $(docker ps -a -q)

- name: Upload Report
Expand Down
1 change: 1 addition & 0 deletions __mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ export * from './queue-rooms.mock';
export * from './search.mock';
export * from './session.mock';
export * from './wards.mock';
export * from './ward-patient';
export * from './visits.mock';
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@
"dayjs": "^1.8.36",
"dotenv": "^16.0.3",
"eslint": "^8.55.0",
"eslint-plugin-jest-dom": "^5.4.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-testing-library": "^6.2.2",
"husky": "^8.0.3",
"i18next": "^21.10.0",
"i18next-parser": "^6.6.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('ActiveVisitsTable', () => {
await user.type(searchInput, 'John');

expect(screen.getByText('John Doe')).toBeInTheDocument();
expect(screen.queryByText('Some One')).toBeNull();
expect(screen.queryByText('Some One')).not.toBeInTheDocument();
});

it('displays empty state when there are no active visits', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { render, screen, act } from '@testing-library/react';
import VisitDetailComponent from './visit-detail.component';
import { useVisit } from './visit.resource';
import { formatDate } from '@openmrs/esm-framework';
import { useVisit } from './visit.resource';
import VisitDetailComponent from './visit-detail.component';

jest.mock('./visit.resource');

Expand Down Expand Up @@ -117,6 +117,6 @@ describe('VisitDetailComponent', () => {

render(<VisitDetailComponent visitUuid={visitUuid} patientUuid={patientUuid} />);

expect(screen.queryByRole('button', { name: 'All Encounters' })).toBeNull();
expect(screen.queryByRole('button', { name: 'All Encounters' })).not.toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion packages/esm-active-visits-app/translations/am.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"noDiagnosesFound": "No diagnoses found",
"noEncountersFound": "No encounters found",
"noMedicationsFound": "No medications found",
"noNotesToShowForPatient": "There are no notes to display for this patient",
"noNotesToShowForPatient": "No hay notas para mostrar de este paciente",
"noObservationsFound": "No observations found",
"notes": "Notes",
"noVisitsToDisplay": "No visits to display",
Expand Down
2 changes: 1 addition & 1 deletion packages/esm-active-visits-app/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"noObservationsFound": "No se encontraron observaciones",
"notes": "Notas",
"noVisitsToDisplay": "No hay visitas para mostrar",
"orderDurationAndUnit": "para {duración} {duraciónUnidad}",
"orderDurationAndUnit": "para {{duration}} {{durationUnit}}",
"orderIndefiniteDuration": "Duración indefinida",
"provider": "Proveedor",
"quantity": "Cantidad",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import dayjs from 'dayjs';
import AppointmentTabs from './appointments/appointment-tabs.component';
import AppointmentsHeader from './header/appointments-header.component';
import AppointmentMetrics from './metrics/appointments-metrics.component';
import { WorkspaceOverlay } from '@openmrs/esm-framework';
import { useParams } from 'react-router-dom';
import SelectedDateContext from './hooks/selectedDateContext';
import { omrsDateFormat } from './constants';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render } from '@testing-library/react';
import React from 'react';
import AppointmentActions from './appointments-actions.component';
import { render, screen } from '@testing-library/react';
import { useConfig } from '@openmrs/esm-framework';
import { useTodaysVisits } from '../../hooks/useTodaysVisits';
import { type Appointment, AppointmentKind, AppointmentStatus } from '../../types';
import { useConfig } from '@openmrs/esm-framework';
import AppointmentActions from './appointments-actions.component';

const appointment: Appointment = {
uuid: '7cd38a6d-377e-491b-8284-b04cf8b8c6d8',
Expand Down Expand Up @@ -46,8 +46,13 @@ const appointment: Appointment = {
voided: false,
teleconsultationLink: null,
extensions: [],
endDateTime: null,
dateAppointmentScheduled: null,
};

const mockUseConfig = useConfig as jest.Mock;
const mockUseTodaysVisits = useTodaysVisits as jest.Mock;

jest.mock('../../hooks/useTodaysVisits', () => {
const originalModule = jest.requireActual('../../hooks/useTodaysVisits');

Expand Down Expand Up @@ -79,41 +84,41 @@ describe('AppointmentActions', () => {

it('renders the check in button when appointment is today and the patient has not checked in and check in button enabled', () => {
appointment.status = AppointmentStatus.SCHEDULED;
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [],
}));
const props = { ...defaultProps };
const { getByText } = render(<AppointmentActions {...props} />);
const button = getByText(/check in/i);
expect(button).toBeInTheDocument();
render(<AppointmentActions {...props} />);

expect(screen.getByText(/check in/i)).toBeInTheDocument();
});

it('does not renders the check in button when appointment is today and the patient has not checked in but the check-in button is disabled', () => {
appointment.status = AppointmentStatus.SCHEDULED;
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: false },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [],
}));
const props = { ...defaultProps };
const { queryByText } = render(<AppointmentActions {...props} />);
const button = queryByText('Check In');
expect(button).not.toBeInTheDocument();
render(<AppointmentActions {...props} />);

expect(screen.queryByText(/check in/i)).not.toBeInTheDocument();
});

it('renders the checked out button when the patient has checked out', () => {
appointment.status = AppointmentStatus.COMPLETED;
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [
{
patient: { uuid: '8673ee4f-e2ab-4077-ba55-4980f408773e' },
Expand All @@ -123,18 +128,18 @@ describe('AppointmentActions', () => {
],
}));
const props = { ...defaultProps };
const { getByText } = render(<AppointmentActions {...props} />);
const button = getByText('Checked out');
expect(button).toBeInTheDocument();
render(<AppointmentActions {...props} />);

expect(screen.getByText('Checked out')).toBeInTheDocument();
});

it('renders the check out button when the patient has an active visit and today is the appointment date and the check out button enabled', () => {
appointment.status = AppointmentStatus.CHECKEDIN;
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [
{
patient: { uuid: '8673ee4f-e2ab-4077-ba55-4980f408773e' },
Expand All @@ -144,18 +149,18 @@ describe('AppointmentActions', () => {
],
}));
const props = { ...defaultProps, scheduleType: 'Scheduled' };
const { getByText } = render(<AppointmentActions {...props} />);
const button = getByText('Check out');
expect(button).toBeInTheDocument();
render(<AppointmentActions {...props} />);

expect(screen.getByText(/check out/i)).toBeInTheDocument();
});

it('does not render check out button when the patient has an active visit and today is the appointment date but the check out button is disabled', () => {
appointment.status = AppointmentStatus.CHECKEDIN;
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: false },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [
{
patient: { uuid: '8673ee4f-e2ab-4077-ba55-4980f408773e' },
Expand All @@ -165,18 +170,18 @@ describe('AppointmentActions', () => {
],
}));
const props = { ...defaultProps, scheduleType: 'Scheduled' };
const { queryByText } = render(<AppointmentActions {...props} />);
const button = queryByText('Check out');
expect(button).not.toBeInTheDocument();
render(<AppointmentActions {...props} />);

expect(screen.queryByText(/check out/i)).not.toBeInTheDocument();
});

// commenting these tests out as this functionality is not implemented yet so not sure how they would have ever passed?
/*it('renders the correct button when today is the appointment date and the schedule type is pending', () => {
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [],
}));
const props = { ...defaultProps, scheduleType: 'Pending' };
Expand All @@ -186,11 +191,11 @@ describe('AppointmentActions', () => {
});
it('renders the correct button when today is the appointment date and the schedule type is not pending', () => {
useConfig.mockImplementation(() => ({
mockUseConfig.mockImplementation(() => ({
checkInButton: { enabled: true },
checkOutButton: { enabled: true },
}));
useTodaysVisits.mockImplementation(() => ({
mockUseTodaysVisits.mockImplementation(() => ({
visits: [],
}));
const props = { ...defaultProps, scheduleType: 'Confirmed' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('EndAppointmentModal', () => {
render(<EndAppointmentModal appointmentUuid={'abc'} patientUuid={'123'} closeModal={closeModal} />);

const submitButton = screen.getByRole('button', { name: /check out/i });
expect(submitButton).not.toBeDisabled();
expect(submitButton).toBeEnabled();
await user.click(submitButton);

expect(changeAppointmentStatus).toHaveBeenCalledWith('Completed', 'abc');
Expand All @@ -63,7 +63,7 @@ describe('EndAppointmentModal', () => {
render(<EndAppointmentModal appointmentUuid={'abc'} patientUuid={'123'} closeModal={closeModal} />);

const submitButton = screen.getByRole('button', { name: /check out/i });
expect(submitButton).not.toBeDisabled();
expect(submitButton).toBeEnabled();
await user.click(submitButton);

expect(changeAppointmentStatus).toHaveBeenCalledWith('Completed', 'abc');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import AppointmentDetails from './appointment-details.component';
import { render, screen } from '@testing-library/react';
import { type Appointment } from '../../types';
import AppointmentDetails from './appointment-details.component';

const appointment: Appointment = {
uuid: '7cd38a6d-377e-491b-8284-b04cf8b8c6d8',
Expand Down Expand Up @@ -77,27 +77,27 @@ jest.mock('@openmrs/esm-framework', () => {
});

test('renders appointment details correctly', async () => {
const { getByText } = render(<AppointmentDetails appointment={appointment} />);
expect(getByText(/Patient name/i)).toBeInTheDocument();
expect(getByText(/John Wilson/i)).toBeInTheDocument();
expect(getByText(/Age/i)).toBeInTheDocument();
expect(getByText(/34/i)).toBeInTheDocument();
expect(getByText(/Gender/i)).toBeInTheDocument();
expect(getByText(/Male/i)).toBeInTheDocument();
expect(getByText(/Date of birth/i)).toBeInTheDocument();
expect(getByText(/Date of birth/i)).toBeInTheDocument();
expect(getByText(/22-Mar-2020/i)).toBeInTheDocument();
expect(getByText(/Contact 1/i)).toBeInTheDocument();
expect(getByText(/0899129989932/i)).toBeInTheDocument();
expect(getByText(/Appointment Notes/i)).toBeInTheDocument();
expect(getByText(/Some comments/i)).toBeInTheDocument();
expect(getByText(/Appointment History/i)).toBeInTheDocument();
expect(getByText(/Completed/i)).toBeInTheDocument();
expect(getByText('1', { exact: true })).toBeInTheDocument();
expect(getByText(/Missed/i)).toBeInTheDocument();
expect(getByText('2', { exact: true })).toBeInTheDocument();
expect(getByText(/Cancelled/i)).toBeInTheDocument();
expect(getByText('3', { exact: true })).toBeInTheDocument();
expect(getByText(/Upcoming/i)).toBeInTheDocument();
expect(getByText('4', { exact: true })).toBeInTheDocument();
render(<AppointmentDetails appointment={appointment} />);
expect(screen.getByText(/Patient name/i)).toBeInTheDocument();
expect(screen.getByText(/John Wilson/i)).toBeInTheDocument();
expect(screen.getByText(/Age/i)).toBeInTheDocument();
expect(screen.getByText(/34/i)).toBeInTheDocument();
expect(screen.getByText(/Gender/i)).toBeInTheDocument();
expect(screen.getByText(/Male/i)).toBeInTheDocument();
expect(screen.getByText(/Date of birth/i)).toBeInTheDocument();
expect(screen.getByText(/Date of birth/i)).toBeInTheDocument();
expect(screen.getByText(/22-Mar-2020/i)).toBeInTheDocument();
expect(screen.getByText(/Contact 1/i)).toBeInTheDocument();
expect(screen.getByText(/0899129989932/i)).toBeInTheDocument();
expect(screen.getByText(/Appointment Notes/i)).toBeInTheDocument();
expect(screen.getByText(/Some comments/i)).toBeInTheDocument();
expect(screen.getByText(/Appointment History/i)).toBeInTheDocument();
expect(screen.getByText(/Completed/i)).toBeInTheDocument();
expect(screen.getByText('1', { exact: true })).toBeInTheDocument();
expect(screen.getByText(/Missed/i)).toBeInTheDocument();
expect(screen.getByText('2', { exact: true })).toBeInTheDocument();
expect(screen.getByText(/Cancelled/i)).toBeInTheDocument();
expect(screen.getByText('3', { exact: true })).toBeInTheDocument();
expect(screen.getByText(/Upcoming/i)).toBeInTheDocument();
expect(screen.getByText('4', { exact: true })).toBeInTheDocument();
});
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ describe('AppointmentForm', () => {
const serviceSelect = screen.getByRole('combobox', { name: /Select a service/i });
const appointmentTypeSelect = screen.getByRole('combobox', { name: /Select the type of appointment/i });

expect(saveButton).not.toBeDisabled();
expect(saveButton).toBeEnabled();

await user.clear(dateInput);
await user.type(dateInput, '4/4/2021');
Expand Down
Loading

0 comments on commit 294d56b

Please sign in to comment.