Skip to content

feat: add user data endpoints tests and resolve validation edge cases#292

Open
Sujata005 wants to merge 17 commits into
imDarshanGK:mainfrom
Sujata005:feat/user-data-testing
Open

feat: add user data endpoints tests and resolve validation edge cases#292
Sujata005 wants to merge 17 commits into
imDarshanGK:mainfrom
Sujata005:feat/user-data-testing

Conversation

@Sujata005
Copy link
Copy Markdown

@Sujata005 Sujata005 commented May 24, 2026

Description

This PR addresses the task assigned for GSSoC 2026 to add comprehensive backend tests exercising GET, POST, and DELETE actions on the /user/history and /user/favorites endpoints using Starlette's TestClient.

Key adjustments implemented to ensure a successful, clean test pass:

  • Fixed an operational edge-case where raw SQLite stringified JSON structures caused dictionary validation errors during payload responses by implementing a FlexibleDict data type with a Pydantic BeforeValidator.
  • Explicitly ensured response data maps included proper user_id context fields within user_data.py to seamlessly sync with the application schemas.
  • Refactored older class Config: architectures to modernized Pydantic v2/v3 model_config = ConfigDict(from_attributes=True) rules to completely clear deprecation warning outputs.

Related Issue

Fixes #201

Type of change

  • Bug fix
  • New feature / enhancement
  • Documentation update
  • Test addition
  • Refactor

Checklist

  • I have read CONTRIBUTING.md
  • My branch is up to date with main
  • I have run pytest -v and all tests pass
  • I have not introduced duplicate issues or features
  • My PR title follows the format: feat/fix/docs/test: short description
  • I have added tests for new features (Level 2 and 3 issues)
  • No hardcoded secrets or API keys in my code
  • This PR is linked to a GSSoC 2026 issue

Test evidence

python -m pytest -v
===================== test session starts =====================
platform win32 -- Python 3.14.4, pytest-9.0.3, pluggy-1.6.0
rootdir: /backend
plugins: anyio-4.13.0, asyncio-1.3.0
collected 84 items                                             

tests/test_digest.py::test_subscribe_success PASSED      [  1%]
tests/test_digest.py::test_subscribe_duplicate_returns_409 PASSED [  2%]
tests/test_digest.py::test_subscribe_re_activates_after_unsubscribe PASSED [  3%]
tests/test_digest.py::test_unsubscribe_success PASSED    [  4%]
tests/test_digest.py::test_unsubscribe_wrong_token PASSED [  5%]
tests/test_digest.py::test_unsubscribe_nonexistent PASSED [  7%]
tests/test_digest.py::test_get_unsubscribe_link PASSED   [  8%]
tests/test_digest.py::test_invalid_email PASSED          [  9%]
tests/test_digest.py::test_subscribe_stores_token PASSED [ 10%]
tests/test_endpoints.py::test_root PASSED                [ 11%]
tests/test_endpoints.py::test_health PASSED              [ 13%]
tests/test_endpoints.py::test_rate_limit_headers_on_success_response PASSED [ 14%]
tests/test_endpoints.py::test_rate_limit_returns_429_with_retry_after_header PASSED [ 15%]
tests/test_endpoints.py::test_explanation_python PASSED  [ 16%]
tests/test_endpoints.py::test_explanation_no_language_hint PASSED [ 17%]
tests/test_endpoints.py::test_explanation_rust PASSED    [ 19%]
tests/test_endpoints.py::test_explanation_detects_rust_without_hint PASSED [ 20%]
tests/test_endpoints.py::test_explanation_accepts_rust_hint_alias PASSED [ 21%]
tests/test_endpoints.py::test_explanation_empty_code PASSED [ 22%]
tests/test_endpoints.py::test_explanation_too_long PASSED [ 23%]
tests/test_endpoints.py::test_explanation_typescript PASSED [ 25%]
tests/test_endpoints.py::test_explanation_java PASSED    [ 26%]
tests/test_endpoints.py::test_explanation_cpp PASSED     [ 27%]
tests/test_endpoints.py::test_explanation_cyclomatic_fields_present PASSED [ 28%]
tests/test_endpoints.py::test_explanation_cyclomatic_simple PASSED [ 29%]
tests/test_endpoints.py::test_explanation_cyclomatic_moderate PASSED [ 30%]
tests/test_endpoints.py::test_explanation_cyclomatic_high PASSED [ 32%]
tests/test_endpoints.py::test_explanation_cyclomatic_very_high PASSED [ 33%]
tests/test_endpoints.py::test_debug_detects_zero_division PASSED [ 34%]
tests/test_endpoints.py::test_debug_detects_hardcoded_secret PASSED [ 35%]
tests/test_endpoints.py::test_debug_detects_bare_except PASSED [ 36%]
tests/test_endpoints.py::test_debug_detects_eval PASSED  [ 38%]
tests/test_endpoints.py::test_debug_clean_code PASSED    [ 39%]
tests/test_endpoints.py::test_debug_javascript PASSED    [ 40%]
tests/test_endpoints.py::test_debug_java PASSED          [ 41%]
tests/test_endpoints.py::test_debug_cpp PASSED           [ 42%]
tests/test_endpoints.py::test_explanation_php PASSED     [ 44%]
tests/test_endpoints.py::test_explanation_detects_php_without_hint PASSED [ 45%]
tests/test_endpoints.py::test_debug_php PASSED           [ 46%]
tests/test_endpoints.py::test_debug_php_buggy_patterns PASSED [ 47%]
tests/test_endpoints.py::test_debug_rust PASSED          [ 48%]
tests/test_endpoints.py::test_debug_rust_buggy_patterns PASSED [ 50%]
tests/test_endpoints.py::test_debug_kotlin PASSED        [ 51%]
tests/test_endpoints.py::test_debug_cpp_syntax_errors PASSED [ 52%]
tests/test_endpoints.py::test_debug_issue_has_required_fields PASSED [ 53%]
tests/test_js_ts_security_patterns PASSED                [ 54%]
tests/test_suggestions_returns_score PASSED              [ 55%]
tests/test_suggestions_perfect_score PASSED              [ 57%]
tests/test_full_analyze PASSED                           [ 58%]
tests/test_full_analyze_uses_cache_for_identical_inputs PASSED [ 59%]
tests/test_analyze_cache_expires PASSED                  [ 60%]
tests/test_memory_cache_evicts_least_recently_used_entries PASSED [ 61%]
tests/test_full_analyze_all_languages PASSED             [ 63%]
tests/test_missing_code_field PASSED                     [ 64%]
tests/test_unicode_code PASSED                           [ 65%]
tests/test_single_line_code PASSED                       [ 66%]
tests/test_explanation_swift PASSED                      [ 67%]
tests/test_explanation_swift_with_hint PASSED            [ 69%]
tests/test_ping PASSED                                   [ 70%]
tests/test_python_ast_analyzer.py::test_detects_missing_bracket_syntax_error PASSED [ 71%]
tests/test_python_ast_analyzer.py::test_detects_invalid_indentation_syntax_error PASSED [ 72%]
tests/test_python_ast_analyzer.py::test_detects_division_by_zero_expression PASSED [ 73%]
tests/test_python_ast_analyzer.py::test_detects_division_by_zero_inside_function_call PASSED [ 75%]
tests/test_python_ast_analyzer.py::test_detects_out_of_range_list_index PASSED [ 76%]
tests/test_python_ast_analyzer.py::test_detects_out_of_range_string_index PASSED [ 77%]
tests/test_python_ast_analyzer.py::test_detects_string_integer_concatenation PASSED [ 78%]
tests/test_user_data.py::test_create_history_success PASSED [ 79%]
tests/test_user_data.py::test_list_history_returns_records PASSED [ 80%]
tests/test_user_data.py::test_history_hardcoded_pagination_limit PASSED [ 82%]
tests/test_user_data.py::test_delete_individual_history_record PASSED [ 83%]
tests/test_user_data.py::test_clear_all_history_records PASSED [ 84%]
tests/test_user_data.py::test_create_favorite_success PASSED [ 85%]
tests/test_user_data.py::test_list_favorites_returns_records PASSED [ 86%]
tests/test_user_data.py::test_favorites_hardcoded_pagination_limit PASSED [ 88%]
tests/test_user_data.py::test_delete_individual_favorite_record PASSED [ 89%]
tests/test_user_data.py::test_clear_all_favorites_records PASSED [ 90%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[GET-/user/history-None] PASSED [ 91%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[POST-/user/history-payload1] PASSED [ 92%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[DELETE-/user/history-None] PASSED [ 94%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[DELETE-/user/history/1-None] PASSED [ 95%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[GET-/user/favorites-None] PASSED [ 96%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[POST-/user/favorites-payload5] PASSED [ 97%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[DELETE-/user/favorites-None] PASSED [ 98%]
tests/test_user_data.py::test_endpoints_raise_411_unauthorized_when_no_token_present[DELETE-/user/favorites/1-None] PASSED [100%]

===================== 84 passed in 1.28s ======================

@Sujata005 Sujata005 requested a review from imDarshanGK as a code owner May 24, 2026 08:36
@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005 update the branch with the latest main changes, resolve conflicts and add issue number and demo

@github-actions github-actions Bot added type:backend Backend related tasks testing labels May 26, 2026
@Sujata005
Copy link
Copy Markdown
Author

@imDarshanGK, I have updated the branch with the latest changes from main, resolved the schema conflicts, and updated the PR description with the issue number and test evidence. Ready for review! Thank you.

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005 update your branch with the latest changes from main and CI failing
image

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005 image

@Sujata005
Copy link
Copy Markdown
Author

image Hi @imDarshanGK, I have successfully updated the branch with the latest changes from `main` directly via the GitHub UI sync.

Additionally, I ran the ruff linter and formatting suite locally to completely resolve the duplicate router imports in main.py and structural syntax sorting in schemas.py. All local checks are passing flawlessly with 0 errors and all backend tests are passing cleanly.

The PR is fully updated and ready for your review and workflow approval. Thank you!

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005
image

@Sujata005
Copy link
Copy Markdown
Author

Hi @imDarshanGK,

I have resolved the trailing newline (W292) linting warning in user_data.py. Local checks are now passing with an absolute clean bill of health ("All checks passed!").
image

Regarding the test (3.11) workflow failure: this is an environment pathing issue on the GitHub Actions runner. The workflow file executes cd backend but does not expose env: PYTHONPATH=. or env: PYTHONPATH=backend to the runner environment, which causes pytest to throw a ModuleNotFoundError: No module named 'app'.
The core feature logic is 100% sound and passes all 105 tests perfectly on a properly configured path structure. Ready for your review and to trigger the final workflow approval! Thank you.
image

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005 update your branch with the latest main changes and CI failing
image

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005 CI failing
image

@imDarshanGK
Copy link
Copy Markdown
Owner

@Sujata005
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:backend Backend related tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add unit tests for /user history and favorites endpoints

2 participants