import pytest from django.contrib.auth import get_user_model from django.test import RequestFactory from archivebox.config import views as config_views from archivebox.plugins import views as plugin_views from archivebox.core import views as core_views from archivebox.config import CONSTANTS from archivebox.machine.models import Machine from archivebox.tests.conftest import install_real_binary pytestmark = pytest.mark.django_db User = get_user_model() @pytest.fixture def admin_user(): return User.objects.create_superuser( username="configviewadmin", email="configviewadmin@test.com", password="testpassword", ) @pytest.fixture def admin_request(admin_user): def request_for(path: str): request = RequestFactory().get(path) request.user = admin_user return request return request_for @pytest.fixture def machine(): return Machine.current(refresh=True) @pytest.mark.django_db(transaction=True) def test_get_db_binaries_by_name_collapses_youtube_dl_aliases(machine): install_real_binary( "youtube-dl", machine=machine, binproviders="env,uv,brew", overrides={"uv": {"install_args": ["youtube_dl"]}}, ) ytdlp = install_real_binary( "yt-dlp", machine=machine, binproviders="env,uv,brew", overrides={"uv": {"install_args": ["yt-dlp[default]"]}}, ) binaries = config_views.get_db_binaries_by_name() assert "yt-dlp" in binaries assert "youtube-dl" not in binaries assert binaries["yt-dlp"].id == ytdlp.id assert binaries["yt-dlp"].version == ytdlp.version assert binaries["yt-dlp"].abspath == ytdlp.abspath @pytest.mark.django_db(transaction=True) def test_binaries_list_view_uses_db_version_and_hides_youtube_dl_alias(admin_request, machine): binary = install_real_binary( "youtube-dl", machine=machine, binproviders="env,uv,brew", overrides={"uv": {"install_args": ["youtube_dl"]}}, ) context = config_views.binaries_list_view.__wrapped__(admin_request("/admin/environment/binaries/")) assert len(context["table"]["Binary Name"]) == 1 assert str(context["table"]["Binary Name"][0].link_item) == "yt-dlp" assert context["table"]["Found Version"][0] == f"✅ {binary.version}" assert context["table"]["Provided By"][0] == binary.binprovider assert context["table"]["Found Abspath"][0] == binary.abspath def test_binaries_list_view_only_shows_persisted_records(admin_request): context = config_views.binaries_list_view.__wrapped__(admin_request("/admin/environment/binaries/")) assert context["table"]["Binary Name"] == [] assert context["table"]["Found Version"] == [] assert context["table"]["Provided By"] == [] assert context["table"]["Found Abspath"] == [] @pytest.mark.django_db(transaction=True) def test_binary_detail_view_uses_canonical_db_record(admin_request, machine): db_binary = install_real_binary( "yt-dlp", machine=machine, binproviders="env,uv,brew", overrides={"uv": {"install_args": ["yt-dlp[default]"]}}, ) context = config_views.binary_detail_view.__wrapped__(admin_request("/admin/environment/binaries/youtube-dl/"), key="youtube-dl") section = context["data"][0] assert context["title"] == "yt-dlp" assert section["fields"]["name"] == "yt-dlp" assert section["fields"]["version"] == db_binary.version assert section["fields"]["binprovider"] == db_binary.binprovider assert section["fields"]["abspath"] == db_binary.abspath assert f"/admin/machine/binary/{db_binary.id}/change/?_changelist_filters=q%3Dyt-dlp" in section["description"] def test_binary_detail_view_marks_unrecorded_binary(admin_request): context = config_views.binary_detail_view.__wrapped__(admin_request("/admin/environment/binaries/wget/"), key="wget") section = context["data"][0] assert section["description"] == "No persisted Binary record found" assert section["fields"]["status"] == "unrecorded" assert section["fields"]["binprovider"] == "not recorded" def test_plugin_detail_view_renders_shipped_plugin_config_in_dedicated_sections(admin_request, machine): context = plugin_views.plugin_detail_view.__wrapped__(admin_request("/admin/environment/plugins/builtin.wget/"), key="builtin.wget") assert context["title"] == "wget" assert len(context["data"]) == 5 summary_section, hooks_section, metadata_section, config_section, properties_section = context["data"] assert summary_section["fields"] == { "id": "builtin.wget", "name": "wget", "source": "builtin", } assert "abx_plugins/plugins/wget" in summary_section["description"] assert "https://archivebox.github.io/abx-plugins/#wget" in summary_section["description"] assert hooks_section["name"] == "Hooks" assert hooks_section["fields"] == {} assert "on_Snapshot__35_wget.finite.bg.py" in hooks_section["description"] assert metadata_section["name"] == "Plugin Metadata" assert metadata_section["fields"] == {} assert "Archive pages and their requisites with wget" in metadata_section["description"] assert "WGET_BINARY" in metadata_section["description"] assert "text/html" in metadata_section["description"] assert "application/warc" in metadata_section["description"] assert config_section["name"] == "config.json" assert config_section["fields"] == {} assert "
"properties"' in config_section["description"]
assert properties_section["name"] == "Config Properties"
assert properties_section["fields"] == {}
assert f"/admin/machine/machine/{machine.id}/change/" in properties_section["description"]
assert "/admin/machine/binary/" in properties_section["description"]
assert "/admin/environment/binaries/" in properties_section["description"]
assert "WGET_ENABLED" in properties_section["description"]
assert "boolean" in properties_section["description"]
assert "Enable wget archiving" in properties_section["description"]
assert "/admin/environment/config/WGET_ENABLED/" in properties_section["description"]
assert "/admin/environment/config/CHECK_SSL_VALIDITY/" in properties_section["description"]
assert "/admin/environment/config/SAVE_WGET/" in properties_section["description"]
assert "/admin/environment/binaries/wget/" in properties_section["description"]
assert "WGET_BINARY" in properties_section["description"]
def test_get_config_definition_link_keeps_core_config_search_link():
url, label = core_views.get_config_definition_link("CHECK_SSL_VALIDITY")
assert "github.com/search" in url
assert "CHECK_SSL_VALIDITY" in url
assert label == "archivebox/config"
def test_get_config_definition_link_uses_plugin_config_json_for_plugin_options():
url, label = core_views.get_config_definition_link("PARSE_DOM_OUTLINKS_ENABLED")
assert url == "https://github.com/ArchiveBox/abx-plugins/tree/main/abx_plugins/plugins/parse_dom_outlinks/config.json"
assert label == "abx_plugins/plugins/parse_dom_outlinks/config.json"
def test_live_config_value_view_renames_source_field_and_uses_plugin_definition_link(admin_request):
context = core_views.live_config_value_view.__wrapped__(
admin_request("/admin/environment/config/PARSE_DOM_OUTLINKS_ENABLED/"),
key="PARSE_DOM_OUTLINKS_ENABLED",
)
section = context["data"][0]
assert "Currently read from" in section["fields"]
assert "Source" not in section["fields"]
assert section["fields"]["Currently read from"] == "Plugin Default"
assert "abx_plugins/plugins/parse_dom_outlinks/config.json" in section["help_texts"]["Type"]
def test_live_config_list_view_escapes_machine_config_values(admin_request, machine):
payload = ''
machine.config = {"USER_AGENT": payload}
machine.save(update_fields=["config"])
context = core_views.live_config_list_view.__wrapped__(admin_request("/admin/environment/config/"))
keys = [str(item.link_item) for item in context["table"]["Key"]]
value_cell = str(context["table"]["Value"][keys.index("USER_AGENT")])
assert ''
machine.config = {"USER_AGENT": payload}
machine.save(update_fields=["config"])
context = core_views.live_config_value_view.__wrapped__(
admin_request("/admin/environment/config/USER_AGENT/"),
key="USER_AGENT",
)
section = context["data"][0]
assert section["fields"]["Currently read from"] == "Machine"
assert section["fields"]["Value"] == payload
help_text = str(section["help_texts"]["Value"])
assert '