Skip to content

Commit

Permalink
Add iteration work items (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
timmo001 committed Jun 15, 2024
1 parent be22f5e commit 443c12a
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 0 deletions.
35 changes: 35 additions & 0 deletions aioazuredevops/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
VersionControl,
)
from .models.iteration import Iteration, IterationAttributes
from .models.iteration_work_item import (
IterationWorkItemsResult,
WorkItemRelation,
WorkItemRelationTarget,
)
from .models.wiql import WIQLColumn, WIQLResult, WIQLWorkItem
from .models.work_item import (
WorkItem,
Expand Down Expand Up @@ -370,6 +375,36 @@ async def get_iteration(
url=iteration["url"],
)

async def get_iteration_work_items(
self,
organization: str,
project: str,
iteration_id: str,
) -> IterationWorkItemsResult | None:
"""Get Azure DevOps iteration work items."""
response: aiohttp.ClientResponse = await self._get(
f"{DEFAULT_BASE_URL}/{organization}/{project}/_apis/work/teamsettings/iterations/{iteration_id}/workitems?api-version={DEFAULT_API_VERSION}"
)
if response.status != 200:
return None
if (data := await response.json()) is None:
return None

return IterationWorkItemsResult(
work_item_relations=[
WorkItemRelation(
rel=work_item_relation.get("rel", None),
source=work_item_relation.get("source", None),
target=WorkItemRelationTarget(
id=work_item_relation["target"]["id"],
url=work_item_relation["target"]["url"],
),
)
for work_item_relation in data["workItemRelations"]
],
url=data["url"],
)

async def get_work_item_ids_from_wiql(
self,
organization: str,
Expand Down
29 changes: 29 additions & 0 deletions aioazuredevops/models/iteration_work_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Model for Iteration Work Item."""

from dataclasses import dataclass
from typing import Any


@dataclass
class WorkItemRelationTarget:
"""Work item relation target."""

id: int
url: str


@dataclass
class WorkItemRelation:
"""Work item relation."""

rel: Any
source: Any
target: WorkItemRelationTarget


@dataclass
class IterationWorkItemsResult:
"""Iteration work items result."""

work_item_relations: list[WorkItemRelation]
url: str
7 changes: 7 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@
"value": [RESPONSE_JSON_DEVOPS_ITERATION],
}

RESPONSE_JSON_DEVOPS_ITERATION_WORK_ITEMS: Final[dict] = {
"workItemRelations": [
{"rel": None, "source": None, "target": {"id": 1, "url": "testurl"}}
],
"url": "testurl",
}

RESPONSE_JSON_DEVOPS_WIQL_RESULT: Final[dict] = {
"queryType": "testqueryType",
"queryResultType": "testqueryResultType",
Expand Down
3 changes: 3 additions & 0 deletions tests/__snapshots__/test_client.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# name: test_get_iteration[iteration]
Iteration(id='abc123', name='testname', path='testname\\Sprint 1', attributes=IterationAttributes(start_date='2021-01-01T00:00:00Z', finish_date='2021-01-31T00:00:00Z', time_frame='current'), url='testurl')
# ---
# name: test_get_iteration_work_items[iteration_work_items]
IterationWorkItemsResult(work_item_relations=[WorkItemRelation(rel=None, source=None, target=WorkItemRelationTarget(id=1, url='testurl'))], url='testurl')
# ---
# name: test_get_iterations[iterations]
list([
Iteration(id='abc123', name='testname', path='testname\\Sprint 1', attributes=IterationAttributes(start_date='2021-01-01T00:00:00Z', finish_date='2021-01-31T00:00:00Z', time_frame='current'), url='testurl'),
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
RESPONSE_JSON_DEVOPS_BUILD,
RESPONSE_JSON_DEVOPS_BUILDS,
RESPONSE_JSON_DEVOPS_ITERATION,
RESPONSE_JSON_DEVOPS_ITERATION_WORK_ITEMS,
RESPONSE_JSON_DEVOPS_ITERATIONS,
RESPONSE_JSON_DEVOPS_PROJECT,
RESPONSE_JSON_DEVOPS_WIQL_RESULT,
Expand Down Expand Up @@ -88,6 +89,12 @@ def mock_aioresponse():
status=200,
repeat=True,
)
mocker.get(
f"{DEFAULT_BASE_URL}/{ORGANIZATION}/{PROJECT}/_apis/work/teamsettings/iterations/abc123/workitems?api-version={DEFAULT_API_VERSION}",
payload=RESPONSE_JSON_DEVOPS_ITERATION_WORK_ITEMS,
status=200,
repeat=True,
)
mocker.post(
f"{DEFAULT_BASE_URL}/{ORGANIZATION}/{PROJECT}/_apis/wit/wiql?api-version={DEFAULT_API_VERSION}",
payload=RESPONSE_JSON_DEVOPS_WIQL_RESULT,
Expand Down
47 changes: 47 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,53 @@ async def test_get_iteration(
assert empty_iteration is None


@pytest.mark.asyncio
async def test_get_iteration_work_items(
devops_client: DevOpsClient,
mock_aioresponse: aioresponses,
snapshot: SnapshotAssertion,
) -> None:
"""Test the get_iteration_work_items method."""
iteration_work_items = await devops_client.get_iteration_work_items(
organization=ORGANIZATION,
project=PROJECT,
iteration_id="abc123",
)

assert iteration_work_items == snapshot(
name="iteration_work_items",
)

# Test with bad request
mock_aioresponse.get(
f"{DEFAULT_BASE_URL}/{ORGANIZATION}/{BAD_PROJECT_NAME}/_apis/work/teamsettings/iterations/abc123/workitems?api-version={DEFAULT_API_VERSION}",
status=400,
)

bad_iteration_work_items = await devops_client.get_iteration_work_items(
organization=ORGANIZATION,
project=BAD_PROJECT_NAME,
iteration_id="abc123",
)

assert bad_iteration_work_items is None

# Test with empty response
mock_aioresponse.get(
f"{DEFAULT_BASE_URL}/{ORGANIZATION}/{EMPTY_PROJECT_NAME}/_apis/work/teamsettings/iterations/abc123/workitems?api-version={DEFAULT_API_VERSION}",
payload=None,
status=200,
)

empty_iteration_work_items = await devops_client.get_iteration_work_items(
organization=ORGANIZATION,
project=EMPTY_PROJECT_NAME,
iteration_id="abc123",
)

assert empty_iteration_work_items is None


@pytest.mark.asyncio
async def test_get_work_items_ids(
devops_client: DevOpsClient,
Expand Down

0 comments on commit 443c12a

Please sign in to comment.