|
| 1 | +import asyncio |
| 2 | +import pytest |
| 3 | +from pathlib import Path |
| 4 | +from datetime import datetime |
| 5 | + |
| 6 | +from forklet.core.orchestrator import DownloadOrchestrator |
| 7 | +from forklet.services.github_api import GitHubAPIService |
| 8 | +from forklet.services.download import DownloadService |
| 9 | +from forklet.infrastructure.retry_manager import RetryManager |
| 10 | +from forklet.infrastructure.rate_limiter import RateLimiter |
| 11 | +from forklet.models.github import GitHubFile |
| 12 | +from forklet.models.download import DownloadRequest, FilterCriteria |
| 13 | +from forklet.models.github import RepositoryInfo, GitReference, RepositoryType |
| 14 | + |
| 15 | + |
| 16 | +@pytest.mark.asyncio |
| 17 | +async def test_orchestrator_dry_run(tmp_path, monkeypatch): |
| 18 | + # Arrange: create mock files returned by GitHub API |
| 19 | + files = [ |
| 20 | + GitHubFile(path="src/main.py", type="blob", size=100, download_url="https://api.github.com/file1"), |
| 21 | + GitHubFile(path="README.md", type="blob", size=50, download_url="https://api.github.com/file2"), |
| 22 | + ] |
| 23 | + |
| 24 | + async def mock_get_repository_tree(owner, repo, ref): |
| 25 | + return files |
| 26 | + |
| 27 | + # Setup services |
| 28 | + rate_limiter = RateLimiter() |
| 29 | + retry_manager = RetryManager() |
| 30 | + github_service = GitHubAPIService(rate_limiter, retry_manager) |
| 31 | + download_service = DownloadService(retry_manager) |
| 32 | + |
| 33 | + # Monkeypatch the github_service.get_repository_tree to return our files |
| 34 | + monkeypatch.setattr(github_service, 'get_repository_tree', mock_get_repository_tree) |
| 35 | + |
| 36 | + orchestrator = DownloadOrchestrator(github_service, download_service) |
| 37 | + |
| 38 | + # Create a fake repository and ref |
| 39 | + repo = RepositoryInfo( |
| 40 | + owner='test', name='repo', full_name='test/repo', url='https://github.com/test/repo', |
| 41 | + default_branch='main', repo_type=RepositoryType.PUBLIC, size=1, |
| 42 | + is_private=False, is_fork=False, created_at=datetime.now(), updated_at=datetime.now() |
| 43 | + ) |
| 44 | + ref = GitReference(name='main', ref_type='branch', sha='abc') |
| 45 | + |
| 46 | + # Create destination and create one existing file to test skipped detection |
| 47 | + dest = tmp_path / "out" |
| 48 | + dest.mkdir() |
| 49 | + existing = dest / "README.md" |
| 50 | + existing.write_text("existing") |
| 51 | + |
| 52 | + request = DownloadRequest( |
| 53 | + repository=repo, |
| 54 | + git_ref=ref, |
| 55 | + destination=dest, |
| 56 | + strategy=None, |
| 57 | + filters=FilterCriteria(), |
| 58 | + dry_run=True |
| 59 | + ) |
| 60 | + |
| 61 | + # Act |
| 62 | + result = await orchestrator.execute_download(request) |
| 63 | + |
| 64 | + # Assert |
| 65 | + assert result is not None |
| 66 | + assert result.progress.total_files == 2 |
| 67 | + assert result.progress.total_bytes == 150 |
| 68 | + # No files should be downloaded in dry-run |
| 69 | + assert result.downloaded_files == [] |
| 70 | + # README.md should be reported as skipped |
| 71 | + assert "README.md" in result.skipped_files |
0 commit comments