|
1 | 1 | import importlib |
2 | 2 | from datetime import datetime, time |
3 | | -from io import StringIO |
4 | 3 | from unittest.mock import patch |
5 | 4 |
|
6 | 5 | import pymongo |
7 | | -from bson import json_util |
8 | 6 | from bson.binary import Binary |
9 | 7 | from django.conf import settings |
10 | | -from django.core.management import call_command |
11 | 8 | from django.db import connections, models |
12 | 9 | from django.test import TransactionTestCase, modify_settings, override_settings |
13 | 10 |
|
|
23 | 20 | ) |
24 | 21 | from .routers import TestEncryptedRouter |
25 | 22 |
|
26 | | -EXPECTED_ENCRYPTED_FIELDS_MAP = { |
27 | | - "encryption__billing": { |
28 | | - "fields": [ |
29 | | - { |
30 | | - "bsonType": "string", |
31 | | - "path": "cc_type", |
32 | | - "queries": {"queryType": "equality"}, |
33 | | - # "keyId": Binary(b" \x901\x89\x1f\xafAX\x9b*\xb1\xc7\xc5\xfdl\xa4", 4), |
34 | | - }, |
35 | | - { |
36 | | - "bsonType": "long", |
37 | | - "path": "cc_number", |
38 | | - "queries": {"queryType": "equality"}, |
39 | | - # "keyId": Binary(b"\x97\xb4\x9d\xb8\xd5\xa6Ay\x85\xfe\x00\xc0\xd4{\xa2\xff", 4), |
40 | | - }, |
41 | | - { |
42 | | - "bsonType": "decimal", |
43 | | - "path": "account_balance", |
44 | | - "queries": {"queryType": "range"}, |
45 | | - # "keyId": Binary(b"\xcc\x01-s\xea\xd9B\x8d\x80\xd7\xf8!n\xc6\xf5U", 4), |
46 | | - }, |
47 | | - ] |
48 | | - }, |
49 | | - "encryption__patientrecord": { |
50 | | - "fields": [ |
51 | | - { |
52 | | - "bsonType": "string", |
53 | | - "path": "ssn", |
54 | | - "queries": {"queryType": "equality"}, |
55 | | - # "keyId": Binary(b"\x14F\x89\xde\x8d\x04K7\xa9\x9a\xaf_\xca\x8a\xfb&", 4), |
56 | | - }, |
57 | | - { |
58 | | - "bsonType": "date", |
59 | | - "path": "birth_date", |
60 | | - "queries": {"queryType": "range"}, |
61 | | - # "keyId": Binary(b"@\xdd\xb4\xd2%\xc2B\x94\xb5\x07\xbc(ER[s", 4), |
62 | | - }, |
63 | | - { |
64 | | - "bsonType": "binData", |
65 | | - "path": "profile_picture", |
66 | | - "queries": {"queryType": "equality"}, |
67 | | - # "keyId": Binary(b"Q\xa2\xebc!\xecD,\x8b\xe4$\xb6ul9\x9a", 4), |
68 | | - }, |
69 | | - { |
70 | | - "bsonType": "int", |
71 | | - "path": "patient_age", |
72 | | - "queries": {"queryType": "range"}, |
73 | | - # "keyId": Binary(b"\ro\x80\x1e\x8e1K\xde\xbc_\xc3bi\x95\xa6j", 4), |
74 | | - }, |
75 | | - { |
76 | | - "bsonType": "double", |
77 | | - "path": "weight", |
78 | | - "queries": {"queryType": "range"}, |
79 | | - # "keyId": Binary(b"\x9b\xfd:n\xe1\xd0N\xdd\xb3\xe7e)\x06\xea\x8a\x1d", 4), |
80 | | - }, |
81 | | - ] |
82 | | - }, |
83 | | - "encryption__patient": { |
84 | | - "fields": [ |
85 | | - { |
86 | | - "bsonType": "int", |
87 | | - "path": "patient_id", |
88 | | - "queries": {"queryType": "equality"}, |
89 | | - # "keyId": Binary(b"\x8ft\x16:\x8a\x91D\xc7\x8a\xdf\xe5O\n[\xfd\\", 4), |
90 | | - }, |
91 | | - { |
92 | | - "bsonType": "string", |
93 | | - "path": "patient_name", |
94 | | - # "keyId": Binary(b"<\x9b\xba\xeb:\xa4@m\x93\x0e\x0c\xcaN\x03\xfb\x05", 4), |
95 | | - }, |
96 | | - { |
97 | | - "bsonType": "string", |
98 | | - "path": "patient_notes", |
99 | | - "queries": {"queryType": "equality"}, |
100 | | - # "keyId": Binary(b"\x01\xe7\xd1isnB$\xa9(gwO\xca\x10\xbd", 4), |
101 | | - }, |
102 | | - { |
103 | | - "bsonType": "date", |
104 | | - "path": "registration_date", |
105 | | - "queries": {"queryType": "equality"}, |
106 | | - # "keyId": Binary(b"F\xfb\xae\x82\xd5\x9a@\xee\xbfJ\xaf#\x9c:-I", 4), |
107 | | - }, |
108 | | - { |
109 | | - "bsonType": "bool", |
110 | | - "path": "is_active", |
111 | | - "queries": {"queryType": "equality"}, |
112 | | - # "keyId": Binary(b"\xb2\xb5\xc4K53A\xda\xb9V\xa6\xa9\x97\x94\xea;", 4), |
113 | | - }, |
114 | | - {"bsonType": "string", "path": "email", "queries": {"queryType": "equality"}}, |
115 | | - ] |
116 | | - }, |
117 | | - "encryption__patientportaluser": { |
118 | | - "fields": [ |
119 | | - {"bsonType": "string", "path": "ip_address", "queries": {"queryType": "equality"}}, |
120 | | - {"bsonType": "string", "path": "url", "queries": {"queryType": "equality"}}, |
121 | | - ] |
122 | | - }, |
123 | | - "encryption__encryptednumbers": { |
124 | | - "fields": [ |
125 | | - {"bsonType": "int", "path": "pos_bigint", "queries": {"queryType": "equality"}}, |
126 | | - {"bsonType": "int", "path": "pos_smallint", "queries": {"queryType": "equality"}}, |
127 | | - {"bsonType": "int", "path": "smallint", "queries": {"queryType": "equality"}}, |
128 | | - ] |
129 | | - }, |
130 | | - "encryption__appointment": { |
131 | | - "fields": [{"bsonType": "date", "path": "time", "queries": {"queryType": "equality"}}] |
132 | | - }, |
133 | | -} |
134 | | - |
135 | 23 |
|
136 | 24 | class EncryptedDurationField(EncryptedFieldMixin, models.DurationField): |
137 | 25 | """ |
@@ -166,38 +54,36 @@ class EncryptedFieldTests(TransactionTestCase): |
166 | 54 | available_apps = ["django_mongodb_backend", "encryption_"] |
167 | 55 |
|
168 | 56 | def setUp(self): |
169 | | - self.appointment = Appointment(time="8:00") |
170 | | - self.appointment.save() |
| 57 | + self.appointment = Appointment.objects.create(time="8:00") |
171 | 58 |
|
172 | | - self.billing = Billing(cc_type="Visa", cc_number=1234567890123456, account_balance=100.50) |
173 | | - self.billing.save() |
| 59 | + self.billing = Billing.objects.create( |
| 60 | + cc_type="Visa", cc_number=1234567890123456, account_balance=100.50 |
| 61 | + ) |
174 | 62 |
|
175 | | - self.portal_user = PatientPortalUser( |
| 63 | + self.portal_user = PatientPortalUser.objects.create( |
176 | 64 | ip_address="127.0.0.1", |
177 | 65 | url="https://example.com", |
178 | 66 | ) |
179 | | - self.portal_user.save() |
180 | 67 |
|
181 | | - self.patientrecord = PatientRecord( |
| 68 | + self.patientrecord = PatientRecord.objects.create( |
182 | 69 | ssn="123-45-6789", |
183 | 70 | birth_date="1970-01-01", |
184 | 71 | profile_picture=b"image data", |
185 | 72 | weight=175.5, |
186 | 73 | patient_age=47, |
187 | 74 | ) |
188 | | - self.patientrecord.save() |
189 | 75 |
|
190 | | - self.patient = Patient( |
| 76 | + self.patient = Patient.objects.create( |
191 | 77 | patient_id=1, |
192 | 78 | patient_name="John Doe", |
193 | 79 | patient_notes="patient notes " * 25, |
194 | 80 | registration_date=datetime(2023, 10, 1, 12, 0, 0), |
195 | 81 | is_active=True, |
196 | 82 | email="john.doe@example.com", |
197 | 83 | ) |
198 | | - self.patient.save() |
199 | 84 |
|
200 | | - # TODO: Embed billing and patient_record models in patient model then add tests |
| 85 | + # TODO: Embed billing and patient_record models in patient model |
| 86 | + # then add tests |
201 | 87 |
|
202 | 88 | @classmethod |
203 | 89 | def setUpClass(cls): |
@@ -284,25 +170,6 @@ def test_get_encrypted_fields_map(self): |
284 | 170 | expected_encrypted_fields_map[db_table], |
285 | 171 | ) |
286 | 172 |
|
287 | | - def test_show_schema_map(self): |
288 | | - self.maxDiff = None |
289 | | - out = StringIO() |
290 | | - call_command( |
291 | | - "showschemamap", |
292 | | - "--database", |
293 | | - "encrypted", |
294 | | - verbosity=0, |
295 | | - stdout=out, |
296 | | - ) |
297 | | - # Remove keyIds since they are different for each run. |
298 | | - output_json = json_util.loads(out.getvalue()) |
299 | | - for table in output_json: |
300 | | - for field in output_json[table]["fields"]: |
301 | | - del field["keyId"] |
302 | | - # TODO: probably we don't need to test the entire mapping, otherwise it |
303 | | - # requires updates every time a new model or field is added! |
304 | | - self.assertEqual(EXPECTED_ENCRYPTED_FIELDS_MAP, output_json) |
305 | | - |
306 | 173 | def test_set_encrypted_fields_map_in_client(self): |
307 | 174 | # TODO: Create new client with and without schema map provided then |
308 | 175 | # sync database to ensure encrypted collections are created in both |
@@ -373,9 +240,10 @@ def test_patient(self): |
373 | 240 | records = connections["encrypted"].database.encryption__patientrecord.find() |
374 | 241 | self.assertTrue("__safeContent__" in records[0]) |
375 | 242 |
|
376 | | - |
377 | | -class EncryptedNumberFieldTests(EncryptedFieldTests): |
378 | | - def test_create_and_query(self): |
| 243 | + def test_numeric_fields(self): |
| 244 | + """ |
| 245 | + Fields that have not been tested elsewhere. |
| 246 | + """ |
379 | 247 | EncryptedNumbers.objects.create( |
380 | 248 | pos_bigint=1000000, |
381 | 249 | # FIXME: pymongo.errors.EncryptionError: Cannot encrypt element of type int |
|
0 commit comments