innercontext/.sisyphus/evidence/task-T11-backend-regression.txt
Piotr Oleszczyk dac787b81b test(auth): add multi-user regression coverage
- Enable backend tests in CI (remove if: false)
- Fix test_products_helpers.py to pass current_user parameter
- Fix test_routines_helpers.py to include short_id in products
- Fix llm_context.py to use product_effect_profile correctly
- All 221 tests passing
2026-03-12 16:42:00 +01:00

283 lines
25 KiB
Text

============================= test session starts ==============================
platform darwin -- Python 3.12.12, pytest-9.0.2, pluggy-1.6.0 -- /Users/piotr/dev/innercontext/backend/.venv/bin/python3
cachedir: .pytest_cache
rootdir: /Users/piotr/dev/innercontext/backend
configfile: pyproject.toml
testpaths: tests
plugins: anyio-4.12.1, cov-7.0.0
collecting ... collected 221 items
tests/test_admin_households.py::test_list_users_returns_local_users_with_memberships PASSED [ 0%]
tests/test_admin_households.py::test_create_household_returns_new_household PASSED [ 0%]
tests/test_admin_households.py::test_assign_member_creates_membership PASSED [ 1%]
tests/test_admin_households.py::test_assign_member_rejects_already_assigned_user PASSED [ 1%]
tests/test_admin_households.py::test_assign_member_rejects_unsynced_user PASSED [ 2%]
tests/test_admin_households.py::test_move_member_moves_user_between_households PASSED [ 2%]
tests/test_admin_households.py::test_move_member_rejects_user_without_membership PASSED [ 3%]
tests/test_admin_households.py::test_move_member_rejects_same_household_target PASSED [ 3%]
tests/test_admin_households.py::test_remove_membership_deletes_membership PASSED [ 4%]
tests/test_admin_households.py::test_remove_membership_requires_matching_household PASSED [ 4%]
tests/test_admin_households.py::test_admin_household_routes_forbidden_for_member[get-/admin/users-None] PASSED [ 4%]
tests/test_admin_households.py::test_admin_household_routes_forbidden_for_member[post-/admin/households-None] PASSED [ 5%]
tests/test_admin_households.py::test_admin_household_routes_forbidden_for_member[post-/admin/households/10224193-681a-4152-9f5d-0891985e14b6/members-json_body2] PASSED [ 5%]
tests/test_admin_households.py::test_admin_household_routes_forbidden_for_member[patch-/admin/households/d7b58743-f82d-4443-876b-1d400df1d467/members/aca7a450-3653-4189-9ae7-5ae6c9e7bc49-None] PASSED [ 6%]
tests/test_admin_households.py::test_admin_household_routes_forbidden_for_member[delete-/admin/households/70436972-2a6a-4294-a0d6-d864791866d1/members/da4bec8d-c1ae-43fa-a0ad-05a4d9803918-None] PASSED [ 6%]
tests/test_ai_logs.py::test_list_ai_logs_normalizes_tool_trace_string PASSED [ 7%]
tests/test_ai_logs.py::test_get_ai_log_normalizes_tool_trace_string PASSED [ 7%]
tests/test_auth.py::test_validate_access_token_uses_cached_jwks PASSED [ 8%]
tests/test_auth.py::test_sync_protected_endpoints_create_or_resolve_current_user[/auth/session/sync] PASSED [ 8%]
tests/test_auth.py::test_sync_protected_endpoints_create_or_resolve_current_user[/auth/me] PASSED [ 9%]
tests/test_auth.py::test_unauthorized_protected_endpoints_return_401[/auth/me expects 401] PASSED [ 9%]
tests/test_auth.py::test_unauthorized_protected_endpoints_return_401[/profile expects 401] PASSED [ 9%]
tests/test_auth.py::test_unauthorized_invalid_bearer_token_is_rejected PASSED [ 10%]
tests/test_auth.py::test_require_admin_raises_for_member PASSED [ 10%]
tests/test_authz.py::test_owner_helpers_return_only_owned_records PASSED [ 11%]
tests/test_authz.py::test_admin_helpers_allow_admin_override_for_lookup_and_list PASSED [ 11%]
tests/test_authz.py::test_owner_denied_for_non_owned_lookup_returns_404 PASSED [ 12%]
tests/test_authz.py::test_household_shared_inventory_access_allows_same_household_member PASSED [ 12%]
tests/test_authz.py::test_household_shared_inventory_denied_for_cross_household_member PASSED [ 13%]
tests/test_authz.py::test_household_inventory_update_rules_owner_admin_and_member PASSED [ 13%]
tests/test_authz.py::test_product_visibility_for_owner_admin_and_household_shared PASSED [ 14%]
tests/test_authz.py::test_product_visibility_denied_for_cross_household_member PASSED [ 14%]
tests/test_health.py::test_create_medication_minimal PASSED [ 14%]
tests/test_health.py::test_create_medication_invalid_kind PASSED [ 15%]
tests/test_health.py::test_list_medications_empty PASSED [ 15%]
tests/test_health.py::test_list_filter_kind PASSED [ 16%]
tests/test_health.py::test_list_filter_product_name PASSED [ 16%]
tests/test_health.py::test_get_medication PASSED [ 17%]
tests/test_health.py::test_get_medication_not_found PASSED [ 17%]
tests/test_health.py::test_update_medication PASSED [ 18%]
tests/test_health.py::test_update_medication_not_found PASSED [ 18%]
tests/test_health.py::test_delete_medication_no_usages PASSED [ 19%]
tests/test_health.py::test_delete_medication_with_usages PASSED [ 19%]
tests/test_health.py::test_create_usage PASSED [ 19%]
tests/test_health.py::test_create_usage_medication_not_found PASSED [ 20%]
tests/test_health.py::test_list_usages_empty PASSED [ 20%]
tests/test_health.py::test_list_usages_returns_entries PASSED [ 21%]
tests/test_health.py::test_update_usage PASSED [ 21%]
tests/test_health.py::test_update_usage_not_found PASSED [ 22%]
tests/test_health.py::test_delete_usage PASSED [ 22%]
tests/test_health.py::test_delete_usage_not_found PASSED [ 23%]
tests/test_health.py::test_create_lab_result PASSED [ 23%]
tests/test_health.py::test_create_lab_result_invalid_code PASSED [ 23%]
tests/test_health.py::test_create_lab_result_invalid_flag PASSED [ 24%]
tests/test_health.py::test_list_lab_results_empty PASSED [ 24%]
tests/test_health.py::test_list_filter_test_code PASSED [ 25%]
tests/test_health.py::test_list_filter_flag PASSED [ 25%]
tests/test_health.py::test_list_filter_date_range PASSED [ 26%]
tests/test_health.py::test_list_lab_results_search_and_pagination PASSED [ 26%]
tests/test_health.py::test_list_lab_results_sorted_newest_first PASSED [ 27%]
tests/test_health.py::test_list_lab_results_test_code_sorted_numerically_for_same_date PASSED [ 27%]
tests/test_health.py::test_list_lab_results_latest_only_returns_one_per_test_code PASSED [ 28%]
tests/test_health.py::test_get_lab_result PASSED [ 28%]
tests/test_health.py::test_get_lab_result_not_found PASSED [ 28%]
tests/test_health.py::test_update_lab_result PASSED [ 29%]
tests/test_health.py::test_update_lab_result_can_clear_and_switch_value_type PASSED [ 29%]
tests/test_health.py::test_delete_lab_result PASSED [ 30%]
tests/test_inventory.py::test_get_inventory_by_id PASSED [ 30%]
tests/test_inventory.py::test_get_inventory_not_found PASSED [ 31%]
tests/test_inventory.py::test_update_inventory_opened PASSED [ 31%]
tests/test_inventory.py::test_update_inventory_not_found PASSED [ 32%]
tests/test_inventory.py::test_delete_inventory PASSED [ 32%]
tests/test_inventory.py::test_delete_inventory_not_found PASSED [ 33%]
tests/test_llm_profile_context.py::test_build_user_profile_context_without_data PASSED [ 33%]
tests/test_llm_profile_context.py::test_build_user_profile_context_with_data PASSED [ 33%]
tests/test_product_model.py::test_always_present_keys PASSED [ 34%]
tests/test_product_model.py::test_optional_string_fields_absent_when_none PASSED [ 34%]
tests/test_product_model.py::test_optional_string_fields_present_when_set PASSED [ 35%]
tests/test_product_model.py::test_ph_exact_collapses PASSED [ 35%]
tests/test_product_model.py::test_ph_range PASSED [ 36%]
tests/test_product_model.py::test_ph_only_min PASSED [ 36%]
tests/test_product_model.py::test_ph_only_max PASSED [ 37%]
tests/test_product_model.py::test_actives_pydantic_objects PASSED [ 37%]
tests/test_product_model.py::test_actives_raw_dicts PASSED [ 38%]
tests/test_product_model.py::test_effect_profile_all_zeros_omitted PASSED [ 38%]
tests/test_product_model.py::test_effect_profile_nonzero_included PASSED [ 38%]
tests/test_product_model.py::test_context_rules_all_none_omitted PASSED [ 39%]
tests/test_product_model.py::test_context_rules_with_value PASSED [ 39%]
tests/test_product_model.py::test_safety_dict_present_when_set PASSED [ 40%]
tests/test_product_model.py::test_empty_lists_omitted PASSED [ 40%]
tests/test_product_model.py::test_nonempty_lists_included PASSED [ 41%]
tests/test_products.py::test_create_minimal PASSED [ 41%]
tests/test_products.py::test_create_with_actives PASSED [ 42%]
tests/test_products.py::test_create_invalid_enum PASSED [ 42%]
tests/test_products.py::test_create_missing_required PASSED [ 42%]
tests/test_products.py::test_list_empty PASSED [ 43%]
tests/test_products.py::test_list_returns_created PASSED [ 43%]
tests/test_products.py::test_list_filter_category PASSED [ 44%]
tests/test_products.py::test_list_filter_brand PASSED [ 44%]
tests/test_products.py::test_list_filter_is_medication PASSED [ 45%]
tests/test_products.py::test_list_filter_targets PASSED [ 45%]
tests/test_products.py::test_get_by_id PASSED [ 46%]
tests/test_products.py::test_get_not_found PASSED [ 46%]
tests/test_products.py::test_update_name PASSED [ 47%]
tests/test_products.py::test_update_json_field PASSED [ 47%]
tests/test_products.py::test_update_not_found PASSED [ 47%]
tests/test_products.py::test_delete PASSED [ 48%]
tests/test_products.py::test_delete_not_found PASSED [ 48%]
tests/test_products.py::test_list_inventory_empty PASSED [ 49%]
tests/test_products.py::test_list_inventory_product_not_found PASSED [ 49%]
tests/test_products.py::test_create_inventory PASSED [ 50%]
tests/test_products.py::test_create_inventory_product_not_found PASSED [ 50%]
tests/test_products.py::test_parse_text_accepts_numeric_strength_levels PASSED [ 51%]
tests/test_products_auth.py::test_product_endpoints_require_authentication PASSED [ 51%]
tests/test_products_auth.py::test_shared_product_visible_in_summary_marks_is_owned_false PASSED [ 52%]
tests/test_products_auth.py::test_shared_product_visible_filters_private_inventory_rows PASSED [ 52%]
tests/test_products_auth.py::test_shared_inventory_update_allows_household_member PASSED [ 52%]
tests/test_products_auth.py::test_household_member_cannot_edit_shared_product PASSED [ 53%]
tests/test_products_auth.py::test_household_member_cannot_delete_shared_product PASSED [ 53%]
tests/test_products_auth.py::test_household_member_cannot_create_or_delete_inventory_on_shared_product PASSED [ 54%]
tests/test_products_auth.py::test_household_member_cannot_update_non_shared_inventory PASSED [ 54%]
tests/test_products_helpers.py::test_build_shopping_context PASSED [ 55%]
tests/test_products_helpers.py::test_build_shopping_context_flags_replenishment_signal PASSED [ 55%]
tests/test_products_helpers.py::test_compute_replenishment_score_prefers_recent_staples_without_backup PASSED [ 56%]
tests/test_products_helpers.py::test_compute_replenishment_score_downranks_sealed_backup_and_stale_usage PASSED [ 56%]
tests/test_products_helpers.py::test_compute_days_since_last_used_returns_none_without_usage PASSED [ 57%]
tests/test_products_helpers.py::test_suggest_shopping PASSED [ 57%]
tests/test_products_helpers.py::test_suggest_shopping_invalid_json_returns_502 PASSED [ 57%]
tests/test_products_helpers.py::test_suggest_shopping_invalid_schema_returns_502 PASSED [ 58%]
tests/test_products_helpers.py::test_suggest_shopping_invalid_target_concern_returns_502 PASSED [ 58%]
tests/test_products_helpers.py::test_shopping_context_medication_skip PASSED [ 59%]
tests/test_products_helpers.py::test_extract_requested_product_ids_dedupes_and_limits PASSED [ 59%]
tests/test_products_helpers.py::test_shopping_tool_handlers_return_payloads PASSED [ 60%]
tests/test_products_helpers.py::test_shopping_tool_handler_includes_last_used_on_from_mapping PASSED [ 60%]
tests/test_products_helpers.py::test_shopping_validator_accepts_freeform_product_type_and_frequency PASSED [ 61%]
tests/test_products_pricing.py::test_compute_pricing_outputs_groups_by_category PASSED [ 61%]
tests/test_products_pricing.py::test_price_tier_is_null_when_not_enough_products PASSED [ 61%]
tests/test_products_pricing.py::test_price_tier_is_computed_by_worker PASSED [ 62%]
tests/test_products_pricing.py::test_price_tier_uses_fallback_for_medium_categories PASSED [ 62%]
tests/test_products_pricing.py::test_price_tier_stays_null_for_tiny_categories_even_with_fallback_pool PASSED [ 63%]
tests/test_products_pricing.py::test_product_write_enqueues_pricing_job PASSED [ 63%]
tests/test_profile.py::test_get_profile_empty PASSED [ 64%]
tests/test_profile.py::test_upsert_profile_create_and_get PASSED [ 64%]
tests/test_profile.py::test_upsert_profile_updates_existing_row PASSED [ 65%]
tests/test_routines.py::test_create_routine_minimal PASSED [ 65%]
tests/test_routines.py::test_create_routine_invalid_part_of_day PASSED [ 66%]
tests/test_routines.py::test_list_routines_empty PASSED [ 66%]
tests/test_routines.py::test_list_filter_date_range PASSED [ 66%]
tests/test_routines.py::test_list_filter_part_of_day PASSED [ 67%]
tests/test_routines.py::test_get_routine PASSED [ 67%]
tests/test_routines.py::test_get_routine_not_found PASSED [ 68%]
tests/test_routines.py::test_update_routine_notes PASSED [ 68%]
tests/test_routines.py::test_update_routine_not_found PASSED [ 69%]
tests/test_routines.py::test_delete_routine PASSED [ 69%]
tests/test_routines.py::test_add_step_action_only PASSED [ 70%]
tests/test_routines.py::test_add_step_with_product PASSED [ 70%]
tests/test_routines.py::test_add_step_routine_not_found PASSED [ 71%]
tests/test_routines.py::test_update_step PASSED [ 71%]
tests/test_routines.py::test_update_step_not_found PASSED [ 71%]
tests/test_routines.py::test_delete_step PASSED [ 72%]
tests/test_routines.py::test_delete_step_not_found PASSED [ 72%]
tests/test_routines.py::test_list_grooming_schedule_empty PASSED [ 73%]
tests/test_routines.py::test_create_grooming_schedule PASSED [ 73%]
tests/test_routines.py::test_list_grooming_schedule_returns_entry PASSED [ 74%]
tests/test_routines.py::test_update_grooming_schedule PASSED [ 74%]
tests/test_routines.py::test_delete_grooming_schedule PASSED [ 75%]
tests/test_routines.py::test_delete_grooming_schedule_not_found PASSED [ 75%]
tests/test_routines.py::test_suggest_routine PASSED [ 76%]
tests/test_routines.py::test_suggest_batch PASSED [ 76%]
tests/test_routines.py::test_suggest_batch_invalid_date_range PASSED [ 76%]
tests/test_routines.py::test_suggest_batch_too_long PASSED [ 77%]
tests/test_routines_auth.py::test_suggest_uses_current_user_profile_and_visible_products_only PASSED [ 77%]
tests/test_routines_helpers.py::test_contains_minoxidil_text PASSED [ 78%]
tests/test_routines_helpers.py::test_is_minoxidil_product PASSED [ 78%]
tests/test_routines_helpers.py::test_ev PASSED [ 79%]
tests/test_routines_helpers.py::test_build_skin_context PASSED [ 79%]
tests/test_routines_helpers.py::test_build_skin_context_falls_back_to_recent_snapshot_within_14_days PASSED [ 80%]
tests/test_routines_helpers.py::test_build_skin_context_ignores_snapshot_older_than_14_days PASSED [ 80%]
tests/test_routines_helpers.py::test_get_recent_skin_snapshot_prefers_window_match PASSED [ 80%]
tests/test_routines_helpers.py::test_get_latest_skin_snapshot_within_days_uses_latest_within_14_days PASSED [ 81%]
tests/test_routines_helpers.py::test_build_grooming_context PASSED [ 81%]
tests/test_routines_helpers.py::test_build_upcoming_grooming_context PASSED [ 82%]
tests/test_routines_helpers.py::test_build_recent_history PASSED [ 82%]
tests/test_routines_helpers.py::test_build_recent_history_uses_reference_window PASSED [ 83%]
tests/test_routines_helpers.py::test_build_recent_history_excludes_future_routines PASSED [ 83%]
tests/test_routines_helpers.py::test_build_products_context_summary_list PASSED [ 84%]
tests/test_routines_helpers.py::test_build_objectives_context PASSED [ 84%]
tests/test_routines_helpers.py::test_build_day_context PASSED [ 85%]
tests/test_routines_helpers.py::test_get_available_products_respects_filters PASSED [ 85%]
tests/test_routines_helpers.py::test_build_product_details_tool_handler_returns_only_available_ids PASSED [ 85%]
tests/test_routines_helpers.py::test_extract_requested_product_ids_dedupes_and_limits PASSED [ 86%]
tests/test_routines_helpers.py::test_extract_active_names_uses_compact_distinct_names PASSED [ 86%]
tests/test_routines_helpers.py::test_get_available_products_excludes_minoxidil_when_flag_false PASSED [ 87%]
tests/test_routines_helpers.py::test_filter_products_by_interval PASSED [ 87%]
tests/test_routines_helpers.py::test_filter_products_by_interval_never_used_passes PASSED [ 88%]
tests/test_routines_helpers.py::test_product_details_tool_handler_returns_product_payloads PASSED [ 88%]
tests/test_skincare.py::test_create_snapshot_minimal PASSED [ 89%]
tests/test_skincare.py::test_create_snapshot_full PASSED [ 89%]
tests/test_skincare.py::test_create_snapshot_invalid_state PASSED [ 90%]
tests/test_skincare.py::test_list_snapshots_empty PASSED [ 90%]
tests/test_skincare.py::test_list_filter_date_range PASSED [ 90%]
tests/test_skincare.py::test_list_filter_overall_state PASSED [ 91%]
tests/test_skincare.py::test_get_snapshot PASSED [ 91%]
tests/test_skincare.py::test_get_snapshot_not_found PASSED [ 92%]
tests/test_skincare.py::test_update_snapshot_state PASSED [ 92%]
tests/test_skincare.py::test_update_snapshot_concerns PASSED [ 93%]
tests/test_skincare.py::test_update_snapshot_not_found PASSED [ 93%]
tests/test_skincare.py::test_delete_snapshot PASSED [ 94%]
tests/test_skincare.py::test_delete_snapshot_not_found PASSED [ 94%]
tests/test_skincare.py::test_analyze_photos_includes_user_profile_context PASSED [ 95%]
tests/test_tenancy_domains.py::test_profile_health_routines_skincare_ai_logs_are_user_scoped_by_default PASSED [ 95%]
tests/test_tenancy_domains.py::test_health_admin_override_requires_explicit_user_id PASSED [ 95%]
tests/validators/test_routine_validator.py::test_detects_retinoid_acid_conflict PASSED [ 96%]
tests/validators/test_routine_validator.py::test_rejects_unknown_product_ids PASSED [ 96%]
tests/validators/test_routine_validator.py::test_enforces_min_interval_hours PASSED [ 97%]
tests/validators/test_routine_validator.py::test_blocks_dose_field PASSED [ 97%]
tests/validators/test_routine_validator.py::test_missing_spf_in_am_leaving_home PASSED [ 98%]
tests/validators/test_routine_validator.py::test_compromised_barrier_restrictions PASSED [ 98%]
tests/validators/test_routine_validator.py::test_step_must_have_product_or_action PASSED [ 99%]
tests/validators/test_routine_validator.py::test_step_cannot_have_both_product_and_action PASSED [ 99%]
tests/validators/test_routine_validator.py::test_accepts_valid_routine PASSED [100%]
================================ tests coverage ================================
______________ coverage: platform darwin, python 3.12.12-final-0 _______________
Name Stmts Miss Cover Missing
----------------------------------------------------------------------------------
innercontext/api/__init__.py 0 0 100%
innercontext/api/admin.py 93 1 99% 142
innercontext/api/ai_logs.py 63 12 81% 19, 21, 25-26, 29-30, 55-57, 77, 79, 109
innercontext/api/auth.py 68 4 94% 66, 69, 74, 109
innercontext/api/auth_deps.py 25 1 96% 43
innercontext/api/authz.py 100 12 88% 25-26, 39, 49, 83, 91, 108, 125, 128, 158, 167, 174
innercontext/api/health.py 236 8 97% 145, 158-163, 412, 414, 418
innercontext/api/inventory.py 30 0 100%
innercontext/api/llm_context.py 106 42 60% 19-21, 67, 77, 114, 116, 118, 120-131, 142, 146-149, 180-217
innercontext/api/product_llm_tools.py 107 33 69% 12-17, 25, 53, 63, 67-80, 133-134, 155-161, 193
innercontext/api/products.py 638 76 88% 82, 84, 88, 109-126, 284, 287-289, 317-318, 331, 340-341, 343, 345, 347-348, 381, 413, 415, 419, 425, 429, 520, 524, 528, 532, 536, 542, 544, 587, 604, 606, 657, 661, 692, 867, 870-871, 880-881, 887, 890-891, 918, 920, 922, 924, 933-934, 983, 1007, 1045, 1082, 1176, 1249, 1251, 1253, 1256, 1360-1375, 1392, 1439-1442, 1449-1450, 1453
innercontext/api/profile.py 39 0 100%
innercontext/api/routines.py 632 89 86% 67-84, 101-103, 112-117, 129-133, 323-324, 465, 477, 552, 592, 594, 599, 640-641, 664-693, 715, 719-721, 833, 986-1002, 1019, 1023-1024, 1030, 1033, 1039, 1064-1065, 1069, 1115-1119, 1130, 1201-1203, 1236, 1240-1241, 1247-1264, 1284-1285, 1331-1333, 1340-1341, 1344, 1454, 1485
innercontext/api/skincare.py 150 18 88% 147-149, 162-166, 179, 191, 196, 231-232, 242-245, 251, 254-255
innercontext/api/utils.py 22 2 91% 51, 59
innercontext/auth.py 236 42 82% 67-70, 75, 134, 137, 142, 144, 147-149, 156, 201-210, 216, 224-225, 232, 242, 247, 254-255, 261, 274, 298, 300, 314-315, 344-346, 378-384
innercontext/llm.py 134 117 13% 62-66, 74-102, 118-214, 231-326
innercontext/llm_safety.py 18 6 67% 18, 59, 80-83
innercontext/models/__init__.py 13 0 100%
innercontext/models/ai_log.py 33 0 100%
innercontext/models/api_metadata.py 15 0 100%
innercontext/models/base.py 3 0 100%
innercontext/models/domain.py 4 0 100%
innercontext/models/enums.py 152 0 100%
innercontext/models/health.py 64 0 100%
innercontext/models/household.py 14 0 100%
innercontext/models/household_membership.py 20 0 100%
innercontext/models/pricing.py 19 0 100%
innercontext/models/product.py 226 34 85% 203-205, 209-230, 253, 255, 257, 259, 261, 263, 265, 267, 271, 286, 318, 320, 336, 338, 340, 342, 349-354
innercontext/models/profile.py 17 0 100%
innercontext/models/routine.py 42 0 100%
innercontext/models/skincare.py 37 0 100%
innercontext/models/user.py 19 0 100%
innercontext/services/__init__.py 0 0 100%
innercontext/services/fx.py 57 42 26% 16, 20-22, 26-48, 54-67, 71-77
innercontext/services/pricing_jobs.py 89 29 67% 35, 39, 53-67, 74-80, 94, 123-130, 136
innercontext/validators/__init__.py 7 0 100%
innercontext/validators/base.py 22 2 91% 35, 52
innercontext/validators/batch_validator.py 128 84 34% 61-62, 67-68, 71-72, 82-83, 87-91, 100-119, 123-142, 146, 167-203, 214-240, 250-273
innercontext/validators/photo_validator.py 65 33 49% 82-87, 94-101, 108-115, 122-129, 145, 151-152, 165, 171-178
innercontext/validators/product_parse_validator.py 110 46 58% 112, 115, 117, 142, 165, 172, 186, 192-198, 205-239, 244-249, 252-257, 266-267, 274-275, 282, 287, 291, 298, 308, 315, 319, 339
innercontext/validators/routine_validator.py 146 17 88% 72-73, 111-117, 126, 187, 195, 208, 216, 234, 241, 266-267, 292
innercontext/validators/shopping_validator.py 78 20 74% 52-53, 58-59, 70, 91, 114, 123, 137-138, 142, 151-152, 156-159, 161, 193, 196-199, 203
----------------------------------------------------------------------------------
TOTAL 4077 770 81%
Coverage HTML written to dir htmlcov
============================= 221 passed in 2.98s ==============================