From fe1cc38e2f49f97f1cce0c573cbdfe39ef23c0be Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 08:24:18 +0000 Subject: [PATCH 01/11] Add initial API tests for user and repo --- .../test_users.cpython-312-pytest-8.4.1.pyc | Bin 0 -> 11076 bytes tests/api/test_users.py | 103 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 tests/api/__pycache__/test_users.cpython-312-pytest-8.4.1.pyc create mode 100644 tests/api/test_users.py diff --git a/tests/api/__pycache__/test_users.cpython-312-pytest-8.4.1.pyc b/tests/api/__pycache__/test_users.cpython-312-pytest-8.4.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03bec7c8b04eba64560bad2d2bc341154136ea8e GIT binary patch literal 11076 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 literal 0 HcmV?d00001 diff --git a/tests/api/test_users.py b/tests/api/test_users.py new file mode 100644 index 0000000000000..31822a711bb30 --- /dev/null +++ b/tests/api/test_users.py @@ -0,0 +1,103 @@ +import requests +import random +import string + +BASE_URL = "http://localhost:3000" +API_TOKEN = "ed10e99db13b34b5b45be5c44d1197eb1f161a32" + +def test_get_users(): + headers = { + "Authorization": f"token {API_TOKEN}" + } + + response = requests.get(f"{BASE_URL}/api/v1/admin/users", headers=headers) + + assert response.status_code == 200 + users = response.json() + assert isinstance(users, list) + + +def generate_random_username(prefix="user"): + suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=5)) + return f"{prefix}_{suffix}" + +def test_create_user(): + headers = { + "Authorization": f"token {API_TOKEN}" + } + + username = generate_random_username() + payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False + } + + response = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=payload) + + assert response.status_code == 201, f"Response: {response.text}" + user = response.json() + assert user["username"] == username + +def test_list_user_repos(): + headers = { + "Authorization": f"token {API_TOKEN}" + } + + # Create a new user first + username = generate_random_username() + payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False + } + create_response = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=payload) + assert create_response.status_code == 201 + + # Now fetch their repositories + list_response = requests.get(f"{BASE_URL}/api/v1/users/{username}/repos", headers=headers) + + assert list_response.status_code == 200 + repos = list_response.json() + assert isinstance(repos, list) + assert len(repos) == 0 # New user should have no repos + +def test_create_repo_for_user(): + headers = { + "Authorization": f"token {API_TOKEN}" + } + + # Step 1: Create a new user + username = generate_random_username() + payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False + } + create_user_response = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=payload) + assert create_user_response.status_code == 201 + + # Step 2: Create a repository for the new user + repo_name = f"repo_{username}" + repo_payload = { + "name": repo_name, + "description": "This is a test repo", + "private": False, + "auto_init": True + } + create_repo_response = requests.post( + f"{BASE_URL}/api/v1/admin/users/{username}/repos", + headers=headers, + json=repo_payload + ) + + assert create_repo_response.status_code == 201, f"Error: {create_repo_response.text}" + repo = create_repo_response.json() + assert repo["name"] == repo_name + assert repo["owner"]["login"] == username From f578a04bf5d0bab4fc8c16307164e1439e641b11 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 08:46:47 +0000 Subject: [PATCH 02/11] Add GitHub Actions workflow for API tests --- .github/workflows/api-tests.yml | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/api-tests.yml diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml new file mode 100644 index 0000000000000..3dd032310318a --- /dev/null +++ b/.github/workflows/api-tests.yml @@ -0,0 +1,36 @@ +name: API Tests + +on: + push: + paths: + - 'tests/api/**' + - '.github/workflows/api-tests.yml' + pull_request: + paths: + - 'tests/api/**' + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest requests + + - name: Run tests + env: + API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} + run: | + echo "BASE_URL = 'http://localhost:3000'" > config.py + echo "API_TOKEN = '${API_TOKEN}'" >> config.py + pytest tests/api -v From 9b6a142f42ea4e0522c7b4f371a4ad10a34c1bdc Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 09:45:25 +0000 Subject: [PATCH 03/11] Update BASE_URL to public Gitea server --- tests/api/test_users.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api/test_users.py b/tests/api/test_users.py index 31822a711bb30..e7dd47b6782b5 100644 --- a/tests/api/test_users.py +++ b/tests/api/test_users.py @@ -2,7 +2,7 @@ import random import string -BASE_URL = "http://localhost:3000" +BASE_URL = "http://18.202.226.4:3000/" API_TOKEN = "ed10e99db13b34b5b45be5c44d1197eb1f161a32" def test_get_users(): From d1df7a5de42b5392b2e712c12c192a26fb226051 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 09:52:44 +0000 Subject: [PATCH 04/11] updated yml to connt to the remote host --- .github/workflows/api-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index 3dd032310318a..a3c4bd729f319 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -31,6 +31,6 @@ jobs: env: API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} run: | - echo "BASE_URL = 'http://localhost:3000'" > config.py + echo "BASE_URL = 'http://18.202.226.4:3000/'" > config.py echo "API_TOKEN = '${API_TOKEN}'" >> config.py pytest tests/api -v From b32fd747ae942dd1a0b4669ebb3cb9e7a8e0721f Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 19:28:41 +0000 Subject: [PATCH 05/11] fixed token --- .github/workflows/api-tests.yml | 2 +- tests/api/test_users.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index a3c4bd729f319..cc28d7a55e864 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -31,6 +31,6 @@ jobs: env: API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} run: | - echo "BASE_URL = 'http://18.202.226.4:3000/'" > config.py + echo "BASE_URL = 'http://54.247.213.28:3000/'" > config.py echo "API_TOKEN = '${API_TOKEN}'" >> config.py pytest tests/api -v diff --git a/tests/api/test_users.py b/tests/api/test_users.py index e7dd47b6782b5..34f1fc4fd739d 100644 --- a/tests/api/test_users.py +++ b/tests/api/test_users.py @@ -2,7 +2,7 @@ import random import string -BASE_URL = "http://18.202.226.4:3000/" +BASE_URL = "http://54.247.213.28:3000/" API_TOKEN = "ed10e99db13b34b5b45be5c44d1197eb1f161a32" def test_get_users(): From ded2be7ceb0c03f3fc86757478c0ea471d062d49 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Tue, 5 Aug 2025 19:38:41 +0000 Subject: [PATCH 06/11] Fix: load token and URL from config.py --- tests/api/config.py | 2 ++ tests/api/test_users.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 tests/api/config.py diff --git a/tests/api/config.py b/tests/api/config.py new file mode 100644 index 0000000000000..bde7aebd8848a --- /dev/null +++ b/tests/api/config.py @@ -0,0 +1,2 @@ +BASE_URL = 'http://54.247.213.28:3000' +API_TOKEN = 'f1600abdf735b9e11dbfc45e57db04319d58235e' diff --git a/tests/api/test_users.py b/tests/api/test_users.py index 34f1fc4fd739d..c4221dcc2e6f4 100644 --- a/tests/api/test_users.py +++ b/tests/api/test_users.py @@ -2,8 +2,8 @@ import random import string -BASE_URL = "http://54.247.213.28:3000/" -API_TOKEN = "ed10e99db13b34b5b45be5c44d1197eb1f161a32" +# Load from config.py written in GitHub Actions +from config import BASE_URL, API_TOKEN def test_get_users(): headers = { From d9a6faf57cc308712e0a400c96d18eeabd9be621 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Mon, 11 Aug 2025 09:37:13 +0300 Subject: [PATCH 07/11] added pem key --- gitea-tests.pem | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 gitea-tests.pem diff --git a/gitea-tests.pem b/gitea-tests.pem new file mode 100644 index 0000000000000..65c9ec0e01248 --- /dev/null +++ b/gitea-tests.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAtpFEkGJbDhqrrjAk44uAf5Wr5/nPTso1hGdXVyeXKY/f44kk +G03FUdcydLtO9SeMZeuHjDNOZIDf4N5eEMEYQWZazJRRESzFG1XzokqO4NqjqlxX +o/67hxM+UGiZAlgOyPwQj9ewhg5ZMrv2kcHbTmEyxiTkbkb+d9+ryqKkAlO3KqJW +P9SU3mtuCLG01Tqm0dBaZgxnpLqjBK/OOMW4G8KKl6q92+7GEF/XNP8G5gWDdMiI +fEMzRVorqALGxKTjcvMgIKG9dmeI5hE7cgnVzdlQ6xSZ2i/awGPNGF33VIaHCU3S +Upve8nxsybizEijkXuhbhnhco2w+E1iEBgmnRQIDAQABAoIBAFArjItG1atk5N0S +ATD28o+UPzAYEAQOYd/prX31Qbkbl/qIH5Xp2ettb5e5JRwcqNeczSIw6YzS1v0d +SPtcf/VAKEFMJClBmrC9VsZ+rS1qdZJ7CHVYiCrxtVyEAiT4XE2/+tnfooHLzTmt +NsKc+Vv67Nv8GV+fx2EGlJ7gOttV/8Hy3oT4jqkvTJWlenzxOJdGQiVXtos8YpX8 +MM/PkS5Sauu6OU5ArSXXHg7C/bNOYgWKXfDP9MQn8IxflSzVAOn+Ad7dXkjTC3Ua +a4xv9PeRVekfEi3WmahQxhXDVTrVZwiGUJ8hxZMvNteNPMWcSJdlo014Ly/Qjx5M +jlBKhOUCgYEA4UygCtTbSf5zeilqESqfnAzH+yhieAKA2E6g67zX0h76UKMiU1Vc +efNQEiFYFeIbhXUBLCdiT7C8gpgm5QvUWpsNFjqSKV844ZBc2TZXsB6J/JEZKUuN +6x3SRKNmuFtiW7J78hdLCHj/l+FukdtSRBNQco+cOFs5HT55qLD8LvcCgYEAz3H6 +WxM876n7npxJyCtXkyYuMQGafqUk4WHWtlPTWIQw7DwqgeF0p4SOkwYIabI6ILEY +gAAbQVrFmChvh/tQmDk29gubKdMe7JM3nIRXBPaDwSxnBs0EjgAJiXdYlpCCHVIX +4Za2Vi1M9N7cGZecVT0sBUuMaBmya/IBeyOWQKMCgYBX46pzT0IUhXzK5SkJdVU6 +bQn+gmyXYHKe7117WPngcFE578nONHiU4kQULonMT55o25IPhXWmnM2NLInPxGOc +zOu4BjVKimkIJWbzHW3ruJ4ftwLXxy+fzsxeFlhWBuBB4UjU0h1lOr6Ko1ic8bAP ++nDhoABTQ9LuA5c2JYTbVQKBgC7CDiBBMdcDhYe2ypqnylGMpZS+O8iYCLwUhYUL +V/P3t99HoH0uCFFJ+6kADx1j4t5DjLYtT/dnMmqdkqYf64akPtMuwoam462HcV2C +JusjdYcxLvfFdmVbdMrbb8hgQjPBsUhT5D2AcHwxT4MlPUOpSibXZIqCYEkcf2D2 +IIPpAoGADaSAsjcGFBWgQco2i/gUHxMuNE425mcNcXQ+zutSNyZ2TVpLXJukIjsx +cB8YqTQ16X0wls79fu92A4QfYpG4POXn+usD9T5r4R/b+ofZCTHEYi1j4MCcUhcQ +AK6vnjryobdhniZCFREdcX0yPjT0ZC0pZcVarqVu4tLoRHFLqcs= +-----END RSA PRIVATE KEY----- \ No newline at end of file From b278e6572a9ef936420a7636b81924b4aa8124e6 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Mon, 11 Aug 2025 09:45:40 +0300 Subject: [PATCH 08/11] modified config file --- tests/api/config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/api/config.py b/tests/api/config.py index bde7aebd8848a..f6ed13d4fb7d5 100644 --- a/tests/api/config.py +++ b/tests/api/config.py @@ -1,2 +1,3 @@ -BASE_URL = 'http://54.247.213.28:3000' -API_TOKEN = 'f1600abdf735b9e11dbfc45e57db04319d58235e' +import os +API_TOKEN = 'b32712d989aeee1e78f112ba4fc8e9f93ae7fe78' +BASE_URL = os.getenv('GITEA_URL', 'http://localhost:3000') \ No newline at end of file From a8f6c563a2b2bca7cb6ae7e6f7de102cee16a129 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Mon, 11 Aug 2025 09:50:37 +0300 Subject: [PATCH 09/11] config update --- .github/workflows/api-tests.yml | 2 +- tests/api/config.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index cc28d7a55e864..fafcc1b9c1a66 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -31,6 +31,6 @@ jobs: env: API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} run: | - echo "BASE_URL = 'http://54.247.213.28:3000/'" > config.py + echo "BASE_URL = 'http://108.130.122.66:3000/'" > config.py echo "API_TOKEN = '${API_TOKEN}'" >> config.py pytest tests/api -v diff --git a/tests/api/config.py b/tests/api/config.py index f6ed13d4fb7d5..328ff28a90470 100644 --- a/tests/api/config.py +++ b/tests/api/config.py @@ -1,3 +1,4 @@ import os API_TOKEN = 'b32712d989aeee1e78f112ba4fc8e9f93ae7fe78' -BASE_URL = os.getenv('GITEA_URL', 'http://localhost:3000') \ No newline at end of file +#BASE_URL = os.getenv('GITEA_URL', 'http://localhost:3000') +BASE_URL = 'http://108.130.122.66:3000' \ No newline at end of file From a075ef76906c5d7da4e6990ef8f94dd23e41daba Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Mon, 11 Aug 2025 09:55:45 +0300 Subject: [PATCH 10/11] updated token --- tests/api/config.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/api/config.py b/tests/api/config.py index 328ff28a90470..46e67eff4cd24 100644 --- a/tests/api/config.py +++ b/tests/api/config.py @@ -1,4 +1,10 @@ import os -API_TOKEN = 'b32712d989aeee1e78f112ba4fc8e9f93ae7fe78' + +#local API_TOKEN +#API_TOKEN = 'b32712d989aeee1e78f112ba4fc8e9f93ae7fe78' + +#remote API_TOKEN: +API_TOKEN = 'f1600abdf735b9e11dbfc45e57db04319d58235e' + #BASE_URL = os.getenv('GITEA_URL', 'http://localhost:3000') BASE_URL = 'http://108.130.122.66:3000' \ No newline at end of file From 27de0ac3cd0ef224d66d36d63edf25b54a72c804 Mon Sep 17 00:00:00 2001 From: AdhamSaif16 Date: Mon, 11 Aug 2025 17:57:54 +0300 Subject: [PATCH 11/11] added new tests --- .github/workflows/api-tests.yml | 2 +- tests/api/config.py | 2 +- tests/api/test_auth.py | 16 +++++++++ tests/api/test_branches.py | 50 ++++++++++++++++++++++++++ tests/api/test_duplicate_users.py | 38 ++++++++++++++++++++ tests/api/test_issues.py | 58 +++++++++++++++++++++++++++++++ tests/api/test_repos.py | 55 +++++++++++++++++++++++++++++ 7 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 tests/api/test_auth.py create mode 100644 tests/api/test_branches.py create mode 100644 tests/api/test_duplicate_users.py create mode 100644 tests/api/test_issues.py create mode 100644 tests/api/test_repos.py diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index fafcc1b9c1a66..7bd754e0a539a 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -31,6 +31,6 @@ jobs: env: API_TOKEN: ${{ secrets.GITEA_API_TOKEN }} run: | - echo "BASE_URL = 'http://108.130.122.66:3000/'" > config.py + echo "BASE_URL = 'http://52.211.112.5:3000/'" > config.py echo "API_TOKEN = '${API_TOKEN}'" >> config.py pytest tests/api -v diff --git a/tests/api/config.py b/tests/api/config.py index 46e67eff4cd24..06eb2fa967f88 100644 --- a/tests/api/config.py +++ b/tests/api/config.py @@ -7,4 +7,4 @@ API_TOKEN = 'f1600abdf735b9e11dbfc45e57db04319d58235e' #BASE_URL = os.getenv('GITEA_URL', 'http://localhost:3000') -BASE_URL = 'http://108.130.122.66:3000' \ No newline at end of file +BASE_URL = 'http://52.211.112.5:3000' \ No newline at end of file diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py new file mode 100644 index 0000000000000..fca27a390b0bd --- /dev/null +++ b/tests/api/test_auth.py @@ -0,0 +1,16 @@ +import requests +from config import BASE_URL, API_TOKEN # uses the same config.py you already generate in CI + +def test_me_endpoint_returns_current_user_and_is_admin(): + headers = {"Authorization": f"token {API_TOKEN}"} + + r = requests.get(f"{BASE_URL}/api/v1/user", headers=headers) + assert r.status_code == 200, f"Unexpected status: {r.status_code} body={r.text}" + + me = r.json() + # Basic shape checks + for key in ["id", "login", "email", "is_admin", "created"]: + assert key in me, f"Missing key '{key}' in /user response: {me}" + + # If the token is an admin (your token is), this should be True + assert me["is_admin"] is True diff --git a/tests/api/test_branches.py b/tests/api/test_branches.py new file mode 100644 index 0000000000000..ef6fe4ee70c76 --- /dev/null +++ b/tests/api/test_branches.py @@ -0,0 +1,50 @@ +import requests +import random +import string +from config import BASE_URL, API_TOKEN + +def _headers(): + return {"Authorization": f"token {API_TOKEN}"} + +def _rand(prefix): + return prefix + "_" + "".join(random.choices(string.ascii_lowercase + string.digits, k=6)) + +def test_list_branches_contains_default_branch(): + headers = _headers() + + # 1) Create owner user + username = _rand("owner") + user_payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False, + } + r_user = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=user_payload) + assert r_user.status_code == 201, f"User create failed: {r_user.status_code} {r_user.text}" + + # 2) Create repo with auto_init so default branch exists + repo_name = _rand("repo") + repo_payload = {"name": repo_name, "description": "Branches test", "private": False, "auto_init": True} + r_repo = requests.post(f"{BASE_URL}/api/v1/admin/users/{username}/repos", headers=headers, json=repo_payload) + assert r_repo.status_code == 201, f"Repo create failed: {r_repo.status_code} {r_repo.text}" + + # 3) Get repo to read its default_branch + r_get = requests.get(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}", headers=headers) + assert r_get.status_code == 200, f"Get repo failed: {r_get.status_code} {r_get.text}" + default_branch = r_get.json().get("default_branch") + assert default_branch, "Expected default_branch to be set" + + # 4) List branches and verify default branch is present + r_branches = requests.get(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}/branches", headers=headers) + assert r_branches.status_code == 200, f"List branches failed: {r_branches.status_code} {r_branches.text}" + branches = r_branches.json() + assert isinstance(branches, list) and branches, "Expected non-empty branches list" + + names = {b.get("name") for b in branches} + assert default_branch in names, f"default branch '{default_branch}' not found in {names}" + + # 5) Cleanup (best-effort) + requests.delete(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}", headers=headers) + requests.delete(f"{BASE_URL}/api/v1/admin/users/{username}", headers=headers) diff --git a/tests/api/test_duplicate_users.py b/tests/api/test_duplicate_users.py new file mode 100644 index 0000000000000..db8d1c1c0665f --- /dev/null +++ b/tests/api/test_duplicate_users.py @@ -0,0 +1,38 @@ +import requests +import string +import random +from config import BASE_URL, API_TOKEN + +def _headers(): + return {"Authorization": f"token {API_TOKEN}"} + +def _rand_username(prefix="dupuser"): + return prefix + "_" + "".join(random.choices(string.ascii_lowercase + string.digits, k=6)) + +def test_create_duplicate_user_should_fail(): + headers = _headers() + username = _rand_username() + payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False, + } + + # First creation should succeed + r1 = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=payload) + assert r1.status_code == 201, f"First create failed: {r1.status_code} {r1.text}" + + # Second creation with the same username should fail + r2 = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=payload) + + # Gitea typically returns 422 for duplicate username; some setups may return 409 + assert r2.status_code in (422, 409), f"Expected 422/409 on duplicate, got {r2.status_code} {r2.text}" + + # Error body should hint user exists + err_text = r2.text.lower() + assert ("exist" in err_text) or ("already" in err_text), f"Unexpected error message: {r2.text}" + + # Cleanup: best-effort delete the user we created (ignore errors) + requests.delete(f"{BASE_URL}/api/v1/admin/users/{username}", headers=headers) diff --git a/tests/api/test_issues.py b/tests/api/test_issues.py new file mode 100644 index 0000000000000..62013542791d5 --- /dev/null +++ b/tests/api/test_issues.py @@ -0,0 +1,58 @@ +import requests +import random +import string +from config import BASE_URL, API_TOKEN + +def _headers(): + return {"Authorization": f"token {API_TOKEN}"} + +def _rand(prefix): + return prefix + "_" + "".join(random.choices(string.ascii_lowercase + string.digits, k=6)) + +def test_create_issue_and_list_it(): + headers = _headers() + + # 1) Create owner user + username = _rand("owner") + user_payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False, + } + r_user = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=user_payload) + assert r_user.status_code == 201, f"User create failed: {r_user.status_code} {r_user.text}" + + # 2) Create repo + repo_name = _rand("repo") + repo_payload = {"name": repo_name, "description": "Issues test", "private": False, "auto_init": True} + r_repo = requests.post(f"{BASE_URL}/api/v1/admin/users/{username}/repos", headers=headers, json=repo_payload) + assert r_repo.status_code == 201, f"Repo create failed: {r_repo.status_code} {r_repo.text}" + + # 3) Create an issue + title = f"Issue { _rand('t') }" + body = "Created by API test" + issue_payload = {"title": title, "body": body} + r_issue = requests.post( + f"{BASE_URL}/api/v1/repos/{username}/{repo_name}/issues", + headers=headers, + json=issue_payload + ) + assert r_issue.status_code == 201, f"Issue create failed: {r_issue.status_code} {r_issue.text}" + issue = r_issue.json() + number = issue.get("number") + assert number, f"Expected issue number, got {issue}" + assert issue["title"] == title + assert issue["state"] == "open" + + # 4) List issues and verify the created one is present + r_list = requests.get(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}/issues", headers=headers) + assert r_list.status_code == 200, f"Issues list failed: {r_list.status_code} {r_list.text}" + issues = r_list.json() + numbers = {i.get("number") for i in issues} + assert number in numbers, f"Issue #{number} not found in list: {numbers}" + + # 5) Cleanup (best-effort) + requests.delete(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}", headers=headers) + requests.delete(f"{BASE_URL}/api/v1/admin/users/{username}", headers=headers) diff --git a/tests/api/test_repos.py b/tests/api/test_repos.py new file mode 100644 index 0000000000000..4c64be4b21f6c --- /dev/null +++ b/tests/api/test_repos.py @@ -0,0 +1,55 @@ +import requests +import random +import string +from config import BASE_URL, API_TOKEN + +def _headers(): + return {"Authorization": f"token {API_TOKEN}"} + +def _rand(s="user"): + return s + "_" + "".join(random.choices(string.ascii_lowercase + string.digits, k=6)) + +def test_create_repo_then_get_details(): + headers = _headers() + + # 1) Create a user (owner) + username = _rand("owner") + user_payload = { + "email": f"{username}@example.com", + "username": username, + "password": "TestPass123!", + "must_change_password": False, + "send_notify": False, + } + r_user = requests.post(f"{BASE_URL}/api/v1/admin/users", headers=headers, json=user_payload) + assert r_user.status_code == 201, f"User create failed: {r_user.status_code} {r_user.text}" + + # 2) Create a repository for that user + repo_name = _rand("repo") + repo_payload = { + "name": repo_name, + "description": "API test repo", + "private": False, + "auto_init": True, # so default branch & README exist + } + r_repo = requests.post(f"{BASE_URL}/api/v1/admin/users/{username}/repos", headers=headers, json=repo_payload) + assert r_repo.status_code == 201, f"Repo create failed: {r_repo.status_code} {r_repo.text}" + created = r_repo.json() + assert created["name"] == repo_name + assert created["owner"]["login"] == username + + # 3) GET repo details and verify fields + r_get = requests.get(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}", headers=headers) + assert r_get.status_code == 200, f"Get repo failed: {r_get.status_code} {r_get.text}" + repo = r_get.json() + + # Basic shape checks + assert repo["name"] == repo_name + assert repo["owner"]["login"] == username + assert repo["private"] is False + # default branch commonly 'main' or 'master' depending on settings; assert it's non-empty + assert repo.get("default_branch"), f"Expected default_branch to be set, got {repo.get('default_branch')}" + + # 4) Cleanup (best-effort) + requests.delete(f"{BASE_URL}/api/v1/repos/{username}/{repo_name}", headers=headers) + requests.delete(f"{BASE_URL}/api/v1/admin/users/{username}", headers=headers)