python-gitea 0.3.1__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. python_gitea-0.4.0/.github/workflows/semantic_pull_request.yml +20 -0
  2. {python_gitea-0.3.1 → python_gitea-0.4.0}/.pre-commit-config.yaml +2 -2
  3. {python_gitea-0.3.1 → python_gitea-0.4.0}/PKG-INFO +1 -1
  4. {python_gitea-0.3.1 → python_gitea-0.4.0}/mkdocs.yml +4 -0
  5. python_gitea-0.4.0/src/gitea/repository/__init__.py +8 -0
  6. python_gitea-0.4.0/src/gitea/repository/async_repository.py +75 -0
  7. python_gitea-0.4.0/src/gitea/repository/base.py +59 -0
  8. python_gitea-0.4.0/src/gitea/repository/repository.py +75 -0
  9. python_gitea-0.4.0/tests/repository/__init__.py +1 -0
  10. python_gitea-0.4.0/tests/repository/test_repository_async_repository.py +128 -0
  11. python_gitea-0.4.0/tests/repository/test_repository_base.py +91 -0
  12. python_gitea-0.4.0/tests/repository/test_repository_repository.py +119 -0
  13. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/dependabot.yml +0 -0
  14. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/CI.yml +0 -0
  15. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/create_tag.yml +0 -0
  16. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/documentation.yml +0 -0
  17. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/draft_release.yml +0 -0
  18. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/publish.yml +0 -0
  19. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/publish_testpypi.yml +0 -0
  20. {python_gitea-0.3.1 → python_gitea-0.4.0}/.github/workflows/release.yml +0 -0
  21. {python_gitea-0.3.1 → python_gitea-0.4.0}/.gitignore +0 -0
  22. {python_gitea-0.3.1 → python_gitea-0.4.0}/.ignore_words.txt +0 -0
  23. {python_gitea-0.3.1 → python_gitea-0.4.0}/.markdownlint.yaml +0 -0
  24. {python_gitea-0.3.1 → python_gitea-0.4.0}/.pypirc +0 -0
  25. {python_gitea-0.3.1 → python_gitea-0.4.0}/CITATION.cff +0 -0
  26. {python_gitea-0.3.1 → python_gitea-0.4.0}/CODE_OF_CONDUCT.md +0 -0
  27. {python_gitea-0.3.1 → python_gitea-0.4.0}/CONTRIBUTING.md +0 -0
  28. {python_gitea-0.3.1 → python_gitea-0.4.0}/LICENSE +0 -0
  29. {python_gitea-0.3.1 → python_gitea-0.4.0}/README.md +0 -0
  30. {python_gitea-0.3.1 → python_gitea-0.4.0}/SECURITY.md +0 -0
  31. {python_gitea-0.3.1 → python_gitea-0.4.0}/SUPPORT.md +0 -0
  32. {python_gitea-0.3.1 → python_gitea-0.4.0}/cliff.toml +0 -0
  33. {python_gitea-0.3.1 → python_gitea-0.4.0}/commitlint.config.js +0 -0
  34. {python_gitea-0.3.1 → python_gitea-0.4.0}/cspell.json +0 -0
  35. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/dev/troubleshooting.md +0 -0
  36. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/gen_ref_pages.py +0 -0
  37. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/index.md +0 -0
  38. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/javascripts/mathjax.js +0 -0
  39. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/style/api.css +0 -0
  40. {python_gitea-0.3.1 → python_gitea-0.4.0}/docs/user_guide/installation.md +0 -0
  41. {python_gitea-0.3.1 → python_gitea-0.4.0}/package.json +0 -0
  42. {python_gitea-0.3.1 → python_gitea-0.4.0}/pyproject.toml +0 -0
  43. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/__init__.py +0 -0
  44. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/__main__.py +0 -0
  45. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/__init__.py +0 -0
  46. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/main.py +0 -0
  47. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/__init__.py +0 -0
  48. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/delete_user_level_runner.py +0 -0
  49. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/get_registration_token.py +0 -0
  50. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/get_user.py +0 -0
  51. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/get_user_level_runners.py +0 -0
  52. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/get_workflow_jobs.py +0 -0
  53. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/get_workflow_runs.py +0 -0
  54. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/user/main.py +0 -0
  55. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/cli/utils.py +0 -0
  56. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/client/__init__.py +0 -0
  57. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/client/async_gitea.py +0 -0
  58. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/client/base.py +0 -0
  59. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/client/gitea.py +0 -0
  60. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/issue/__init__.py +0 -0
  61. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/issue/async_issue.py +0 -0
  62. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/issue/base.py +0 -0
  63. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/issue/issue.py +0 -0
  64. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/resource/__init__.py +0 -0
  65. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/resource/async_resource.py +0 -0
  66. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/resource/resource.py +0 -0
  67. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/user/__init__.py +0 -0
  68. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/user/async_user.py +0 -0
  69. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/user/base.py +0 -0
  70. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/user/user.py +0 -0
  71. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/utils/__init__.py +0 -0
  72. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/utils/log.py +0 -0
  73. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/utils/response.py +0 -0
  74. {python_gitea-0.3.1 → python_gitea-0.4.0}/src/gitea/version.py +0 -0
  75. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/__init__.py +0 -0
  76. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/__init__.py +0 -0
  77. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/test_cli_main.py +0 -0
  78. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/test_cli_utils.py +0 -0
  79. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/__init__.py +0 -0
  80. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_delete_user_level_runner.py +0 -0
  81. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_get_registration_token.py +0 -0
  82. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_get_user.py +0 -0
  83. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_get_user_level_runners.py +0 -0
  84. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_get_workflow_jobs.py +0 -0
  85. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_get_workflow_runs.py +0 -0
  86. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/cli/user/test_cli_user_main.py +0 -0
  87. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/client/__init__.py +0 -0
  88. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/client/test_client_async_gitea.py +0 -0
  89. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/client/test_client_base.py +0 -0
  90. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/client/test_client_gitea.py +0 -0
  91. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/conftest.py +0 -0
  92. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/issue/__init__.py +0 -0
  93. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/issue/test_issue_async_issue.py +0 -0
  94. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/issue/test_issue_base.py +0 -0
  95. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/issue/test_issue_issue.py +0 -0
  96. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/resource/__init__.py +0 -0
  97. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/resource/test_resource_async_resource.py +0 -0
  98. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/resource/test_resource_resource.py +0 -0
  99. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/test_import.py +0 -0
  100. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/test_main.py +0 -0
  101. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/test_version.py +0 -0
  102. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/user/__init__.py +0 -0
  103. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/user/test_user_async_user.py +0 -0
  104. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/user/test_user_base.py +0 -0
  105. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/user/test_user_user.py +0 -0
  106. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/utils/__init__.py +0 -0
  107. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/utils/test_utils_log.py +0 -0
  108. {python_gitea-0.3.1 → python_gitea-0.4.0}/tests/utils/test_utils_response.py +0 -0
@@ -0,0 +1,20 @@
1
+ name: "Lint PR"
2
+
3
+ on:
4
+ pull_request_target:
5
+ types:
6
+ - opened
7
+ - reopened
8
+ - edited
9
+ - synchronize
10
+
11
+ jobs:
12
+ main:
13
+ name: Validate PR title
14
+ runs-on: ubuntu-slim
15
+ permissions:
16
+ pull-requests: read
17
+ steps:
18
+ - uses: amannn/action-semantic-pull-request@v6
19
+ env:
20
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -50,7 +50,7 @@ repos:
50
50
  stages: [pre-commit]
51
51
 
52
52
  - repo: https://github.com/astral-sh/ruff-pre-commit
53
- rev: v0.14.13
53
+ rev: v0.14.14
54
54
  hooks:
55
55
  - id: ruff
56
56
  args: [--fix, --config=pyproject.toml]
@@ -77,7 +77,7 @@ repos:
77
77
  stages: [pre-commit]
78
78
 
79
79
  - repo: https://github.com/streetsidesoftware/cspell-cli
80
- rev: v9.4.0 # Keep this version or update to the latest stable
80
+ rev: v9.6.0 # Keep this version or update to the latest stable
81
81
  hooks:
82
82
  - id: cspell
83
83
  name: Check spelling in Python, reSt, and Markdown files.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-gitea
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: A Python package for interacting with the Gitea API, offering a simple interface to access repositories, users, organizations, issues, and more for automation and data management.
5
5
  Project-URL: Documentation, https://isaac-cf-wong.github.io/python-gitea
6
6
  Project-URL: Source, https://github.com/isaac-cf-wong/python-gitea
@@ -82,6 +82,10 @@ nav:
82
82
  - Overview: reference/gitea/resource/index.md
83
83
  - Resource: reference/gitea/resource/resource.md
84
84
  - Async Resource: reference/gitea/resource/async_resource.md
85
+ - Repository:
86
+ - Overview: reference/gitea/repository/index.md
87
+ - Repository: reference/gitea/repository/repository.md
88
+ - Async Repository: reference/gitea/repository/async_repository.md
85
89
  - Issue:
86
90
  - Overview: reference/gitea/issue/index.md
87
91
  - Issue: reference/gitea/issue/issue.md
@@ -0,0 +1,8 @@
1
+ """Repository package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from gitea.repository.async_repository import AsyncRepository
6
+ from gitea.repository.repository import Repository
7
+
8
+ __all__ = ["AsyncRepository", "Repository"]
@@ -0,0 +1,75 @@
1
+ """Asynchronous Gitea Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, cast
6
+
7
+ from aiohttp import ClientResponse
8
+
9
+ from gitea.repository.base import BaseRepository
10
+ from gitea.resource.async_resource import AsyncResource
11
+ from gitea.utils.response import process_async_response
12
+
13
+
14
+ class AsyncRepository(AsyncResource, BaseRepository):
15
+ """Asynchronous Gitea Repository resource."""
16
+
17
+ async def _list_repositories(
18
+ self,
19
+ username: str | None = None,
20
+ organization: str | None = None,
21
+ page: int | None = None,
22
+ limit: int | None = None,
23
+ **kwargs: Any,
24
+ ) -> ClientResponse:
25
+ """List repositories for a user, organization, or authenticated user.
26
+
27
+ Args:
28
+ username: The username to list repositories for.
29
+ organization: The organization to list repositories for.
30
+ page: The page number for pagination.
31
+ limit: The number of repositories per page.
32
+ **kwargs: Additional arguments to pass to the request.
33
+
34
+ Returns:
35
+ The response object containing the list of repositories.
36
+
37
+ """
38
+ endpoint, params = self._list_repositories_helper(
39
+ username=username,
40
+ organization=organization,
41
+ page=page,
42
+ limit=limit,
43
+ )
44
+ return await self._get(endpoint=endpoint, params=params, **kwargs)
45
+
46
+ async def list_repositories(
47
+ self,
48
+ username: str | None = None,
49
+ organization: str | None = None,
50
+ page: int | None = None,
51
+ limit: int | None = None,
52
+ **kwargs: Any,
53
+ ) -> tuple[list[dict[str, Any]], int]:
54
+ """List repositories for a user, organization, or authenticated user.
55
+
56
+ Args:
57
+ username: The username to list repositories for.
58
+ organization: The organization to list repositories for.
59
+ page: The page number for pagination.
60
+ limit: The number of repositories per page.
61
+ **kwargs: Additional arguments to pass to the request.
62
+
63
+ Returns:
64
+ A tuple containing a list of repositories and the status code.
65
+
66
+ """
67
+ response = await self._list_repositories(
68
+ username=username,
69
+ organization=organization,
70
+ page=page,
71
+ limit=limit,
72
+ **kwargs,
73
+ )
74
+ data, status_code = await process_async_response(response=response)
75
+ return cast(list[dict[str, Any]], data), status_code
@@ -0,0 +1,59 @@
1
+ """Base class for Gitea Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ class BaseRepository:
9
+ """Base class for Gitea Repository resource."""
10
+
11
+ def _list_repositories_endpoint(self, username: str | None = None, organization: str | None = None) -> str:
12
+ """Construct the endpoint URL for listing repositories.
13
+
14
+ If both username and organization are None, it lists repositories for the authenticated user.
15
+ If username is provided, it lists repositories for that user.
16
+ If organization is provided, it lists repositories for that organization.
17
+
18
+ Args:
19
+ username: The username to list repositories for.
20
+ organization: The organization to list repositories for.
21
+
22
+ Returns:
23
+ The endpoint URL for listing repositories.
24
+
25
+ """
26
+ if username is None and organization is None:
27
+ return "/user/repos"
28
+ if username is not None and organization is None:
29
+ return f"/users/{username}/repos"
30
+ if username is None and organization is not None:
31
+ return f"/orgs/{organization}/repos"
32
+ raise ValueError("Either username or organization must be provided, not both.")
33
+
34
+ def _list_repositories_helper(
35
+ self,
36
+ username: str | None = None,
37
+ organization: str | None = None,
38
+ page: int | None = None,
39
+ limit: int | None = None,
40
+ ) -> tuple[str, dict[str, Any]]:
41
+ """Get the endpoint and parameters for listing repositories.
42
+
43
+ Args:
44
+ username: The username to list repositories for.
45
+ organization: The organization to list repositories for.
46
+ page: The page number for pagination.
47
+ limit: The number of repositories per page.
48
+
49
+ Returns:
50
+ A tuple containing the endpoint URL and a dictionary of parameters.
51
+
52
+ """
53
+ endpoint = self._list_repositories_endpoint(username=username, organization=organization)
54
+ params = {}
55
+ if page is not None:
56
+ params["page"] = page
57
+ if limit is not None:
58
+ params["limit"] = limit
59
+ return endpoint, params
@@ -0,0 +1,75 @@
1
+ """Gitea Repository resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, cast
6
+
7
+ from requests import Response
8
+
9
+ from gitea.repository.base import BaseRepository
10
+ from gitea.resource.resource import Resource
11
+ from gitea.utils.response import process_response
12
+
13
+
14
+ class Repository(Resource, BaseRepository):
15
+ """Gitea Repository resource."""
16
+
17
+ def _list_repositories(
18
+ self,
19
+ username: str | None = None,
20
+ organization: str | None = None,
21
+ page: int | None = None,
22
+ limit: int | None = None,
23
+ **kwargs: Any,
24
+ ) -> Response:
25
+ """List repositories for a user, organization, or authenticated user.
26
+
27
+ Args:
28
+ username: The username to list repositories for.
29
+ organization: The organization to list repositories for.
30
+ page: The page number for pagination.
31
+ limit: The number of repositories per page.
32
+ **kwargs: Additional arguments to pass to the request.
33
+
34
+ Returns:
35
+ The response object containing the list of repositories.
36
+
37
+ """
38
+ endpoint, params = self._list_repositories_helper(
39
+ username=username,
40
+ organization=organization,
41
+ page=page,
42
+ limit=limit,
43
+ )
44
+ return self._get(endpoint=endpoint, params=params, **kwargs)
45
+
46
+ def list_repositories(
47
+ self,
48
+ username: str | None = None,
49
+ organization: str | None = None,
50
+ page: int | None = None,
51
+ limit: int | None = None,
52
+ **kwargs: Any,
53
+ ) -> tuple[list[dict[str, Any]], int]:
54
+ """List repositories for a user, organization, or authenticated user.
55
+
56
+ Args:
57
+ username: The username to list repositories for.
58
+ organization: The organization to list repositories for.
59
+ page: The page number for pagination.
60
+ limit: The number of repositories per page.
61
+ **kwargs: Additional arguments to pass to the request.
62
+
63
+ Returns:
64
+ A tuple containing a list of repositories and the status code.
65
+
66
+ """
67
+ response = self._list_repositories(
68
+ username=username,
69
+ organization=organization,
70
+ page=page,
71
+ limit=limit,
72
+ **kwargs,
73
+ )
74
+ data, status_code = process_response(response=response)
75
+ return cast(list[dict[str, Any]], data), status_code
@@ -0,0 +1 @@
1
+ """Unit tests for repository package."""
@@ -0,0 +1,128 @@
1
+ """Unit tests for the AsyncRepository class."""
2
+
3
+ from unittest.mock import AsyncMock, MagicMock, patch
4
+
5
+ import pytest
6
+
7
+ from gitea.repository.async_repository import AsyncRepository
8
+
9
+
10
+ class TestAsyncRepository:
11
+ """Test cases for the AsyncRepository class."""
12
+
13
+ @pytest.fixture
14
+ def mock_client(self):
15
+ """Fixture to create a mock AsyncGitea client."""
16
+ client = MagicMock()
17
+ mock_response = MagicMock()
18
+ mock_response.json = AsyncMock(return_value=[{"id": 1, "name": "repo1"}])
19
+ mock_response.status = 200
20
+ client._request = AsyncMock(return_value=mock_response)
21
+ return client
22
+
23
+ @pytest.fixture
24
+ def async_repository(self, mock_client):
25
+ """Fixture to create an AsyncRepository instance."""
26
+ return AsyncRepository(client=mock_client)
27
+
28
+ @pytest.mark.asyncio
29
+ async def test_list_repositories_authenticated(self, async_repository, mock_client):
30
+ """Test list_repositories for authenticated user."""
31
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
32
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
33
+ result = await async_repository.list_repositories()
34
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/user/repos", params={})
35
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
36
+
37
+ @pytest.mark.asyncio
38
+ async def test_list_repositories_by_username(self, async_repository, mock_client):
39
+ """Test list_repositories for a specific user."""
40
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
41
+ mock_process.return_value = ([{"id": 2, "name": "other_repo"}], 200)
42
+ result = await async_repository.list_repositories(username="testuser")
43
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/users/testuser/repos", params={})
44
+ assert result == ([{"id": 2, "name": "other_repo"}], 200)
45
+
46
+ @pytest.mark.asyncio
47
+ async def test_list_repositories_by_organization(self, async_repository, mock_client):
48
+ """Test list_repositories for a specific organization."""
49
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
50
+ mock_process.return_value = (
51
+ [{"id": 3, "name": "org_repo1"}, {"id": 4, "name": "org_repo2"}],
52
+ 200,
53
+ )
54
+ result = await async_repository.list_repositories(organization="test_org")
55
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/orgs/test_org/repos", params={})
56
+ assert result == (
57
+ [{"id": 3, "name": "org_repo1"}, {"id": 4, "name": "org_repo2"}],
58
+ 200,
59
+ )
60
+
61
+ @pytest.mark.asyncio
62
+ async def test_list_repositories_with_pagination(self, async_repository, mock_client):
63
+ """Test list_repositories with pagination parameters."""
64
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
65
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
66
+ result = await async_repository.list_repositories(page=2, limit=50)
67
+ mock_client._request.assert_called_once_with(
68
+ method="GET", endpoint="/user/repos", params={"page": 2, "limit": 50}
69
+ )
70
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
71
+
72
+ @pytest.mark.asyncio
73
+ async def test_list_repositories_by_username_with_pagination(self, async_repository, mock_client):
74
+ """Test list_repositories for a user with pagination."""
75
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
76
+ mock_process.return_value = ([{"id": 5, "name": "paginated_repo"}], 200)
77
+ result = await async_repository.list_repositories(username="testuser", page=1, limit=25)
78
+ mock_client._request.assert_called_once_with(
79
+ method="GET",
80
+ endpoint="/users/testuser/repos",
81
+ params={"page": 1, "limit": 25},
82
+ )
83
+ assert result == ([{"id": 5, "name": "paginated_repo"}], 200)
84
+
85
+ @pytest.mark.asyncio
86
+ async def test_list_repositories_by_organization_with_pagination(self, async_repository, mock_client):
87
+ """Test list_repositories for an organization with pagination."""
88
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
89
+ mock_process.return_value = (
90
+ [{"id": 6, "name": "org_paginated_repo"}],
91
+ 200,
92
+ )
93
+ result = await async_repository.list_repositories(organization="test_org", page=3, limit=100)
94
+ mock_client._request.assert_called_once_with(
95
+ method="GET",
96
+ endpoint="/orgs/test_org/repos",
97
+ params={"page": 3, "limit": 100},
98
+ )
99
+ assert result == ([{"id": 6, "name": "org_paginated_repo"}], 200)
100
+
101
+ @pytest.mark.asyncio
102
+ async def test_list_repositories_empty_result(self, async_repository, mock_client):
103
+ """Test list_repositories with empty result."""
104
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
105
+ mock_process.return_value = ([], 200)
106
+ result = await async_repository.list_repositories()
107
+ mock_client._request.assert_called_once()
108
+ assert result == ([], 200)
109
+
110
+ @pytest.mark.asyncio
111
+ async def test_list_repositories_error_response(self, async_repository, mock_client):
112
+ """Test list_repositories with error response."""
113
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
114
+ mock_process.return_value = ({"error": "Not Found"}, 404)
115
+ result = await async_repository.list_repositories(username="nonexistent")
116
+ mock_client._request.assert_called_once()
117
+ assert result == ({"error": "Not Found"}, 404)
118
+
119
+ @pytest.mark.asyncio
120
+ async def test_list_repositories_with_kwargs(self, async_repository, mock_client):
121
+ """Test list_repositories passing additional kwargs to _get method."""
122
+ with patch("gitea.repository.async_repository.process_async_response") as mock_process:
123
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
124
+ result = await async_repository.list_repositories(headers={"Custom": "Header"})
125
+ mock_client._request.assert_called_once_with(
126
+ method="GET", endpoint="/user/repos", params={}, headers={"Custom": "Header"}
127
+ )
128
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
@@ -0,0 +1,91 @@
1
+ """Unit tests for the BaseRepository class."""
2
+
3
+ import pytest
4
+
5
+ from gitea.repository.base import BaseRepository
6
+
7
+
8
+ class TestBaseRepository:
9
+ """Test cases for the BaseRepository base class."""
10
+
11
+ def test_list_repositories_endpoint_authenticated(self):
12
+ """Test _list_repositories_endpoint for authenticated user."""
13
+ base_repo = BaseRepository()
14
+ endpoint = base_repo._list_repositories_endpoint(username=None, organization=None)
15
+ assert endpoint == "/user/repos"
16
+
17
+ def test_list_repositories_endpoint_by_username(self):
18
+ """Test _list_repositories_endpoint for a specific user."""
19
+ base_repo = BaseRepository()
20
+ endpoint = base_repo._list_repositories_endpoint(username="testuser", organization=None)
21
+ assert endpoint == "/users/testuser/repos"
22
+
23
+ def test_list_repositories_endpoint_by_organization(self):
24
+ """Test _list_repositories_endpoint for a specific organization."""
25
+ base_repo = BaseRepository()
26
+ endpoint = base_repo._list_repositories_endpoint(username=None, organization="test_org")
27
+ assert endpoint == "/orgs/test_org/repos"
28
+
29
+ def test_list_repositories_endpoint_both_raises_error(self):
30
+ """Test _list_repositories_endpoint raises error when both username and organization are provided."""
31
+ base_repo = BaseRepository()
32
+ with pytest.raises(ValueError, match=r"Either username or organization must be provided, not both."):
33
+ base_repo._list_repositories_endpoint(username="testuser", organization="test_org")
34
+
35
+ def test_list_repositories_helper_authenticated(self):
36
+ """Test _list_repositories_helper for authenticated user."""
37
+ base_repo = BaseRepository()
38
+ endpoint, params = base_repo._list_repositories_helper(username=None, organization=None)
39
+ assert endpoint == "/user/repos"
40
+ assert params == {}
41
+
42
+ def test_list_repositories_helper_with_pagination(self):
43
+ """Test _list_repositories_helper with pagination parameters."""
44
+ base_repo = BaseRepository()
45
+ endpoint, params = base_repo._list_repositories_helper(username=None, organization=None, page=2, limit=50)
46
+ assert endpoint == "/user/repos"
47
+ assert params == {"page": 2, "limit": 50}
48
+
49
+ def test_list_repositories_helper_by_username(self):
50
+ """Test _list_repositories_helper for a specific user."""
51
+ base_repo = BaseRepository()
52
+ endpoint, params = base_repo._list_repositories_helper(username="testuser", organization=None)
53
+ assert endpoint == "/users/testuser/repos"
54
+ assert params == {}
55
+
56
+ def test_list_repositories_helper_by_username_with_pagination(self):
57
+ """Test _list_repositories_helper for a specific user with pagination."""
58
+ base_repo = BaseRepository()
59
+ endpoint, params = base_repo._list_repositories_helper(username="testuser", organization=None, page=1, limit=20)
60
+ assert endpoint == "/users/testuser/repos"
61
+ assert params == {"page": 1, "limit": 20}
62
+
63
+ def test_list_repositories_helper_by_organization(self):
64
+ """Test _list_repositories_helper for a specific organization."""
65
+ base_repo = BaseRepository()
66
+ endpoint, params = base_repo._list_repositories_helper(username=None, organization="test_org")
67
+ assert endpoint == "/orgs/test_org/repos"
68
+ assert params == {}
69
+
70
+ def test_list_repositories_helper_by_organization_with_pagination(self):
71
+ """Test _list_repositories_helper for a specific organization with pagination."""
72
+ base_repo = BaseRepository()
73
+ endpoint, params = base_repo._list_repositories_helper(
74
+ username=None, organization="test_org", page=3, limit=100
75
+ )
76
+ assert endpoint == "/orgs/test_org/repos"
77
+ assert params == {"page": 3, "limit": 100}
78
+
79
+ def test_list_repositories_helper_page_only(self):
80
+ """Test _list_repositories_helper with only page parameter."""
81
+ base_repo = BaseRepository()
82
+ endpoint, params = base_repo._list_repositories_helper(username=None, organization=None, page=5)
83
+ assert endpoint == "/user/repos"
84
+ assert params == {"page": 5}
85
+
86
+ def test_list_repositories_helper_limit_only(self):
87
+ """Test _list_repositories_helper with only limit parameter."""
88
+ base_repo = BaseRepository()
89
+ endpoint, params = base_repo._list_repositories_helper(username=None, organization=None, limit=75)
90
+ assert endpoint == "/user/repos"
91
+ assert params == {"limit": 75}
@@ -0,0 +1,119 @@
1
+ """Unit tests for the Repository class."""
2
+
3
+ from unittest.mock import MagicMock, patch
4
+
5
+ import pytest
6
+
7
+ from gitea.repository.repository import Repository
8
+
9
+
10
+ class TestRepository:
11
+ """Test cases for the Repository class."""
12
+
13
+ @pytest.fixture
14
+ def mock_client(self):
15
+ """Fixture to create a mock Gitea client."""
16
+ client = MagicMock()
17
+ mock_response = MagicMock()
18
+ mock_response.json.return_value = [{"id": 1, "name": "repo1"}]
19
+ mock_response.status_code = 200
20
+ client._request.return_value = mock_response
21
+ return client
22
+
23
+ @pytest.fixture
24
+ def repository(self, mock_client):
25
+ """Fixture to create a Repository instance."""
26
+ return Repository(client=mock_client)
27
+
28
+ def test_list_repositories_authenticated(self, repository, mock_client):
29
+ """Test list_repositories for authenticated user."""
30
+ with patch("gitea.repository.repository.process_response") as mock_process:
31
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
32
+ result = repository.list_repositories()
33
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/user/repos", params={})
34
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
35
+
36
+ def test_list_repositories_by_username(self, repository, mock_client):
37
+ """Test list_repositories for a specific user."""
38
+ with patch("gitea.repository.repository.process_response") as mock_process:
39
+ mock_process.return_value = ([{"id": 2, "name": "other_repo"}], 200)
40
+ result = repository.list_repositories(username="testuser")
41
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/users/testuser/repos", params={})
42
+ assert result == ([{"id": 2, "name": "other_repo"}], 200)
43
+
44
+ def test_list_repositories_by_organization(self, repository, mock_client):
45
+ """Test list_repositories for a specific organization."""
46
+ with patch("gitea.repository.repository.process_response") as mock_process:
47
+ mock_process.return_value = (
48
+ [{"id": 3, "name": "org_repo1"}, {"id": 4, "name": "org_repo2"}],
49
+ 200,
50
+ )
51
+ result = repository.list_repositories(organization="test_org")
52
+ mock_client._request.assert_called_once_with(method="GET", endpoint="/orgs/test_org/repos", params={})
53
+ assert result == (
54
+ [{"id": 3, "name": "org_repo1"}, {"id": 4, "name": "org_repo2"}],
55
+ 200,
56
+ )
57
+
58
+ def test_list_repositories_with_pagination(self, repository, mock_client):
59
+ """Test list_repositories with pagination parameters."""
60
+ with patch("gitea.repository.repository.process_response") as mock_process:
61
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
62
+ result = repository.list_repositories(page=2, limit=50)
63
+ mock_client._request.assert_called_once_with(
64
+ method="GET", endpoint="/user/repos", params={"page": 2, "limit": 50}
65
+ )
66
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
67
+
68
+ def test_list_repositories_by_username_with_pagination(self, repository, mock_client):
69
+ """Test list_repositories for a user with pagination."""
70
+ with patch("gitea.repository.repository.process_response") as mock_process:
71
+ mock_process.return_value = ([{"id": 5, "name": "paginated_repo"}], 200)
72
+ result = repository.list_repositories(username="testuser", page=1, limit=25)
73
+ mock_client._request.assert_called_once_with(
74
+ method="GET",
75
+ endpoint="/users/testuser/repos",
76
+ params={"page": 1, "limit": 25},
77
+ )
78
+ assert result == ([{"id": 5, "name": "paginated_repo"}], 200)
79
+
80
+ def test_list_repositories_by_organization_with_pagination(self, repository, mock_client):
81
+ """Test list_repositories for an organization with pagination."""
82
+ with patch("gitea.repository.repository.process_response") as mock_process:
83
+ mock_process.return_value = (
84
+ [{"id": 6, "name": "org_paginated_repo"}],
85
+ 200,
86
+ )
87
+ result = repository.list_repositories(organization="test_org", page=3, limit=100)
88
+ mock_client._request.assert_called_once_with(
89
+ method="GET",
90
+ endpoint="/orgs/test_org/repos",
91
+ params={"page": 3, "limit": 100},
92
+ )
93
+ assert result == ([{"id": 6, "name": "org_paginated_repo"}], 200)
94
+
95
+ def test_list_repositories_empty_result(self, repository, mock_client):
96
+ """Test list_repositories with empty result."""
97
+ with patch("gitea.repository.repository.process_response") as mock_process:
98
+ mock_process.return_value = ([], 200)
99
+ result = repository.list_repositories()
100
+ mock_client._request.assert_called_once()
101
+ assert result == ([], 200)
102
+
103
+ def test_list_repositories_error_response(self, repository, mock_client):
104
+ """Test list_repositories with error response."""
105
+ with patch("gitea.repository.repository.process_response") as mock_process:
106
+ mock_process.return_value = ({"error": "Not Found"}, 404)
107
+ result = repository.list_repositories(username="nonexistent")
108
+ mock_client._request.assert_called_once()
109
+ assert result == ({"error": "Not Found"}, 404)
110
+
111
+ def test_list_repositories_with_kwargs(self, repository, mock_client):
112
+ """Test list_repositories passing additional kwargs to _get method."""
113
+ with patch("gitea.repository.repository.process_response") as mock_process:
114
+ mock_process.return_value = ([{"id": 1, "name": "repo1"}], 200)
115
+ result = repository.list_repositories(headers={"Custom": "Header"})
116
+ mock_client._request.assert_called_once_with(
117
+ method="GET", endpoint="/user/repos", params={}, headers={"Custom": "Header"}
118
+ )
119
+ assert result == ([{"id": 1, "name": "repo1"}], 200)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes