import subprocess from pathlib import Path import pytest import tools.sync.wiki_git as wiki_git @pytest.mark.parametrize('value', ['', '../master', '-main', 'a..b', 'a b', 'a.lock', 'a/@{x', 'a//b']) def test_invalid_branch_configuration_is_rejected(monkeypatch, value): monkeypatch.setenv('EXPECTED_GITEA_BRANCH', value) with pytest.raises(RuntimeError, match='EXPECTED_GITEA_BRANCH'): wiki_git.expected_branch() @pytest.mark.parametrize('url', ['git@git.kemt.fei.tuke.sk:jp170na/zpwiki.git', 'ssh://git@git.kemt.fei.tuke.sk/jp170na/zpwiki.git', 'https://git.kemt.fei.tuke.sk/jp170na/zpwiki']) def test_repository_identity_from_transport_url(url): assert wiki_git.repository_from_url(url) == 'jp170na/zpwiki' def test_real_git_fetch_fast_forward_and_local_change_protection(tmp_path, monkeypatch): run = subprocess.run def git(root, *args): return run(['git', '-C', str(root), *args], capture_output=True, text=True, check=True).stdout.strip() bare, author, checkout = (tmp_path / name for name in ('remote.git', 'author', 'checkout')) run(['git', 'init', '--bare', str(bare)], check=True, capture_output=True) run(['git', 'clone', str(bare), str(author)], check=True, capture_output=True) git(author, 'checkout', '-b', 'master') git(author, 'config', 'user.name', 'Sync test') git(author, 'config', 'user.email', 'sync@example.test') (author / 'README.md').write_text('old') git(author, 'add', '.') git(author, 'commit', '-m', 'initial') git(author, 'push', 'origin', 'master') run(['git', 'clone', str(bare), str(checkout)], check=True, capture_output=True) git(checkout, 'remote', 'set-url', 'origin', 'git@example.test:KEMT/zpwiki.git') (author / 'README.md').write_text('new') git(author, 'commit', '-am', 'update') git(author, 'push', 'origin', 'master') wanted = git(author, 'rev-parse', 'HEAD') # Exercise real Git fetch/merge against a local bare remote. Only transport # is redirected, so the production origin/branch validation still runs. def local_transport(args, **kw): if args[:2] == ['git', 'fetch']: args = [str(bare) if arg == 'origin' else arg for arg in args] return run(args, **kw) monkeypatch.setattr(wiki_git.subprocess, 'run', local_transport) wiki_git.update_wiki(checkout) assert git(checkout, 'rev-parse', 'HEAD') == wanted assert (checkout / 'README.md').read_text() == 'new' (checkout / 'untracked.md').write_text('local notes') with pytest.raises(RuntimeError, match='lokálne zmeny'): wiki_git.update_wiki(checkout) (checkout / 'untracked.md').unlink() (checkout / 'README.md').write_text('local modification') with pytest.raises(RuntimeError, match='lokálne zmeny'): wiki_git.update_wiki(checkout) assert (checkout / 'README.md').read_text() == 'local modification' git(checkout, 'restore', 'README.md') monkeypatch.setenv('EXPECTED_GITEA_BRANCH', 'other') with pytest.raises(RuntimeError, match='Aktívna Git vetva'): wiki_git.update_wiki(checkout) monkeypatch.setenv('EXPECTED_GITEA_BRANCH', 'master') monkeypatch.setenv('EXPECTED_GITEA_REPOSITORY', 'OTHER/zpwiki') with pytest.raises(RuntimeError, match='origin nezodpovedá'): wiki_git.update_wiki(checkout) monkeypatch.setenv('EXPECTED_GITEA_REPOSITORY', 'KEMT/zpwiki') git(checkout, 'config', 'user.name', 'Local author') git(checkout, 'config', 'user.email', 'local@example.test') (checkout / 'local.md').write_text('local commit') git(checkout, 'add', 'local.md') git(checkout, 'commit', '-m', 'local') local_head = git(checkout, 'rev-parse', 'HEAD') (author / 'README.md').write_text('remote update') git(author, 'commit', '-am', 'remote') git(author, 'push', 'origin', 'master') with pytest.raises(RuntimeError, match='Git operácia merge zlyhala'): wiki_git.update_wiki(checkout) assert git(checkout, 'rev-parse', 'HEAD') == local_head assert (checkout / 'local.md').read_text() == 'local commit'