feat: Add installation scripts for Windows and Unix-based systems
- Created `install_and_run.bat` for Windows installation and setup. - Created `install_and_run.sh` for Unix-based systems installation and setup. - Removed `main.py` as it is no longer needed. - Updated `requirements.txt` to specify package versions and added PyQt5. - Deleted `start.bat` as it is redundant. - Added unit tests for core functionality and scraping modes. - Implemented input validation utilities in `utils/validators.py`. - Added support for dual scraping modes in the scraper.
This commit is contained in:
221
tests/test_core.py
Normal file
221
tests/test_core.py
Normal file
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Basic test script for core functionality without GUI dependencies.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add project root to path
|
||||
project_root = Path(__file__).parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
def test_imports():
|
||||
"""Test that core modules can be imported."""
|
||||
print("Testing core module imports...")
|
||||
|
||||
try:
|
||||
from core.credentials import CredentialManager
|
||||
print("✓ CredentialManager import successful")
|
||||
|
||||
from utils.validators import validate_page_range, validate_username, validate_password
|
||||
print("✓ Validators import successful")
|
||||
|
||||
from core.scraper import Scraper
|
||||
print("✓ Scraper import successful")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Import failed: {e}")
|
||||
return False
|
||||
|
||||
def test_credential_manager():
|
||||
"""Test basic credential manager functionality."""
|
||||
print("\nTesting credential manager...")
|
||||
|
||||
try:
|
||||
from core.credentials import CredentialManager
|
||||
cm = CredentialManager("test_app")
|
||||
|
||||
# Test default settings
|
||||
defaults = cm.get_default_settings()
|
||||
print(f"✓ Default settings: {len(defaults)} items")
|
||||
|
||||
# Test validation
|
||||
validation = cm.validate_credentials("testuser", "testpass")
|
||||
print(f"✓ Credential validation: {validation['valid']}")
|
||||
|
||||
# Test config file path
|
||||
config_path = cm.get_config_file_path()
|
||||
print(f"✓ Config file path: {config_path}")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Credential manager test failed: {e}")
|
||||
return False
|
||||
|
||||
def test_validators():
|
||||
"""Test validation functions."""
|
||||
print("\nTesting validators...")
|
||||
|
||||
try:
|
||||
from utils.validators import validate_page_range, validate_username, validate_password
|
||||
|
||||
# Test page range validation
|
||||
valid_range = validate_page_range(1, 5)
|
||||
print(f"✓ Valid page range (1-5): {valid_range['valid']}")
|
||||
|
||||
invalid_range = validate_page_range(5, 1)
|
||||
print(f"✓ Invalid page range (5-1): {not invalid_range['valid']}")
|
||||
|
||||
# Test username validation
|
||||
valid_username = validate_username("testuser")
|
||||
print(f"✓ Valid username: {valid_username['valid']}")
|
||||
|
||||
invalid_username = validate_username("")
|
||||
print(f"✓ Invalid username (empty): {not invalid_username['valid']}")
|
||||
|
||||
# Test password validation
|
||||
valid_password = validate_password("password123")
|
||||
print(f"✓ Valid password: {valid_password['valid']}")
|
||||
|
||||
invalid_password = validate_password("")
|
||||
print(f"✓ Invalid password (empty): {not invalid_password['valid']}")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Validator test failed: {e}")
|
||||
return False
|
||||
|
||||
def test_scraper_init():
|
||||
"""Test scraper initialization without actually running it."""
|
||||
print("\nTesting scraper initialization...")
|
||||
|
||||
try:
|
||||
# Test importing selenium
|
||||
import selenium
|
||||
print(f"✓ Selenium available: {selenium.__version__}")
|
||||
|
||||
# Test callback mechanism
|
||||
events = []
|
||||
|
||||
def test_callback(event_type, data):
|
||||
events.append((event_type, data))
|
||||
|
||||
print("✓ Callback mechanism ready")
|
||||
|
||||
# We won't actually create a Scraper instance since it requires Chrome
|
||||
# but we can test that the class is properly defined
|
||||
from core.scraper import Scraper
|
||||
|
||||
# Check that the class has the expected methods
|
||||
expected_methods = ['login', 'scrape', 'trigger_download', 'human_delay', 'close']
|
||||
for method in expected_methods:
|
||||
if hasattr(Scraper, method):
|
||||
print(f"✓ Scraper has {method} method")
|
||||
else:
|
||||
print(f"✗ Scraper missing {method} method")
|
||||
return False
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Scraper test failed: {e}")
|
||||
return False
|
||||
|
||||
def test_project_structure():
|
||||
"""Test that all expected files are present."""
|
||||
print("\nTesting project structure...")
|
||||
|
||||
expected_files = [
|
||||
"core/__init__.py",
|
||||
"core/scraper.py",
|
||||
"core/credentials.py",
|
||||
"core/scraper_thread.py",
|
||||
"gui/__init__.py",
|
||||
"gui/main_window.py",
|
||||
"gui/login_dialog.py",
|
||||
"gui/progress_dialog.py",
|
||||
"utils/__init__.py",
|
||||
"utils/validators.py",
|
||||
"gui_main.py",
|
||||
"requirements.txt",
|
||||
"install_and_run.bat",
|
||||
"install_and_run.sh"
|
||||
]
|
||||
|
||||
missing_files = []
|
||||
for file_path in expected_files:
|
||||
full_path = project_root / file_path
|
||||
if full_path.exists():
|
||||
print(f"✓ {file_path}")
|
||||
else:
|
||||
print(f"✗ {file_path} missing")
|
||||
missing_files.append(file_path)
|
||||
|
||||
if missing_files:
|
||||
print(f"\nMissing files: {len(missing_files)}")
|
||||
return False
|
||||
else:
|
||||
print(f"\n✓ All {len(expected_files)} expected files present")
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Run all tests."""
|
||||
print("=== EBoek.info Scraper Core Test ===\n")
|
||||
|
||||
tests = [
|
||||
("Project Structure", test_project_structure),
|
||||
("Module Imports", test_imports),
|
||||
("Credential Manager", test_credential_manager),
|
||||
("Validators", test_validators),
|
||||
("Scraper Initialization", test_scraper_init),
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for test_name, test_func in tests:
|
||||
print(f"\n{'='*50}")
|
||||
print(f"Running: {test_name}")
|
||||
print('='*50)
|
||||
|
||||
try:
|
||||
result = test_func()
|
||||
results.append((test_name, result))
|
||||
except Exception as e:
|
||||
print(f"✗ Test '{test_name}' crashed: {e}")
|
||||
results.append((test_name, False))
|
||||
|
||||
# Summary
|
||||
print(f"\n{'='*50}")
|
||||
print("TEST SUMMARY")
|
||||
print('='*50)
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
for test_name, result in results:
|
||||
status = "PASS" if result else "FAIL"
|
||||
symbol = "✓" if result else "✗"
|
||||
print(f"{symbol} {test_name}: {status}")
|
||||
|
||||
if result:
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
print(f"\nResults: {passed} passed, {failed} failed")
|
||||
|
||||
if failed == 0:
|
||||
print("\n🎉 All tests passed! The core functionality is ready.")
|
||||
print("\nNext steps:")
|
||||
print("1. Install PyQt5: pip install PyQt5")
|
||||
print("2. Run the GUI: python3 gui_main.py")
|
||||
print("3. Or use the installer: ./install_and_run.sh")
|
||||
else:
|
||||
print(f"\n⚠️ {failed} test(s) failed. Please check the errors above.")
|
||||
|
||||
return failed == 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user