Protokoll #33453

ID33453
Zeitstempel2026-04-21 02:26:11.829838
Clientroot
IP62.246.34.195
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens1,871 (Input: 930, Output: 941)
Dauer60 ms
Request-Zeit2026-04-21 02:26:11.829838
Response-Zeit2026-04-21 02:26:11.889495

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/crawler\/tests\/unit\/domain\/test_quality_flag_calculator.py",
        "content": "from __future__ import annotations\n\nfrom src.domain.services.quality_flag_calculator import QualityFlagCalculator\nfrom src.domain.value_objects.head_meta import HeadMeta\nfrom src.domain.value_objects.http_status import HttpStatus\nfrom src.domain.value_objects.meta_robots import parse_meta_robots\nfrom src.domain.value_objects.quality_flag import QualityFlagKey\n\nCALC = QualityFlagCalculator()\nPAGE_URL = \"https:\/\/example.com\/\"\n\n\ndef _head(**o: object) -> HeadMeta:\n    defaults: dict[str, object] = {\n        \"title\": \"A\" * 40,\n        \"description\": \"D\" * 120,\n        \"keywords\": None,\n        \"robots\": None,\n        \"canonical\": PAGE_URL,\n        \"lang\": \"de\",\n        \"charset\": \"utf-8\",\n        \"viewport\": None,\n    }\n    defaults.update(o)\n    return HeadMeta(**defaults)  # type: ignore[arg-type]\n\n\ndef _keys(flags: tuple[object, ...]) -> set[QualityFlagKey]:\n    return {f.key for f in flags}  # type: ignore[attr-defined]\n\n\ndef test_happy_path_has_no_flags() -> None:\n    flags = CALC.calculate(head=_head(), h1_count=1, http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert flags == ()\n\n\ndef test_title_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(title=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_MISSING in _keys(flags)\n\n\ndef test_title_too_short_flag() -> None:\n    flags = CALC.calculate(head=_head(title=\"short\"), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_TOO_SHORT in _keys(flags)\n\n\ndef test_title_too_long_flag() -> None:\n    flags = CALC.calculate(head=_head(title=\"A\" * 90), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_TOO_LONG in _keys(flags)\n\n\ndef test_description_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(description=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.DESCRIPTION_MISSING in _keys(flags)\n\n\ndef test_h1_missing_and_multiple_flags() -> None:\n    zero = CALC.calculate(head=_head(), h1_count=0, http_status=HttpStatus(200), page_url=PAGE_URL)\n    many = CALC.calculate(head=_head(), h1_count=3, http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.H1_MISSING in _keys(zero)\n    assert QualityFlagKey.H1_MULTIPLE in _keys(many)\n\n\ndef test_noindex_flag() -> None:\n    flags = CALC.calculate(head=_head(robots=parse_meta_robots(\"noindex\")), h1_count=1,\n                           http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.NOINDEX in _keys(flags)\n\n\ndef test_canonical_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(canonical=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.CANONICAL_MISSING in _keys(flags)\n\n\ndef test_canonical_not_self_flag() -> None:\n    flags = CALC.calculate(head=_head(canonical=\"https:\/\/other\/\"), h1_count=1,\n                           http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.CANONICAL_NOT_SELF in _keys(flags)\n\n\ndef test_http_error_flag() -> None:\n    flags = CALC.calculate(head=_head(), h1_count=1, http_status=HttpStatus(500),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.HTTP_ERROR in _keys(flags)\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/crawler\/tests\/unit\/domain\/test_quality_flag_calculator.py",
        "content": "from __future__ import annotations\n\nfrom src.domain.services.quality_flag_calculator import QualityFlagCalculator\nfrom src.domain.value_objects.head_meta import HeadMeta\nfrom src.domain.value_objects.http_status import HttpStatus\nfrom src.domain.value_objects.meta_robots import parse_meta_robots\nfrom src.domain.value_objects.quality_flag import QualityFlagKey\n\nCALC = QualityFlagCalculator()\nPAGE_URL = \"https:\/\/example.com\/\"\n\n\ndef _head(**o: object) -> HeadMeta:\n    defaults: dict[str, object] = {\n        \"title\": \"A\" * 40,\n        \"description\": \"D\" * 120,\n        \"keywords\": None,\n        \"robots\": None,\n        \"canonical\": PAGE_URL,\n        \"lang\": \"de\",\n        \"charset\": \"utf-8\",\n        \"viewport\": None,\n    }\n    defaults.update(o)\n    return HeadMeta(**defaults)  # type: ignore[arg-type]\n\n\ndef _keys(flags: tuple[object, ...]) -> set[QualityFlagKey]:\n    return {f.key for f in flags}  # type: ignore[attr-defined]\n\n\ndef test_happy_path_has_no_flags() -> None:\n    flags = CALC.calculate(head=_head(), h1_count=1, http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert flags == ()\n\n\ndef test_title_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(title=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_MISSING in _keys(flags)\n\n\ndef test_title_too_short_flag() -> None:\n    flags = CALC.calculate(head=_head(title=\"short\"), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_TOO_SHORT in _keys(flags)\n\n\ndef test_title_too_long_flag() -> None:\n    flags = CALC.calculate(head=_head(title=\"A\" * 90), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.TITLE_TOO_LONG in _keys(flags)\n\n\ndef test_description_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(description=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.DESCRIPTION_MISSING in _keys(flags)\n\n\ndef test_h1_missing_and_multiple_flags() -> None:\n    zero = CALC.calculate(head=_head(), h1_count=0, http_status=HttpStatus(200), page_url=PAGE_URL)\n    many = CALC.calculate(head=_head(), h1_count=3, http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.H1_MISSING in _keys(zero)\n    assert QualityFlagKey.H1_MULTIPLE in _keys(many)\n\n\ndef test_noindex_flag() -> None:\n    flags = CALC.calculate(head=_head(robots=parse_meta_robots(\"noindex\")), h1_count=1,\n                           http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.NOINDEX in _keys(flags)\n\n\ndef test_canonical_missing_flag() -> None:\n    flags = CALC.calculate(head=_head(canonical=None), h1_count=1, http_status=HttpStatus(200),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.CANONICAL_MISSING in _keys(flags)\n\n\ndef test_canonical_not_self_flag() -> None:\n    flags = CALC.calculate(head=_head(canonical=\"https:\/\/other\/\"), h1_count=1,\n                           http_status=HttpStatus(200), page_url=PAGE_URL)\n    assert QualityFlagKey.CANONICAL_NOT_SELF in _keys(flags)\n\n\ndef test_http_error_flag() -> None:\n    flags = CALC.calculate(head=_head(), h1_count=1, http_status=HttpStatus(500),\n                           page_url=PAGE_URL)\n    assert QualityFlagKey.HTTP_ERROR in _keys(flags)\n",
        "structuredPatch": [],
        "originalFile": null,
        "userModified": false
    }
}
← Vorheriger Zur Liste Nächster →