{
"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"
}
}
{
"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
}
}