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:
2026-01-07 02:12:12 +00:00
parent 4bc0fd203f
commit 97d2b66f02
33 changed files with 4394 additions and 1088 deletions

317
tests/test_vendor_update.py Normal file
View 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'])