-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add openmrs listener and remove sync
- Loading branch information
Showing
11 changed files
with
324 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { sync, startListeners, stopListeners } from '../openmrs'; | ||
import * as openmrsSync from '../../utils/openmrs_sync'; | ||
import * as openmrsListener from '../../utils/openmrs-listener'; | ||
import { logger } from '../../../logger'; | ||
import { SYNC_PERIOD } from '../../../config'; | ||
|
||
jest.mock('../../../logger'); | ||
jest.mock('../../utils/openmrs_sync'); | ||
jest.mock('../../utils/openmrs-listener'); | ||
|
||
describe('OpenMRS Controller', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('sync', () => { | ||
it('syncs patients and encounters successfully', async () => { | ||
const syncPatientsSpy = jest.spyOn(openmrsSync, 'syncPatients').mockResolvedValueOnce(); | ||
const syncEncountersSpy = jest.spyOn(openmrsSync, 'syncEncounters').mockResolvedValueOnce(); | ||
|
||
const result = await sync(); | ||
|
||
// Verify sync period calculation | ||
const expectedStartTime = new Date(Date.now() - parseInt(SYNC_PERIOD, 10) * 1000); | ||
expect(syncPatientsSpy).toHaveBeenCalledWith(expect.any(Date)); | ||
expect(syncEncountersSpy).toHaveBeenCalledWith(expect.any(Date)); | ||
|
||
// Verify the timestamps are within 1 second of expected | ||
const patientCallTime = syncPatientsSpy.mock.calls[0][0] as Date; | ||
const encounterCallTime = syncEncountersSpy.mock.calls[0][0] as Date; | ||
expect(Math.abs(patientCallTime.getTime() - expectedStartTime.getTime())).toBeLessThan(1000); | ||
expect(Math.abs(encounterCallTime.getTime() - expectedStartTime.getTime())).toBeLessThan(1000); | ||
|
||
expect(result).toEqual({ | ||
status: 200, | ||
data: { message: 'OpenMRS sync completed successfully' } | ||
}); | ||
}); | ||
|
||
it('handles sync errors', async () => { | ||
const error = new Error('Sync failed'); | ||
jest.spyOn(openmrsSync, 'syncPatients').mockRejectedValueOnce(error); | ||
|
||
const result = await sync(); | ||
|
||
expect(logger.error).toHaveBeenCalledWith(error); | ||
expect(result).toEqual({ | ||
status: 500, | ||
data: { message: 'Error during OpenMRS Sync' } | ||
}); | ||
}); | ||
}); | ||
|
||
describe('startListeners', () => { | ||
it('starts listeners successfully', async () => { | ||
const addListenersSpy = jest.spyOn(openmrsListener, 'addListeners'); | ||
|
||
const result = await startListeners(); | ||
|
||
expect(addListenersSpy).toHaveBeenCalled(); | ||
expect(result).toEqual({ | ||
status: 200, | ||
data: { message: 'OpenMRS listeners started successfully' } | ||
}); | ||
}); | ||
|
||
it('handles listener start errors', async () => { | ||
const error = new Error('Failed to start listeners'); | ||
jest.spyOn(openmrsListener, 'addListeners').mockImplementationOnce(() => { | ||
throw error; | ||
}); | ||
|
||
const result = await startListeners(); | ||
|
||
expect(logger.error).toHaveBeenCalledWith(error); | ||
expect(result).toEqual({ | ||
status: 500, | ||
data: { message: 'Error starting OpenMRS listeners' } | ||
}); | ||
}); | ||
}); | ||
|
||
describe('stopListeners', () => { | ||
it('stops listeners successfully', async () => { | ||
const removeListenersSpy = jest.spyOn(openmrsListener, 'removeListeners'); | ||
|
||
const result = await stopListeners(); | ||
|
||
expect(removeListenersSpy).toHaveBeenCalled(); | ||
expect(result).toEqual({ | ||
status: 200, | ||
data: { message: 'OpenMRS listeners stopped successfully' } | ||
}); | ||
}); | ||
|
||
it('handles listener stop errors', async () => { | ||
const error = new Error('Failed to stop listeners'); | ||
jest.spyOn(openmrsListener, 'removeListeners').mockImplementationOnce(() => { | ||
throw error; | ||
}); | ||
|
||
const result = await stopListeners(); | ||
|
||
expect(logger.error).toHaveBeenCalledWith(error); | ||
expect(result).toEqual({ | ||
status: 500, | ||
data: { message: 'Error stopping OpenMRS listeners' } | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { chtEventEmitter, CHT_EVENTS } from './cht'; | ||
import { sendPatientToOpenMRS, sendEncounterToOpenMRS } from './openmrs_sync'; | ||
import { logger } from '../../logger'; | ||
|
||
// Store active listeners to allow for deregistration | ||
type PatientListener = (patient: fhir4.Patient) => Promise<void>; | ||
type EncounterListener = (data: { encounter: fhir4.Encounter, references: fhir4.Resource[] }) => Promise<void>; | ||
const activeListeners: { [key: string]: PatientListener | EncounterListener } = {}; | ||
|
||
function registerPatientListener() { | ||
if (activeListeners[CHT_EVENTS.PATIENT_CREATED]) { | ||
return; // Already registered | ||
} | ||
const listener = async (patient: fhir4.Patient) => { | ||
try { | ||
await sendPatientToOpenMRS(patient); | ||
} catch (error) { | ||
logger.error(`Error sending patient to OpenMRS: ${error}`); | ||
} | ||
}; | ||
chtEventEmitter.on(CHT_EVENTS.PATIENT_CREATED, listener); | ||
activeListeners[CHT_EVENTS.PATIENT_CREATED] = listener; | ||
logger.info('Patient listener registered'); | ||
} | ||
|
||
function registerEncounterListener() { | ||
if (activeListeners[CHT_EVENTS.ENCOUNTER_CREATED]) { | ||
return; // Already registered | ||
} | ||
const listener = async (data: { | ||
encounter: fhir4.Encounter, | ||
references: fhir4.Resource[] | ||
}) => { | ||
try { | ||
await sendEncounterToOpenMRS(data.encounter, data.references); | ||
} catch (error) { | ||
logger.error(`Error sending encounter to OpenMRS: ${error}`); | ||
} | ||
}; | ||
chtEventEmitter.on(CHT_EVENTS.ENCOUNTER_CREATED, listener); | ||
activeListeners[CHT_EVENTS.ENCOUNTER_CREATED] = listener; | ||
logger.info('Encounter listener registered'); | ||
} | ||
|
||
function deregisterListener(eventName: string) { | ||
if (activeListeners[eventName]) { | ||
chtEventEmitter.off(eventName, activeListeners[eventName]); | ||
delete activeListeners[eventName]; | ||
logger.info(`Deregistered listener for ${eventName}`); | ||
} | ||
} | ||
|
||
export function addListeners() { | ||
registerPatientListener(); | ||
registerEncounterListener(); | ||
logger.info('OpenMRS listeners added successfully'); | ||
} | ||
|
||
export function removeListeners() { | ||
deregisterListener(CHT_EVENTS.PATIENT_CREATED); | ||
deregisterListener(CHT_EVENTS.ENCOUNTER_CREATED); | ||
logger.info('OpenMRS listeners removed successfully'); | ||
} |
Oops, something went wrong.