@@ -219,3 +219,159 @@ def test_cant_delete_template_workspace(api_client, data_fixture):
219219 assert response .status_code == HTTP_400_BAD_REQUEST
220220 assert response .json ()["error" ] == "ERROR_CANNOT_DELETE_A_TEMPLATE_GROUP"
221221 assert Workspace .objects .all ().count () == 1
222+
223+
224+ @pytest .mark .django_db
225+ @override_settings (DEBUG = True )
226+ def test_non_admin_list_workspaces_as_options (api_client , data_fixture ):
227+ (
228+ admin_user ,
229+ admin_token ,
230+ ) = data_fixture .create_user_and_token ()
231+
232+ # no search query should return all workspaces
233+ response = api_client .get (
234+ reverse ("api:admin:workspaces:options" ),
235+ format = "json" ,
236+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
237+ )
238+ assert response .status_code == HTTP_403_FORBIDDEN
239+
240+
241+ @pytest .mark .django_db
242+ @override_settings (DEBUG = True )
243+ def test_admin_list_workspaces_as_options (api_client , data_fixture ):
244+ (
245+ admin_user ,
246+ admin_token ,
247+ ) = data_fixture .create_user_and_token (is_staff = True )
248+ workspace_1 = data_fixture .create_workspace (name = "workspace 1" , user = admin_user )
249+ workspace_2 = data_fixture .create_workspace (name = "workspace 2" , user = admin_user )
250+
251+ # no search query should return all workspaces
252+ response = api_client .get (
253+ reverse ("api:admin:workspaces:options" ),
254+ format = "json" ,
255+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
256+ )
257+ assert response .status_code == HTTP_200_OK
258+ assert response .json () == {
259+ "count" : 2 ,
260+ "next" : None ,
261+ "previous" : None ,
262+ "results" : [
263+ {"id" : workspace_1 .id , "value" : workspace_1 .name },
264+ {"id" : workspace_2 .id , "value" : workspace_2 .name },
265+ ],
266+ }
267+
268+ # searching by name should return only the correct workspace
269+ response = api_client .get (
270+ reverse ("api:admin:workspaces:options" ) + "?search=1" ,
271+ format = "json" ,
272+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
273+ )
274+ assert response .status_code == HTTP_200_OK
275+ assert response .json () == {
276+ "count" : 1 ,
277+ "next" : None ,
278+ "previous" : None ,
279+ "results" : [{"id" : workspace_1 .id , "value" : workspace_1 .name }],
280+ }
281+
282+
283+ @pytest .mark .django_db
284+ @override_settings (DEBUG = True )
285+ def test_admin_list_workspaces_as_options_filter_by_ids (api_client , data_fixture ):
286+ (
287+ admin_user ,
288+ admin_token ,
289+ ) = data_fixture .create_user_and_token (is_staff = True )
290+ workspace_1 = data_fixture .create_workspace (name = "workspace 1" , user = admin_user )
291+ workspace_2 = data_fixture .create_workspace (name = "workspace 2" , user = admin_user )
292+ data_fixture .create_workspace (name = "workspace 3" , user = admin_user )
293+
294+ # filtering by a single id should return only that workspace
295+ response = api_client .get (
296+ reverse ("api:admin:workspaces:options" ) + f"?ids={ workspace_1 .id } " ,
297+ format = "json" ,
298+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
299+ )
300+ assert response .status_code == HTTP_200_OK
301+ assert response .json () == {
302+ "count" : 1 ,
303+ "next" : None ,
304+ "previous" : None ,
305+ "results" : [{"id" : workspace_1 .id , "value" : workspace_1 .name }],
306+ }
307+
308+ # filtering by multiple ids should return all matching workspaces
309+ response = api_client .get (
310+ reverse ("api:admin:workspaces:options" )
311+ + f"?ids={ workspace_1 .id } ,{ workspace_2 .id } " ,
312+ format = "json" ,
313+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
314+ )
315+ assert response .status_code == HTTP_200_OK
316+ assert response .json () == {
317+ "count" : 2 ,
318+ "next" : None ,
319+ "previous" : None ,
320+ "results" : [
321+ {"id" : workspace_1 .id , "value" : workspace_1 .name },
322+ {"id" : workspace_2 .id , "value" : workspace_2 .name },
323+ ],
324+ }
325+
326+
327+ @pytest .mark .django_db
328+ @override_settings (DEBUG = True )
329+ def test_admin_list_workspaces_as_options_filter_by_invalid_ids (
330+ api_client , data_fixture
331+ ):
332+ _ , admin_token = data_fixture .create_user_and_token (is_staff = True )
333+
334+ # Negative IDs should be rejected.
335+ response = api_client .get (
336+ reverse ("api:admin:workspaces:options" ) + "?ids=-1" ,
337+ format = "json" ,
338+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
339+ )
340+ assert response .status_code == HTTP_400_BAD_REQUEST
341+ assert response .json ()["error" ] == "ERROR_QUERY_PARAMETER_VALIDATION"
342+ assert response .json ()["detail" ]["ids" ] == [
343+ {
344+ "code" : "invalid" ,
345+ "error" : "'-1' is not a valid ID. Only positive integers are accepted." ,
346+ }
347+ ]
348+
349+ # Non-numeric values should be rejected.
350+ response = api_client .get (
351+ reverse ("api:admin:workspaces:options" ) + "?ids=abc" ,
352+ format = "json" ,
353+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
354+ )
355+ assert response .status_code == HTTP_400_BAD_REQUEST
356+ assert response .json ()["error" ] == "ERROR_QUERY_PARAMETER_VALIDATION"
357+ assert response .json ()["detail" ]["ids" ] == [
358+ {
359+ "code" : "invalid" ,
360+ "error" : "'abc' is not a valid ID. Only positive integers are accepted." ,
361+ }
362+ ]
363+
364+ # A mix of valid and invalid values should still be rejected.
365+ response = api_client .get (
366+ reverse ("api:admin:workspaces:options" ) + "?ids=1,-2,3" ,
367+ format = "json" ,
368+ HTTP_AUTHORIZATION = f"JWT { admin_token } " ,
369+ )
370+ assert response .status_code == HTTP_400_BAD_REQUEST
371+ assert response .json ()["error" ] == "ERROR_QUERY_PARAMETER_VALIDATION"
372+ assert response .json ()["detail" ]["ids" ] == [
373+ {
374+ "code" : "invalid" ,
375+ "error" : "'-2' is not a valid ID. Only positive integers are accepted." ,
376+ }
377+ ]
0 commit comments