"""Recognize the observed lookup 404 template without publishing an outage as empty."""
import json
import zipfile
from unittest.mock import Mock
from urllib.parse import parse_qs, urlsplit
import pytest
from apps.parsers.models import ParserSourceArtifact, SroOrganizationLookup
from apps.parsers.registry_snapshots import SnapshotValidationError
from apps.parsers.sro_http import SroHttpClient, SroPage
from apps.parsers.sro_membership import (
SRO_LOOKUP_URL,
parse_sro_lookup,
refresh_sro_membership,
)
from django.utils import timezone
from organizations.models import Organization, OrganizationSourceRecord
from tests.apps.parsers.test_sro_membership import FixtureSite
LOOKUP_TITLE = (
"Проверка членства в реестре СРО, проверить допуск организации в СРО по ИНН"
)
NOT_FOUND_HEADING = "Запрашиваемая страница на сайте отсутствует."
LOOKUP_EMPTY = (
f"
{LOOKUP_TITLE}"
f"{NOT_FOUND_HEADING}
"
).encode()
@pytest.fixture(autouse=True)
def sro_settings(settings):
settings.SRO_DEV_COLLECTION_ENABLED = True
def response_404(body=LOOKUP_EMPTY):
response = Mock(status_code=404, is_redirect=False)
response.iter_content.return_value = [body]
return response
@pytest.mark.parametrize("query", ("1234567890", "1027700132195"))
def test_http_returns_bounded_lookup_404_with_status(query):
response = response_404()
session = Mock()
session.get.return_value = response
url = f"{SRO_LOOKUP_URL}?q={query}&sro_name=&search=Find"
page = SroHttpClient(session=session).get(url)
assert (page.url, page.body, page.status_code) == (url, LOOKUP_EMPTY, 404)
session.get.assert_called_once()
response.close.assert_called_once()
@pytest.mark.parametrize(
"suffix",
(
"/",
"/members/?q=1234567890",
"/proverka_dopuska/extra/?q=1234567890",
"/proverka_dopuska/",
"/proverka_dopuska/?q=12345678901",
"/proverka_dopuska/?q=1234567890&q=",
"/proverka_dopuska/?q=1234567890&q=1027700132195",
"/proverka_dopuska/?q=not-an-identifier",
"/proverka_dopuska/?q=1234567890",
),
)
def test_other_404s_are_not_reclassified_or_read(suffix):
response = response_404()
session = Mock()
session.get.return_value = response
with pytest.raises(SnapshotValidationError, match="^sro_page_not_found$"):
SroHttpClient(session=session).get(f"https://www.reestr-sro.ru{suffix}")
response.iter_content.assert_not_called()
response.close.assert_called_once()
def test_lookup_404_response_body_size_limit(settings):
settings.SRO_HTTP_MAX_RESPONSE_BYTES = 4
response = response_404(b"12345")
session = Mock()
session.get.return_value = response
with pytest.raises(SnapshotValidationError, match="^source_response_too_large$"):
SroHttpClient(session=session).get(f"{SRO_LOOKUP_URL}?q=1234567890")
response.close.assert_called_once()
def test_parser_recognizes_only_observed_negative_404():
page = SroPage(f"{SRO_LOOKUP_URL}?q=1234567890", LOOKUP_EMPTY, status_code=404)
assert parse_sro_lookup(page) == ([], None)
assert SroPage(page.url, b"fixture").status_code == 200
@pytest.mark.parametrize(
"body",
(
b"404 Not Found
",
b"LoginSign in
",
"Ничего не найдено".encode(),
LOOKUP_EMPTY.replace(LOOKUP_TITLE.encode(), b"Other source"),
LOOKUP_EMPTY.replace(NOT_FOUND_HEADING.encode(), b"Captcha"),
LOOKUP_EMPTY.replace(b"