Каталог тестов¶
Каталог содержит 108 test functions. Parametrization может превращать одну функцию в несколько pytest cases, поэтому число runtime tests обычно больше.
tests/api/test_api.py¶
Уровень: api · cases: 15
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_live_health_does_not_require_dependencies |
Проверяет: live health выполняет не require dependencies. | — |
L107–L113 |
test_ready_health_success |
Проверяет: ready health success. | — |
L116–L121 |
test_ready_health_db_failure_is_503 |
Проверяет: ready health db failure is 503. | — |
L124–L129 |
test_missing_api_key_is_401 |
Проверяет: missing api key is 401. | — |
L132–L137 |
test_unknown_api_key_is_401 |
Проверяет: unknown api key is 401. | — |
L140–L149 |
test_disabled_api_key_is_403 |
Проверяет: disabled api key is 403. | — |
L152–L163 |
test_search_contract_and_rate_headers |
Проверяет: search contract and rate headers. | — |
L166–L181 |
test_search_and_ask_share_counter_and_sixth_is_429 |
Проверяет: search and ask share counter and sixth is 429. | — |
L184–L195 |
test_ask_limit_is_at_most_five_while_search_accepts_ten |
Проверяет: ask limit is at most five while search accepts ten. | — |
L198–L209 |
test_validation_error_is_stable |
Проверяет: validation error is stable. | — |
L212–L221 |
test_static_ui_and_assets_are_local |
Проверяет: static ui and assets are local. | — |
L224–L235 |
test_openapi_contains_required_routes |
Проверяет: openapi contains required routes. | — |
L238–L245 |
test_tender_details_are_sanitized |
Проверяет: tender details are sanitized. | — |
L270–L311 |
test_unknown_tender_is_404 |
Проверяет: unknown tender is 404. | — |
L314–L325 |
test_internal_exception_is_hidden |
Проверяет: internal exception is hidden. | — |
L328–L353 |
tests/e2e/test_fixture_pipeline.py¶
Уровень: e2e · cases: 3
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_fixture_to_database_index_search_and_ask |
Проверяет: fixture to database index search and ask. | pytest.mark.asyncio, pytest.mark.parametrize('source,fixture_name,query', [('ted', 'ted_search_response.json', 'server equipment storage warranty'), ('contracts_finder', 'contracts_finder_ocds.json', 'rack servers network storage')]) |
L83–L136 |
test_repeat_fixture_crawl_does_not_create_duplicate_event |
Проверяет: repeat fixture crawl выполняет не create duplicate событие. | pytest.mark.asyncio |
L140–L169 |
test_real_nats_to_indexer_to_protected_api_pipeline |
Проверяет: real nats to indexer to protected api pipeline. | pytest.mark.asyncio |
L173–L265 |
tests/integration/test_database_pipeline.py¶
Уровень: integration · cases: 12
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_migration_created_exact_tables_and_vector_extension |
Проверяет: migration created exact tables and vector extension. | pytest.mark.asyncio |
L96–L114 |
test_new_unchanged_changed_upsert |
Проверяет: new unchanged changed upsert. | pytest.mark.asyncio |
L118–L138 |
test_same_external_id_is_independent_between_sources |
Проверяет: одинаковый external id is independent between sources. | pytest.mark.asyncio |
L142–L163 |
test_cursor_advances_only_after_processed_page |
Проверяет: cursor advances only после processed page. | pytest.mark.asyncio |
L167–L184 |
test_cursor_is_not_advanced_after_record_failure |
Проверяет: cursor is не advanced после record failure. | pytest.mark.asyncio |
L188–L208 |
test_pending_event_is_republished_after_publish_failure |
Проверяет: pending событие is republished после publish failure. | pytest.mark.asyncio |
L212–L228 |
test_indexer_idempotency_and_exact_search |
Проверяет: indexer idempotency and exact search. | pytest.mark.asyncio |
L232–L263 |
test_indexer_batches_embeddings |
Проверяет: indexer batches embeddings. | pytest.mark.asyncio |
L267–L292 |
test_stale_event_does_not_overwrite_new_version |
Проверяет: stale событие выполняет не overwrite new version. | pytest.mark.asyncio |
L296–L315 |
test_old_failed_event_does_not_mark_new_version_failed |
Проверяет: old failed событие выполняет не mark new version failed. | pytest.mark.asyncio |
L319–L348 |
test_irrelevant_question_skips_generation |
Проверяет: irrelevant question skips generation. | pytest.mark.asyncio |
L352–L405 |
test_rate_limiter_is_atomic_under_concurrency |
Проверяет: rate limiter is atomic under concurrency. | pytest.mark.asyncio |
L409–L437 |
tests/integration/test_nats.py¶
Уровень: integration · cases: 2
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_jetstream_publish_consume_and_ack |
Проверяет: jetstream publish consume and ack. | pytest.mark.asyncio |
L15–L33 |
test_stream_initialization_is_idempotent |
Проверяет: stream initialization is idempotent. | pytest.mark.asyncio |
L37–L45 |
tests/unit/test_adapters.py¶
Уровень: unit · cases: 12
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_ted_fixture_mapping |
Проверяет: ted fixture mapping. | — |
L25–L34 |
test_contracts_finder_fixture_mapping |
Проверяет: contracts finder fixture mapping. | — |
L37–L43 |
test_contracts_finder_allows_known_official_attachment_hosts |
Проверяет: contracts finder allows known official вложение hosts. | — |
L46–L52 |
test_common_adapter_contract |
Проверяет: common adapter contract. | pytest.mark.parametrize('mapper,fixture_name,collection', [(TedAdapter.map_notice, 'ted_search_response.json', 'notices'), (ContractsFinderAdapter.map_release, 'contracts_finder_ocds.json', 'releases')]) |
L62–L70 |
test_missing_optional_contracts_finder_fields_are_none |
Проверяет: missing optional contracts finder fields are none. | — |
L73–L81 |
test_ted_request_uses_iteration_token_and_caps_limit |
Проверяет: ted request uses iteration token and caps limit. | pytest.mark.asyncio |
L85–L110 |
test_contracts_finder_uses_cursor_and_limit |
Проверяет: contracts finder uses cursor and limit. | pytest.mark.asyncio |
L114–L139 |
test_ted_invalid_notice_is_skipped_and_logged |
Проверяет: ted невалидный notice is skipped and logged. | pytest.mark.asyncio |
L143–L173 |
test_contracts_finder_invalid_release_is_skipped_and_logged |
Проверяет: contracts finder невалидный release is skipped and logged. | pytest.mark.asyncio |
L177–L206 |
test_empty_source_pages_return_no_records |
Проверяет: empty источник pages return no records. | pytest.mark.asyncio |
L210–L250 |
test_ted_maps_current_search_api_fields |
Проверяет: ted maps current search api fields. | — |
L253–L274 |
test_ted_requests_only_current_official_field_names |
Проверяет: ted requests only current official field names. | pytest.mark.asyncio |
L278–L307 |
tests/unit/test_ai_and_search.py¶
Уровень: unit · cases: 7
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_fake_embeddings_are_deterministic_and_semantic_enough |
Проверяет: fake embeddings are deterministic and semantic enough. | pytest.mark.asyncio |
L15–L22 |
test_ollama_embed_sends_one_batch_request |
Проверяет: ollama embed sends one batch request. | pytest.mark.asyncio |
L26–L43 |
test_ollama_rejects_wrong_embedding_shape |
Проверяет: ollama отклоняется wrong embedding shape. | pytest.mark.asyncio |
L47–L60 |
test_ollama_generate_and_health |
Проверяет: ollama generate and health. | pytest.mark.asyncio |
L64–L79 |
test_ollama_http_error_is_dependency_error |
Проверяет: ollama http error is dependency error. | pytest.mark.asyncio |
L83–L96 |
test_rag_prompt_marks_documents_as_untrusted_data |
Проверяет: rag prompt marks documents as untrusted data. | — |
L110–L115 |
test_vector_literal_is_stable |
Проверяет: vector literal is stable. | — |
L118–L119 |
tests/unit/test_auth_and_rate_limit.py¶
Уровень: unit · cases: 5
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_generated_key_has_prefix_entropy_and_matching_hash |
Проверяет: generated key has prefix entropy and matching hash. | — |
L31–L38 |
test_minute_start_is_utc_and_truncated |
Проверяет: minute start is utc and truncated. | — |
L41–L43 |
test_first_five_requests_pass_and_sixth_fails |
Проверяет: first five requests pass and sixth fails. | pytest.mark.asyncio |
L47–L57 |
test_counter_resets_in_new_utc_minute |
Проверяет: counter resets in new utc minute. | pytest.mark.asyncio |
L61–L74 |
test_two_keys_have_independent_state |
Проверяет: two keys have independent state. | pytest.mark.asyncio |
L78–L86 |
tests/unit/test_cli.py¶
Уровень: unit · cases: 2
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_cli_limit_accepts_supported_range |
Проверяет: cli limit accepts supported range. | — |
L10–L14 |
test_cli_limit_rejects_invalid_values |
Проверяет: cli limit отклоняется невалидный values. | pytest.mark.parametrize('raw', ['0', '1001', 'not-a-number']) |
L18–L20 |
tests/unit/test_extraction_and_chunking.py¶
Уровень: unit · cases: 12
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_metadata_has_labels |
Проверяет: metadata has labels. | — |
L38–L59 |
test_text_pdf_is_extracted |
Проверяет: text pdf is extracted. | — |
L62–L66 |
test_malformed_pdf_raises_typed_error |
Проверяет: malformed pdf raises typed error. | — |
L69–L73 |
test_xml_does_not_resolve_external_entity |
Проверяет: xml выполняет не resolve external entity. | — |
L76–L79 |
test_html_removes_script_and_style |
Проверяет: html removes script and style. | — |
L82–L87 |
test_json_and_text_extraction |
Проверяет: json and text extraction. | — |
L90–L94 |
test_unsupported_binary_is_skipped |
Проверяет: unsupported binary is skipped. | — |
L97–L99 |
test_missing_file_is_typed_error |
Проверяет: missing file is typed error. | — |
L102–L105 |
test_short_text_creates_one_chunk |
Проверяет: short text создаётся one chunk. | — |
L108–L111 |
test_long_text_respects_limit_and_overlap |
Проверяет: long text respects limit and overlap. | — |
L114–L121 |
test_chunking_is_deterministic_and_keeps_unicode |
Проверяет: chunking is deterministic and keeps unicode. | — |
L124–L129 |
test_invalid_chunk_settings |
Проверяет: невалидный chunk settings. | pytest.mark.parametrize('max_chars,overlap', [(50, 0), (100, 100), (100, -1)]) |
L133–L135 |
tests/unit/test_http_and_storage.py¶
Уровень: unit · cases: 15
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_safe_filename |
Проверяет: safe filename. | pytest.mark.parametrize('value,expected', [('../../secret.pdf', 'secret.pdf'), ('C:\\temp\\x.pdf', 'x.pdf'), ('..', 'attachment.bin'), ('a\x00b?.pdf', 'ab_.pdf')]) |
L50–L51 |
test_http_concurrency_is_bounded |
Проверяет: http concurrency is bounded. | pytest.mark.asyncio |
L55–L73 |
test_retry_after_is_respected |
Проверяет: retry после is respected. | pytest.mark.asyncio |
L77–L94 |
test_optional_403_cooldown_is_respected |
Проверяет: optional 403 cooldown is respected. | pytest.mark.asyncio |
L98–L120 |
test_403_without_source_cooldown_is_not_retried |
Проверяет: 403 без источник cooldown is не retried. | pytest.mark.asyncio |
L124–L136 |
test_network_timeout_is_retried_then_fails |
Проверяет: network timeout is retried then fails. | pytest.mark.asyncio |
L140–L151 |
test_redirect_to_unknown_host_is_rejected |
Проверяет: redirect to unknown host is rejected. | pytest.mark.asyncio |
L155–L161 |
test_invalid_json_is_typed_error |
Проверяет: невалидный json is typed error. | pytest.mark.asyncio |
L165–L171 |
test_stream_download_success |
Проверяет: stream download success. | pytest.mark.asyncio |
L175–L197 |
test_declared_large_attachment_fails_before_write |
Проверяет: declared large вложение fails до write. | pytest.mark.asyncio |
L201–L216 |
test_stream_over_limit_removes_temp_file |
Проверяет: stream over limit removes temp file. | pytest.mark.asyncio |
L220–L236 |
test_redirect_to_allowed_host_is_followed |
Проверяет: redirect to allowed host is followed. | pytest.mark.asyncio |
L240–L253 |
test_redirects_do_not_consume_retry_attempts |
Проверяет: redirects do не consume retry attempts. | pytest.mark.asyncio |
L257–L271 |
test_stream_redirects_do_not_consume_retry_attempts |
Проверяет: stream redirects do не consume retry attempts. | pytest.mark.asyncio |
L275–L297 |
test_local_redirect_targets_are_rejected |
Проверяет: local redirect targets are rejected. | pytest.mark.asyncio, pytest.mark.parametrize('url', ['http://localhost/file', 'http://127.0.0.1/file']) |
L302–L308 |
tests/unit/test_nats_message.py¶
Уровень: unit · cases: 1
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_message_supports_ack_retry_and_permanent_termination |
Проверяет: message supports ack retry and permanent termination. | pytest.mark.asyncio |
L25–L33 |
tests/unit/test_project_contract.py¶
Уровень: unit · cases: 10
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_entrypoints_import_without_external_connections |
Проверяет: entrypoints import без external connections. | pytest.mark.parametrize('module', ['tender_lens', 'tender_lens.crawler.__main__', 'tender_lens.indexer.__main__', 'tender_lens.api.main', 'tender_lens.cli']) |
L25–L26 |
test_default_settings_are_valid |
Проверяет: default settings are valid. | — |
L29–L37 |
test_example_environment_file_is_valid |
Проверяет: example environment file is valid. | — |
L40–L43 |
test_invalid_settings_are_rejected |
Проверяет: невалидный settings are rejected. | pytest.mark.parametrize('field,value', [('crawl_max_concurrency', 0), ('attachment_max_concurrency', 0), ('max_attachment_bytes', 10), ('default_rate_limit_per_minute', 0), ('api_port', 70000), ('embedding_dimensions', 768), ('embedding_batch_size', 0), ('ollama_timeout_seconds', 0), ('min_relevance_score', 2)]) |
L60–L62 |
test_json_formatter_has_required_fields_and_masks_secrets |
Проверяет: json formatter has required fields and masks secrets. | — |
L65–L82 |
test_checked_in_json_schemas_are_current |
Проверяет: checked in json schemas are current. | — |
L85–L92 |
test_required_delivery_files_exist_and_are_nonempty |
Проверяет: required delivery files exist and are nonempty. | — |
L95–L113 |
test_static_ui_has_no_remote_dependencies_or_unsafe_rendering |
Проверяет: static ui has no remote dependencies or unsafe rendering. | — |
L116–L129 |
test_shell_scripts_have_valid_shebang |
Проверяет: shell scripts have valid shebang. | — |
L132–L134 |
test_default_ted_query_uses_current_search_field |
Проверяет: default ted запрос uses current search field. | — |
L137–L141 |
tests/unit/test_schemas_and_hashing.py¶
Уровень: unit · cases: 12
| Test | Проверяемое поведение | Mark/decorator | Исходник |
|---|---|---|---|
test_normalized_fixture_is_valid |
Проверяет: normalized fixture is valid. | — |
L22–L27 |
test_required_strings_reject_blank |
Проверяет: required strings reject blank. | pytest.mark.parametrize('field', ['external_id', 'title']) |
L31–L35 |
test_currency_validation |
Проверяет: currency validation. | pytest.mark.parametrize('currency', ['EU', 'EURO', '12A', '€€€']) |
L39–L43 |
test_negative_amount_is_rejected |
Проверяет: negative amount is rejected. | — |
L46–L50 |
test_extra_internal_field_is_rejected |
Проверяет: extra internal field is rejected. | — |
L53–L57 |
test_attachment_normalizes_optional_empty_strings |
Проверяет: вложение normalizes optional empty strings. | — |
L60–L69 |
test_hash_does_not_depend_on_raw_json_key_order |
Проверяет: hash выполняет не depend on raw json key order. | — |
L72–L78 |
test_hash_does_not_depend_on_attachment_order |
Проверяет: hash выполняет не depend on вложение order. | — |
L81–L95 |
test_hash_changes_when_meaningful_field_changes |
Проверяет: hash changes когда meaningful field changes. | — |
L98–L103 |
test_event_rejects_bad_hash_and_extra_field |
Проверяет: событие отклоняется bad hash and extra field. | — |
L106–L118 |
test_chunk_key_is_deterministic |
Проверяет: chunk key is deterministic. | — |
L121–L124 |
test_json_schemas_accept_examples |
Проверяет: json schemas accept examples. | — |
L127–L133 |