mirror of
https://github.com/arkorty/B.Tech-Project-III.git
synced 2026-04-19 12:41:48 +00:00
185 lines
6.7 KiB
Python
185 lines
6.7 KiB
Python
"""
|
|
Test Milestone 17: Jira API client.
|
|
Tests real API connectivity — your .env must have valid Jira credentials.
|
|
"""
|
|
import asyncio
|
|
import os
|
|
import sys
|
|
|
|
# Fix Windows console encoding for emoji support
|
|
if sys.platform == "win32":
|
|
import codecs
|
|
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.buffer, errors="replace")
|
|
sys.stderr = codecs.getwriter("utf-8")(sys.stderr.buffer, errors="replace")
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
|
|
async def test_config_loaded():
|
|
"""Test that all Jira config vars are present."""
|
|
from backend.config import (
|
|
JIRA_BASE_URL, JIRA_EMAIL, JIRA_API_TOKEN,
|
|
JIRA_DEFAULT_PROJECT, ENABLE_JIRA
|
|
)
|
|
checks = {
|
|
"JIRA_BASE_URL": JIRA_BASE_URL,
|
|
"JIRA_EMAIL": JIRA_EMAIL,
|
|
"JIRA_API_TOKEN": JIRA_API_TOKEN,
|
|
"JIRA_DEFAULT_PROJECT": JIRA_DEFAULT_PROJECT,
|
|
}
|
|
all_pass = True
|
|
for name, val in checks.items():
|
|
ok = bool(val and len(val) >= 2)
|
|
status = "✅" if ok else "❌ MISSING"
|
|
if not ok:
|
|
all_pass = False
|
|
print(f" {status} {name}: {val[:30] if val else '(empty)'}...")
|
|
assert all_pass, "Fix missing Jira config vars in .env before continuing"
|
|
print(f" ✅ ENABLE_JIRA: {ENABLE_JIRA}")
|
|
|
|
|
|
async def test_connection():
|
|
"""Test that credentials are valid and can reach the Jira API."""
|
|
from backend.integrations.jira_client import test_connection
|
|
|
|
print("\nTesting Jira API connection...")
|
|
result = await test_connection()
|
|
|
|
assert result.get("ok"), f"Connection failed: {result.get('error')}"
|
|
print(f" ✅ Connected as: {result['display_name']} ({result['email']})")
|
|
print(f" Account ID: {result['account_id']}")
|
|
|
|
|
|
async def test_list_projects():
|
|
"""Test listing projects — must return at least one."""
|
|
from backend.integrations.jira_client import list_projects
|
|
from backend.config import JIRA_DEFAULT_PROJECT
|
|
|
|
print("\nTesting list_projects()...")
|
|
projects = await list_projects()
|
|
|
|
assert len(projects) > 0, "No projects returned. Make sure your account has at least one project."
|
|
print(f" ✅ Found {len(projects)} project(s):")
|
|
for p in projects[:5]:
|
|
print(f" [{p['key']}] {p['name']}")
|
|
|
|
keys = [p["key"] for p in projects]
|
|
assert JIRA_DEFAULT_PROJECT in keys, (
|
|
f"JIRA_DEFAULT_PROJECT '{JIRA_DEFAULT_PROJECT}' not found in your projects: {keys}\n"
|
|
"Update JIRA_DEFAULT_PROJECT in .env to one of the listed keys."
|
|
)
|
|
print(f" ✅ Default project '{JIRA_DEFAULT_PROJECT}' exists")
|
|
|
|
|
|
async def test_list_issue_types():
|
|
"""Test listing issue types for the default project."""
|
|
from backend.integrations.jira_client import list_issue_types
|
|
from backend.config import JIRA_DEFAULT_PROJECT
|
|
|
|
print("\nTesting list_issue_types()...")
|
|
types = await list_issue_types(JIRA_DEFAULT_PROJECT)
|
|
|
|
assert len(types) > 0, f"No issue types returned for project {JIRA_DEFAULT_PROJECT}"
|
|
names = [t["name"] for t in types]
|
|
print(f" ✅ Issue types in '{JIRA_DEFAULT_PROJECT}': {names}")
|
|
|
|
|
|
async def test_create_and_get_issue():
|
|
"""Test creating a real Jira issue and then retrieving it."""
|
|
from backend.integrations.jira_client import create_issue, get_issue
|
|
from backend.config import JIRA_DEFAULT_PROJECT
|
|
|
|
print("\nTesting create_issue() and get_issue()...")
|
|
|
|
result = await create_issue(
|
|
project_key=JIRA_DEFAULT_PROJECT,
|
|
summary="[ThirdEye Test] Milestone 17 verification ticket",
|
|
description=(
|
|
"This ticket was created automatically by the ThirdEye test suite.\n\n"
|
|
"It verifies that the Jira API client can create issues successfully.\n\n"
|
|
"Safe to close or delete."
|
|
),
|
|
issue_type="Task",
|
|
priority="Low",
|
|
labels=["thirdeye", "test", "automated"],
|
|
)
|
|
|
|
assert result.get("ok"), f"create_issue failed: {result.get('error')} — details: {result.get('details')}"
|
|
issue_key = result["key"]
|
|
print(f" ✅ Created issue: {issue_key}")
|
|
print(f" URL: {result['url']}")
|
|
|
|
# Retrieve it
|
|
issue = await get_issue(issue_key)
|
|
assert issue["key"] == issue_key
|
|
assert "ThirdEye Test" in issue["summary"]
|
|
assert issue["status"] in ("To Do", "Open", "Backlog", "New")
|
|
print(f" ✅ Retrieved issue: [{issue['key']}] {issue['summary']}")
|
|
print(f" Status: {issue['status']} | Priority: {issue['priority']}")
|
|
|
|
return issue_key
|
|
|
|
|
|
async def test_search_issues(issue_key: str):
|
|
"""Test searching issues by JQL."""
|
|
from backend.integrations.jira_client import search_issues
|
|
from backend.config import JIRA_DEFAULT_PROJECT
|
|
|
|
print("\nTesting search_issues() via JQL...")
|
|
jql = f'project = {JIRA_DEFAULT_PROJECT} AND labels = "thirdeye" AND labels = "test" ORDER BY created DESC'
|
|
results = await search_issues(jql, max_results=5)
|
|
|
|
assert len(results) > 0, f"Expected at least one result for JQL: {jql}"
|
|
keys = [r["key"] for r in results]
|
|
assert issue_key in keys, f"Newly created issue {issue_key} not found in search results"
|
|
print(f" ✅ JQL search returned {len(results)} result(s), including {issue_key}")
|
|
|
|
|
|
async def test_add_comment(issue_key: str):
|
|
"""Test adding a comment to an existing issue."""
|
|
from backend.integrations.jira_client import add_comment
|
|
|
|
print("\nTesting add_comment()...")
|
|
result = await add_comment(
|
|
issue_key,
|
|
"ThirdEye test comment — verifying comment API works correctly."
|
|
)
|
|
assert result.get("ok"), f"add_comment failed: {result.get('error')}"
|
|
print(f" ✅ Comment added to {issue_key} (comment id: {result.get('id')})")
|
|
|
|
|
|
async def test_adf_conversion():
|
|
"""Test that _text_to_adf produces valid ADF structure."""
|
|
from backend.integrations.jira_client import _text_to_adf
|
|
|
|
print("\nTesting ADF conversion...")
|
|
text = "This is paragraph one.\n\nThis is paragraph two.\n\n- Bullet A\n- Bullet B"
|
|
adf = _text_to_adf(text)
|
|
|
|
assert adf["type"] == "doc"
|
|
assert adf["version"] == 1
|
|
assert len(adf["content"]) >= 2
|
|
print(f" ✅ ADF produced {len(adf['content'])} content block(s)")
|
|
|
|
# Empty text should not crash
|
|
adf_empty = _text_to_adf("")
|
|
assert adf_empty["type"] == "doc"
|
|
print(" ✅ Empty text handled gracefully")
|
|
|
|
|
|
async def main():
|
|
print("Running Milestone 17 tests...\n")
|
|
await test_config_loaded()
|
|
await test_connection()
|
|
await test_list_projects()
|
|
await test_list_issue_types()
|
|
issue_key = await test_create_and_get_issue()
|
|
await test_search_issues(issue_key)
|
|
await test_add_comment(issue_key)
|
|
await test_adf_conversion()
|
|
print(f"\n🎉 MILESTONE 17 PASSED — Jira API client working. Test ticket: {issue_key}")
|
|
|
|
|
|
asyncio.run(main())
|
|
|