380 lines
12 KiB
Python
380 lines
12 KiB
Python
# This is free software for the public good of a permacomputer hosted at
|
|
# permacomputer.com, an always-on computer by the people, for the people.
|
|
# One which is durable, easy to repair, & distributed like tap water
|
|
# for machine learning intelligence.
|
|
#
|
|
# The permacomputer is community-owned infrastructure optimized around
|
|
# four values:
|
|
#
|
|
# TRUTH First principles, math & science, open source code freely distributed
|
|
# FREEDOM Voluntary partnerships, freedom from tyranny & corporate control
|
|
# HARMONY Minimal waste, self-renewing systems with diverse thriving connections
|
|
# LOVE Be yourself without hurting others, cooperation through natural law
|
|
#
|
|
# This software contributes to that vision by archiving the web, preserving digital knowledge before it disappears.
|
|
# Code is seeds to sprout on any abandoned technology.
|
|
|
|
"""
|
|
Tests for domain_vault module.
|
|
|
|
Tests domain-based vault system for HTML, media, and screenshots.
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
|
import tempfile
|
|
import shutil
|
|
import os
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
from neopig.domain_vault import (
|
|
GitRepo,
|
|
DomainHtmlVault,
|
|
DomainMediaVault,
|
|
DomainLinkpeekVault,
|
|
VaultManager,
|
|
)
|
|
|
|
|
|
class TestGitRepo:
|
|
"""Test GitRepo class."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.repo_path = Path(self.temp_dir) / "test_repo"
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_git_repo_initialization(self):
|
|
"""Test GitRepo initialization."""
|
|
repo = GitRepo(self.repo_path)
|
|
|
|
assert repo.path == self.repo_path
|
|
assert repo.use_lfs is False
|
|
|
|
def test_git_repo_with_lfs(self):
|
|
"""Test GitRepo with LFS enabled."""
|
|
repo = GitRepo(self.repo_path, use_lfs=True)
|
|
|
|
assert repo.use_lfs is True
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_git_repo_init_creates_directory(self):
|
|
"""Test that init creates the directory."""
|
|
repo = GitRepo(self.repo_path)
|
|
|
|
with patch.object(repo, '_run', new_callable=AsyncMock) as mock_run:
|
|
mock_run.return_value = (b'', b'')
|
|
await repo.init()
|
|
|
|
assert self.repo_path.exists()
|
|
|
|
|
|
class TestDomainHtmlVault:
|
|
"""Test DomainHtmlVault class."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.vault_base = os.path.join(self.temp_dir, "vault")
|
|
self.domain = "example.com"
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_html_vault_initialization(self):
|
|
"""Test DomainHtmlVault initialization."""
|
|
vault = DomainHtmlVault(self.vault_base, self.domain)
|
|
|
|
assert vault.domain == self.domain.lower()
|
|
assert vault.media_base_url == '/media'
|
|
|
|
def test_html_vault_media_base_url(self):
|
|
"""Test custom media base URL."""
|
|
vault = DomainHtmlVault(
|
|
self.vault_base,
|
|
self.domain,
|
|
media_base_url="/assets"
|
|
)
|
|
|
|
assert vault.media_base_url == "/assets"
|
|
|
|
def test_get_media_vault_url(self):
|
|
"""Test media URL rewriting."""
|
|
vault = DomainHtmlVault(self.vault_base, self.domain)
|
|
|
|
media_url = "https://example.com/images/photo.jpg"
|
|
result = vault.get_media_vault_url(media_url)
|
|
|
|
assert vault.media_base_url in result
|
|
assert "photo.jpg" in result or "images" in result
|
|
|
|
def test_rewrite_media_urls(self):
|
|
"""Test HTML media URL rewriting."""
|
|
vault = DomainHtmlVault(self.vault_base, self.domain)
|
|
|
|
html = '<img src="https://example.com/photo.jpg">'
|
|
mappings = {"https://example.com/photo.jpg": "/media/abc123.jpg"}
|
|
|
|
result = vault.rewrite_media_urls(html, "https://example.com/", mappings)
|
|
|
|
# Should contain the rewritten URL
|
|
assert "/media/abc123.jpg" in result
|
|
|
|
|
|
class TestDomainMediaVault:
|
|
"""Test DomainMediaVault class."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.vault_base = os.path.join(self.temp_dir, "vault")
|
|
self.domain = "example.com"
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_media_vault_initialization(self):
|
|
"""Test DomainMediaVault initialization."""
|
|
vault = DomainMediaVault(self.vault_base, self.domain)
|
|
|
|
assert vault.domain == self.domain.lower()
|
|
|
|
|
|
class TestDomainLinkpeekVault:
|
|
"""Test DomainLinkpeekVault class."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.vault_base = os.path.join(self.temp_dir, "vault")
|
|
self.domain = "example.com"
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_linkpeek_vault_initialization(self):
|
|
"""Test DomainLinkpeekVault initialization."""
|
|
vault = DomainLinkpeekVault(self.vault_base, self.domain)
|
|
|
|
assert vault.domain == self.domain.lower()
|
|
|
|
def test_url_to_screenshot_path(self):
|
|
"""Test URL to screenshot path conversion."""
|
|
vault = DomainLinkpeekVault(self.vault_base, self.domain)
|
|
|
|
url = "https://example.com/page"
|
|
path = vault.url_to_screenshot_path(url)
|
|
|
|
# Should generate a path ending in .png
|
|
assert path.endswith('.png')
|
|
|
|
|
|
class TestVaultManager:
|
|
"""Test VaultManager class."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.html_base = os.path.join(self.temp_dir, "html_vault")
|
|
self.media_base = os.path.join(self.temp_dir, "media_vault")
|
|
self.linkpeek_base = os.path.join(self.temp_dir, "linkpeek_vault")
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_vault_manager_initialization(self):
|
|
"""Test VaultManager initialization."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
assert str(manager.html_base) == self.html_base
|
|
|
|
def test_vault_manager_default_init(self):
|
|
"""Test VaultManager with defaults."""
|
|
manager = VaultManager()
|
|
|
|
assert manager.html_base == Path('html_vault')
|
|
assert manager.media_base == Path('media_vault')
|
|
assert manager.linkpeek_base == Path('linkpeek_vault')
|
|
|
|
def test_get_html_vault(self):
|
|
"""Test getting HTML vault for domain."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
vault = manager.get_html_vault("example.com")
|
|
|
|
assert isinstance(vault, DomainHtmlVault)
|
|
assert vault.domain == "example.com"
|
|
|
|
def test_get_html_vault_caches(self):
|
|
"""Test that HTML vaults are cached."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
vault1 = manager.get_html_vault("example.com")
|
|
vault2 = manager.get_html_vault("example.com")
|
|
|
|
assert vault1 is vault2
|
|
|
|
def test_get_html_vault_case_insensitive(self):
|
|
"""Test that domain lookup is case insensitive."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
vault1 = manager.get_html_vault("Example.COM")
|
|
vault2 = manager.get_html_vault("example.com")
|
|
|
|
assert vault1 is vault2
|
|
assert vault1.domain == "example.com"
|
|
|
|
def test_get_media_vault(self):
|
|
"""Test getting media vault for domain."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
vault = manager.get_media_vault("example.com")
|
|
|
|
assert isinstance(vault, DomainMediaVault)
|
|
assert vault.domain == "example.com"
|
|
|
|
def test_get_linkpeek_vault(self):
|
|
"""Test getting linkpeek vault for domain."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
vault = manager.get_linkpeek_vault("example.com")
|
|
|
|
assert isinstance(vault, DomainLinkpeekVault)
|
|
assert vault.domain == "example.com"
|
|
|
|
def test_get_vaults_for_url(self):
|
|
"""Test getting all vaults for a URL."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
html_vault, media_vault, linkpeek_vault = manager.get_vaults_for_url(
|
|
"https://example.com/page"
|
|
)
|
|
|
|
assert isinstance(html_vault, DomainHtmlVault)
|
|
assert isinstance(media_vault, DomainMediaVault)
|
|
assert isinstance(linkpeek_vault, DomainLinkpeekVault)
|
|
assert html_vault.domain == "example.com"
|
|
|
|
def test_get_linkpeek_url(self):
|
|
"""Test generating linkpeek URL."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
linkpeek_base_url="/screenshots"
|
|
)
|
|
|
|
url = manager.get_linkpeek_url("https://example.com/page")
|
|
|
|
assert "/screenshots/" in url
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_domains_empty(self):
|
|
"""Test listing domains on empty vault."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
# Create the base directory
|
|
os.makedirs(self.html_base, exist_ok=True)
|
|
|
|
domains = await manager.list_domains("html")
|
|
|
|
assert domains == []
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_all_stats(self):
|
|
"""Test getting all stats."""
|
|
manager = VaultManager(
|
|
html_vault_base=self.html_base,
|
|
media_vault_base=self.media_base,
|
|
linkpeek_vault_base=self.linkpeek_base,
|
|
)
|
|
|
|
# Create base directories
|
|
os.makedirs(self.html_base, exist_ok=True)
|
|
os.makedirs(self.media_base, exist_ok=True)
|
|
os.makedirs(self.linkpeek_base, exist_ok=True)
|
|
|
|
stats = await manager.get_all_stats()
|
|
|
|
assert 'html_vaults' in stats
|
|
assert 'media_vaults' in stats
|
|
assert 'linkpeek_vaults' in stats
|
|
|
|
|
|
class TestVaultManagerDomainExtraction:
|
|
"""Test domain extraction from URLs."""
|
|
|
|
def setup_method(self):
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.manager = VaultManager(
|
|
html_vault_base=os.path.join(self.temp_dir, "html"),
|
|
media_vault_base=os.path.join(self.temp_dir, "media"),
|
|
linkpeek_vault_base=os.path.join(self.temp_dir, "linkpeek"),
|
|
)
|
|
|
|
def teardown_method(self):
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_extract_domain_basic(self):
|
|
"""Test extracting domain from basic URL."""
|
|
vault = self.manager.get_html_vault("example.com")
|
|
assert vault.domain == "example.com"
|
|
|
|
def test_vaults_for_subdomain(self):
|
|
"""Test getting vaults for subdomain."""
|
|
html, media, linkpeek = self.manager.get_vaults_for_url(
|
|
"https://sub.example.com/page"
|
|
)
|
|
|
|
assert html.domain == "sub.example.com"
|
|
assert media.domain == "sub.example.com"
|
|
|
|
def test_vaults_for_url_with_port(self):
|
|
"""Test getting vaults for URL with port."""
|
|
html, media, linkpeek = self.manager.get_vaults_for_url(
|
|
"https://example.com:8080/page"
|
|
)
|
|
|
|
# Domain includes port
|
|
assert "example.com" in html.domain
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v'])
|