From 437bf081dd0a2e44d06fc3eacdbc46f63d11ca64 Mon Sep 17 00:00:00 2001 From: fredkingham Date: Sat, 23 Feb 2019 20:39:07 +0000 Subject: [PATCH] changes user profile so that its created by a signal --- changelog.md | 2 ++ doc/docs/reference/upgrading.md | 4 ++++ opal/core/episodes.py | 2 +- opal/core/patient_lists.py | 2 +- opal/core/test.py | 6 ++++-- opal/models.py | 9 +++++++++ opal/tests/test_api.py | 2 -- opal/tests/test_core_episodes.py | 6 ++++-- opal/tests/test_episode.py | 9 +++++++-- opal/tests/test_models.py | 7 +++++++ opal/tests/test_patient_lists.py | 6 ++++-- opal/tests/test_user_profile.py | 2 +- opal/views.py | 14 ++------------ 13 files changed, 46 insertions(+), 25 deletions(-) diff --git a/changelog.md b/changelog.md index 3350eb99e..bef447380 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,7 @@ ### 0.14.0 (Major Release) +A User's UserProfile is now automatically created when you create a user in a post save signal. + ### 0.13.1 (Minor Release) Upgrades the setup.py Django version from 2.0.9 to 2.0.13. Removes the six library dependency from setup.py. diff --git a/doc/docs/reference/upgrading.md b/doc/docs/reference/upgrading.md index 50b0cef10..03df8408e 100644 --- a/doc/docs/reference/upgrading.md +++ b/doc/docs/reference/upgrading.md @@ -3,6 +3,10 @@ This document provides instructions for specific steps required to upgrading your Opal application to a later version where there are extra steps required. +### 0.13.1 -> 0.14.0 +If you were creating a UserProfile, this will now fail as a UserProfile is created automatically after creating a user (by a signal). + + ### 0.13.0 -> 0.13.1 Upgrades django (minor security upgrade). diff --git a/opal/core/episodes.py b/opal/core/episodes.py index a4ed3e1ac..cce7cbaa7 100644 --- a/opal/core/episodes.py +++ b/opal/core/episodes.py @@ -41,7 +41,7 @@ def episode_visible_to(kls, episode, user): """ from opal.models import UserProfile # Avoid circular import - profile, _ = UserProfile.objects.get_or_create(user=user) + profile = UserProfile.objects.get(user=user) if profile.restricted_only: return False diff --git a/opal/core/patient_lists.py b/opal/core/patient_lists.py index 9c467fafb..109675630 100644 --- a/opal/core/patient_lists.py +++ b/opal/core/patient_lists.py @@ -141,7 +141,7 @@ def list(klass): def visible_to(klass, user): from opal.models import UserProfile # Avoid circular import - profile, _ = UserProfile.objects.get_or_create(user=user) + profile = UserProfile.objects.get(user=user) if profile.restricted_only: return False diff --git a/opal/core/test.py b/opal/core/test.py index 9c86acfea..a86c84d21 100644 --- a/opal/core/test.py +++ b/opal/core/test.py @@ -34,10 +34,12 @@ def user(self): is_staff=True, is_superuser=True ) - profile, _ = UserProfile.objects.get_or_create( + profile = UserProfile.objects.get( user=user, - can_extract=True ) + if not profile.can_extract: + profile.can_extract = True + profile.save() return user def post_json(self, path, data): diff --git a/opal/models.py b/opal/models.py index d5a1d2958..81f79e9b1 100644 --- a/opal/models.py +++ b/opal/models.py @@ -19,6 +19,7 @@ from django.urls import reverse from django.core.exceptions import FieldDoesNotExist from django.utils.encoding import force_str +from django.db.models.signals import post_save from opal.core import ( application, exceptions, lookuplists, plugins, patient_lists, tagging @@ -1656,6 +1657,14 @@ def explicit_access_only(self): return any(r for r in all_roles if r == "scientist") +def save_profile(sender, instance, **kwargs): + if not UserProfile.objects.filter(user=instance).exists(): + UserProfile.objects.create(user=instance) + + +post_save.connect(save_profile, sender=User) + + class InpatientAdmission(PatientSubrecord, ExternallySourcedModel): _icon = 'fa fa-map-marker' _sort = "-admitted" diff --git a/opal/tests/test_api.py b/opal/tests/test_api.py index 1353c0088..2b2200e52 100644 --- a/opal/tests/test_api.py +++ b/opal/tests/test_api.py @@ -576,7 +576,6 @@ class UserProfileTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='testuser') - models.UserProfile.objects.create(user=self.user) self.mock_request = MagicMock(name='request') self.mock_request.user = self.user @@ -605,7 +604,6 @@ class UserTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='testuser') - models.UserProfile.objects.create(user=self.user) self.mock_request = MagicMock(name='request') self.mock_request.user = self.user diff --git a/opal/tests/test_core_episodes.py b/opal/tests/test_core_episodes.py index d72f4e75a..3450c17ef 100644 --- a/opal/tests/test_core_episodes.py +++ b/opal/tests/test_core_episodes.py @@ -14,8 +14,10 @@ class EpisodeCategoryTestCase(test.OpalTestCase): def setUp(self): self.restricted_user = User.objects.create(username='restrictedonly') - self.profile, _ = UserProfile.objects.get_or_create( - user=self.restricted_user, restricted_only=True + UserProfile.objects.filter( + user=self.restricted_user + ).update( + restricted_only=True ) self.patient = Patient.objects.create() self.inpatient_episode = self.patient.create_episode( diff --git a/opal/tests/test_episode.py b/opal/tests/test_episode.py index d11677738..9ac844aac 100644 --- a/opal/tests/test_episode.py +++ b/opal/tests/test_episode.py @@ -230,14 +230,19 @@ def setUp(self): def test_episode_visible_false(self): user = User.objects.create() - UserProfile.objects.create(user=user, restricted_only=True) + UserProfile.objects.filter(user=user).update( + restricted_only=True + ) self.assertFalse( self.episode.category.episode_visible_to(self.episode, user) ) def test_episode_visible_true(self): user = User.objects.create() - UserProfile.objects.create(user=user, restricted_only=False) + UserProfile.objects.filter() + UserProfile.objects.filter(user=user).update( + restricted_only=False + ) self.assertTrue( self.episode.category.episode_visible_to(self.episode, user) ) diff --git a/opal/tests/test_models.py b/opal/tests/test_models.py index 18125a26b..c6b0b15d9 100644 --- a/opal/tests/test_models.py +++ b/opal/tests/test_models.py @@ -7,6 +7,7 @@ from django.conf import settings from django.utils import timezone +from django.contrib.auth.models import User from opal import models from opal.core import application, exceptions, subrecords @@ -854,3 +855,9 @@ class RoleTestCase(OpalTestCase): def test_str(self): r = models.Role(name='Doctor') self.assertEqual('Doctor', r.__str__()) + + +class UserProfileTestCase(OpalTestCase): + def test_create(self): + user = User.objects.create() + self.assertTrue(bool(user.profile)) \ No newline at end of file diff --git a/opal/tests/test_patient_lists.py b/opal/tests/test_patient_lists.py index 26b829f78..ba1f147a1 100644 --- a/opal/tests/test_patient_lists.py +++ b/opal/tests/test_patient_lists.py @@ -230,8 +230,10 @@ class TestPatientList(OpalTestCase): def setUp(self): self.restricted_user = User.objects.create(username='restrictedonly') - self.profile, _ = UserProfile.objects.get_or_create( - user=self.restricted_user, restricted_only=True + UserProfile.objects.filter( + user=self.restricted_user + ).update( + restricted_only=True ) def test_unimplemented_schema(self): diff --git a/opal/tests/test_user_profile.py b/opal/tests/test_user_profile.py index 9a67afd0c..945d6949c 100644 --- a/opal/tests/test_user_profile.py +++ b/opal/tests/test_user_profile.py @@ -18,7 +18,7 @@ def setUp(self): first_name='Test', last_name='User' ) self.user.save() - self.profile, _ = UserProfile.objects.get_or_create(user=self.user) + self.profile = self.user.profile def test_to_dict_has_full_name(self): as_dict = self.profile.to_dict() diff --git a/opal/views.py b/opal/views.py index afd0f6b1a..e2f9ffbb2 100644 --- a/opal/views.py +++ b/opal/views.py @@ -123,18 +123,8 @@ def check_password_reset(request, *args, **kwargs): """ response = login(request, *args, **kwargs) if response.status_code == 302: - try: - profile = request.user.profile - if profile and profile.force_password_change: - return redirect( - reverse('change-password') - ) - except models.UserProfile.DoesNotExist: - # TODO: This probably doesn't do any harm, but - # we should really never reach this. Creation - # of profiles shouldn't happen in a random view. - models.UserProfile.objects.create( - user=request.user, force_password_change=True) + profile = request.user.profile + if profile and profile.force_password_change: return redirect( reverse('change-password') )