mirror of
https://github.com/smittix/intercept.git
synced 2026-05-29 19:59:27 -07:00
Refactor into modular structure with improvements
- Split monolithic intercept.py (15k lines) into modular structure: - routes/ - Flask blueprints for each feature - templates/ - Jinja2 HTML templates - data/ - OUI database, satellite TLEs, detection patterns - utils/ - dependencies, process management, logging - config.py - centralized configuration with env var support - Add type hints to function signatures - Replace bare except clauses with specific exceptions - Add proper logging module (replaces print statements) - Add environment variable support (INTERCEPT_* prefix) - Add test suite with pytest - Add Dockerfile for containerized deployment - Add pyproject.toml with ruff/black/mypy config - Add requirements-dev.txt for development dependencies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
19
tests/conftest.py
Normal file
19
tests/conftest.py
Normal file
@@ -0,0 +1,19 @@
|
||||
"""Pytest configuration and fixtures."""
|
||||
|
||||
import pytest
|
||||
from app import app as flask_app
|
||||
from routes import register_blueprints
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def app():
|
||||
"""Create application for testing."""
|
||||
register_blueprints(flask_app)
|
||||
flask_app.config['TESTING'] = True
|
||||
return flask_app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(app):
|
||||
"""Create test client."""
|
||||
return app.test_client()
|
||||
39
tests/test_app.py
Normal file
39
tests/test_app.py
Normal file
@@ -0,0 +1,39 @@
|
||||
"""Tests for main application routes."""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_index_page(client):
|
||||
"""Test that index page loads."""
|
||||
response = client.get('/')
|
||||
assert response.status_code == 200
|
||||
assert b'INTERCEPT' in response.data
|
||||
|
||||
|
||||
def test_dependencies_endpoint(client):
|
||||
"""Test dependencies endpoint returns valid JSON."""
|
||||
response = client.get('/dependencies')
|
||||
assert response.status_code == 200
|
||||
data = response.get_json()
|
||||
assert 'modes' in data
|
||||
assert 'os' in data
|
||||
|
||||
|
||||
def test_devices_endpoint(client):
|
||||
"""Test devices endpoint returns list."""
|
||||
response = client.get('/devices')
|
||||
assert response.status_code == 200
|
||||
data = response.get_json()
|
||||
assert isinstance(data, list)
|
||||
|
||||
|
||||
def test_satellite_dashboard(client):
|
||||
"""Test satellite dashboard loads."""
|
||||
response = client.get('/satellite/dashboard')
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_adsb_dashboard(client):
|
||||
"""Test ADS-B dashboard loads."""
|
||||
response = client.get('/adsb/dashboard')
|
||||
assert response.status_code == 200
|
||||
48
tests/test_config.py
Normal file
48
tests/test_config.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Tests for configuration module."""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
class TestConfigEnvVars:
|
||||
"""Tests for environment variable configuration."""
|
||||
|
||||
def test_default_values(self):
|
||||
"""Test that default values are set."""
|
||||
from config import PORT, HOST, DEBUG
|
||||
|
||||
assert PORT == 5050
|
||||
assert HOST == '0.0.0.0'
|
||||
assert DEBUG is False
|
||||
|
||||
def test_env_override(self, monkeypatch):
|
||||
"""Test that environment variables override defaults."""
|
||||
monkeypatch.setenv('INTERCEPT_PORT', '8080')
|
||||
monkeypatch.setenv('INTERCEPT_DEBUG', 'true')
|
||||
|
||||
# Re-import to get new values
|
||||
import importlib
|
||||
import config
|
||||
importlib.reload(config)
|
||||
|
||||
assert config.PORT == 8080
|
||||
assert config.DEBUG is True
|
||||
|
||||
# Reset
|
||||
monkeypatch.delenv('INTERCEPT_PORT', raising=False)
|
||||
monkeypatch.delenv('INTERCEPT_DEBUG', raising=False)
|
||||
importlib.reload(config)
|
||||
|
||||
def test_invalid_env_values(self, monkeypatch):
|
||||
"""Test that invalid env values fall back to defaults."""
|
||||
monkeypatch.setenv('INTERCEPT_PORT', 'invalid')
|
||||
|
||||
import importlib
|
||||
import config
|
||||
importlib.reload(config)
|
||||
|
||||
# Should fall back to default
|
||||
assert config.PORT == 5050
|
||||
|
||||
monkeypatch.delenv('INTERCEPT_PORT', raising=False)
|
||||
importlib.reload(config)
|
||||
73
tests/test_utils.py
Normal file
73
tests/test_utils.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""Tests for utility modules."""
|
||||
|
||||
import pytest
|
||||
from utils.process import is_valid_mac, is_valid_channel
|
||||
from utils.dependencies import check_tool
|
||||
from data.oui import get_manufacturer
|
||||
|
||||
|
||||
class TestMacValidation:
|
||||
"""Tests for MAC address validation."""
|
||||
|
||||
def test_valid_mac(self):
|
||||
"""Test valid MAC addresses."""
|
||||
assert is_valid_mac('AA:BB:CC:DD:EE:FF') is True
|
||||
assert is_valid_mac('aa:bb:cc:dd:ee:ff') is True
|
||||
assert is_valid_mac('00:11:22:33:44:55') is True
|
||||
|
||||
def test_invalid_mac(self):
|
||||
"""Test invalid MAC addresses."""
|
||||
assert is_valid_mac('') is False
|
||||
assert is_valid_mac(None) is False
|
||||
assert is_valid_mac('invalid') is False
|
||||
assert is_valid_mac('AA:BB:CC:DD:EE') is False
|
||||
assert is_valid_mac('AA-BB-CC-DD-EE-FF') is False
|
||||
|
||||
|
||||
class TestChannelValidation:
|
||||
"""Tests for WiFi channel validation."""
|
||||
|
||||
def test_valid_channels(self):
|
||||
"""Test valid channel numbers."""
|
||||
assert is_valid_channel(1) is True
|
||||
assert is_valid_channel(6) is True
|
||||
assert is_valid_channel(11) is True
|
||||
assert is_valid_channel('36') is True
|
||||
assert is_valid_channel(149) is True
|
||||
|
||||
def test_invalid_channels(self):
|
||||
"""Test invalid channel numbers."""
|
||||
assert is_valid_channel(0) is False
|
||||
assert is_valid_channel(-1) is False
|
||||
assert is_valid_channel(201) is False
|
||||
assert is_valid_channel(None) is False
|
||||
assert is_valid_channel('invalid') is False
|
||||
|
||||
|
||||
class TestToolCheck:
|
||||
"""Tests for tool availability checking."""
|
||||
|
||||
def test_common_tools(self):
|
||||
"""Test checking for common tools."""
|
||||
# These should return bool, regardless of whether installed
|
||||
assert isinstance(check_tool('ls'), bool)
|
||||
assert isinstance(check_tool('nonexistent_tool_12345'), bool)
|
||||
|
||||
def test_nonexistent_tool(self):
|
||||
"""Test that nonexistent tools return False."""
|
||||
assert check_tool('nonexistent_tool_xyz_12345') is False
|
||||
|
||||
|
||||
class TestOuiLookup:
|
||||
"""Tests for OUI manufacturer lookup."""
|
||||
|
||||
def test_known_manufacturer(self):
|
||||
"""Test looking up known manufacturers."""
|
||||
# Apple prefix
|
||||
result = get_manufacturer('00:25:DB:AA:BB:CC')
|
||||
assert result == 'Apple' or result == 'Unknown'
|
||||
|
||||
def test_unknown_manufacturer(self):
|
||||
"""Test looking up unknown manufacturer."""
|
||||
result = get_manufacturer('FF:FF:FF:FF:FF:FF')
|
||||
assert result == 'Unknown'
|
||||
Reference in New Issue
Block a user