Update package version to 0.0.1-beta, add new dependencies including ExcelJS, and refactor export utilities to utilize ExcelJS for Excel file generation. Enhance component JSON files with vendor information for improved asset management.
This commit is contained in:
317
tests/test_vendor_update.py
Normal file
317
tests/test_vendor_update.py
Normal file
@@ -0,0 +1,317 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tests for vendor_update.py
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, patch, mock_open
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
|
||||
# Import the module (adjust path as needed)
|
||||
import sys
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / 'scripts'))
|
||||
|
||||
from vendor_update import GitHubAPI, compute_sha256, download_file, update_manifest_entry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir():
|
||||
"""Create a temporary directory for tests."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
yield Path(tmpdir)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_manifest_entry():
|
||||
"""Sample manifest entry for testing."""
|
||||
return {
|
||||
'id': 'test-entry',
|
||||
'source_repo': 'owner/repo',
|
||||
'source_path': 'path/to/file.stl',
|
||||
'source_ref': 'main',
|
||||
'pinned_sha': None,
|
||||
'pinned_raw_url': None,
|
||||
'local_path': 'vendor/owner-repo/path/to/file.stl',
|
||||
'checksum_sha256': None,
|
||||
'last_checked': None,
|
||||
'upstream_latest_sha': None,
|
||||
'status': 'unknown',
|
||||
'license': None
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def github_api():
|
||||
"""Create a GitHubAPI instance for testing."""
|
||||
return GitHubAPI(token='test-token')
|
||||
|
||||
|
||||
def test_compute_sha256(temp_dir):
|
||||
"""Test SHA256 computation."""
|
||||
test_file = temp_dir / 'test.txt'
|
||||
test_file.write_text('test content')
|
||||
|
||||
checksum = compute_sha256(test_file)
|
||||
|
||||
# Verify it's a valid SHA256 hex string
|
||||
assert len(checksum) == 64
|
||||
assert all(c in '0123456789abcdef' for c in checksum.lower())
|
||||
|
||||
# Verify it matches expected hash
|
||||
expected = hashlib.sha256(b'test content').hexdigest()
|
||||
assert checksum == expected
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_download_file_success(temp_dir):
|
||||
"""Test successful file download."""
|
||||
test_url = 'https://example.com/file.stl'
|
||||
test_content = b'STL file content'
|
||||
dest_path = temp_dir / 'downloaded.stl'
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
test_url,
|
||||
body=test_content,
|
||||
status=200
|
||||
)
|
||||
|
||||
result = download_file(test_url, dest_path)
|
||||
|
||||
assert result is True
|
||||
assert dest_path.exists()
|
||||
assert dest_path.read_bytes() == test_content
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_download_file_failure():
|
||||
"""Test file download failure."""
|
||||
test_url = 'https://example.com/missing.stl'
|
||||
dest_path = Path('/tmp/test.stl')
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
test_url,
|
||||
status=404
|
||||
)
|
||||
|
||||
result = download_file(test_url, dest_path)
|
||||
|
||||
assert result is False
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_github_api_get_file_sha(github_api):
|
||||
"""Test getting file SHA from GitHub API."""
|
||||
owner = 'test-owner'
|
||||
repo = 'test-repo'
|
||||
path = 'file.stl'
|
||||
ref = 'main'
|
||||
|
||||
# Mock Contents API response
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/contents/{path}',
|
||||
json={'sha': 'blob-sha-123'},
|
||||
match=[responses.matchers.query_param_matcher({'ref': ref})]
|
||||
)
|
||||
|
||||
# Mock Commits API response
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/commits',
|
||||
json=[{'sha': 'commit-sha-456'}],
|
||||
match=[responses.matchers.query_param_matcher({
|
||||
'path': path,
|
||||
'sha': ref,
|
||||
'per_page': 1
|
||||
})]
|
||||
)
|
||||
|
||||
sha = github_api.get_file_sha(owner, repo, path, ref)
|
||||
|
||||
assert sha == 'commit-sha-456'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_github_api_get_license(github_api):
|
||||
"""Test getting license information."""
|
||||
owner = 'test-owner'
|
||||
repo = 'test-repo'
|
||||
sha = 'abc123'
|
||||
|
||||
# Mock LICENSE file found
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/contents/LICENSE',
|
||||
json={'type': 'file'},
|
||||
match=[responses.matchers.query_param_matcher({'ref': sha})]
|
||||
)
|
||||
|
||||
license_url = github_api.get_license(owner, repo, sha)
|
||||
|
||||
assert license_url == f'https://raw.githubusercontent.com/{owner}/{repo}/{sha}/LICENSE'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_update_manifest_entry_dry_run(temp_dir, sample_manifest_entry):
|
||||
"""Test updating manifest entry in dry-run mode."""
|
||||
owner = 'owner'
|
||||
repo = 'repo'
|
||||
path = 'path/to/file.stl'
|
||||
ref = 'main'
|
||||
|
||||
# Mock API responses
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/contents/{path}',
|
||||
json={'sha': 'blob-sha'},
|
||||
match=[responses.matchers.query_param_matcher({'ref': ref})]
|
||||
)
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/commits',
|
||||
json=[{'sha': 'commit-sha-123'}],
|
||||
match=[responses.matchers.query_param_matcher({
|
||||
'path': path,
|
||||
'sha': ref,
|
||||
'per_page': 1
|
||||
})]
|
||||
)
|
||||
|
||||
api = GitHubAPI(token='test-token')
|
||||
updated_entry = update_manifest_entry(
|
||||
sample_manifest_entry,
|
||||
api,
|
||||
temp_dir,
|
||||
dry_run=True
|
||||
)
|
||||
|
||||
assert updated_entry['pinned_sha'] == 'commit-sha-123'
|
||||
assert updated_entry['pinned_raw_url'] == f'https://raw.githubusercontent.com/{owner}/{repo}/commit-sha-123/{path}'
|
||||
assert updated_entry['status'] == 'up-to-date'
|
||||
assert updated_entry['last_checked'] is not None
|
||||
assert updated_entry['upstream_latest_sha'] == 'commit-sha-123'
|
||||
|
||||
# In dry-run, file should not be downloaded
|
||||
local_path = temp_dir / updated_entry['local_path']
|
||||
assert not local_path.exists()
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_update_manifest_entry_with_download(temp_dir, sample_manifest_entry):
|
||||
"""Test updating manifest entry with actual download."""
|
||||
owner = 'owner'
|
||||
repo = 'repo'
|
||||
path = 'path/to/file.stl'
|
||||
ref = 'main'
|
||||
commit_sha = 'commit-sha-123'
|
||||
file_content = b'STL file content here'
|
||||
|
||||
# Mock API responses
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/contents/{path}',
|
||||
json={'sha': 'blob-sha'},
|
||||
match=[responses.matchers.query_param_matcher({'ref': ref})]
|
||||
)
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/commits',
|
||||
json=[{'sha': commit_sha}],
|
||||
match=[responses.matchers.query_param_matcher({
|
||||
'path': path,
|
||||
'sha': ref,
|
||||
'per_page': 1
|
||||
})]
|
||||
)
|
||||
|
||||
# Mock file download
|
||||
pinned_url = f'https://raw.githubusercontent.com/{owner}/{repo}/{commit_sha}/{path}'
|
||||
responses.add(
|
||||
responses.GET,
|
||||
pinned_url,
|
||||
body=file_content,
|
||||
status=200
|
||||
)
|
||||
|
||||
api = GitHubAPI(token='test-token')
|
||||
updated_entry = update_manifest_entry(
|
||||
sample_manifest_entry,
|
||||
api,
|
||||
temp_dir,
|
||||
dry_run=False
|
||||
)
|
||||
|
||||
assert updated_entry['pinned_sha'] == commit_sha
|
||||
assert updated_entry['checksum_sha256'] is not None
|
||||
assert updated_entry['status'] == 'up-to-date'
|
||||
|
||||
# Verify file was downloaded
|
||||
local_path = temp_dir / updated_entry['local_path']
|
||||
assert local_path.exists()
|
||||
assert local_path.read_bytes() == file_content
|
||||
|
||||
# Verify checksum
|
||||
expected_checksum = hashlib.sha256(file_content).hexdigest()
|
||||
assert updated_entry['checksum_sha256'] == expected_checksum
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_update_manifest_entry_download_failure(temp_dir, sample_manifest_entry):
|
||||
"""Test handling of download failure."""
|
||||
owner = 'owner'
|
||||
repo = 'repo'
|
||||
path = 'path/to/file.stl'
|
||||
ref = 'main'
|
||||
commit_sha = 'commit-sha-123'
|
||||
|
||||
# Mock API responses
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/contents/{path}',
|
||||
json={'sha': 'blob-sha'},
|
||||
match=[responses.matchers.query_param_matcher({'ref': ref})]
|
||||
)
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'https://api.github.com/repos/{owner}/{repo}/commits',
|
||||
json=[{'sha': commit_sha}],
|
||||
match=[responses.matchers.query_param_matcher({
|
||||
'path': path,
|
||||
'sha': ref,
|
||||
'per_page': 1
|
||||
})]
|
||||
)
|
||||
|
||||
# Mock file download failure
|
||||
pinned_url = f'https://raw.githubusercontent.com/{owner}/{repo}/{commit_sha}/{path}'
|
||||
responses.add(
|
||||
responses.GET,
|
||||
pinned_url,
|
||||
status=404
|
||||
)
|
||||
|
||||
api = GitHubAPI(token='test-token')
|
||||
updated_entry = update_manifest_entry(
|
||||
sample_manifest_entry,
|
||||
api,
|
||||
temp_dir,
|
||||
dry_run=False
|
||||
)
|
||||
|
||||
assert updated_entry['status'] == 'error'
|
||||
assert updated_entry['pinned_sha'] == commit_sha # SHA was resolved
|
||||
assert updated_entry['checksum_sha256'] is None # File not downloaded
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__, '-v'])
|
||||
Reference in New Issue
Block a user