@@ -839,26 +839,36 @@ def test_test_feature_branch_accepts_single_prefix(self, tmp_path: Path):
839839 assert result .returncode == 0
840840
841841
842- # ── Deprecation Notice Tests ──────────────────────────────────────────────────
842+ # ── Upcoming Deprecation Notice Tests ──────────────────────────────────────────────────
843843
844844
845845class TestGitExtDeprecationNotice :
846- """Tests for the v1.0.0 deprecation notice shown during specify init."""
846+ """Tests for the v1.0.0 upcoming deprecation notice shown during specify init."""
847847
848- def test_deprecation_notice_shown_on_fresh_install (self , tmp_path : Path ):
849- """specify init shows the git extension deprecation notice on first install."""
848+ def test_upcoming_deprecation_notice_shown_on_fresh_install (self , tmp_path : Path ):
849+ """specify init shows the git extension upcoming deprecation notice on first install."""
850850 from typer .testing import CliRunner
851851 from unittest .mock import patch , MagicMock
852852 from specify_cli import app
853853
854854 project_dir = tmp_path / "test-project"
855855 runner = CliRunner ()
856856
857+ mock_manifest = MagicMock ()
858+ mock_manifest .install_notice = (
859+ "The git extension is currently enabled by default, but starting with\n "
860+ "v1.0.0 it will require explicit opt-in.\n \n "
861+ "To opt in after v1.0.0:\n "
862+ " • specify init --extension git\n "
863+ " • specify extension add git (post-init)"
864+ )
865+
857866 mock_registry = MagicMock ()
858867 mock_registry .is_installed .return_value = False
859868
860869 mock_manager = MagicMock ()
861870 mock_manager .registry = mock_registry
871+ mock_manager .install_from_directory .return_value = mock_manifest
862872
863873 with patch ("specify_cli.extensions.ExtensionManager" , return_value = mock_manager ):
864874 result = runner .invoke (
@@ -870,10 +880,10 @@ def test_deprecation_notice_shown_on_fresh_install(self, tmp_path: Path):
870880 assert result .exit_code == 0 , result .output
871881 assert "Upcoming Change: git Extension" in result .output
872882 assert "v1.0.0" in result .output
873- assert "specify init -- extension git" in result .output
883+ assert "specify extension add git" in result .output
874884
875- def test_deprecation_notice_not_shown_when_already_installed (self , tmp_path : Path ):
876- """specify init does NOT show the deprecation notice when git extension is already installed."""
885+ def test_upcoming_deprecation_notice_not_shown_when_already_installed (self , tmp_path : Path ):
886+ """specify init does NOT show the upcoming deprecation notice when git extension is already installed."""
877887 from typer .testing import CliRunner
878888 from unittest .mock import patch , MagicMock
879889 from specify_cli import app
@@ -897,8 +907,8 @@ def test_deprecation_notice_not_shown_when_already_installed(self, tmp_path: Pat
897907 assert result .exit_code == 0 , result .output
898908 assert "Upcoming Change: git Extension" not in result .output
899909
900- def test_deprecation_notice_not_shown_with_no_git_flag (self , tmp_path : Path ):
901- """specify init does NOT show the deprecation notice when --no-git is passed."""
910+ def test_upcoming_deprecation_notice_not_shown_with_no_git_flag (self , tmp_path : Path ):
911+ """specify init does NOT show the upcoming deprecation notice when --no-git is passed."""
902912 from typer .testing import CliRunner
903913 from specify_cli import app
904914
@@ -913,3 +923,32 @@ def test_deprecation_notice_not_shown_with_no_git_flag(self, tmp_path: Path):
913923
914924 assert result .exit_code == 0 , result .output
915925 assert "Upcoming Change: git Extension" not in result .output
926+
927+ def test_upcoming_deprecation_notice_not_shown_when_no_install_notice (self , tmp_path : Path ):
928+ """specify init does NOT show the upcoming deprecation notice if extension has no install_notice."""
929+ from typer .testing import CliRunner
930+ from unittest .mock import patch , MagicMock
931+ from specify_cli import app
932+
933+ project_dir = tmp_path / "test-project"
934+ runner = CliRunner ()
935+
936+ mock_manifest = MagicMock ()
937+ mock_manifest .install_notice = None # No notice defined
938+
939+ mock_registry = MagicMock ()
940+ mock_registry .is_installed .return_value = False
941+
942+ mock_manager = MagicMock ()
943+ mock_manager .registry = mock_registry
944+ mock_manager .install_from_directory .return_value = mock_manifest
945+
946+ with patch ("specify_cli.extensions.ExtensionManager" , return_value = mock_manager ):
947+ result = runner .invoke (
948+ app ,
949+ ["init" , str (project_dir ), "--ai" , "claude" , "--ignore-agent-tools" , "--script" , "sh" ],
950+ catch_exceptions = False ,
951+ )
952+
953+ assert result .exit_code == 0 , result .output
954+ assert "Upcoming Change: git Extension" not in result .output
0 commit comments