@@ -245,9 +245,12 @@ def test_the_format_asks_git_for_the_hash_and_the_body(self):
245245 self .assertEqual (main .COMMIT_LOG_FORMAT , "--pretty=format:%H%x00%B%x00" )
246246 self .assertNotIn ("\x00 " , main .COMMIT_LOG_FORMAT )
247247
248- def test_an_empty_message_does_not_shift_the_hashes_after_it (self ):
248+ def test_an_empty_message_is_kept_and_does_not_shift_the_hashes (self ):
249249 output = f"{ SHA_A } \x00 \n \x00 \n { SHA_B } \x00 feat: second\n \x00 "
250- self .assertEqual (main .parse_commit_messages (output ), [(SHA_B , "feat: second" )])
250+ self .assertEqual (
251+ main .parse_commit_messages (output ),
252+ [(SHA_A , "" ), (SHA_B , "feat: second" )],
253+ )
251254
252255 def test_empty_output_is_no_commits (self ):
253256 self .assertEqual (main .parse_commit_messages ("" ), [])
@@ -2455,6 +2458,7 @@ def test_updates_existing_comment_when_changed(self):
24552458 def test_skips_when_comment_is_up_to_date (self ):
24562459 body = main .render_pr_comment ([fail_scope ()])
24572460 existing = MagicMock (body = body )
2461+ existing .user .type = "Bot"
24582462 mock_pull_request = MagicMock ()
24592463 mock_pull_request .get_comments .return_value = [existing ]
24602464 mock_repo = MagicMock ()
@@ -2904,6 +2908,14 @@ def test_bot_comment_from_an_older_version_is_adopted(self):
29042908 self .assertIs (target , legacy )
29052909 self .assertEqual (stale , [])
29062910
2911+ def test_human_comment_with_the_marker_is_never_touched (self ):
2912+ """A person can paste the marker too, e.g. quoting a report."""
2913+ quoted = self ._comment (f"{ main .COMMENT_MARKER } \n quoted" , user_type = "User" )
2914+ mine = self ._comment (f"{ main .COMMENT_MARKER } \n report" )
2915+ self .assertEqual (main ._find_own_comments ([quoted , mine ]), (mine , []))
2916+ self .assertEqual (main ._find_own_comments ([mine , quoted ]), (mine , []))
2917+ self .assertEqual (main ._find_own_comments ([quoted ]), (None , []))
2918+
29072919 def test_no_comments_yields_nothing_to_update (self ):
29082920 target , stale = main ._find_own_comments ([])
29092921 self .assertIsNone (target )
@@ -4199,3 +4211,116 @@ def test_a_commit_that_cannot_be_had_falls_back_to_the_tip(self):
41994211 [(s .label , s .status ) for s in results ], [("Author email" , "skip" )]
42004212 )
42014213 self .assertFalse ([c for c in commands if c [0 ] == "commit-check" ], commands )
4214+
4215+
4216+ class TestBooleanInputs (unittest .TestCase ):
4217+ """A boolean input is true or false; anything else fails the step."""
4218+
4219+ def setUp (self ):
4220+ main .INVALID_FLAGS .clear ()
4221+ self .addCleanup (main .INVALID_FLAGS .clear )
4222+
4223+ def test_true_and_false_in_any_case_and_padding (self ):
4224+ for value , expected in (
4225+ ("true" , True ),
4226+ (" True " , True ),
4227+ ("FALSE" , False ),
4228+ ("false" , False ),
4229+ ):
4230+ with patch .dict (os .environ , {"MESSAGE" : value }):
4231+ self .assertIs (main .env_flag ("MESSAGE" ), expected , value )
4232+ self .assertEqual (main .INVALID_FLAGS , [])
4233+
4234+ def test_unset_input_takes_the_default (self ):
4235+ with patch .dict (os .environ , {}, clear = True ):
4236+ self .assertFalse (main .env_flag ("MESSAGE" ))
4237+ self .assertEqual (main .INVALID_FLAGS , [])
4238+
4239+ def test_other_values_are_recorded (self ):
4240+ for value in ("yes" , "on" , "1" , "maybe" ):
4241+ with patch .dict (os .environ , {"MESSAGE" : value }):
4242+ self .assertFalse (main .env_flag ("MESSAGE" ))
4243+ self .assertEqual (
4244+ main .INVALID_FLAGS ,
4245+ [
4246+ ("MESSAGE" , "yes" ),
4247+ ("MESSAGE" , "on" ),
4248+ ("MESSAGE" , "1" ),
4249+ ("MESSAGE" , "maybe" ),
4250+ ],
4251+ )
4252+
4253+ def test_invalid_input_fails_before_any_check (self ):
4254+ main .INVALID_FLAGS .append (("PR_TITLE" , "yes" ))
4255+ out = io .StringIO ()
4256+ with (
4257+ patch ("sys.stdout" , out ),
4258+ patch ("main.run_commit_check" ) as run ,
4259+ self .assertRaises (SystemExit ) as cm ,
4260+ ):
4261+ main .main ()
4262+ self .assertEqual (cm .exception .code , 1 )
4263+ run .assert_not_called ()
4264+ self .assertIn (
4265+ "::error::Input pr-title must be true or false, got 'yes'" , out .getvalue ()
4266+ )
4267+
4268+
4269+ class TestPrCommentApiUrl (unittest .TestCase ):
4270+ """The PR comment goes to the same API host as every other call (GHES)."""
4271+
4272+ def test_comment_client_uses_github_api_url (self ):
4273+ github_module = MagicMock ()
4274+ pull_request = MagicMock ()
4275+ pull_request .get_comments .return_value = []
4276+ github_module .Github .return_value .get_repo .return_value .get_issue .return_value = pull_request
4277+ with (
4278+ patch ("main.PR_COMMENTS_ENABLED" , True ),
4279+ patch ("main.is_fork_pr_with_readonly_token" , return_value = False ),
4280+ patch ("main.get_pr_number" , return_value = 7 ),
4281+ patch .dict (
4282+ os .environ ,
4283+ {
4284+ "GITHUB_EVENT_NAME" : "pull_request" ,
4285+ "GITHUB_TOKEN" : "t" ,
4286+ "GITHUB_REPOSITORY" : "o/r" ,
4287+ "GITHUB_API_URL" : "https://ghe.example.com/api/v3" ,
4288+ },
4289+ ),
4290+ patch .dict (sys .modules , {"github" : github_module }),
4291+ ):
4292+ main .add_pr_comments ([fail_scope ()])
4293+ _ , kwargs = github_module .Github .call_args
4294+ self .assertEqual (kwargs ["base_url" ], "https://ghe.example.com/api/v3" )
4295+
4296+
4297+ class TestEmptyCommitMessage (unittest .TestCase ):
4298+ """An empty message is checked as empty, never as HEAD's message."""
4299+
4300+ def test_an_empty_message_goes_to_the_cli_as_an_empty_file (self ):
4301+ seen : list [tuple [list [str ], str | None , str ]] = []
4302+
4303+ def run (command , ** kwargs ):
4304+ path = command [- 1 ]
4305+ with open (path , encoding = "utf-8" ) as f :
4306+ seen .append ((command , kwargs .get ("input" ), f .read ()))
4307+ return MagicMock (
4308+ returncode = 1 ,
4309+ stdout = json_output (make_check ("allow_empty_commits" , status = "fail" )),
4310+ stderr = "" ,
4311+ )
4312+
4313+ with (
4314+ patch ("main.subprocess.run" , side_effect = run ),
4315+ patch ("main._local_author" , return_value = None ),
4316+ ):
4317+ results = main .run_pr_message_checks ([("a1" , "" )])
4318+ command , piped , content = seen [0 ]
4319+ self .assertEqual (command [:4 ], ["commit-check" , "--format" , "json" , "--message" ])
4320+ self .assertIsNone (piped )
4321+ self .assertEqual (content , "" )
4322+ self .assertFalse (os .path .exists (command [- 1 ]))
4323+ self .assertEqual (
4324+ [(s .label , s .sha , s .status ) for s in results ],
4325+ [("Commit 1/1" , "a1" , "fail" )],
4326+ )
0 commit comments