@@ -550,3 +550,160 @@ def test_link_json_error_for_invalid_jira(mock_jira_cli, temp_daf_home):
550550 assert output_data ["success" ] is False
551551 assert "error" in output_data
552552 assert output_data ["error" ]["code" ] == "VALIDATION_ERROR"
553+
554+
555+ def test_link_with_rename_prefix_jira_key (mock_jira_cli , temp_daf_home ):
556+ """Test --rename-prefix renames session using JIRA-style issue key."""
557+ mock_jira_cli .set_ticket ("PROJ-456" , {
558+ "key" : "PROJ-456" ,
559+ "fields" : {"summary" : "Add caching" , "status" : {"name" : "New" }}
560+ })
561+
562+ runner = CliRunner ()
563+
564+ # Create a session
565+ result = runner .invoke (cli , [
566+ "new" , "--name" , "my-goal-abc123" , "--goal" , "Add caching" ,
567+ "--path" , str (temp_daf_home / "test-project" )
568+ ], input = "n\n " )
569+ assert result .exit_code == 0
570+
571+ # Link with --rename-prefix
572+ result = runner .invoke (cli , [
573+ "link" , "my-goal-abc123" , "--jira" , "PROJ-456" , "--rename-prefix" , "creation"
574+ ])
575+ assert result .exit_code == 0
576+ assert "creation-PROJ-456" in result .output
577+
578+ # Verify: session accessible by new name
579+ config_loader = ConfigLoader ()
580+ sessions = config_loader .load_sessions ().get_sessions ("creation-PROJ-456" )
581+ assert sessions is not None
582+ assert len (sessions ) > 0
583+ assert sessions [0 ].issue_key == "PROJ-456"
584+
585+ # Verify: old name no longer exists
586+ old_sessions = config_loader .load_sessions ().get_sessions ("my-goal-abc123" )
587+ assert len (old_sessions ) == 0
588+
589+
590+ def test_link_rename_prefix_slug_generation ():
591+ """Test that issue_key_to_session_name produces correct slugs for rename-prefix usage."""
592+ from devflow .cli .commands .sync_command import issue_key_to_session_name
593+
594+ # JIRA-style keys
595+ assert issue_key_to_session_name ("PROJ-456" ) == "PROJ-456"
596+
597+ # GitHub-style keys (owner/repo#123)
598+ assert issue_key_to_session_name ("itdove/devaiflow#456" ) == "itdove-devaiflow-456"
599+
600+ # Enterprise hostname keys
601+ assert issue_key_to_session_name ("itdove/devaiflow#60" , "github.enterprise.com" ) == "github-enterprise-com-itdove-devaiflow-60"
602+
603+ # Default hostnames omit hostname
604+ assert issue_key_to_session_name ("itdove/devaiflow#60" , "github.com" ) == "itdove-devaiflow-60"
605+
606+
607+ def test_link_with_rename_prefix_conflict (mock_jira_cli , temp_daf_home ):
608+ """Test --rename-prefix warns but doesn't fail when target name exists."""
609+ mock_jira_cli .set_ticket ("PROJ-111" , {
610+ "key" : "PROJ-111" ,
611+ "fields" : {"summary" : "First" , "status" : {"name" : "New" }}
612+ })
613+ mock_jira_cli .set_ticket ("PROJ-222" , {
614+ "key" : "PROJ-222" ,
615+ "fields" : {"summary" : "Second" , "status" : {"name" : "New" }}
616+ })
617+
618+ runner = CliRunner ()
619+
620+ # Create two sessions — one with the name that the rename would produce
621+ result = runner .invoke (cli , [
622+ "new" , "--name" , "creation-PROJ-222" , "--goal" , "Existing" ,
623+ "--path" , str (temp_daf_home / "project1" )
624+ ], input = "n\n " )
625+ assert result .exit_code == 0
626+
627+ result = runner .invoke (cli , [
628+ "new" , "--name" , "my-session" , "--goal" , "New work" ,
629+ "--path" , str (temp_daf_home / "project2" )
630+ ], input = "n\n " )
631+ assert result .exit_code == 0
632+
633+ # Link with --rename-prefix — target name already exists
634+ result = runner .invoke (cli , [
635+ "link" , "my-session" , "--jira" , "PROJ-222" , "--rename-prefix" , "creation"
636+ ])
637+
638+ # Should succeed (link works) but warn about rename failure
639+ assert result .exit_code == 0
640+ assert "Could not rename" in result .output or "already exists" in result .output
641+
642+ # Verify: session is still linked (even though rename failed)
643+ config_loader = ConfigLoader ()
644+ sessions = config_loader .load_sessions ().get_sessions ("my-session" )
645+ assert len (sessions ) > 0
646+ assert sessions [0 ].issue_key == "PROJ-222"
647+
648+
649+ def test_link_works_inside_claude_session (mock_jira_cli , temp_daf_home , monkeypatch ):
650+ """Test that link_jira works when called from inside a Claude session (no @require_outside_claude)."""
651+ mock_jira_cli .set_ticket ("PROJ-789" , {
652+ "key" : "PROJ-789" ,
653+ "fields" : {"summary" : "Inside session" , "status" : {"name" : "New" }}
654+ })
655+
656+ runner = CliRunner ()
657+
658+ # Create a session
659+ result = runner .invoke (cli , [
660+ "new" , "--name" , "in-agent-test" , "--goal" , "Test inside agent" ,
661+ "--path" , str (temp_daf_home / "test-project" )
662+ ], input = "n\n " )
663+ assert result .exit_code == 0
664+
665+ # Simulate being inside a Claude session
666+ monkeypatch .setenv ("DEVAIFLOW_IN_SESSION" , "in-agent-test" )
667+
668+ # Link should work (not be blocked by require_outside_claude)
669+ result = runner .invoke (cli , [
670+ "link" , "in-agent-test" , "--jira" , "PROJ-789"
671+ ])
672+ assert result .exit_code == 0
673+ assert "Linked" in result .output or "PROJ-789" in result .output
674+
675+ # Verify: session is linked
676+ config_loader = ConfigLoader ()
677+ sessions = config_loader .load_sessions ().get_sessions ("in-agent-test" )
678+ assert len (sessions ) > 0
679+ assert sessions [0 ].issue_key == "PROJ-789"
680+
681+
682+ def test_link_with_rename_prefix_json_output (mock_jira_cli , temp_daf_home ):
683+ """Test --rename-prefix includes renamed_from in JSON output."""
684+ mock_jira_cli .set_ticket ("PROJ-999" , {
685+ "key" : "PROJ-999" ,
686+ "fields" : {"summary" : "JSON test" , "status" : {"name" : "New" }}
687+ })
688+
689+ runner = CliRunner ()
690+
691+ # Create a session
692+ result = runner .invoke (cli , [
693+ "new" , "--name" , "json-rename-test" , "--goal" , "Test JSON" ,
694+ "--path" , str (temp_daf_home / "test-project" )
695+ ], input = "n\n " )
696+ assert result .exit_code == 0
697+
698+ # Link with --rename-prefix and --json
699+ result = runner .invoke (cli , [
700+ "link" , "json-rename-test" , "--jira" , "PROJ-999" ,
701+ "--rename-prefix" , "creation" , "--json"
702+ ])
703+ assert result .exit_code == 0
704+
705+ output_data = json .loads (result .output )
706+ assert output_data ["success" ] is True
707+ assert output_data ["data" ]["session_group" ] == "creation-PROJ-999"
708+ assert output_data ["data" ]["renamed_from" ] == "json-rename-test"
709+ assert output_data ["data" ]["issue_key" ] == "PROJ-999"
0 commit comments