@@ -556,6 +556,99 @@ def test_cve_undo_reject(move_to_reserved):
556556 )
557557
558558
559+ @mock .patch ("cvelib.cli.CveApi.transfer" )
560+ def test_cve_transfer (transfer ):
561+ cve_id = "CVE-2023-1234"
562+ response = {
563+ "updated" : {
564+ "cve_id" : "CVE-2023-1234" ,
565+ "cve_year" : "2023" ,
566+ "owning_cna" : "new-cna" ,
567+ "requested_by" : {"cna" : "old-cna" , "user" : "test@example.com" },
568+ "reserved" : "2021-01-14T18:35:17.469Z" ,
569+ "state" : "RESERVED" ,
570+ "time" : {"created" : "2021-01-14T18:35:17.469Z" , "modified" : "2021-01-14T18:35:17.469Z" },
571+ },
572+ "message" : f"{ cve_id } owning_cna updated" ,
573+ }
574+
575+ transfer .return_value = response
576+ runner = CliRunner ()
577+ result = runner .invoke (cli , DEFAULT_OPTS + ["transfer" , cve_id , "--new-cna" , "new-cna" ])
578+ assert result .exit_code == 0 , result .output
579+ assert result .output == (
580+ "Successfully transferred the following CVE:\n "
581+ "\n "
582+ f"{ cve_id } \n "
583+ "├─ State:\t RESERVED\n "
584+ "├─ Owning CNA:\t new-cna\n "
585+ "├─ Reserved by:\t test@example.com (old-cna)\n "
586+ "├─ Reserved on:\t Thu Jan 14 18:35:17 2021 +0000\n "
587+ "└─ Updated on:\t Thu Jan 14 18:35:17 2021 +0000\n "
588+ )
589+ transfer .assert_called_once_with (cve_id , "new-cna" )
590+
591+
592+ @mock .patch ("cvelib.cli.CveApi.transfer" )
593+ def test_cve_transfer_raw_output (transfer ):
594+ cve_id = "CVE-2023-1234"
595+ response = {
596+ "updated" : {
597+ "cve_id" : "CVE-2023-1234" ,
598+ "owning_cna" : "new-cna" ,
599+ "state" : "RESERVED" ,
600+ },
601+ "message" : f"{ cve_id } owning_cna updated" ,
602+ }
603+
604+ transfer .return_value = response
605+ runner = CliRunner ()
606+ result = runner .invoke (
607+ cli , DEFAULT_OPTS + ["transfer" , cve_id , "--new-cna" , "new-cna" , "--raw" ]
608+ )
609+ assert result .exit_code == 0 , result .output
610+ assert json .loads (result .output ) == response
611+ transfer .assert_called_once_with (cve_id , "new-cna" )
612+
613+
614+ @mock .patch ("cvelib.cli.CveApi.transfer" )
615+ def test_cve_transfer_interactive_confirm (transfer ):
616+ cve_id = "CVE-2023-1234"
617+ transfer_response = {
618+ "updated" : {
619+ "cve_id" : "CVE-2023-1234" ,
620+ "owning_cna" : "new-cna" ,
621+ "state" : "RESERVED" ,
622+ },
623+ "message" : f"{ cve_id } owning_cna updated" ,
624+ }
625+
626+ transfer .return_value = transfer_response
627+ runner = CliRunner ()
628+ result = runner .invoke (
629+ cli , DEFAULT_OPTS + ["-i" , "transfer" , cve_id , "--new-cna" , "new-cna" ], input = "y\n "
630+ )
631+ assert result .exit_code == 0 , result .output
632+ assert "You are about to transfer ownership of CVE-2023-1234 to CNA new-cna" in result .output
633+ assert "Do you want to continue?" in result .output
634+ transfer .assert_called_once_with (cve_id , "new-cna" )
635+
636+
637+ @mock .patch ("cvelib.cli.CveApi.transfer" )
638+ def test_cve_transfer_interactive_abort (transfer ):
639+ cve_id = "CVE-2023-1234"
640+
641+ runner = CliRunner ()
642+ result = runner .invoke (
643+ cli , DEFAULT_OPTS + ["-i" , "transfer" , cve_id , "--new-cna" , "new-cna" ], input = "n\n "
644+ )
645+ assert result .exit_code == 0 , result .output
646+ assert "You are about to transfer ownership of CVE-2023-1234 to CNA new-cna" in result .output
647+ assert "Do you want to continue?" in result .output
648+ assert "Exiting..." in result .output
649+ transfer .assert_not_called ()
650+
651+
559652def test_quota ():
560653 quota = {"id_quota" : 100 , "total_reserved" : 10 , "available" : 90 }
561654 with mock .patch ("cvelib.cli.CveApi.quota" ) as get_quota :
0 commit comments