77from rest_framework import status
88from rest_framework .test import APIClient , APITestCase
99
10- from eox_tenant .models import TenantConfig
10+ from eox_tenant .models import Route , TenantConfig
1111
1212
13- class TenantConfigAPITest (APITestCase ):
13+ class TenantConfigAPITest (APITestCase ): # pylint: disable=too-many-instance-attributes
1414 """TenantConfig API TestCase."""
1515
1616 patch_permissions = patch ('eox_tenant.api.v1.permissions.EoxTenantAPIPermission.has_permission' , return_value = True )
@@ -31,6 +31,16 @@ def setUp(self):
3131 theming_configs = {'key' : 'value' },
3232 meta = {'key' : 'value' },
3333 )
34+ self .tenant_config_with_route = TenantConfig .objects .create (
35+ external_key = 'test_key_with_route' ,
36+ lms_configs = {'PLATFORM_NAME' : 'Old Name' },
37+ studio_configs = {'key' : 'value' },
38+ theming_configs = {'key' : 'value' },
39+ meta = {'key' : 'value' },
40+ )
41+ self .domain = 'site3.localhost'
42+ self .route = Route .objects .create (domain = self .domain , config = self .tenant_config_with_route )
43+ self .update_by_domain_url = f'{ self .url } update-by-domain/'
3444 self .url_detail = f'{ self .url } { self .tenant_config_example .pk } /'
3545
3646 @patch_permissions
@@ -50,8 +60,10 @@ def test_get_valid_single_tenant_config(self, _):
5060 @patch_permissions
5161 def test_create_tenant_config (self , _ ):
5262 """Must create new TenantConfig."""
63+ tenant_config_objects_count = TenantConfig .objects .count ()
64+ external_key = 'test_key_3'
5365 data = {
54- 'external_key' : 'test_key' ,
66+ 'external_key' : external_key ,
5567 'lms_configs' : {'key' : 'value' },
5668 'studio_configs' : {'key' : 'value' },
5769 'theming_configs' : {'key' : 'value' },
@@ -61,12 +73,11 @@ def test_create_tenant_config(self, _):
6173 response = self .client .post (self .url , data = data , format = 'json' )
6274
6375 self .assertEqual (response .status_code , status .HTTP_201_CREATED )
64- self .assertEqual (TenantConfig .objects .count (), 2 )
65- self .assertEqual (TenantConfig .objects .get (pk = 2 ).external_key , 'test_key' )
66- self .assertEqual (TenantConfig .objects .get (pk = 2 ).lms_configs , {'key' : 'value' })
67- self .assertEqual (TenantConfig .objects .get (pk = 2 ).studio_configs , {'key' : 'value' })
68- self .assertEqual (TenantConfig .objects .get (pk = 2 ).theming_configs , {'key' : 'value' })
69- self .assertEqual (TenantConfig .objects .get (pk = 2 ).meta , {'key' : 'value' })
76+ self .assertEqual (TenantConfig .objects .count (), tenant_config_objects_count + 1 )
77+ self .assertEqual (TenantConfig .objects .get (external_key = external_key ).lms_configs , {'key' : 'value' })
78+ self .assertEqual (TenantConfig .objects .get (external_key = external_key ).studio_configs , {'key' : 'value' })
79+ self .assertEqual (TenantConfig .objects .get (external_key = external_key ).theming_configs , {'key' : 'value' })
80+ self .assertEqual (TenantConfig .objects .get (external_key = external_key ).meta , {'key' : 'value' })
7081
7182 @patch_permissions
7283 def test_post_input_empty_data (self , _ ):
@@ -134,3 +145,102 @@ def test_delete_tenant_config(self, _):
134145 response = self .client .delete (self .url_detail )
135146
136147 self .assertEqual (response .status_code , status .HTTP_204_NO_CONTENT )
148+
149+ @patch_permissions
150+ def test_update_tenant_config_by_domain_success (self , _ ):
151+ """Must successfully update a TenantConfig using `route__domain`."""
152+ data = {
153+ "lms_configs" : {
154+ "PLATFORM_NAME" : "Updated Name"
155+ }
156+ }
157+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain={ self .domain } " , data = data , format = 'json' )
158+
159+ self .assertEqual (response .status_code , status .HTTP_200_OK )
160+ self .assertEqual (response .data ["lms_configs" ]["PLATFORM_NAME" ], "Updated Name" )
161+
162+ @patch_permissions
163+ def test_update_tenant_config_by_domain_missing_query_param (self , _ ):
164+ """Must return 400 when domain query parameter is missing."""
165+ data = {
166+ "lms_configs" : {
167+ "PLATFORM_NAME" : "Updated Name"
168+ }
169+ }
170+ response = self .client .patch (self .update_by_domain_url , data = data , format = 'json' )
171+
172+ self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
173+ self .assertEqual (response .data ["error" ], "The 'domain' query parameter is required." )
174+
175+ @patch_permissions
176+ def test_update_tenant_config_by_domain_not_found (self , _ ):
177+ """Must return 404 when no TenantConfig is found for the given domain."""
178+ data = {
179+ "lms_configs" : {
180+ "PLATFORM_NAME" : "Updated Name"
181+ }
182+ }
183+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain=unknown.localhost" , data = data , format = 'json' )
184+
185+ self .assertEqual (response .status_code , status .HTTP_404_NOT_FOUND )
186+ self .assertEqual (response .data ["error" ], "No TenantConfig found for domain 'unknown.localhost'." )
187+
188+ @patch_permissions
189+ def test_update_tenant_config_by_domain_empty_payload (self , _ ):
190+ """Must ensure that if an empty payload is sent, nothing gets changed."""
191+ external_key = self .tenant_config_with_route .external_key
192+ lms_configs = self .tenant_config_with_route .lms_configs
193+ studio_configs = self .tenant_config_with_route .studio_configs
194+ theming_configs = self .tenant_config_with_route .theming_configs
195+ meta = self .tenant_config_with_route .meta
196+
197+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain={ self .domain } " , data = {}, format = 'json' )
198+ self .tenant_config_with_route .refresh_from_db ()
199+
200+ self .assertEqual (response .status_code , status .HTTP_200_OK )
201+ self .assertEqual (self .tenant_config_with_route .external_key , external_key )
202+ self .assertEqual (self .tenant_config_with_route .lms_configs , lms_configs )
203+ self .assertEqual (self .tenant_config_with_route .studio_configs , studio_configs )
204+ self .assertEqual (self .tenant_config_with_route .theming_configs , theming_configs )
205+ self .assertEqual (self .tenant_config_with_route .meta , meta )
206+
207+ @patch_permissions
208+ def test_update_tenant_config_by_domain_invalid_data (self , _ ):
209+ """Must return 400 when the payload contains invalid data."""
210+ data = {
211+ "lms_configs" : "Invalid structure" # Should be a dictionary
212+ }
213+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain={ self .domain } " , data = data , format = 'json' )
214+
215+ self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
216+
217+ @patch_permissions
218+ def test_partial_update_tenant_config_by_domain (self , _ ):
219+ """Must allow partial updates without modifying other fields."""
220+ data = {
221+ "lms_configs" : {
222+ "PLATFORM_NAME" : "New Partial Update"
223+ }
224+ }
225+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain={ self .domain } " , data = data , format = 'json' )
226+ print (100 * "#" )
227+ print (response .content )
228+
229+ self .assertEqual (response .status_code , status .HTTP_200_OK )
230+ self .tenant_config_with_route .refresh_from_db ()
231+ self .assertEqual (self .tenant_config_with_route .lms_configs ["PLATFORM_NAME" ], "New Partial Update" )
232+
233+ @patch_permissions
234+ def test_update_tenant_config_by_domain_preserves_other_fields (self , _ ):
235+ """Ensure updating one field does not erase other fields."""
236+ data = {
237+ "lms_configs" : {
238+ "PLATFORM_NAME" : "Updated Platform Name"
239+ }
240+ }
241+ response = self .client .patch (f"{ self .update_by_domain_url } ?domain={ self .domain } " , data = data , format = 'json' )
242+
243+ self .assertEqual (response .status_code , status .HTTP_200_OK )
244+ self .tenant_config_with_route .refresh_from_db ()
245+ self .assertEqual (self .tenant_config_with_route .lms_configs ["PLATFORM_NAME" ], "Updated Platform Name" )
246+ self .assertEqual (self .tenant_config_with_route .studio_configs , {"key" : "value" })
0 commit comments