GabLeRoux / time-sync-tools

MIT License
2 stars 0 forks source link

Fix the tests #1

Open GabLeRoux opened 2 days ago

GabLeRoux commented 2 days ago
The Failing tests

``` Run source .venv/bin/activate ============================= test session starts ============================== platform linux -- Python 3.11.10, pytest-7.3.2, pluggy-1.3.0 rootdir: /home/runner/work/time-sync-tools/time-sync-tools configfile: pytest.ini plugins: playwright-0.3.3, base-url-2.0.0, cov-4.1.0 collected 12 items tests/test_main.py FFF [ 25%] tests/test_match_tasks.py . [ 33%] tests/test_openai.py FFFF [ 66%] tests/test_toggl.py .F [ 83%] tests/test_wrike.py .F [100%] =================================== FAILURES =================================== ______________ test_fire_cli[command0-Toggl functions available] _______________ command = ['python', '-m', 'src.main', 'toggl'] expected_output = 'Toggl functions available' @pytest.mark.parametrize( "command, expected_output", [ ( ["python", "-m", "src.main", "toggl"], "Toggl functions available", ), # Add expected output or part of it ( ["python", "-m", "src.main", "wrike"], "Wrike functions available", ), # Add expected output or part of it ( ["python", "-m", "src.main", "openai"], "OpenAI functions available", ), # Add expected output or part of it ], ) def test_fire_cli(command, expected_output): reason = self.reason.decode("iso-8859-1") else: reason = self.reason if 400 <= self.status_code < 500: http_error_msg = ( f"{self.status_code} Client Error: {reason} for url: {self.url}" ) elif 500 <= self.status_code < 600: http_error_msg = ( f"{self.status_code} Server Error: {reason} for url: {self.url}" ) if http_error_msg: > raise HTTPError(http_error_msg, response=self) E requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://api.track.toggl.com/api/v8/time_entries?start_date=2023-06-01T00%3A00%3A00Z&end_date=2023-06-30T00%3A00%3A00Z .venv/lib/python3.11/site-packages/requests/models.py:1021: HTTPError _____________________________ test_get_task_by_id ______________________________ mock_get = @patch("requests.get") def test_get_task_by_id(mock_get): # Mocking a successful API response mock_get.return_value.status_code = 200 mock_get.return_value.json = MockResponse.json > task = get_task_by_id("abc123") tests/test_wrike.py:26: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ src/wrike.py:156: in get_task_by_id return fetch_data(_get_task_by_id_internal, task_id) src/wrike.py:54: in fetch_data result = func(*args, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ task_id = 'abc123' def _get_task_by_id_internal(task_id): task_id = _validate_task_id(task_id) spinner = Halo(text="Fetching task from Wrike...", spinner="dots") spinner.start() > response = requests.get(f"{WRIKE_API_URL}/tasks/{task_id}", headers=_get_headers()) E NameError: name 'WRIKE_API_URL' is not defined src/wrike.py:165: NameError ----------------------------- Captured stdout call ----------------------------- . ---------- coverage: platform linux, python 3.11.10-final-0 ---------- Name Stmts Miss Cover ----------------------------------------------- main.py 2 2 0% src/__init__.py 0 0 100% src/clockify.py 30 30 0% src/config.py 23 5 78% src/google_sheets.py [14](https://github.com/GabLeRoux/time-sync-tools/actions/runs/11602178916/job/32306579143#step:8:15)5 145 0% src/jira.py 73 73 0% src/match_tasks.py 8 0 100% src/openai.py 20 17 [15](https://github.com/GabLeRoux/time-sync-tools/actions/runs/11602178916/job/32306579143#step:8:16)% src/toggl.py 32 13 59% src/wrike.py [16](https://github.com/GabLeRoux/time-sync-tools/actions/runs/11602178916/job/32306579143#step:8:17)9 119 30% tests/__init__.py 0 0 100% tests/test_main.py 9 1 89% tests/test_match_tasks.py 16 0 100% tests/test_openai.py 33 8 76% tests/test_toggl.py 11 3 73% tests/test_wrike.py 22 7 68% ----------------------------------------------- TOTAL 593 423 29% =========================== short test summary info ============================ FAILED tests/test_main.py::test_fire_cli[command0-Toggl functions available] - Failed: Command 'python -m src.main toggl' failed with error: Command '['python', '-m', 'src.main', 'toggl']' returned non-zero exit status 1. FAILED tests/test_main.py::test_fire_cli[command1-Wrike functions available] - Failed: Command 'python -m src.main wrike' failed with error: Command '['python', '-m', 'src.main', 'wrike']' returned non-zero exit status 1. FAILED tests/test_main.py::test_fire_cli[command2-OpenAI functions available] - Failed: Command 'python -m src.main openai' failed with error: Command '['python', '-m', 'src.main', 'openai']' returned non-zero exit status 1. FAILED tests/test_openai.py::test_find_closest_match - TypeError: find_closest_match() got an unexpected keyword argument 'prompt' FAILED tests/test_openai.py::test_find_closest_match_no_choices - TypeError: find_closest_match() got an unexpected keyword argument 'prompt' FAILED tests/test_openai.py::test_find_closest_match_exception - TypeError: find_closest_match() got an unexpected keyword argument 'prompt' FAILED tests/test_openai.py::test_find_closest_match_with_options_none - TypeError: find_closest_match() got an unexpected keyword argument 'prompt' FAILED tests/test_toggl.py::test_get_time_entries - requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://api.track.toggl.com/api/v8/time_entries?start_date=[20](https://github.com/GabLeRoux/time-sync-tools/actions/runs/11602178916/job/32306579143#step:8:21)23-06-01T00%3A00%3A00Z&end_date=2023-06-30T00%3A00%3A00Z FAILED tests/test_wrike.py::test_get_task_by_id - NameError: name 'WRIKE_API_URL' is not defined ========================= 9 failed, 3 passed in 1.91s ========================== ```

[!TIP] For best results, initiate chat on the files or code changes.

CodeRabbitI noticed that the workflows are failing with several errors:

  1. Module Not Found Error in tests/test_main.py:

    /opt/hostedtoolcache/Python/3.11.10/x64/bin/python: No module named src.main

    This suggests that the src.main module cannot be found. Please verify that src/main.py exists and that the module path is correctly specified. If the module was moved or renamed, make sure to update the import statements and any references in your test commands.

  2. TypeError in tests/test_openai.py:

    TypeError: find_closest_match() got an unexpected keyword argument 'prompt'

    It appears that the find_closest_match function does not accept a prompt keyword argument. Please check the function definition to ensure it matches the parameters used in your tests. You might need to update either the function or the test cases to align the parameters.

  3. HTTP Error in tests/test_toggl.py:

    requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://api.track.toggl.com/api/v8/time_entries...

    A 404 error indicates that the requested URL is not found. This could be due to an incorrect API endpoint or missing credentials. Please confirm that the API URL is correct and that any necessary authentication tokens are properly configured in the test environment.

  4. NameError in tests/test_wrike.py:

    NameError: name 'WRIKE_API_URL' is not defined

    This suggests that WRIKE_API_URL is not defined or not imported where it's being used. Ensure that WRIKE_API_URL is correctly defined in src/wrike.py or imported from the appropriate module.

  5. Coverage Report Shows Missing Coverage: The coverage report indicates low coverage in several modules. Consider adding more tests or adjusting existing ones to improve test coverage.

Recommendations:

GabLeRoux commented 1 day ago

@coderabbitai Can you read related files for this issue and suggest tests?

coderabbitai[bot] commented 1 day ago

[!TIP] For best results, initiate chat on the files or code changes.

@GabLeRoux, after reviewing the test files and the corresponding source code, I have several suggestions to fix and improve your tests:

  1. Install Missing Dependencies: The errors indicate that modules like requests and openai are not found. Ensure that these dependencies are included in your requirements.txt or installed in your testing environment.

    pip install requests openai tqdm diskcache halo pytest

    Update your requirements.txt with all necessary packages to avoid such issues in the future.

  2. Update Import Statements: Some test files use relative imports that may cause issues. Change them to absolute imports. For example, in tests/test_match_tasks.py, update:

    from src.match_tasks import match_toggl_entries_to_wrike_tasks

    to

    from match_tasks import match_toggl_entries_to_wrike_tasks

    Ensure that your project structure supports these imports or adjust your PYTHONPATH accordingly.

  3. Mock External API Calls: Your tests should not rely on external API calls. Use mocking to simulate API responses. For example, in test_toggl.py:

    from unittest.mock import patch, MagicMock
    
    @patch('requests.get')
    def test_get_time_entries(mock_get):
       mock_response = MagicMock()
       mock_response.status_code = 200
       mock_response.json.return_value = [{'id': 'entry1', 'description': 'Test Entry'}]
       mock_get.return_value = mock_response
    
       entries = get_time_entries("2023-06-01", "2023-06-30")
       assert isinstance(entries, list)
       assert entries[0]['id'] == 'entry1'

    Apply similar mocking in other tests that depend on external services.

  4. Correct OpenAI API Usage in Tests: In test_openai.py, the mock should match the actual function called. Since find_closest_match uses openai.ChatCompletion.create, update your mock accordingly:

    @patch("openai.ChatCompletion.create")
    def test_find_closest_match(mock_create):
       mock_create.return_value = {
           'choices': [{'message': {'content': 'option 1'}}],
           'usage': {'total_tokens': 10}
       }
    
       options = ["option 1", "option 2", "option 3"]
       result = find_closest_match("search_param", options=options)
       assert result == "option 1"
  5. Test Error Handling: Ensure your tests cover exceptions and error cases. For example, in test_wrike.py, test the scenario where the API returns an error:

    @patch("requests.get")
    def test_get_task_by_id_error(mock_get):
       mock_get.return_value.status_code = 400
       mock_get.return_value.json.return_value = {"error": "Invalid request"}
    
       task = get_task_by_id("invalid_id")
       assert task is None
  6. Use Fixtures and Parameterization: Simplify your tests using pytest fixtures and parameterization. For instance:

    @pytest.fixture
    def valid_date():
       return "2023-06-01"
    
    @pytest.fixture
    def invalid_date():
       return "invalid_date"
    
    def test_validate_date(valid_date):
       assert validate_date(valid_date)
    
    def test_validate_date_invalid(invalid_date):
       with pytest.raises(ValueError):
           validate_date(invalid_date)
  7. Increase Test Coverage: Review the code coverage report and identify untested functions, especially in wrike.py and google_sheets.py. Write tests for critical functions like _handle_api_response, create_timelog, and any data processing logic.

  8. Consistent Testing Patterns: Ensure consistency across your test files. For example, always use either absolute or relative imports, and standardize your mocking strategy.

  9. Clean Up Test Code: Remove any redundant code in your test files. For example, in test_match_tasks.py, there seems to be duplicated code appended from match_tasks.py. Ensure only test-related code exists in the test files.

  10. Set Up Continuous Integration (CI): Integrate your tests with a CI tool like GitHub Actions to automatically run tests on each push or pull request. This helps catch issues early.

By addressing these points, your tests should run successfully and provide better coverage for your application. Let me know if you need further assistance!

🔗 Analysis chain
🏁 Scripts executed The following scripts were executed for the analysis: Script: ```shell #!/bin/bash # Display the contents of the failing test files fd -e py 'test_match_tasks.py' --exec cat {} fd -e py 'test_openai.py' --exec cat {} fd -e py 'test_toggl.py' --exec cat {} fd -e py 'test_wrike.py' --exec cat {} # Display the contents of the corresponding source files fd -e py 'match_tasks.py' --exec cat {} fd -e py 'toggl.py' --exec cat {} fd -e py 'wrike.py' --exec cat {} fd -e py 'openai.py' --exec cat {} ``` Length of output: 25276
GabLeRoux commented 1 day ago

@coderabbitai I think the problem about the missing packages might be related to the fact that packages are not being installed as part of .github/workflows/test.yml file. Can you rewrite it so it uses caching, install uv and use uv pip sync requirements.txt?

coderabbitai[bot] commented 1 day ago

[!TIP] For best results, initiate chat on the files or code changes.

@GabLeRoux, certainly! Here's a rewritten version of your .github/workflows/test.yml file that uses caching, installs uv, and uses uv pip sync requirements.txt:

name: Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - name: Check out repository
      uses: actions/checkout@v3

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'

    - name: Cache pip packages
      uses: actions/cache@v3
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
        restore-keys: |
          ${{ runner.os }}-pip-

    - name: Install UV
      run: pip install uv

    - name: Install dependencies
      run: uv pip sync requirements.txt

    - name: Run tests
      run: pytest --cov=./

    - name: Upload Coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        token: ${{ secrets.CODECOV_TOKEN }}

Explanation:

Make sure your requirements.txt is up-to-date with all the necessary dependencies for your project.

Let me know if you need any further assistance!

( ・◇・)?