@@ -3658,6 +3658,128 @@ def test_archive_experiment_endpoint_not_ended(self):
36583658 )
36593659 self .assertEqual (archive_response .status_code , status .HTTP_400_BAD_REQUEST )
36603660
3661+ def _create_running_experiment (self , name : str = "Running Test" , flag_key : str = "running-flag" ) -> dict :
3662+ """Helper: create an experiment and launch it via the API."""
3663+ response = self .client .post (
3664+ f"/api/projects/{ self .team .id } /experiments/" ,
3665+ {
3666+ "name" : name ,
3667+ "feature_flag_key" : flag_key ,
3668+ "metrics" : [
3669+ {
3670+ "kind" : "ExperimentMetric" ,
3671+ "metric_type" : "mean" ,
3672+ "source" : {"kind" : "EventsNode" , "event" : "$pageview" },
3673+ }
3674+ ],
3675+ },
3676+ format = "json" ,
3677+ )
3678+ self .assertEqual (response .status_code , status .HTTP_201_CREATED )
3679+ experiment_id = response .json ()["id" ]
3680+
3681+ launch_response = self .client .post (
3682+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /launch/" ,
3683+ )
3684+ self .assertEqual (launch_response .status_code , status .HTTP_200_OK )
3685+ return launch_response .json ()
3686+
3687+ def test_pause_experiment_endpoint (self ):
3688+ data = self ._create_running_experiment (name = "Pause Endpoint" , flag_key = "pause-endpoint-flag" )
3689+ experiment_id = data ["id" ]
3690+
3691+ # Flag should be active after launch
3692+ flag = FeatureFlag .objects .get (key = "pause-endpoint-flag" , team = self .team )
3693+ self .assertTrue (flag .active )
3694+
3695+ pause_response = self .client .post (
3696+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" ,
3697+ )
3698+ self .assertEqual (pause_response .status_code , status .HTTP_200_OK )
3699+ self .assertEqual (pause_response .json ()["status" ], "running" )
3700+ self .assertFalse (pause_response .json ()["feature_flag" ]["active" ])
3701+
3702+ # Verify flag is now inactive
3703+ flag .refresh_from_db ()
3704+ self .assertFalse (flag .active )
3705+
3706+ def test_resume_experiment_endpoint (self ):
3707+ data = self ._create_running_experiment (name = "Resume Endpoint" , flag_key = "resume-endpoint-flag" )
3708+ experiment_id = data ["id" ]
3709+
3710+ # Pause first
3711+ pause_response = self .client .post (
3712+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" ,
3713+ )
3714+ self .assertEqual (pause_response .status_code , status .HTTP_200_OK )
3715+
3716+ # Resume
3717+ resume_response = self .client .post (
3718+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /resume/" ,
3719+ )
3720+ self .assertEqual (resume_response .status_code , status .HTTP_200_OK )
3721+ self .assertEqual (resume_response .json ()["status" ], "running" )
3722+ self .assertTrue (resume_response .json ()["feature_flag" ]["active" ])
3723+
3724+ flag = FeatureFlag .objects .get (key = "resume-endpoint-flag" , team = self .team )
3725+ self .assertTrue (flag .active )
3726+
3727+ def test_pause_experiment_already_paused_returns_400 (self ):
3728+ data = self ._create_running_experiment (name = "Double Pause" , flag_key = "double-pause-flag" )
3729+ experiment_id = data ["id" ]
3730+
3731+ self .client .post (f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" )
3732+
3733+ second_pause = self .client .post (
3734+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" ,
3735+ )
3736+ self .assertEqual (second_pause .status_code , status .HTTP_400_BAD_REQUEST )
3737+
3738+ def test_resume_experiment_not_paused_returns_400 (self ):
3739+ data = self ._create_running_experiment (name = "Resume Not Paused" , flag_key = "resume-not-paused-flag" )
3740+ experiment_id = data ["id" ]
3741+
3742+ resume_response = self .client .post (
3743+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /resume/" ,
3744+ )
3745+ self .assertEqual (resume_response .status_code , status .HTTP_400_BAD_REQUEST )
3746+
3747+ def test_pause_draft_experiment_returns_400 (self ):
3748+ response = self .client .post (
3749+ f"/api/projects/{ self .team .id } /experiments/" ,
3750+ {
3751+ "name" : "Pause Draft" ,
3752+ "feature_flag_key" : "pause-draft-flag" ,
3753+ },
3754+ format = "json" ,
3755+ )
3756+ self .assertEqual (response .status_code , status .HTTP_201_CREATED )
3757+ experiment_id = response .json ()["id" ]
3758+
3759+ pause_response = self .client .post (
3760+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" ,
3761+ )
3762+ self .assertEqual (pause_response .status_code , status .HTTP_400_BAD_REQUEST )
3763+
3764+ def test_pause_ended_experiment_returns_400 (self ):
3765+ response = self .client .post (
3766+ f"/api/projects/{ self .team .id } /experiments/" ,
3767+ {
3768+ "name" : "Pause Ended" ,
3769+ "feature_flag_key" : "pause-ended-flag" ,
3770+ "start_date" : "2024-01-01T10:00" ,
3771+ "end_date" : "2024-01-15T10:00" ,
3772+ },
3773+ format = "json" ,
3774+ )
3775+ self .assertEqual (response .status_code , status .HTTP_201_CREATED )
3776+ experiment_id = response .json ()["id" ]
3777+
3778+ pause_response = self .client .post (
3779+ f"/api/projects/{ self .team .id } /experiments/{ experiment_id } /pause/" ,
3780+ )
3781+ self .assertEqual (pause_response .status_code , status .HTTP_400_BAD_REQUEST )
3782+
36613783
36623784class TestExperimentAuxiliaryEndpoints (ClickhouseTestMixin , APILicensedTest ):
36633785 def _generate_experiment (self , start_date = "2024-01-01T10:23" , extra_parameters = None ):
0 commit comments