Skip to content

Commit

Permalink
Merge pull request #528 from openhealthcare/v0.3.7-api-refactor
Browse files Browse the repository at this point in the history
V0.3.7 api refactor
  • Loading branch information
davidmiller committed Nov 20, 2018
2 parents 4f610d2 + 9f3bfbb commit 1af8e5d
Show file tree
Hide file tree
Showing 91 changed files with 5,179 additions and 3,282 deletions.
2 changes: 1 addition & 1 deletion elcid/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ def list(self, request, *args, **kwargs):
))
else:
if settings.USE_UPSTREAM_DEMOGRAPHICS:
demographics = loader.load_demographics(hospital_number)
demographics = loader.query_patient_demographics(hospital_number)

if demographics:
return json_response(dict(
Expand Down
44 changes: 44 additions & 0 deletions elcid/migrations/0029_appointment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-11-15 11:37
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import opal.models


class Migration(migrations.Migration):

dependencies = [
('opal', '0036_merge_20181030_1654'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('elcid', '0028_auto_20181101_1146'),
]

operations = [
migrations.CreateModel(
name='Appointment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(blank=True, null=True)),
('updated', models.DateTimeField(blank=True, null=True)),
('consistency_token', models.CharField(max_length=8)),
('state', models.CharField(blank=True, default=b'', max_length=256)),
('start', models.DateTimeField(blank=True, null=True)),
('end', models.DateTimeField(blank=True, null=True)),
('clinic_resource', models.CharField(blank=True, default=b'', max_length=256)),
('appointment_type', models.CharField(blank=True, default=b'', max_length=256)),
('location', models.CharField(blank=True, default=b'', max_length=256)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_elcid_appointment_subrecords', to=settings.AUTH_USER_MODEL)),
('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='opal.Patient')),
('updated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='updated_elcid_appointment_subrecords', to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['-start'],
'verbose_name': 'Appointments',
'verbose_name_plural': 'Appointments',
},
bases=(opal.models.UpdatesFromDictMixin, opal.models.ToDictMixin, models.Model),
),
]
35 changes: 35 additions & 0 deletions elcid/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,3 +675,38 @@ class GP(omodels.PatientSubrecord):
max_length=256
)
contact_details = models.TextField()


class Appointment(omodels.PatientSubrecord):
state = models.CharField(
max_length=256, blank=True, default=""
)
start = models.DateTimeField(blank=True, null=True)
end = models.DateTimeField(blank=True, null=True)
clinic_resource = models.CharField(
max_length=256, blank=True, default=""
)
appointment_type = models.CharField(
max_length=256, blank=True, default=""
)

location = models.CharField(
max_length=256, blank=True, default=""
)

def update_from_dict(self, *args, **kwargs):
"""
This model is read only from the front end
"""
pass

def update_from_api_dict(self, *args, **kwargs):
return super(Appointment, self).update_from_dict(
*args, force=True, **kwargs
)

class Meta:
verbose_name = "Appointments"
verbose_name_plural = "Appointments"
ordering = ["-start"]

24 changes: 12 additions & 12 deletions elcid/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
TEMPLATE_DEBUG = DEBUG
AUTOCOMPLETE_SEARCH = True

# The intrahospital API is what we use to connect to the rest of the hospital.
INTRAHOSPITAL_API = 'intrahospital_api.apis.dev_api.DevApi'

ADMINS = (
('Support', 'support@openhealthcare.org.uk',),
)
Expand Down Expand Up @@ -179,24 +182,24 @@

#### API Settings

# The intrahospital api is what we use to connect to the rest of the hospital
INTRAHOSPITAL_API = 'intrahospital_api.apis.dev_api.DevApi'

# when running the batch load, this user needs to be set
API_USER = "needs to be set"
API_USER = "super"

# Use the dev api by default, options are dev or live.
API_STATE = "dev"

# this needs to be set to true on prod
ASYNC_API = False


# if the intrahospital api is prod, we need
# an ip address, a database, a username and a password for
# the hospital db
HOSPITAL_DB = dict(
ip_address=None,
database=None,
username=None,
password=None,
view=None
IP_ADDRESS=None,
DATABASE=None,
USERNAME=None,
PASSWORD=None,
)


Expand Down Expand Up @@ -348,9 +351,6 @@



# The intrahospital api is what we use to connect to the rest of the hospital
INTRAHOSPITAL_API = 'intrahospital_api.apis.dev_api.DevApi'

# search with external demographics when adding a patient
USE_UPSTREAM_DEMOGRAPHICS = True

Expand Down
4 changes: 2 additions & 2 deletions elcid/test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ def test_without_hospital_number(self):
self.assertEqual(self.client.get(self.raw_url).status_code, 400)

@override_settings(USE_UPSTREAM_DEMOGRAPHICS=True)
@mock.patch("elcid.api.loader.load_demographics")
@mock.patch("elcid.api.loader.query_patient_demographics")
def test_with_demographics_add_patient_not_found(
self, load_demographics
):
Expand All @@ -268,7 +268,7 @@ def test_with_demographics_add_patient_not_found(
)

@override_settings(USE_UPSTREAM_DEMOGRAPHICS=True)
@mock.patch("elcid.api.loader.load_demographics")
@mock.patch("elcid.api.loader.query_patient_demographics")
def test_with_demographics_add_patient_found_upstream(
self, load_demographics
):
Expand Down
54 changes: 36 additions & 18 deletions elcid/test/test_fabric.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,19 +565,27 @@ def test_restart_nginx(self, local, print_function):
@mock.patch('fabfile.local')
@mock.patch('fabfile.print', create=True)
class CronTestCase(FabfileTestCase):
def test_write_cron_lab_tests(
self, print_function, local
@mock.patch('fabfile.glob.glob')
@mock.patch("fabfile.jinja_env.get_template")
def test_write_cron_jobs(
self, get_template, glob, print_function, local
):
fabfile.write_cron_lab_tests(self.prod_env)
local.assert_called_once_with("echo '0/5 * * * * ohc \
/home/ohc/.virtualenvs/elcidrfh-some_branch/bin/python \
/usr/lib/ohc/elcidrfh-some_branch/manage.py \
batch_load >> /usr/lib/ohc/log/cron_synch.log 2>&1' | sudo tee \
/etc/cron.d/elcid_batch_test_load")
print_function.assert_called_once_with(
'Writing cron elcid_batch_test_load'

glob.return_value = [
'etc/cron_templates/cron_demographics_load.jinja2'
]
fabfile.write_cron_jobs(self.prod_env)

self.assertEqual(
get_template.call_count, 1
)

self.assertEqual(
get_template.call_args[0][0],
'etc/cron_templates/cron_demographics_load.jinja2'
)


@mock.patch("fabfile.os")
def test_write_cron_backup(self, os, print_function, local):
os.path.abspath.return_value = "/somthing/somewhere/fabfile.py"
Expand Down Expand Up @@ -815,6 +823,14 @@ def test_get_private_settings(self, os, json):

self.assertEqual(result, expected)

class GetCronOutputFileName(FabfileTestCase):
def test_get_cron_output_file_name(self):
result = fabfile.get_cron_output_file_name(
"etc/cron_templates/cron_demographics_load.jinja2"
)
self.assertEqual(
result, "/etc/cron.d/elcid_cron_demographics_load"
)

class DeployTestCase(FabfileTestCase):
@mock.patch("fabfile.Env")
Expand All @@ -829,7 +845,7 @@ class DeployTestCase(FabfileTestCase):
@mock.patch("fabfile.services_symlink_nginx")
@mock.patch("fabfile.services_symlink_upstart")
@mock.patch("fabfile.services_create_celery_conf")
@mock.patch("fabfile.write_cron_lab_tests")
@mock.patch("fabfile.write_cron_jobs")
@mock.patch("fabfile.services_create_local_settings")
@mock.patch("fabfile.services_create_upstart_conf")
@mock.patch("fabfile.services_create_gunicorn_conf")
Expand All @@ -844,7 +860,7 @@ def test_deploy_no_backup(
services_create_gunicorn_conf,
services_create_upstart_conf,
services_create_local_settings,
write_cron_lab_tests,
write_cron_jobs,
services_create_celery_conf,
services_symlink_upstart,
services_symlink_nginx,
Expand Down Expand Up @@ -941,7 +957,7 @@ def test_deploy_no_backup(
@mock.patch("fabfile.services_symlink_nginx")
@mock.patch("fabfile.services_symlink_upstart")
@mock.patch("fabfile.services_create_local_settings")
@mock.patch("fabfile.write_cron_lab_tests")
@mock.patch("fabfile.write_cron_jobs")
@mock.patch("fabfile.services_create_celery_conf")
@mock.patch("fabfile.services_create_upstart_conf")
@mock.patch("fabfile.services_create_gunicorn_conf")
Expand All @@ -956,7 +972,7 @@ def test_deploy_backup(
services_create_gunicorn_conf,
services_create_upstart_conf,
services_create_celery_conf,
write_cron_lab_tests,
write_cron_jobs,
services_create_local_settings,
services_symlink_upstart,
services_symlink_nginx,
Expand Down Expand Up @@ -1008,12 +1024,12 @@ def test_deploy_backup(
services_create_local_settings.assert_called_once_with(
self.prod_env, pv
)
write_cron_lab_tests.assert_called_once_with(
write_cron_jobs.assert_called_once_with(
self.prod_env
)
services_create_gunicorn_conf.assert_called_once_with(self.prod_env)
services_create_upstart_conf.assert_called_once_with(self.prod_env)
write_cron_lab_tests.assert_called_once_with(self.prod_env)
write_cron_jobs.assert_called_once_with(self.prod_env)
services_create_celery_conf.assert_called_once_with(self.prod_env)
self.assertEqual(
run_management_command.call_count, 4
Expand Down Expand Up @@ -1310,13 +1326,15 @@ def test_different_amount(self, print_function):
@mock.patch("fabfile.copy_backup")
@mock.patch("fabfile.send_error_email")
class DumpAndCopyTestCase(FabfileTestCase):
@mock.patch("fabfile.Env")
def test_error_raised(
self, send_error_email, copy_backup, dump_database
self, Env, send_error_email, copy_backup, dump_database
):
env = Env.return_value
dump_database.side_effect = ValueError("break")
fabfile.dump_and_copy("some_env")
send_error_email.assert_called_once_with(
"database backup failed with 'break'"
"database backup failed with 'break'", env
)
self.assertFalse(copy_backup.called)

Expand Down
24 changes: 24 additions & 0 deletions elcid/test/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,27 @@ def test_update_from_dict_with_new_condition(self):
self.diagnosis.update_from_dict(data, self.user)
diagnosis = self.episode.diagnosis_set.first()
self.assertEqual('New condition', diagnosis.condition)


class AppointmentsTestCase(OpalTestCase):
def setUp(self):
super(AppointmentsTestCase, self).setUp()
self.patient, _ = self.new_patient_and_episode_please()
self.appointment = emodels.Appointment(patient=self.patient)

def test_update_from_dict(self):
data = timezone.now()
self.appointment.update_from_dict(data, self.user)
self.assertIsNone(self.appointment.start)

def test_update_from_api_dict(self):
now = timezone.now()
data = dict(start=now)
self.appointment.update_from_api_dict(data, self.user)
self.assertEqual(self.appointment.start, now)
then = now + datetime.timedelta(minutes=10)

# make sure we don't get burned by consistency token issues
data = dict(start=then)
self.appointment.update_from_api_dict(data, self.user)
self.assertEqual(self.appointment.start, then)
1 change: 1 addition & 0 deletions etc/cron_templates/cron_appointments.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 4 * * * {{ unix_user }} {{ virtualenv }}/bin/python {{ project_dir }}/manage.py batch_appointments_load >> /usr/lib/ohc/log/cron_synch.log 2>&1
1 change: 1 addition & 0 deletions etc/cron_templates/cron_demographics_load.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 4 * * * {{ unix_user }} {{ virtualenv }}/bin/python {{ project_dir }}/manage.py batch_demographics_load >> /usr/lib/ohc/log/cron_synch.log 2>&1
1 change: 1 addition & 0 deletions etc/cron_templates/cron_lab_tests.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0/5 * * * * {{ unix_user }} {{ virtualenv }}/bin/python {{ project_dir }}/manage.py batch_test_load >> /usr/lib/ohc/log/cron_synch.log 2>&1
1 change: 1 addition & 0 deletions etc/cron_templates/cron_smoke_test.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0 1 * * * {{ unix_user }} {{ virtualenv }}/bin/python {{ project_dir }}/manage.py smoke_test >> /usr/lib/ohc/log/cron_synch.log 2>&1
Loading

0 comments on commit 1af8e5d

Please sign in to comment.