@@ -310,3 +310,83 @@ def test_retrieve_incident_does_not_fail_on_sync_error(self):
310310
311311 assert response .status_code == 200
312312 assert response .data ["id" ] == incident .incident_number
313+
314+ def test_sync_participants_endpoint (self ):
315+ """Test POST /api/ui/incidents/{id}/sync-participants/ forces sync"""
316+ incident = Incident .objects .create (
317+ title = "Test Incident" ,
318+ status = IncidentStatus .ACTIVE ,
319+ severity = IncidentSeverity .P1 ,
320+ )
321+
322+ with patch (
323+ "firetower.incidents.views.sync_incident_participants_from_slack"
324+ ) as mock_sync :
325+ mock_sync .return_value = {
326+ "added" : 3 ,
327+ "already_existed" : 5 ,
328+ "errors" : [],
329+ "skipped" : False ,
330+ }
331+
332+ self .client .force_authenticate (user = self .user )
333+ response = self .client .post (
334+ f"/api/ui/incidents/{ incident .incident_number } /sync-participants/"
335+ )
336+
337+ assert response .status_code == 200
338+ assert response .data ["success" ] is True
339+ assert response .data ["stats" ]["added" ] == 3
340+ assert response .data ["stats" ]["already_existed" ] == 5
341+ mock_sync .assert_called_once_with (incident , force = True )
342+
343+ def test_sync_participants_endpoint_handles_errors (self ):
344+ """Test sync endpoint returns 500 on error"""
345+ incident = Incident .objects .create (
346+ title = "Test Incident" ,
347+ status = IncidentStatus .ACTIVE ,
348+ severity = IncidentSeverity .P1 ,
349+ )
350+
351+ with patch (
352+ "firetower.incidents.views.sync_incident_participants_from_slack"
353+ ) as mock_sync :
354+ mock_sync .side_effect = Exception ("Slack API error" )
355+
356+ self .client .force_authenticate (user = self .user )
357+ response = self .client .post (
358+ f"/api/ui/incidents/{ incident .incident_number } /sync-participants/"
359+ )
360+
361+ assert response .status_code == 500
362+ assert response .data ["success" ] is False
363+ assert "Slack API error" in response .data ["error" ]
364+ assert len (response .data ["stats" ]["errors" ]) > 0
365+
366+ def test_sync_participants_endpoint_respects_privacy (self ):
367+ """Test sync endpoint returns 404 for private incidents user can't access"""
368+ other_user = User .objects .create_user (
369+ 370+ password = "testpass123" ,
371+ )
372+ incident = Incident .objects .create (
373+ title = "Private Incident" ,
374+ status = IncidentStatus .ACTIVE ,
375+ severity = IncidentSeverity .P1 ,
376+ is_private = True ,
377+ captain = other_user ,
378+ )
379+
380+ self .client .force_authenticate (user = self .user )
381+ response = self .client .post (
382+ f"/api/ui/incidents/{ incident .incident_number } /sync-participants/"
383+ )
384+
385+ assert response .status_code == 404
386+
387+ def test_sync_participants_endpoint_invalid_format (self ):
388+ """Test sync endpoint returns 400 for invalid incident ID"""
389+ self .client .force_authenticate (user = self .user )
390+ response = self .client .post ("/api/ui/incidents/INVALID-123/sync-participants/" )
391+
392+ assert response .status_code == 400
0 commit comments