@@ -502,129 +502,106 @@ def test_rework_cycles_returs_1_for_multiple_approvals():
502502 )
503503
504504
505- def test_create_pr_metrics_filters_bot_events ():
505+ def test_filter_non_bot_events_common_patterns ():
506506 pr_service = CodeETLAnalyticsService ()
507- t1 = time_now ()
508- t2 = t1 + timedelta (hours = 1 )
509- t3 = t2 + timedelta (hours = 1 )
510- pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
511- bot_event = get_pull_request_event (
512- pull_request_id = pr .id ,
513- reviewer = "test-bot[bot]" ,
514- state = PullRequestEventState .COMMENTED .value ,
515- created_at = t2 ,
516- )
517- human_event = get_pull_request_event (
518- pull_request_id = pr .id ,
519- reviewer = "human_user" ,
520- state = PullRequestEventState .APPROVED .value ,
521- created_at = t3 ,
522- )
523- pr_metrics = pr_service .create_pr_metrics (pr , [bot_event , human_event ], [])
524- assert "human_user" in pr_metrics .reviewers
525- assert "test-bot[bot]" not in pr_metrics .reviewers
526-
527507
528- def test_create_pr_metrics_no_bot_first_response_time ():
508+ bot_events = [
509+ get_pull_request_event (reviewer = "github-actions[bot]" ),
510+ get_pull_request_event (reviewer = "jenkins-bot" ),
511+ get_pull_request_event (reviewer = "renovate[bot]" ),
512+ get_pull_request_event (reviewer = "test_bot_service" ),
513+ get_pull_request_event (reviewer = "my_bot" ),
514+ get_pull_request_event (reviewer = "bot_user" ),
515+ get_pull_request_event (reviewer = "SomeService-bot-123" ),
516+ get_pull_request_event (reviewer = "CI-BOT" ),
517+ get_pull_request_event (reviewer = "bot-123[bot]" ),
518+ get_pull_request_event (reviewer = "helper_bot_v2" ),
519+ ]
520+ human_events = [
521+ get_pull_request_event (reviewer = "john_doe" ),
522+ get_pull_request_event (reviewer = "robotics_expert" ),
523+ get_pull_request_event (reviewer = "sabotage" ),
524+ get_pull_request_event (reviewer = "lobotomy" ),
525+ get_pull_request_event (reviewer = "cubot" ),
526+ get_pull_request_event (reviewer = "botany" ),
527+ ]
528+
529+ all_events = bot_events + human_events
530+ filtered_events = pr_service .filter_non_bot_events (all_events )
531+
532+ assert len (filtered_events ) == len (human_events )
533+
534+ filtered_usernames = [e .actor_username for e in filtered_events ]
535+ for event in bot_events :
536+ assert event .actor_username not in filtered_usernames
537+
538+ for event in human_events :
539+ assert event .actor_username in filtered_usernames
540+
541+
542+ def test_filter_non_bot_events_edge_cases ():
529543 pr_service = CodeETLAnalyticsService ()
530- t1 = time_now ()
531- t2 = t1 + timedelta (hours = 1 )
532- pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
533- first_review_event = get_pull_request_event (
534- pull_request_id = pr .id ,
535- reviewer = "reviewer" ,
536- state = PullRequestEventState .COMMENTED .value ,
537- created_at = t2 ,
538- )
539- pr_metrics = pr_service .create_pr_metrics (pr , [first_review_event ], [])
540- assert pr_metrics .first_response_time == 3600
541-
542-
543- def test_create_pr_metrics_no_bot_rework_time ():
544- pr_service = CodeETLAnalyticsService ()
545- t1 = time_now ()
546- t2 = t1 + timedelta (hours = 1 )
547- t3 = t2 + timedelta (hours = 1 )
548- pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
549- changes_requested_event = get_pull_request_event (
550- pull_request_id = pr .id ,
551- reviewer = "reviewer" ,
552- state = PullRequestEventState .CHANGES_REQUESTED .value ,
553- created_at = t2 ,
554- )
555- approval_event = get_pull_request_event (
556- pull_request_id = pr .id ,
557- reviewer = "reviewer" ,
558- state = PullRequestEventState .APPROVED .value ,
559- created_at = t3 ,
560- )
561- pr_metrics = pr_service .create_pr_metrics (
562- pr , [changes_requested_event , approval_event ], []
563- )
564- assert pr_metrics .rework_time == 3600
565544
545+ events = [
546+ get_pull_request_event (reviewer = "test-bot[123]" ),
547+ get_pull_request_event (reviewer = "deploy bot" ),
548+ get_pull_request_event (reviewer = "special@bot@chars" ),
549+ get_pull_request_event (reviewer = "robo" ),
550+ get_pull_request_event (reviewer = "botanic" ),
551+ get_pull_request_event (reviewer = "robot" ),
552+ get_pull_request_event (reviewer = "abot" ),
553+ ]
566554
567- def test_create_pr_metrics_no_human_first_response_time ():
568- pr_service = CodeETLAnalyticsService ()
569- t1 = time_now ()
570- t2 = t1 + timedelta (hours = 1 )
571- pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
572- first_review_event = get_pull_request_event (
573- pull_request_id = pr .id ,
574- reviewer = "test-bot[bot]" ,
575- state = PullRequestEventState .COMMENTED .value ,
576- created_at = t2 ,
577- )
578- pr_metrics = pr_service .create_pr_metrics (pr , [first_review_event ], [])
579- assert pr_metrics .first_response_time is None
555+ filtered_events = pr_service .filter_non_bot_events (events )
580556
557+ expected_remaining = ["robo" , "botanic" , "robot" , "abot" ]
558+ filtered_usernames = [e .actor_username for e in filtered_events ]
581559
582- def test_create_pr_metrics_no_human_rework_time ():
583- pr_service = CodeETLAnalyticsService ()
584- t1 = time_now ()
585- t2 = t1 + timedelta (hours = 1 )
586- t3 = t2 + timedelta (hours = 1 )
587- pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
588- changes_requested_event = get_pull_request_event (
589- pull_request_id = pr .id ,
590- reviewer = "test-bot[bot]" ,
591- state = PullRequestEventState .CHANGES_REQUESTED .value ,
592- created_at = t2 ,
593- )
594- approval_event = get_pull_request_event (
595- pull_request_id = pr .id ,
596- reviewer = "test-bot[bot]" ,
597- state = PullRequestEventState .APPROVED .value ,
598- created_at = t3 ,
599- )
600- pr_metrics = pr_service .create_pr_metrics (
601- pr , [changes_requested_event , approval_event ], []
602- )
603- assert pr_metrics .rework_time is None
560+ assert len (filtered_events ) == 4
561+ for username in expected_remaining :
562+ assert username in filtered_usernames
604563
605564
606- def test_create_pr_metrics_filters_bot_type_events ():
565+ def test_create_pr_metrics_bot_detection_in_review_events ():
607566 pr_service = CodeETLAnalyticsService ()
608567 t1 = time_now ()
609- t2 = t1 + timedelta (hours = 1 )
610- t3 = t2 + timedelta (hours = 1 )
611568 pr = get_pull_request (state = PullRequestState .MERGED , created_at = t1 , updated_at = t1 )
612569
613- bot_event = get_pull_request_event (
614- pull_request_id = pr .id ,
615- reviewer = "github_app" ,
616- state = PullRequestEventState .COMMENTED .value ,
617- created_at = t2 ,
618- data = {"user" : {"type" : "Bot" }},
619- )
570+ bot_reviewers = [
571+ "github-actions[bot]" ,
572+ "dependabot-preview[bot]" ,
573+ "Jenkins_Bot" ,
574+ "ci_bot_service" ,
575+ "bot_reviewer" ,
576+ "tool-bot-123" ,
577+ "_bot_helper" ,
578+ "helper_bot" ,
579+ ]
580+
581+ bot_events = []
582+ for i , reviewer in enumerate (bot_reviewers ):
583+ bot_events .append (
584+ get_pull_request_event (
585+ pull_request_id = pr .id ,
586+ reviewer = reviewer ,
587+ state = PullRequestEventState .COMMENTED .value ,
588+ created_at = t1 + timedelta (minutes = i + 1 ),
589+ )
590+ )
620591
621592 human_event = get_pull_request_event (
622593 pull_request_id = pr .id ,
623- reviewer = "human_user " ,
594+ reviewer = "human_reviewer " ,
624595 state = PullRequestEventState .APPROVED .value ,
625- created_at = t3 ,
596+ created_at = t1 + timedelta ( hours = 1 ) ,
626597 )
627598
628- pr_metrics = pr_service .create_pr_metrics (pr , [bot_event , human_event ], [])
629- assert "human_user" in pr_metrics .reviewers
630- assert "github_app" not in pr_metrics .reviewers
599+ all_events = bot_events + [human_event ]
600+
601+ pr_metrics = pr_service .create_pr_metrics (pr , all_events , [])
602+
603+ assert len (pr_metrics .reviewers ) == 1
604+ assert "human_reviewer" in pr_metrics .reviewers
605+
606+ for bot_reviewer in bot_reviewers :
607+ assert bot_reviewer not in pr_metrics .reviewers
0 commit comments