Skip to content

Commit

Permalink
Merge d9a7e99 into 11bf3ae
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmiller committed Dec 1, 2017
2 parents 11bf3ae + d9a7e99 commit 2d97746
Show file tree
Hide file tree
Showing 52 changed files with 2,121 additions and 169 deletions.
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
[run]
source =
elcid
intrahospital_api

omit =
*/migrations/*
elcid/test/*
intrahospital_api/test/*
elcid/wsgi*
elcid/settings.py
elcid/local_settings.py
elcid/templates/acceptance/*


Expand Down
4 changes: 3 additions & 1 deletion config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ module.exports = function(config){
__dirname + '/../elcid/assets/js/elcid/*',
__dirname + '/../elcid/assets/js/elcid/controllers/*',
__dirname + '/../elcid/assets/js/elcid/services/*',
__dirname + '/../elcid/assets/js/elcid/services/records/*'
__dirname + '/../elcid/assets/js/elcid/services/records/*',
__dirname + '/../intrahospital_api/static/js/intrahospital_api/controllers/*',
];
var includedFiles = [
'opal/app.js',
__dirname + '/../elcid/assets/js/elcid/**/*.js',
__dirname + '/../elcid/assets/js/elcidtest/*.js',
__dirname + '/../intrahospital_api/static/js/intrahospital_api/*.js',
];

var defaultConfig = karmaDefaults(includedFiles, baseDir, coverageFiles);
Expand Down
4 changes: 4 additions & 0 deletions elcid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class Application(application.OpalApplication):
'js/elcid/controllers/rfh_find_patient.js',
'js/elcid/controllers/bloodculture_pathway_form.js',
'js/elcid/controllers/remove_patient_step.js',

'js/elcid/services/demographics_search.js',


'js/elcid/controllers/tagging_step.js',
# used in the blood culture forms
'js/elcid/services/blood_culture_helper.js',
Expand Down
36 changes: 35 additions & 1 deletion elcid/api.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import datetime
from django.conf import settings
from collections import defaultdict
from intrahospital_api import get_api

from rest_framework import viewsets
from opal.core.api import OPALRouter
from opal.core.api import patient_from_pk
from opal.core.api import patient_from_pk, LoginRequiredViewset
from opal.core.views import json_response
from elcid import models as emodels

Expand Down Expand Up @@ -119,5 +120,38 @@ def retrieve(self, request, patient):
culture_order=culture_order
))


class DemographicsSearch(LoginRequiredViewset):
base_name = 'demographics_search'
PATIENT_FOUND_IN_ELCID = "patient_found_in_elcid"
PATIENT_FOUND_UPSTREAM = "patient_found_upstream"
PATIENT_NOT_FOUND = "patient_not_found"

def retrieve(self, request, *args, **kwargs):
hospital_number = kwargs["pk"]
demographics = emodels.Demographics.objects.filter(
hospital_number=hospital_number
).last()

# the patient is in elcid
if demographics:
return json_response(dict(
patient=demographics.patient.to_dict(request.user),
status=self.PATIENT_FOUND_IN_ELCID
))
else:
if settings.USE_UPSTREAM_DEMOGRAPHICS:
api = get_api()
demographics = api.demographics(hospital_number)

if demographics:
return json_response(dict(
patient=dict(demographics=[demographics]),
status=self.PATIENT_FOUND_UPSTREAM
))
return json_response(dict(status=self.PATIENT_NOT_FOUND))


elcid_router = OPALRouter()
elcid_router.register(BloodCultureResultApi.base_name, BloodCultureResultApi)
elcid_router.register(DemographicsSearch.base_name, DemographicsSearch)
22 changes: 11 additions & 11 deletions elcid/assets/js/elcid/controllers/rfh_find_patient.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
angular.module('opal.controllers').controller('RfhFindPatientCtrl',
function(scope, Episode, step, episode, $window) {
function(scope, step, episode, DemographicsSearch, $window) {
"use strict";

scope.lookup_hospital_number = function() {
Episode.findByHospitalNumber(
scope.demographics.hospital_number,
{
newPatient: scope.new_patient,
newForPatient: scope.new_for_patient,
error : function(){
// this shouldn't happen, but we should probably handle it better
$window.alert('ERROR: More than one patient found with hospital number');
}
});
DemographicsSearch.find(
scope.demographics.hospital_number,
{
// we can't find the patient on either elicd or the hospital demographcis
patient_not_found: scope.new_patient,
// the patient has been entered into elcid before
patient_found_in_elcid: scope.new_for_patient,
// the patient exists on the intrahospital api, but not in elcid
patient_found_upstream: scope.new_for_patient
});
};

this.initialise = function(scope){
Expand Down
61 changes: 61 additions & 0 deletions elcid/assets/js/elcid/services/demographics_search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
angular.module('opal.services').factory('DemographicsSearch', function($q, $http, $window, Patient, ngProgressLite) {
"use strict";
/*
* The demographics search used by the find patient
* pathway.
*/

var url = '/elcid/v0.1/demographics_search/';

// we have four call backs that we are expecting

// patient is found in elcid (Yay!)
var PATIENT_FOUND_IN_ELCID = "patient_found_in_elcid";

// patient is not found in elcid but is found
// in the hospital (Yay!)
var PATIENT_FOUND_UPSTREAM = "patient_found_upstream";

// patient is not found
var PATIENT_NOT_FOUND = "patient_not_found";

var expectedStatuses = [
PATIENT_FOUND_IN_ELCID,
PATIENT_FOUND_UPSTREAM,
PATIENT_NOT_FOUND,
]

var find = function(hospitalNumber, findPatientOptions){
ngProgressLite.set(0);
ngProgressLite.start();
var callBackNames = _.keys(findPatientOptions);
_.each(callBackNames, function(key){
if(expectedStatuses.indexOf(key) === -1){
throw "unknown call back";
}
});
var patientUrl = url + hospitalNumber + "/"
$http.get(patientUrl).then(function(response) {
ngProgressLite.done();
if(response.data.status == PATIENT_FOUND_IN_ELCID){
findPatientOptions[PATIENT_FOUND_IN_ELCID](response.data.patient);
}
else if(response.data.status == PATIENT_FOUND_UPSTREAM){
findPatientOptions[PATIENT_FOUND_UPSTREAM](response.data.patient);
}
else if(response.data.status == PATIENT_NOT_FOUND){
findPatientOptions[PATIENT_NOT_FOUND](response.data.patient);
}
else{
$window.alert('DemographicsSearch could not be loaded');
}
}, function(){
ngProgressLite.done();
$window.alert('DemographicsSearch could not be loaded');
});
}

return {
find: find
};
});
149 changes: 149 additions & 0 deletions elcid/assets/js/elcidtest/demographics_search.service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
describe("DemographicsSearch", function(){
"use strict";

var DemographicsSearch, $rootScope, $httpBackend, $window, ngProgressLite;

beforeEach(function(){
module('opal.services', function($provide){
ngProgressLite = jasmine.createSpyObj([
"set", "start", "done"
])
$provide.service('ngProgressLite', function(){
return ngProgressLite
});

});
inject(function($injector){
DemographicsSearch = $injector.get('DemographicsSearch');
$rootScope = $injector.get('$rootScope');
$httpBackend = $injector.get('$httpBackend');
$window = $injector.get('$window');
});
});

afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});

it('should blow up if we pass in an unknown call back', function(){
expect(function(){
DemographicsSearch.find(
"1231231221",
{
blahblah: function(){}
});
}).toThrow("unknown call back");

});

it('should call find patient found in elcid', function(){
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
{status: "patient_found_in_elcid", patient: "some_patient"}
);

DemographicsSearch.find(
"52",
{
patient_found_in_elcid: function(some_result){
called_result = some_result;
}
});

$rootScope.$apply();
$httpBackend.flush();
expect(called_result).toBe("some_patient");
});

it('should call done on the ng progress lite', function(){
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
{status: "patient_found_in_elcid", patient: "some_patient"}
);

DemographicsSearch.find(
"52",
{
patient_found_in_elcid: function(some_result){
called_result = some_result;
}
});

$rootScope.$apply();
$httpBackend.flush();
expect(ngProgressLite.set).toHaveBeenCalledWith(0);
expect(ngProgressLite.start).toHaveBeenCalled();
expect(ngProgressLite.done).toHaveBeenCalled();
});

it('should call patient found in hosptial', function(){
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
{status: "patient_found_upstream", patient: "some_patient"}
);

DemographicsSearch.find(
"52",
{
patient_found_upstream: function(some_result){
called_result = some_result;
}
});

$rootScope.$apply();
$httpBackend.flush();
expect(called_result).toBe("some_patient");
});

it('should call patient not found', function(){
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
{status: "patient_found_upstream"}
);

DemographicsSearch.find(
"52",
{
patient_found_upstream: function(some_result){
called_result = undefined;
}
});

$rootScope.$apply();
$httpBackend.flush();
expect(_.isUndefined(called_result)).toBe(true);
});

it('should raise an alert if an unknown status is returned', function(){
spyOn($window, "alert");
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
{status: "blah blah"}
);

DemographicsSearch.find("52");

$rootScope.$apply();
$httpBackend.flush();
expect($window.alert).toHaveBeenCalledWith(
"DemographicsSearch could not be loaded"
)
});

it('should blow up if the search errors', function(){
spyOn($window, "alert");
var called_result = false;
$httpBackend.expectGET('/elcid/v0.1/demographics_search/52/').respond(
500, "NO"
);

DemographicsSearch.find("52");

$rootScope.$apply();
$httpBackend.flush();
expect($window.alert).toHaveBeenCalledWith(
"DemographicsSearch could not be loaded"
)
});
});
26 changes: 8 additions & 18 deletions elcid/assets/js/elcidtest/rfh_find_patient.controller.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
describe('RfhFindPatientCtrl', function() {
"use strict";
var scope, Episode, $controller, controller, $window;
var scope, DemographicsSearch, $controller, controller, $window;

beforeEach(function(){
module('opal.controllers');
inject(function($injector){
var $rootScope = $injector.get('$rootScope');
scope = $rootScope.$new();
Episode = $injector.get('Episode');
DemographicsSearch = $injector.get('DemographicsSearch');
$controller = $injector.get('$controller');
});

Expand All @@ -18,7 +18,7 @@ describe('RfhFindPatientCtrl', function() {
};
controller = $controller('RfhFindPatientCtrl', {
scope: scope,
Episode: Episode,
DemographicsSearch: DemographicsSearch,
step: {},
episode: {},
$window: $window
Expand All @@ -41,26 +41,16 @@ describe('RfhFindPatientCtrl', function() {
});

it("should look up hospital numbers", function(){
spyOn(Episode, "findByHospitalNumber");
spyOn(DemographicsSearch, "find");
scope.demographics.hospital_number = "12";
scope.lookup_hospital_number();
var allCallArgs = Episode.findByHospitalNumber.calls.all();
var allCallArgs = DemographicsSearch.find.calls.all();
expect(allCallArgs.length).toBe(1);
var callArgs = allCallArgs[0].args;
expect(callArgs[0]).toBe("12");
expect(callArgs[1].newPatient).toEqual(scope.new_patient);
expect(callArgs[1].newForPatient).toEqual(scope.new_for_patient);
});

it("should throw an error if the hospital number isn't found", function(){
spyOn(Episode, "findByHospitalNumber");
scope.demographics.hospital_number = "12";
scope.lookup_hospital_number();
var allCallArgs = Episode.findByHospitalNumber.calls.all();
expect(allCallArgs.length).toBe(1);
var callArgs = allCallArgs[0].args;
expect(callArgs[1].error());
expect($window.alert).toHaveBeenCalledWith('ERROR: More than one patient found with hospital number');
expect(callArgs[1].patient_not_found).toEqual(scope.new_patient);
expect(callArgs[1].patient_found_in_elcid).toEqual(scope.new_for_patient);
expect(callArgs[1].patient_found_upstream).toEqual(scope.new_for_patient);
});

it('should only show next if state is has_demographics or editing_demographics', function(){
Expand Down
Loading

0 comments on commit 2d97746

Please sign in to comment.