zotero-addons-scraper/tests/unit/test_parsers.py
2025-12-23 16:22:54 +08:00

150 lines
5.1 KiB
Python

"""Unit tests for parsers."""
import json
import tempfile
import zipfile
from pathlib import Path
import pytest
from zotero_scraper.models.xpi import XpiDetail
from zotero_scraper.parsers.manifest import JsonManifestParser, RdfManifestParser
from zotero_scraper.parsers.xpi_parser import XPIParser
class TestJsonManifestParser:
"""Tests for JsonManifestParser."""
@pytest.fixture
def parser(self):
return JsonManifestParser()
@pytest.fixture
def sample_xpi(self, sample_manifest_json, temp_dir):
"""Create a sample XPI file with manifest.json."""
xpi_path = temp_dir / "test.xpi"
with zipfile.ZipFile(xpi_path, "w") as zf:
zf.writestr("manifest.json", json.dumps(sample_manifest_json))
return xpi_path
def test_parse_from_xpi(self, parser, sample_xpi, sample_manifest_json):
"""Test parsing manifest.json from XPI file."""
manifest = parser.parse(sample_xpi)
assert manifest is not None
assert manifest["name"] == sample_manifest_json["name"]
assert manifest["version"] == sample_manifest_json["version"]
def test_parse_from_directory(self, parser, sample_manifest_json, temp_dir):
"""Test parsing manifest.json from directory."""
manifest_path = temp_dir / "manifest.json"
with open(manifest_path, "w") as f:
json.dump(sample_manifest_json, f)
manifest = parser.parse(temp_dir)
assert manifest is not None
assert manifest["name"] == sample_manifest_json["name"]
def test_parse_nonexistent(self, parser, temp_dir):
"""Test parsing from nonexistent path."""
manifest = parser.parse(temp_dir / "nonexistent.xpi")
assert manifest is None
def test_extract_details(self, parser, sample_xpi, sample_manifest_json):
"""Test extracting details from manifest."""
manifest = parser.parse(sample_xpi)
details = parser.extract_details(sample_xpi, manifest)
assert details["name"] == "Test Addon"
assert details["version"] == "1.0.0"
assert details["id"] == "test@addon.com"
assert details["min_version"] == "6.0"
assert details["max_version"] == "7.*"
class TestXpiDetail:
"""Tests for XpiDetail model."""
def test_append_info(self):
"""Test appending info to XpiDetail."""
detail = XpiDetail()
detail.append_info({
"id": "test@addon.com",
"name": "Test Addon",
"version": "1.0.0",
"min_version": "6.0",
"max_version": "7.*",
})
assert detail.id == "test@addon.com"
assert detail.name == "Test Addon"
assert detail.version == "1.0.0"
assert detail.min_version == "6.0"
assert detail.max_version == "7.*"
def test_check_compatible_zotero7(self):
"""Test compatibility check for Zotero 7."""
detail = XpiDetail()
detail.min_version = "7.0"
detail.max_version = "7.*"
assert detail.check_compatible("7.*") is True
assert detail.check_compatible("6.*") is False
def test_check_compatible_both_versions(self):
"""Test compatibility check for both Zotero versions."""
detail = XpiDetail()
detail.min_version = "6.0"
detail.max_version = "7.*"
assert detail.check_compatible("7.*") is True
assert detail.check_compatible("6.*") is True
def test_is_valid(self):
"""Test validity check."""
detail = XpiDetail()
assert detail.is_valid() is False
detail.id = "test@addon.com"
assert detail.is_valid() is True
class TestXPIParser:
"""Tests for XPIParser."""
@pytest.fixture
def parser(self):
return XPIParser()
def test_parse_json_manifest(self, parser, sample_manifest_json, temp_dir):
"""Test parsing XPI with JSON manifest."""
xpi_path = temp_dir / "test.xpi"
with zipfile.ZipFile(xpi_path, "w") as zf:
zf.writestr("manifest.json", json.dumps(sample_manifest_json))
details = parser.parse(xpi_path)
assert details is not None
assert details.id == "test@addon.com"
assert details.name == "Test Addon"
def test_parse_nonexistent_raises(self, parser, temp_dir):
"""Test parsing nonexistent file raises error."""
from zotero_scraper.exceptions import XPIParseError
with pytest.raises(XPIParseError):
parser.parse(temp_dir / "nonexistent.xpi")
def test_parse_priority_sources(self, parser, sample_manifest_json, temp_dir):
"""Test priority sources parameter."""
xpi_path = temp_dir / "test.xpi"
with zipfile.ZipFile(xpi_path, "w") as zf:
zf.writestr("manifest.json", json.dumps(sample_manifest_json))
# Should work with json priority
details = parser.parse(xpi_path, priority_sources=["json"])
assert details is not None
assert details.id == "test@addon.com"
# Should return None with only rdf priority (no install.rdf)
details = parser.parse(xpi_path, priority_sources=["rdf"])
assert details is None