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