|
6 | 6 | from pathlib import Path |
7 | 7 | from unittest.mock import MagicMock, patch |
8 | 8 |
|
9 | | -import pytest # noqa: F401 |
| 9 | +import pytest |
10 | 10 | from click.testing import CliRunner |
11 | 11 |
|
12 | 12 | from apm_cli.cli import cli |
@@ -908,6 +908,51 @@ def test_virtual_dep_processed_normally( |
908 | 908 | # Remote refs were fetched -- virtual deps are NOT silently skipped |
909 | 909 | mock_downloader.list_remote_refs.assert_called_once() |
910 | 910 |
|
| 911 | + @patch(_PATCH_AUTH) |
| 912 | + @patch(_PATCH_DOWNLOADER) |
| 913 | + @patch(_PATCH_MIGRATE) |
| 914 | + @patch(_PATCH_GET_LOCKFILE_PATH) |
| 915 | + @patch(_PATCH_GET_APM_DIR) |
| 916 | + @patch(_PATCH_LOCKFILE) |
| 917 | + def test_monorepo_virtual_subdir_tag_pattern_recognized( |
| 918 | + self, |
| 919 | + mock_lf_cls, |
| 920 | + mock_get_apm_dir, |
| 921 | + mock_get_path, |
| 922 | + mock_migrate, |
| 923 | + mock_dl_cls, |
| 924 | + mock_auth, |
| 925 | + ): |
| 926 | + """Monorepo tags using virtual-path basename are parsed, not marked unknown.""" |
| 927 | + with self._chdir_tmp() as tmp: |
| 928 | + mock_get_apm_dir.return_value = tmp |
| 929 | + mock_get_path.return_value = tmp / "apm.lock.yaml" |
| 930 | + |
| 931 | + virtual_dep = LockedDependency( |
| 932 | + repo_url="org/monorepo", |
| 933 | + resolved_ref="agent-dev-workflow_v0.0.20260624", |
| 934 | + resolved_commit="d2b0ad19fd792cbb12e0f653b65607b8f9c95d4e", |
| 935 | + is_virtual=True, |
| 936 | + virtual_path="packages/agent-dev-workflow", |
| 937 | + ) |
| 938 | + deps = {"org/monorepo/packages/agent-dev-workflow": virtual_dep} |
| 939 | + mock_lf_cls.read.return_value = _make_lockfile(deps) |
| 940 | + |
| 941 | + mock_downloader = MagicMock() |
| 942 | + mock_downloader.list_remote_refs.return_value = [ |
| 943 | + _remote_tag("agent-dev-workflow_v0.0.20260624"), |
| 944 | + _remote_tag("agent-dev-workflow_v0.0.20260625"), |
| 945 | + ] |
| 946 | + mock_dl_cls.return_value = mock_downloader |
| 947 | + |
| 948 | + result = self.runner.invoke(cli, ["outdated"]) |
| 949 | + |
| 950 | + assert result.exit_code == 0 |
| 951 | + assert "unknown" not in result.output.lower() |
| 952 | + assert "outdated" in result.output.lower() |
| 953 | + # Latest tag is shown (may be truncated in narrow tables) |
| 954 | + assert "agent-dev-" in result.output |
| 955 | + |
911 | 956 | # --- Dev dependency visibility --- |
912 | 957 |
|
913 | 958 | @patch(_PATCH_AUTH) |
@@ -1221,3 +1266,28 @@ def test_ado_dep_builds_correct_reference( |
1221 | 1266 | assert result.exit_code == 0 |
1222 | 1267 | # Verify list_remote_refs was called (dep was not silently skipped) |
1223 | 1268 | mock_downloader.list_remote_refs.assert_called_once() |
| 1269 | + |
| 1270 | + |
| 1271 | +class TestPackageBasename: |
| 1272 | + """Direct unit tests for _package_basename edge cases.""" |
| 1273 | + |
| 1274 | + @pytest.mark.parametrize( |
| 1275 | + "virtual_path,expected", |
| 1276 | + [ |
| 1277 | + ("packages/agent-dev-workflow", "agent-dev-workflow"), |
| 1278 | + ("packages/agent-dev-workflow/", "agent-dev-workflow"), |
| 1279 | + ("packages/deep/nested/pkg", "pkg"), |
| 1280 | + ("pkg", "pkg"), |
| 1281 | + ], |
| 1282 | + ) |
| 1283 | + def test_virtual_subdir_basename_variants(self, virtual_path, expected): |
| 1284 | + """Trailing slashes, deep nesting, and simple names all resolve correctly.""" |
| 1285 | + dep = LockedDependency( |
| 1286 | + repo_url="org/monorepo", |
| 1287 | + resolved_ref="v1.0.0", |
| 1288 | + is_virtual=True, |
| 1289 | + virtual_path=virtual_path, |
| 1290 | + ) |
| 1291 | + from apm_cli.commands.outdated import _package_basename |
| 1292 | + |
| 1293 | + assert _package_basename(dep) == expected |
0 commit comments