fix(tests): repair three mock-wiring bugs in doc_sync_executor tests
test_executor_successful_sync_entire_repo: _get_git_commit is patched separately and never calls the real _run_command, so it does not consume a slot in mock_run.side_effect. The list reserved one anyway (labelled "git rev-parse HEAD"), which shifted "M README.md\n" one call late — git status --porcelain saw "" (no changes) instead, so execute() took the no-changes branch and the test asserted "Successfully synced" against "already up to date". Removed the phantom slot. Also gave the iterdir() mock items real string .name attributes: MagicMock(name="X") sets the mock's repr, not the .name attribute read by execute()'s `item.name != '.git'` check, so every item was being treated as non-.git regardless of the intended value. test_executor_sync_specific_paths, test_executor_handles_no_changes: mock_upstream_dir/mock_gitea_dir were built but never wired to mock_path.return_value, so `work_dir = Path(...)` and `upstream_dir = work_dir / "upstream"` resolved to a different, unconfigured auto-generated MagicMock. `source.name` on that mock is itself a MagicMock, not a string, so `', '.join(copied_paths)` raised TypeError. Wired mock_path.return_value to a work_dir mock whose __truediv__ yields the intended upstream/gitea mocks, matching the pattern the first test already used correctly. All three are test-side: doc_sync_executor.py is unchanged. Confirmed via git log -p that this file and its test have exactly one commit in this repo's history (the initial extraction), so there is no prior passing version to regress from — these tests appear to have never passed.
This commit is contained in:
@@ -60,23 +60,36 @@ class TestDocSyncExecutor:
|
||||
mock_upstream_dir = MagicMock()
|
||||
mock_gitea_dir = MagicMock()
|
||||
|
||||
# Setup directory mocking
|
||||
mock_upstream_dir.iterdir.return_value = [
|
||||
MagicMock(name=".git", is_dir=lambda: True),
|
||||
MagicMock(name="README.md", is_dir=lambda: False),
|
||||
MagicMock(name="docs", is_dir=lambda: True),
|
||||
]
|
||||
mock_gitea_dir.iterdir.return_value = [
|
||||
MagicMock(name=".git", is_dir=lambda: True)
|
||||
]
|
||||
# Setup directory mocking. MagicMock(name=...) sets the mock's
|
||||
# repr, not its .name attribute (classic gotcha — see
|
||||
# test_executor_sync_specific_paths) — set .name explicitly so
|
||||
# execute()'s `item.name != '.git'` check actually excludes it.
|
||||
git_item = MagicMock(is_dir=lambda: True)
|
||||
git_item.name = ".git"
|
||||
readme_item = MagicMock(is_dir=lambda: False)
|
||||
readme_item.name = "README.md"
|
||||
docs_item = MagicMock(is_dir=lambda: True)
|
||||
docs_item.name = "docs"
|
||||
mock_upstream_dir.iterdir.return_value = [git_item, readme_item, docs_item]
|
||||
|
||||
gitea_git_item = MagicMock(is_dir=lambda: True)
|
||||
gitea_git_item.name = ".git"
|
||||
mock_gitea_dir.iterdir.return_value = [gitea_git_item]
|
||||
|
||||
mock_path.return_value = mock_work_dir
|
||||
mock_work_dir.__truediv__.side_effect = [mock_upstream_dir, mock_gitea_dir]
|
||||
|
||||
# Mock git status to show changes
|
||||
# Mock git status to show changes. _get_git_commit is patched
|
||||
# separately above and never calls the real _run_command, so it
|
||||
# does not consume a slot in this side_effect list — the actual
|
||||
# call order for this (clone-succeeds, entire-repo) path is:
|
||||
# clone upstream, clone gitea, add, status, commit, tag, push
|
||||
# branch, push tag. The list previously reserved a slot for
|
||||
# "git rev-parse HEAD" that _run_command is never asked for,
|
||||
# which shifted "M README.md\n" one call late and made
|
||||
# `git status --porcelain` see "" (no changes) instead.
|
||||
mock_run.side_effect = [
|
||||
"", # git clone upstream
|
||||
"", # git rev-parse HEAD
|
||||
"", # git clone gitea
|
||||
"", # git add
|
||||
"M README.md\n", # git status --porcelain (has changes)
|
||||
@@ -108,7 +121,15 @@ class TestDocSyncExecutor:
|
||||
|
||||
mock_get_commit.return_value = "abc123"
|
||||
|
||||
# Mock path operations
|
||||
# Mock path operations. work_dir = Path(...) resolves to
|
||||
# mock_path.return_value — mock_upstream_dir/mock_gitea_dir have
|
||||
# to be reachable from there via __truediv__, the same way
|
||||
# test_executor_successful_sync_entire_repo wires it, or
|
||||
# `upstream_dir / doc_path` never reaches these mocks at all and
|
||||
# falls through to an unconfigured auto-generated MagicMock
|
||||
# instead (observed failure: TypeError joining a MagicMock into
|
||||
# ', '.join(copied_paths)).
|
||||
mock_work_dir = MagicMock()
|
||||
mock_upstream_dir = MagicMock()
|
||||
mock_gitea_dir = MagicMock()
|
||||
mock_docs = MagicMock(name="docs")
|
||||
@@ -121,6 +142,8 @@ class TestDocSyncExecutor:
|
||||
mock_examples.is_dir.return_value = True
|
||||
mock_examples.name = "examples"
|
||||
|
||||
mock_path.return_value = mock_work_dir
|
||||
mock_work_dir.__truediv__.side_effect = [mock_upstream_dir, mock_gitea_dir]
|
||||
mock_upstream_dir.__truediv__.side_effect = [mock_docs, mock_examples]
|
||||
mock_gitea_dir.iterdir.return_value = []
|
||||
|
||||
@@ -159,13 +182,27 @@ class TestDocSyncExecutor:
|
||||
|
||||
mock_run.side_effect = run_command_side_effect
|
||||
|
||||
# Setup minimal mocking
|
||||
# Setup minimal mocking. sample_doc_sync_config's docs_paths is
|
||||
# ["/docs"] (tests/conftest.py), so execute() takes the
|
||||
# specific-paths branch and needs `upstream_dir / "docs"` wired
|
||||
# to something with a real string .name — see
|
||||
# test_executor_sync_specific_paths for the same wiring gap and
|
||||
# the TypeError it produces unwired.
|
||||
mock_work_dir = MagicMock()
|
||||
mock_upstream_dir = MagicMock()
|
||||
mock_gitea_dir = MagicMock()
|
||||
mock_gitea_dir.iterdir.return_value = []
|
||||
mock_upstream_dir.iterdir.return_value = []
|
||||
|
||||
mock_docs = MagicMock()
|
||||
mock_docs.exists.return_value = True
|
||||
mock_docs.is_dir.return_value = True
|
||||
mock_docs.name = "docs"
|
||||
|
||||
mock_path.return_value = mock_work_dir
|
||||
mock_work_dir.__truediv__.side_effect = [mock_upstream_dir, mock_gitea_dir]
|
||||
mock_upstream_dir.__truediv__.side_effect = [mock_docs]
|
||||
|
||||
result = await doc_sync_executor.execute(sample_doc_sync_config, test_settings)
|
||||
|
||||
assert "already up to date" in result.lower() or "no changes" in result.lower()
|
||||
|
||||
Reference in New Issue
Block a user