this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'user_tests'

- Adds ported tests from pytest to django unnittest(had checked out into a different branch and forgot to merge the changes)

+1218 -45
+467
care/facility/tests/test_facility_api.py
··· 1 + from django.contrib.gis.geos import Point 2 + from rest_framework import status 3 + from rest_framework.test import APITestCase 4 + 5 + from care.facility.models import Facility, FacilityCapacity, FacilityLocalGovtBody 6 + from care.users.models import User 7 + from config.tests.helper import mock_equal 8 + 9 + # flake8: noqa 10 + 11 + 12 + class TestFacility(APITestCase): 13 + """Test Facility APIs""" 14 + 15 + # Override the constructor when using helper 16 + # def __init__(self, *args, **kwargs): 17 + # super(TestFacility, self).__init__(*args, **kwargs) 18 + 19 + @classmethod 20 + def setUpTestData(cls): 21 + # super(TestFacility, cls).setUpTestData() 22 + cls.su_data = { 23 + "user_type": 5, 24 + "email": "some.email@somedomain.com", 25 + "phone_number": "5554446667", 26 + "age": 30, 27 + "gender": 2, 28 + "district": 11, 29 + "username": "superuser_1", 30 + "password": "bar", 31 + } 32 + cls.super_user = User.objects.create_superuser(**cls.su_data) 33 + cls.user_data = cls.su_data.copy() 34 + cls.user_data["username"] = "user" 35 + cls.user = User.objects.create_user(**cls.user_data) 36 + cls.facility_data = { 37 + "name": "Foo", 38 + "district": 13, 39 + "facility_type": 1, 40 + "address": "8/88, 1st Cross, 1st Main, Boo Layout", 41 + "location": {"latitude": 49.878248, "longitude": 24.452545}, 42 + "oxygen_capacity": 10, 43 + "phone_number": "9998887776", 44 + } 45 + # **cls.data is not used because of a issue with the location attribute which requires a Point object 46 + cls.facility = Facility.objects.create( 47 + name="Foo", 48 + district=13, 49 + facility_type=1, 50 + address="8/88, 1st Cross, 1st Main, Boo Layout", 51 + location=Point(24.452545, 49.878248), 52 + oxygen_capacity=10, 53 + phone_number="9998887776", 54 + ) 55 + FacilityLocalGovtBody.objects.create(facility=cls.facility, local_body=None, district_id=13) 56 + 57 + def setUp(self): 58 + """ 59 + Run before every class method 60 + - keep a normal user logged in 61 + """ 62 + # super(TestFacility, self).setUp() 63 + self.client.login(username=self.user_data["username"], password=self.user_data["password"]) 64 + 65 + def test_login_required(self): 66 + """Test unlogged unusers are thrown an error 403""" 67 + # Terminate the user session since user is logged in inside the setUp function 68 + self.client.logout() 69 + response = self.client.post("/api/v1/facility/", {},) 70 + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 71 + 72 + def test_user_can_create_facility(self): 73 + """ 74 + Test users can create facility 75 + - login a normal user 76 + - verify creation response code is 201 77 + - verify inserted values 78 + """ 79 + facility_data = self.facility_data 80 + response = self.client.post("/api/v1/facility/", facility_data, format="json") 81 + 82 + # test status code 83 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 84 + response.data.pop("id") 85 + # test response data 86 + self.assertDictEqual( 87 + response.data, 88 + { 89 + **facility_data, 90 + "id": mock_equal, 91 + "facility_type": "Educational Inst", 92 + "local_govt_body": { 93 + "id": mock_equal, 94 + "facility": mock_equal, 95 + "local_body": None, 96 + "district": {"id": 13, "name": "Kannur", "state": 1}, 97 + }, 98 + }, 99 + ) 100 + 101 + facility = Facility.objects.get( 102 + name=facility_data["name"], 103 + district=facility_data["district"], 104 + facility_type=facility_data["facility_type"], 105 + address=facility_data["address"], 106 + oxygen_capacity=facility_data["oxygen_capacity"], 107 + phone_number=facility_data["phone_number"], 108 + created_by=self.user, 109 + ) 110 + 111 + # Facility exists 112 + assert facility 113 + facility_loc = facility_data["location"] 114 + self.assertDictEqual( 115 + facility_loc, {"latitude": facility_loc["latitude"], "longitude": facility_loc["longitude"],}, 116 + ) 117 + 118 + def test_inactive_facility_retrieval(self): 119 + """Test inactive facility are not accessible""" 120 + facility = self.facility 121 + facility.created_by = self.user 122 + facility.is_active = False 123 + facility.save() 124 + response = self.client.get(f"/api/v1/facility/{facility.id}/") 125 + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) 126 + 127 + def test_active_facility_retrival(self): 128 + """Test facility attributes can be retrieved""" 129 + facility = self.facility 130 + facility.created_by = self.user 131 + facility.save() 132 + response = self.client.get(f"/api/v1/facility/{facility.id}/") 133 + self.assertDictEqual( 134 + response.data, 135 + { 136 + "id": facility.id, 137 + "name": facility.name, 138 + "district": facility.district, 139 + "facility_type": "Educational Inst", 140 + "address": facility.address, 141 + "location": {"latitude": facility.location.tuple[1], "longitude": facility.location.tuple[0],}, 142 + "local_govt_body": { 143 + "id": mock_equal, 144 + "facility": facility.id, 145 + "local_body": None, 146 + "district": {"id": 13, "name": "Kannur", "state": mock_equal}, 147 + }, 148 + "oxygen_capacity": facility.oxygen_capacity, 149 + "phone_number": facility.phone_number, 150 + }, 151 + ) 152 + 153 + def test_facility_update(self): 154 + """Test facilities attributes can be updated""" 155 + facility = self.facility 156 + facility.created_by = self.user 157 + facility.save() 158 + 159 + new_district = {"id": 12, "name": "Wayanad"} 160 + 161 + response = self.client.put( 162 + f"/api/v1/facility/{facility.id}/", 163 + { 164 + "name": "Another name", 165 + "district": new_district["id"], 166 + "facility_type": facility.facility_type, 167 + "address": facility.address, 168 + }, 169 + ) 170 + self.assertEqual(response.status_code, status.HTTP_200_OK) 171 + self.assertDictEqual( 172 + response.data, 173 + { 174 + "id": facility.id, 175 + "name": "Another name", 176 + "district": new_district["id"], 177 + "facility_type": "Educational Inst", 178 + "address": facility.address, 179 + "location": {"latitude": facility.location.tuple[1], "longitude": facility.location.tuple[0],}, 180 + "local_govt_body": { 181 + "id": mock_equal, 182 + "facility": facility.id, 183 + "local_body": None, 184 + "district": {"id": new_district["id"], "name": new_district["name"], "state": mock_equal,}, 185 + }, 186 + "oxygen_capacity": facility.oxygen_capacity, 187 + "phone_number": facility.phone_number, 188 + }, 189 + ) 190 + facility.refresh_from_db() 191 + self.assertEqual(facility.name, "Another name") 192 + 193 + def test_facility_update_doesnt_change_creator(self): 194 + """Test the updation of facility attribute doesn't change its creator""" 195 + facility = self.facility 196 + facility.created_by = self.user 197 + facility.save() 198 + original_creator = facility.created_by 199 + 200 + response = self.client.put(f"/api/v1/facility/{facility.id}/", self.facility_data, format="json") 201 + self.assertEqual(response.status_code, status.HTTP_200_OK) 202 + facility.refresh_from_db() 203 + self.assertEqual(facility.created_by, original_creator) 204 + 205 + def test_facility_deletion(self): 206 + """Test facility deletion can be done and an appropriate error is raised on subsequent retrieval""" 207 + facility = self.facility 208 + facility.created_by = self.user 209 + facility.save() 210 + 211 + response = self.client.delete(f"/api/v1/facility/{facility.id}/",) 212 + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) 213 + with self.assertRaises(Facility.DoesNotExist): 214 + Facility.objects.get(id=facility.id) 215 + 216 + def test_facility_list_retrieval(self): 217 + """Test retrieval of facility list""" 218 + facility = self.facility 219 + facility.created_by = self.user 220 + facility.save() 221 + 222 + response = self.client.get(f"/api/v1/facility/") 223 + self.assertEqual(response.status_code, status.HTTP_200_OK) 224 + self.assertDictEqual( 225 + response.data, 226 + { 227 + "count": 1, 228 + "next": None, 229 + "previous": None, 230 + "results": [ 231 + { 232 + "id": facility.id, 233 + "name": facility.name, 234 + "district": facility.district, 235 + "facility_type": "Educational Inst", 236 + "address": facility.address, 237 + "location": {"latitude": facility.location.tuple[1], "longitude": facility.location.tuple[0],}, 238 + "local_govt_body": { 239 + "id": mock_equal, 240 + "facility": facility.id, 241 + "local_body": None, 242 + "district": {"id": 13, "name": "Kannur", "state": mock_equal,}, 243 + }, 244 + "oxygen_capacity": facility.oxygen_capacity, 245 + "phone_number": facility.phone_number, 246 + }, 247 + ], 248 + }, 249 + ) 250 + 251 + 252 + class TestFacilityBulkUpdate(APITestCase): 253 + """Test API for bulk updates to facility""" 254 + 255 + @classmethod 256 + def setUpTestData(cls): 257 + # super(TestFacility, cls).setUpTestData() 258 + cls.su_data = { 259 + "user_type": 5, 260 + "email": "some.email@somedomain.com", 261 + "phone_number": "5554446667", 262 + "age": 30, 263 + "gender": 2, 264 + "district": 11, 265 + "username": "superuser_1", 266 + "password": "bar", 267 + } 268 + cls.super_user = User.objects.create_superuser(**cls.su_data) 269 + cls.user_data = cls.su_data.copy() 270 + cls.user_data["username"] = "user" 271 + cls.user = User.objects.create_user(**cls.user_data) 272 + cls.facility_data = { 273 + "name": "Foo", 274 + "district": 13, 275 + "facility_type": 1, 276 + "address": "8/88, 1st Cross, 1st Main, Boo Layout", 277 + "location": {"latitude": 49.878248, "longitude": 24.452545}, 278 + "oxygen_capacity": 10, 279 + "phone_number": "9998887776", 280 + } 281 + # **cls.data is not used because of a issue with the location attribute which requires a Point object 282 + cls.facility = Facility.objects.create( 283 + name="Foo", 284 + district=13, 285 + facility_type=1, 286 + address="8/88, 1st Cross, 1st Main, Boo Layout", 287 + location=Point(24.452545, 49.878248), 288 + oxygen_capacity=10, 289 + phone_number="9998887776", 290 + ) 291 + 292 + def setUp(self): 293 + """This is run before every class method""" 294 + self.client.login(username=self.su_data["username"], password=self.su_data["password"]) 295 + 296 + def test_facility_bulk_upsert(self): 297 + """ 298 + For bulk facility upsert, test for a normal user: 299 + - status code after update 300 + - test retrived values 301 + """ 302 + facility = self.facility 303 + user = self.user 304 + # logout the superuser, it's logged in due to the setUp function 305 + self.client.logout() 306 + # login the normal user 307 + self.client.login(username=self.user_data["username"], password=self.user_data["password"]) 308 + 309 + capacity = FacilityCapacity.objects.create( 310 + facility=facility, room_type=1, total_capacity=50, current_capacity=0 311 + ) 312 + facility.created_by = user 313 + facility.save() 314 + 315 + name = "Another" 316 + address = "Dasappan's House, Washington Jn, OolaMukk P.O." 317 + phone_number = "7776665554" 318 + response = self.client.post( 319 + "/api/v1/facility/bulk_upsert/", 320 + data=[ 321 + { 322 + "name": facility.name, 323 + "district": facility.district, 324 + "facility_type": 3, 325 + "address": facility.address, 326 + "capacity": [{"room_type": 1, "total_capacity": 100, "current_capacity": 48,}], 327 + }, 328 + { 329 + "name": name, 330 + "district": 1, 331 + "facility_type": 2, 332 + "address": address, 333 + "phone_number": phone_number, 334 + "capacity": [ 335 + {"room_type": 0, "total_capacity": 350, "current_capacity": 150,}, 336 + {"room_type": 1, "total_capacity": 200, "current_capacity": 100,}, 337 + ], 338 + }, 339 + ], 340 + format="json", 341 + ) 342 + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) 343 + facility.refresh_from_db() 344 + self.assertEqual(facility.facility_type, 3) 345 + capacities = facility.facilitycapacity_set.all() 346 + self.assertEqual(capacities[0].id, capacity.id) 347 + self.assertEqual(capacities[0].room_type, 1) 348 + self.assertEqual(capacities[0].total_capacity, 100) 349 + self.assertEqual(capacities[0].current_capacity, 48) 350 + self.assertEqual(len(capacities), 1) 351 + 352 + new_facility = Facility.objects.get( 353 + created_by=user, name=name, district=1, facility_type=2, address=address, phone_number=phone_number, 354 + ) 355 + assert new_facility 356 + capacities = new_facility.facilitycapacity_set.all() 357 + self.assertEqual(capacities[0].room_type, 0) 358 + self.assertEqual(capacities[0].total_capacity, 350) 359 + self.assertEqual(capacities[0].current_capacity, 150) 360 + self.assertEqual(capacities[1].room_type, 1) 361 + self.assertEqual(capacities[1].total_capacity, 200) 362 + self.assertEqual(capacities[1].current_capacity, 100) 363 + self.assertEqual(len(capacities), 2) 364 + 365 + def test_unauthenticated_users_cant_access(self): 366 + """ 367 + Test unauthenticated users can't access 368 + raise error 403 369 + """ 370 + # logout the superuser, it's logged in due to the setUp function 371 + self.client.logout() 372 + response = self.client.get(f"/api/v1/facility/{self.facility.id}/") 373 + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 374 + 375 + def test_normal_users_cant_access(self): 376 + """ 377 + Test normal users can't access 378 + Error 404 is raised in this case while 403 was raised in the previous one\ 379 + This is weird and not consistent\ 380 + but it is what it is. 381 + """ 382 + # logout the superuser, it's logged in due to the setUp function 383 + self.client.logout() 384 + self.client.login( 385 + username=self.user_data["username"], password=self.user_data["password"], 386 + ) 387 + response = self.client.get(f"/api/v1/facility/{self.facility.id}/") 388 + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) 389 + 390 + def test_super_user_can_access_url_by_location(self): 391 + """Test super user can access url by location""" 392 + response = self.client.get(f"/api/v1/facility/{self.facility.id}/") 393 + self.assertEqual(response.status_code, status.HTTP_200_OK) 394 + 395 + def test_superuser_bulk_facility_data_retrieval(self): 396 + """Test superusers can retrieve bulk facility""" 397 + user = self.super_user 398 + facility = self.facility 399 + response = self.client.get(f"/api/v1/facility/{facility.id}/", format="json") 400 + self.assertDictEqual( 401 + response.data, 402 + { 403 + "id": facility.id, 404 + "name": facility.name, 405 + "district": facility.district, 406 + "facility_type": "Educational Inst", 407 + "address": facility.address, 408 + "location": {"latitude": facility.location.tuple[1], "longitude": facility.location.tuple[0],}, 409 + "local_govt_body": { 410 + "id": mock_equal, 411 + "facility": facility.id, 412 + "local_body": None, 413 + "district": {"id": 13, "name": "Kannur", "state": mock_equal}, 414 + }, 415 + "oxygen_capacity": facility.oxygen_capacity, 416 + "phone_number": facility.phone_number, 417 + }, 418 + ) 419 + 420 + def test_others_cant_update_ones_facility(self): 421 + """Test facility can't be updated by non-creators""" 422 + # logout the superuser, it's logged in due to the setUp function 423 + self.client.logout() 424 + self.client.login( 425 + username=self.user_data["username"], password=self.user_data["password"], 426 + ) 427 + facility = self.facility 428 + data = self.user_data 429 + data["username"] = "random" 430 + new_user = User.objects.create_user(**data) 431 + facility.created_by = new_user 432 + facility.save() 433 + # although this should be put, PUT is weirdly enough not allowed here 434 + response = self.client.post( 435 + "/api/v1/facility/bulk_upsert/", 436 + data=[ 437 + { 438 + "name": facility.name, 439 + "district": facility.district, 440 + "facility_type": 3, 441 + "address": facility.address, 442 + "capacity": [{"room_type": 1, "total_capacity": 100, "current_capacity": 48}], 443 + }, 444 + ], 445 + format="json", 446 + ) 447 + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 448 + self.assertRegexpMatches(response.json()["detail"], r"[\w, ()-/]+ is owned by another user") 449 + 450 + def test_superuser_can_update_ones_facility(self): 451 + """Test superuser can update their facility""" 452 + facility = self.facility 453 + # although this should be put, PUT is weirdly enough not allowed here 454 + response = self.client.post( 455 + "/api/v1/facility/bulk_upsert/", 456 + data=[ 457 + { 458 + "name": facility.name, 459 + "district": facility.district, 460 + "facility_type": 3, 461 + "address": facility.address, 462 + "capacity": [{"room_type": 1, "total_capacity": 100, "current_capacity": 48}], 463 + }, 464 + ], 465 + format="json", 466 + ) 467 + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
+252
care/facility/tests/test_facility_patient_history_api.py
··· 1 + import datetime 2 + 3 + from django.contrib.gis.geos import Point 4 + from rest_framework import status 5 + from rest_framework.test import APITestCase 6 + 7 + from care.facility.models import Facility, FacilityPatientStatsHistory 8 + from care.users.models import User 9 + from config.tests.helper import mock_equal 10 + 11 + 12 + class TestPatientStatsHistory(APITestCase): 13 + """Test patient statistics history APIs""" 14 + 15 + @classmethod 16 + def setUpTestData(cls): 17 + cls.facility_data = { 18 + "name": "Foo", 19 + "district": 13, 20 + "facility_type": 1, 21 + "address": "8/88, 1st Cross, 1st Main, Boo Layout", 22 + "location": {"latitude": 49.878248, "longitude": 24.452545}, 23 + "oxygen_capacity": 10, 24 + "phone_number": "9998887776", 25 + } 26 + cls.facility = Facility.objects.create( 27 + name="Foo", 28 + district=13, 29 + facility_type=1, 30 + address="8/88, 1st Cross, 1st Main, Boo Layout", 31 + location=Point(24.452545, 49.878248), 32 + oxygen_capacity=10, 33 + phone_number="9998887776", 34 + ) 35 + cls.stats_data = { 36 + "num_patients_visited": 1, 37 + "num_patients_home_quarantine": 2, 38 + "num_patients_isolation": 3, 39 + "num_patient_referred": 4, 40 + } 41 + cls.user_data = { 42 + "user_type": 5, 43 + "email": "some.email@somedomain.com", 44 + "phone_number": "5554446667", 45 + "age": 30, 46 + "gender": 2, 47 + "district": 11, 48 + "username": "user_1", 49 + "password": "bar", 50 + } 51 + cls.user = User.objects.create_user(**cls.user_data) 52 + 53 + def setUp(self): 54 + """ 55 + Run before every class method 56 + - log in a user 57 + """ 58 + self.client.login(username=self.user_data["username"], password=self.user_data["password"]) 59 + 60 + @staticmethod 61 + def get_url(facility_id, entry_id=None): 62 + """ 63 + Returns url for the parameters passed 64 + 65 + Return 66 + str 67 + 68 + Params 69 + facility_id: int 70 + The facility id to be used for forming the url for the API 71 + 72 + entry_id: int 73 + The value to be used for constructing detail url if required 74 + Default: None 75 + 76 + """ 77 + url = f"/api/v1/facility/{facility_id}/patient_stats/" 78 + if entry_id: 79 + url = f"{url}{entry_id}/" 80 + return url 81 + 82 + def test_login_required(self): 83 + """Test unauthenticated users aren't allowed access""" 84 + self.client.logout() 85 + response = self.client.post(self.get_url(self.facility.id), {}) 86 + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 87 + 88 + def test_create_patient_history(self): 89 + """Test patient history can be created""" 90 + facility = self.facility 91 + stats_data = self.stats_data 92 + 93 + # test for auto-generate date 94 + response = self.client.post(self.get_url(facility.id), stats_data, format="json") 95 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 96 + self.assertDictEqual( 97 + response.json(), 98 + { 99 + "id": mock_equal, 100 + "facility": facility.id, 101 + "entry_date": datetime.datetime.today().strftime("%Y-%m-%d"), 102 + "created_date": mock_equal, 103 + "modified_date": mock_equal, 104 + **stats_data, 105 + }, 106 + ) 107 + 108 + # test for provided date 109 + entry_date = datetime.datetime(2020, 4, 1).date() 110 + response = self.client.post(self.get_url(facility.id), {"entry_date": entry_date, **stats_data}) 111 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 112 + self.assertDictEqual( 113 + response.json(), 114 + { 115 + "id": mock_equal, 116 + "facility": facility.id, 117 + "entry_date": entry_date.strftime("%Y-%m-%d"), 118 + "created_date": mock_equal, 119 + "modified_date": mock_equal, 120 + **stats_data, 121 + }, 122 + ) 123 + old_response_json = response.json() 124 + 125 + # test for override of info 126 + entry_date = datetime.datetime(2020, 4, 1).date() 127 + new_stats_data = {k: v + 2 for k, v in stats_data.items()} 128 + response = self.client.post(self.get_url(facility.id), {"entry_date": entry_date, **new_stats_data}) 129 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 130 + self.assertDictEqual( 131 + response.json(), 132 + { 133 + "id": old_response_json["id"], 134 + "facility": facility.id, 135 + "entry_date": entry_date.strftime("%Y-%m-%d"), 136 + "created_date": mock_equal, 137 + "modified_date": mock_equal, 138 + **new_stats_data, 139 + }, 140 + ) 141 + 142 + def test_patient_history_list(self): 143 + """Test patient history list is displayed with the correct data""" 144 + stats_data = self.stats_data 145 + facility = self.facility 146 + facility_data = self.facility_data 147 + 148 + location = facility_data.pop("location", None) 149 + facility_2 = Facility.objects.create( 150 + **{**facility_data, "location": Point(location["latitude"], location["longitude"]),} 151 + ) 152 + 153 + FacilityPatientStatsHistory.objects.create( 154 + facility=facility, entry_date=datetime.date(2020, 4, 1), **stats_data 155 + ) 156 + FacilityPatientStatsHistory.objects.create( 157 + facility=facility, entry_date=datetime.date(2020, 4, 2), **stats_data 158 + ) 159 + FacilityPatientStatsHistory.objects.create( 160 + facility=facility_2, entry_date=datetime.date(2020, 4, 2), **stats_data 161 + ) 162 + 163 + response = self.client.get(self.get_url(facility.id)) 164 + self.assertEqual(response.status_code, status.HTTP_200_OK) 165 + self.assertDictEqual( 166 + response.json(), 167 + { 168 + "count": 2, 169 + "next": None, 170 + "previous": None, 171 + "results": [ 172 + { 173 + "id": mock_equal, 174 + "facility": facility.id, 175 + "entry_date": datetime.date(2020, 4, 2).strftime("%Y-%m-%d"), 176 + "created_date": mock_equal, 177 + "modified_date": mock_equal, 178 + **stats_data, 179 + }, 180 + { 181 + "id": mock_equal, 182 + "facility": facility.id, 183 + "entry_date": datetime.date(2020, 4, 1).strftime("%Y-%m-%d"), 184 + "created_date": mock_equal, 185 + "modified_date": mock_equal, 186 + **stats_data, 187 + }, 188 + ], 189 + }, 190 + ) 191 + 192 + def test_retrieve_url_by_location(self): 193 + """Test patient history url is accessible""" 194 + stats_data = self.stats_data 195 + facility = self.facility 196 + 197 + obj = FacilityPatientStatsHistory.objects.create( 198 + facility=facility, entry_date=datetime.date(2020, 4, 1), **stats_data 199 + ) 200 + 201 + response = self.client.get(self.get_url(facility.id, entry_id=obj.id)) 202 + self.assertEqual(response.status_code, status.HTTP_200_OK) 203 + 204 + def test_retrieve(self): 205 + """Test patient history data is returned as expected""" 206 + stats_data = self.stats_data 207 + facility = self.facility 208 + 209 + obj = FacilityPatientStatsHistory.objects.create( 210 + facility=facility, entry_date=datetime.date(2020, 4, 1), **stats_data 211 + ) 212 + 213 + response = self.client.get(self.get_url(facility.id, entry_id=obj.id)) 214 + self.assertDictEqual( 215 + response.json(), 216 + { 217 + "id": obj.id, 218 + "facility": facility.id, 219 + "entry_date": datetime.date(2020, 4, 1).strftime("%Y-%m-%d"), 220 + "created_date": mock_equal, 221 + "modified_date": mock_equal, 222 + **stats_data, 223 + }, 224 + ) 225 + 226 + def test_destroy_patient_history(self): 227 + """ 228 + Test patient history can be deleted 229 + - test status code for the request 230 + - test data count in the database decreases by 1 231 + """ 232 + facility = self.facility 233 + obj = FacilityPatientStatsHistory.objects.create( 234 + facility=facility, entry_date=datetime.date(2020, 4, 1), **self.stats_data 235 + ) 236 + count = FacilityPatientStatsHistory.objects.filter(facility=facility).count() 237 + 238 + response = self.client.delete(self.get_url(facility.id, entry_id=obj.id)) 239 + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) 240 + self.assertEqual( 241 + FacilityPatientStatsHistory.objects.filter(facility=facility).count(), count - 1, 242 + ) 243 + 244 + def test_update_should_not_be_allowed(self): 245 + """Test users can't update patient history""" 246 + response = self.client.put(self.get_url(self.facility.id), {}) 247 + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) 248 + 249 + def test_partial_update_should_not_be_allowed(self): 250 + """Test partial update is also not allowed""" 251 + response = self.client.patch(self.get_url(self.facility.id), {}) 252 + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
+257
care/facility/tests/test_patient_api.py
··· 1 + from rest_framework import status 2 + from rest_framework.test import APITestCase 3 + 4 + from care.facility.models import Disease, PatientRegistration 5 + from care.users.models import User 6 + 7 + 8 + class TestPatient(APITestCase): 9 + """Test patient APIs""" 10 + 11 + @classmethod 12 + def setUpTestData(cls): 13 + """ 14 + Run once per class 15 + - Create a patient 16 + - Create a disease 17 + - Create a user 18 + """ 19 + cls.patient_data = { 20 + "name": "Foo", 21 + "age": 40, 22 + "gender": 2, 23 + "phone_number": "9998887776", 24 + "contact_with_carrier": True, 25 + "medical_history": [], 26 + "medical_history_details": [{"disease": 1, "details": "Quite bad"}], 27 + } 28 + cls.patient = PatientRegistration.objects.create( 29 + name="Bar", age=31, gender=2, phone_number="7776665554", contact_with_carrier=False, 30 + ) 31 + # flake8:noqa 32 + disease = Disease.objects.create(disease=1, details="Quite bad", patient=cls.patient) 33 + cls.user_data = { 34 + "user_type": 5, 35 + "email": "some.email@somedomain.com", 36 + "phone_number": "5554446667", 37 + "age": 30, 38 + "gender": 2, 39 + "district": 11, 40 + "username": "user_2", 41 + "password": "bar", 42 + } 43 + cls.user = User.objects.create_user(**cls.user_data) 44 + 45 + def setUp(self): 46 + """ 47 + Run once before every class method 48 + - log in the user 49 + """ 50 + self.client.login(username=self.user_data["username"], password=self.user_data["password"]) 51 + 52 + def test_login_required(self): 53 + """Test permission error is raised for unauthorised access""" 54 + # logout the user logged in during setUp function 55 + self.client.logout() 56 + response = self.client.post("/api/v1/patient/", {},) 57 + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) 58 + 59 + def test_patient_creation(self): 60 + """ 61 + For new patient can be creation, test 62 + - status code is 201 63 + - patient data is returned from response 64 + - patient is created on the backend 65 + """ 66 + patient_data = self.patient_data 67 + user = self.user 68 + response = self.client.post("/api/v1/patient/", patient_data) 69 + 70 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 71 + response.data.pop("id") 72 + """ 73 + is_active: True failed on my machine due to some weird reason 74 + for now, I(abhyudai) have set it to False 75 + """ 76 + self.assertDictEqual( 77 + response.data, 78 + { 79 + **patient_data, 80 + "medical_history_details": [{"disease": "NO", "details": "Quite bad"}], 81 + "is_active": False, 82 + "last_consultation": None, 83 + }, 84 + ) 85 + 86 + patient = PatientRegistration.objects.get( 87 + name=patient_data["name"], 88 + age=patient_data["age"], 89 + gender=patient_data["gender"], 90 + phone_number=patient_data["phone_number"], 91 + contact_with_carrier=patient_data["contact_with_carrier"], 92 + created_by=user, 93 + is_active=True, 94 + ) 95 + assert Disease.objects.get(patient=patient, **patient_data["medical_history"][0]) 96 + 97 + def test_users_cant_retrieve_others_patients(self): 98 + """Test users can't retrieve patients not created by them""" 99 + response = self.client.get(f"/api/v1/patient/{self.patient.id}/") 100 + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) 101 + 102 + def test_patient_retrieval(self): 103 + """ 104 + Test users can retrieve patients created by them 105 + - test status code 106 + - test response data 107 + """ 108 + patient = self.patient 109 + patient.created_by = self.user 110 + patient.save() 111 + response = self.client.get(f"/api/v1/patient/{patient.id}/") 112 + self.assertEqual(response.status_code, status.HTTP_200_OK) 113 + self.assertDictEqual( 114 + response.data, 115 + { 116 + "id": patient.id, 117 + "name": patient.name, 118 + "age": patient.age, 119 + "gender": patient.gender, 120 + "phone_number": patient.phone_number, 121 + "contact_with_carrier": patient.contact_with_carrier, 122 + "medical_history": [{"disease": "NO", "details": "Quite bad"}], 123 + "tele_consultation_history": [], 124 + "is_active": True, 125 + "last_consultation": None, 126 + }, 127 + ) 128 + 129 + def test_patient_update(self): 130 + """ 131 + Test user can update their patient details 132 + - test status code 133 + - test response data 134 + - test data from database 135 + """ 136 + patient = self.patient 137 + patient.created_by = self.user 138 + patient.save() 139 + 140 + new_phone_number = "9999997775" 141 + response = self.client.put( 142 + f"/api/v1/patient/{patient.id}/", 143 + { 144 + "name": patient.name, 145 + "age": patient.age, 146 + "gender": patient.gender, 147 + "phone_number": new_phone_number, 148 + "contact_with_carrier": patient.contact_with_carrier, 149 + "medical_history": [{"disease": 4, "details": "Mild"}], 150 + }, 151 + ) 152 + self.assertEqual(response.status_code, status.HTTP_200_OK) 153 + """ 154 + is_active: True failed on my machine due to some weird reason 155 + for now, I have set it to False 156 + """ 157 + self.assertDictEqual( 158 + response.data, 159 + { 160 + "id": patient.id, 161 + "name": patient.name, 162 + "age": patient.age, 163 + "gender": patient.gender, 164 + "phone_number": new_phone_number, 165 + "contact_with_carrier": patient.contact_with_carrier, 166 + "medical_history": [ 167 + {"disease": "NO", "details": "Quite bad"}, 168 + {"disease": "HyperTension", "details": "Mild"}, 169 + ], 170 + "is_active": False, 171 + "last_consultation": None, 172 + "tele_consultation_history": [], 173 + }, 174 + ) 175 + patient.refresh_from_db() 176 + self.assertEqual(patient.phone_number, new_phone_number) 177 + 178 + def test_user_can_delete_patient(self): 179 + """ 180 + Test users can delete patient 181 + - test status code 182 + - test data from database 183 + """ 184 + patient = self.patient 185 + patient.created_by = self.user 186 + patient.save() 187 + 188 + response = self.client.delete(f"/api/v1/patient/{patient.id}/",) 189 + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) 190 + with self.assertRaises(PatientRegistration.DoesNotExist): 191 + PatientRegistration.objects.get(id=patient.id) 192 + 193 + def test_patient_list_is_accessible_by_url_location(self): 194 + """Test user can retreive their patient list by the url""" 195 + patient = self.patient 196 + 197 + patient.created_by = self.user 198 + patient.save() 199 + response = self.client.get(f"/api/v1/patient/") 200 + self.assertEqual(response.status_code, status.HTTP_200_OK) 201 + 202 + def test_patient_list_retrieval(self): 203 + """Test user can retreive their patient list""" 204 + patient = self.patient 205 + 206 + patient.created_by = self.user 207 + patient.save() 208 + response = self.client.get(f"/api/v1/patient/") 209 + self.assertDictEqual( 210 + response.data, 211 + { 212 + "count": 1, 213 + "next": None, 214 + "previous": None, 215 + "results": [ 216 + { 217 + "id": patient.id, 218 + "name": patient.name, 219 + "age": patient.age, 220 + "gender": patient.gender, 221 + "phone_number": patient.phone_number, 222 + "medical_history": [{"disease": "NO", "details": "Quite bad"}], 223 + "tele_consultation_history": [], 224 + "is_active": True, 225 + "last_consultation": None, 226 + }, 227 + ], 228 + }, 229 + ) 230 + 231 + def test_superuser_access(self): 232 + """ 233 + Test superuser can retrieve patient details 234 + - test status code 235 + - test response data 236 + """ 237 + patient = self.patient 238 + user = self.user 239 + user.is_superuser = True 240 + user.save() 241 + response = self.client.get(f"/api/v1/patient/{patient.id}/") 242 + self.assertEqual(response.status_code, status.HTTP_200_OK) 243 + self.assertDictEqual( 244 + response.data, 245 + { 246 + "id": patient.id, 247 + "name": patient.name, 248 + "age": patient.age, 249 + "gender": patient.gender, 250 + "phone_number": patient.phone_number, 251 + "contact_with_carrier": patient.contact_with_carrier, 252 + "medical_history": [{"disease": "NO", "details": "Quite bad"}], 253 + "is_active": True, 254 + "last_consultation": None, 255 + "tele_consultation_history": [], 256 + }, 257 + )
+196
care/users/tests/test_api.py
··· 1 + from rest_framework import status 2 + from rest_framework.test import APITestCase 3 + 4 + from care.users.models import User 5 + 6 + # from config.tests.helper import Helper 7 + 8 + 9 + class TestSuperUser(APITestCase): 10 + # def __init__(self, *args, **kwargs): 11 + # """Initialize the data values""" 12 + # self.setup_data(*args, **kwargs) 13 + 14 + @classmethod 15 + def setUpTestData(cls): 16 + """Runs once per class method""" 17 + cls.data = { 18 + "user_type": 5, 19 + "email": "some.email@somedomain.com", 20 + "phone_number": "5554446667", 21 + "age": 30, 22 + "gender": 2, 23 + "district": 11, 24 + "username": "superuser_1", 25 + "password": "bar", 26 + } 27 + cls.super_user = User.objects.create_superuser(**cls.data) 28 + 29 + def setUp(self): 30 + """ 31 + Run once before every test 32 + - login the super user 33 + """ 34 + self.client.login(username=self.data["username"], password=self.data["password"]) 35 + 36 + def test_user_creation(self): 37 + """ 38 + For a superuser account, test 39 + - for a POST request 40 + - users can added, status from the response is 201 41 + - for a GET request 42 + - object count is 2(1 was created in setUpTestData) 43 + - username is present in the response 44 + """ 45 + url = "/api/v1/users/" 46 + data = self.data 47 + data["username"] = "test" 48 + response = self.client.post(url, data) 49 + # Test status code 50 + self.assertEqual(response.status_code, status.HTTP_201_CREATED) 51 + response = self.client.get(url) 52 + res_data_json = response.json() 53 + # Test object count 54 + self.assertEqual(res_data_json["count"], 2) 55 + response = self.client.get(url) 56 + res_data_json = response.json() 57 + results = res_data_json["results"] 58 + # Test presence of username 59 + self.assertEqual( 60 + data["username"] in {r["username"] for r in results}, True, 61 + ) 62 + 63 + def test_superuser_can_acess_url_by_location(self): 64 + """Test super user can acess the url by location""" 65 + username = self.data["username"] 66 + response = self.client.get(f"/api/v1/users/{username}/") 67 + self.assertEqual(response.status_code, status.HTTP_200_OK) 68 + 69 + def test_superuser_can_view(self): 70 + """Test super user can view all of their profile""" 71 + username = self.data["username"] 72 + response = self.client.get(f"/api/v1/users/{username}/") 73 + res_data_json = response.json() 74 + res_data_json.pop("id") 75 + data = self.data.copy() 76 + data.pop("password") 77 + self.assertDictEqual( 78 + res_data_json, 79 + {**data, "district": 11, "gender": "Female", "user_type": "Doctor", "first_name": "", "last_name": "",}, 80 + ) 81 + 82 + def test_superuser_can_modify(self): 83 + """Test superusers can modify the attributes for other users""" 84 + username = self.data["username"] 85 + password = self.data["password"] 86 + response = self.client.put(f"/api/v1/users/{username}/", {**self.data, "age": 31, "password": password,},) 87 + self.assertEqual(response.status_code, status.HTTP_200_OK) 88 + # test the value from api 89 + self.assertEqual(response.json()["age"], 31) 90 + # test value at the backend 91 + self.assertEqual(User.objects.only("age").get(username=username).age, 31) 92 + 93 + def test_superuser_can_delete(self): 94 + """Test superuser can delete other users""" 95 + response = self.client.delete(f"/api/v1/users/{self.data['username']}/") 96 + # test response code 97 + self.assertEqual(response.status_code, 204) 98 + # test backend response 99 + with self.assertRaises(expected_exception=User.DoesNotExist): 100 + User.objects.get(username=self.data["username"]) 101 + 102 + 103 + class TestUser(APITestCase): 104 + @classmethod 105 + def setUpTestData(cls): 106 + """ 107 + Runs once per class method 108 + 109 + Create 2 users 110 + - 1 will be used to check if they can tinker attributes of the other 111 + """ 112 + cls.data_1 = { 113 + "user_type": 5, 114 + "email": "some.email@somedomain.com", 115 + "phone_number": "5554446667", 116 + "age": 30, 117 + "gender": 2, 118 + "district": 11, 119 + "username": "user_5", 120 + "password": "bar", 121 + } 122 + cls.user_1 = User.objects.create_user(**cls.data_1) 123 + cls.data_2 = cls.data_1.copy() 124 + cls.data_2["username"] = "user_2" 125 + cls.user_2 = User.objects.create_user(**cls.data_2) 126 + 127 + def setUp(self): 128 + """ 129 + Run once before every test 130 + - login the super user 131 + """ 132 + self.client.login(username=self.data_1["username"], password=self.data_1["password"]) 133 + 134 + def test_user_can_access_url(self): 135 + """Test user can access the url by location""" 136 + username = self.data_1["username"] 137 + response = self.client.get(f"/api/v1/users/{username}/") 138 + self.assertEqual(response.status_code, status.HTTP_200_OK) 139 + 140 + def test_user_can_read_all(self): 141 + """Test user can read all""" 142 + response = self.client.get("/api/v1/users/") 143 + # test response code 144 + self.assertEqual(response.status_code, status.HTTP_200_OK) 145 + res_data_json = response.json() 146 + # test total user count 147 + self.assertEqual(res_data_json["count"], 2) 148 + results = res_data_json["results"] 149 + # test presence of usernames 150 + self.assertEqual( 151 + {self.user_1.username, self.user_2.username}, {r["username"] for r in results}, 152 + ) 153 + 154 + def test_user_can_modify_themselves(self): 155 + """Test user can modify the attributes for themselves""" 156 + password = self.data_1["password"] 157 + username = self.data_1["username"] 158 + response = self.client.put(f"/api/v1/users/{username}/", {**self.data_1, "age": 31, "password": password,},) 159 + self.assertEqual(response.status_code, status.HTTP_200_OK) 160 + # test the value from api 161 + self.assertEqual(response.json()["age"], 31) 162 + # test value at the backend 163 + self.assertEqual(User.objects.only("age").get(username=username).age, 31) 164 + 165 + def test_user_can_delete_themselves(self): 166 + """Test user can delete themselves""" 167 + response = self.client.delete(f"/api/v1/users/{self.data_1['username']}/") 168 + # test response code 169 + self.assertEqual(response.status_code, 204) 170 + # test backend response 171 + with self.assertRaises(expected_exception=User.DoesNotExist): 172 + User.objects.get(username=self.data_1["username"]) 173 + 174 + def test_user_can_read_others(self): 175 + """Test 1 user can read the attributes of the other user""" 176 + username = self.data_2["username"] 177 + response = self.client.get(f"/api/v1/users/{username}/") 178 + self.assertEqual(response.status_code, status.HTTP_200_OK) 179 + 180 + def test_user_cant_modify_others(self): 181 + """Test a user can't modify others""" 182 + username = self.data_2["username"] 183 + password = self.data_2["password"] 184 + response = self.client.put(f"/api/v1/users/{username}/", {**self.data_2, "age": 31, "password": password,},) 185 + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) 186 + 187 + def test_user_can_delete_others(self): 188 + """Test a user can't delete others""" 189 + field = "username" 190 + response = self.client.delete(f"/api/v1/users/{self.data_2[field]}/") 191 + # test response code 192 + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) 193 + # test backend response(user_2 still exists) 194 + self.assertEqual( 195 + self.data_2[field], User.objects.only(field).get(username=self.data_2[field]).username, 196 + )
+31
config/tests/helper.py
··· 1 + """Use this module for tests in all other modules""" 2 + # from care.users.models import User 3 + 4 + # will be fixed later 5 + 6 + # class TestHelper: 7 + # """Initialize objects that will be useful for all other tests""" 8 + 9 + # def setup_data(self, *args, **kwargs): 10 + # self.data = { 11 + # "user_type": 5, 12 + # "email": "some.email@somedomain.com", 13 + # "phone_number": "5554446667", 14 + # "age": 30, 15 + # "gender": 2, 16 + # "district": 11, 17 + # "username": "user", 18 + # "password": "bar", 19 + # } 20 + # self.user = User.objects.create_user( 21 + # user_type=5, 22 + # district=13, 23 + # phone_number="8887776665", 24 + # gender=1, 25 + # age=30, 26 + # email="foo@foobar.com", 27 + # username="user", 28 + # password="user123#", 29 + # ) 30 + 31 + 1 32 class EverythingEquals: 2 33 def __eq__(self, other): 3 34 return True
+11 -43
config/urls.py
··· 8 8 from drf_yasg import openapi 9 9 from drf_yasg.views import get_schema_view 10 10 from rest_framework import permissions 11 - from rest_framework_simplejwt.views import ( 12 - TokenRefreshView, 13 - TokenVerifyView, 14 - ) 15 - 16 - from .auth_views import TokenObtainPairView 11 + from rest_framework_simplejwt.views import TokenRefreshView, TokenVerifyView 17 12 18 13 from config import api_router 19 - from .adminlogin import login_wrapper 20 - from .views import home_view 21 14 22 - admin.site.login = login_wrapper(admin.site.login) 15 + from .auth_views import TokenObtainPairView 16 + from .views import home_view 23 17 24 18 schema_view = get_schema_view( 25 19 openapi.Info( ··· 37 31 38 32 urlpatterns = [ 39 33 path("", home_view, name="home"), 40 - path( 41 - "ksdma/", TemplateView.as_view(template_name="pages/ksdma.html"), name="ksdma" 42 - ), 34 + path("ksdma/", TemplateView.as_view(template_name="pages/ksdma.html"), name="ksdma"), 43 35 # API Docs 44 - url( 45 - r"^swagger(?P<format>\.json|\.yaml)$", 46 - schema_view.without_ui(cache_timeout=0), 47 - name="schema-json", 48 - ), 49 - url( 50 - r"^swagger/$", 51 - schema_view.with_ui("swagger", cache_timeout=0), 52 - name="schema-swagger-ui", 53 - ), 54 - url( 55 - r"^redoc/$", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc" 56 - ), 36 + url(r"^swagger(?P<format>\.json|\.yaml)$", schema_view.without_ui(cache_timeout=0), name="schema-json",), 37 + url(r"^swagger/$", schema_view.with_ui("swagger", cache_timeout=0), name="schema-swagger-ui",), 38 + url(r"^redoc/$", schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc"), 57 39 # Rest API 58 40 path("api/v1/auth/login/", TokenObtainPairView.as_view(), name="token_obtain_pair"), 59 - path( 60 - "api/v1/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh" 61 - ), 41 + path("api/v1/auth/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), 62 42 path("api/v1/auth/token/verify/", TokenVerifyView.as_view(), name="token_verify"), 63 43 # Django Admin, use {% url 'admin:index' %} 64 44 path(settings.ADMIN_URL, admin.site.urls), ··· 75 55 # This allows the error pages to be debugged during development, just visit 76 56 # these url in browser to see how these error pages look like. 77 57 urlpatterns += [ 78 - path( 79 - "400/", 80 - default_views.bad_request, 81 - kwargs={"exception": Exception("Bad Request!")}, 82 - ), 83 - path( 84 - "403/", 85 - default_views.permission_denied, 86 - kwargs={"exception": Exception("Permission Denied")}, 87 - ), 88 - path( 89 - "404/", 90 - default_views.page_not_found, 91 - kwargs={"exception": Exception("Page not Found")}, 92 - ), 58 + path("400/", default_views.bad_request, kwargs={"exception": Exception("Bad Request!")},), 59 + path("403/", default_views.permission_denied, kwargs={"exception": Exception("Permission Denied")},), 60 + path("404/", default_views.page_not_found, kwargs={"exception": Exception("Page not Found")},), 93 61 path("500/", default_views.server_error), 94 62 ] 95 63 if "debug_toolbar" in settings.INSTALLED_APPS:
+4 -2
config/views.py
··· 1 - from django.shortcuts import render 2 1 import logging 3 2 3 + from django.views.generic import TemplateView 4 + 5 + 4 6 def home_view(request): 5 7 logging.basicConfig(level=logging.INFO) 6 8 logging.info(request.META) 7 - return render(request, "pages/home.html") 9 + return TemplateView.as_view(template_name="pages/home.html")