Skip to content

Commit

Permalink
merge: Merge pull request #43 from DSD-DBS/rework-document-apis
Browse files Browse the repository at this point in the history
Add Document Outline options and refactor work item layouting
  • Loading branch information
micha91 authored Jul 29, 2024
2 parents 8396621 + 0e07b41 commit 8084982
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 19 deletions.
42 changes: 38 additions & 4 deletions polarion_rest_api_client/clients/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ def get(
home_page_content=home_page_content,
title=self.unset_to_none(attributes.title),
rendering_layouts=rendering_layouts,
outline_numbering=self.unset_to_none(
attributes.uses_outline_numbering
),
outline_numbering_prefix=(
self.unset_to_none(attributes.outline_numbering.prefix)
if attributes.outline_numbering
else None
),
)

return None
Expand Down Expand Up @@ -136,14 +144,18 @@ def _update(self, to_update: dm.Document | list[dm.Document]):
[
api_models.DocumentsSinglePatchRequestDataAttributesRenderingLayoutsItem(
label=layout.label or oa_types.UNSET,
layouter=layout.layouter or oa_types.UNSET,
layouter=(
layout.layouter.value
if layout.layouter is not None
else oa_types.UNSET
),
type=layout.type or oa_types.UNSET,
properties=(
[
api_models.DocumentsSinglePatchRequestDataAttributesRenderingLayoutsItemPropertiesItem.from_dict(
p
)
for p in layout.properties
for p in layout.properties.serialize()
]
if layout.properties
else oa_types.UNSET
Expand All @@ -154,6 +166,15 @@ def _update(self, to_update: dm.Document | list[dm.Document]):
if to_update.rendering_layouts
else oa_types.UNSET
),
uses_outline_numbering=to_update.outline_numbering
or oa_types.UNSET,
outline_numbering=(
api_models.DocumentsSinglePatchRequestDataAttributesOutlineNumbering(
prefix=to_update.outline_numbering_prefix
)
if to_update.outline_numbering_prefix
else oa_types.UNSET
),
),
)
)
Expand Down Expand Up @@ -204,14 +225,18 @@ def _create(self, items: list[dm.Document]):
[
api_models.DocumentsListPostRequestDataItemAttributesRenderingLayoutsItem(
label=layout.label or oa_types.UNSET,
layouter=layout.layouter or oa_types.UNSET,
layouter=(
layout.layouter.value
if layout.layouter is not None
else oa_types.UNSET
),
type=layout.type or oa_types.UNSET,
properties=(
[
api_models.DocumentsListPostRequestDataItemAttributesRenderingLayoutsItemPropertiesItem.from_dict(
p
)
for p in layout.properties
for p in layout.properties.serialize()
]
if layout.properties
else oa_types.UNSET
Expand All @@ -222,6 +247,15 @@ def _create(self, items: list[dm.Document]):
if document.rendering_layouts
else oa_types.UNSET
),
uses_outline_numbering=document.outline_numbering
or oa_types.UNSET,
outline_numbering=(
api_models.DocumentsListPostRequestDataItemAttributesOutlineNumbering(
prefix=document.outline_numbering_prefix
)
if document.outline_numbering_prefix
else oa_types.UNSET
),
),
)
for document in items
Expand Down
84 changes: 82 additions & 2 deletions polarion_rest_api_client/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
import json
import typing as t

BOOLEAN_RENDERING_PROPERTIES = ["fieldsAtEndAsTable", "hidden"]
RENDERING_LAYOUT_FIELDS = {
"fieldsAtEndAsTable": "fields_at_end_as_table",
"fieldsAtStart": "fields_at_start",
"fieldsAtEnd": "fields_at_end",
"sidebarWorkItemFields": "sidebar_work_item_fields",
"hidden": "hidden",
}


@dataclasses.dataclass
class StatusItem:
Expand Down Expand Up @@ -215,6 +224,8 @@ class Document(StatusItem):
module_name: str | None = None
home_page_content: TextContent | None = None
title: str | None = None
outline_numbering: bool | None = None
outline_numbering_prefix: str | None = None

def __init__(
self,
Expand All @@ -226,24 +237,93 @@ def __init__(
home_page_content: TextContent | None = None,
title: str | None = None,
rendering_layouts: list[RenderingLayout] | None = None,
outline_numbering: bool | None = None,
outline_numbering_prefix: str | None = None,
):
super().__init__(id, type, status)
self.module_folder = module_folder
self.module_name = module_name
self.home_page_content = home_page_content
self.title = title
self.rendering_layouts = rendering_layouts
self.outline_numbering = outline_numbering
self.outline_numbering_prefix = outline_numbering_prefix

def __eq__(self, other):
"""Compare dicts instead of hashes."""
return self.__dict__ == other.__dict__


@dataclasses.dataclass
class RenderingLayout:
"""A class to describe how a work item should be rendered in a document."""

label: str | None = None
layouter: str | None = None
properties: list[dict[str, t.Any]] | None = None
layouter: Layouter | None = None
properties: RenderingProperties | None = None
type: str | None = None

def __init__(
self,
label: str | None = None,
layouter: Layouter | str | None = None,
properties: list[dict[str, t.Any]] | RenderingProperties | None = None,
type: str | None = None,
):
if isinstance(layouter, str):
layouter = Layouter(layouter)

if isinstance(properties, list):
_properties: list[dict[str, t.Any]] = properties
properties = RenderingProperties()
for prop in _properties:
key = prop["key"]
value = prop.get("value", "")
if key in BOOLEAN_RENDERING_PROPERTIES:
value = value == "true"
else:
value = value.split(",")
setattr(properties, RENDERING_LAYOUT_FIELDS[key], value)

self.label = label
self.layouter = layouter
self.properties = properties
self.type = type


class Layouter(enum.Enum):
"""Layout selection for work items in documents."""

DEFAULT = "default" # Seems to be title only
TITLE = "title" # Title only
PARAGRAPH = "paragraph" # Description only
SECTION = "section" # Title and description
TITLE_TEST_STEPS = "titleTestSteps" # Title and testSteps
TITLE_DESC_TEST_STEPS = "titleDescTestSteps" # Title,description,testSteps


@dataclasses.dataclass
class RenderingProperties:
"""Properties for custom field rendering of workitems in documents."""

fields_at_start: list[str] | None = None
fields_at_end: list[str] | None = None
sidebar_work_item_fields: list[str] | None = None
fields_at_end_as_table: bool = False
hidden: bool = False

def serialize(self) -> list[dict[str, t.Any]]:
"""Serialize an instance of this class to be sent via the API."""
result = []
for pol_key, key in RENDERING_LAYOUT_FIELDS.items():
if (value := getattr(self, key)) is not None:
if isinstance(value, list):
value = ",".join(value)
else:
value = str(value).lower()
result.append({"key": pol_key, "value": value})
return result


@dataclasses.dataclass
class TestRun(StatusItem):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ no_implicit_optional = true
show_error_codes = true
warn_redundant_casts = true
warn_unreachable = true
python_version = "3.10"
python_version = "3.11"

[[tool.mypy.overrides]]
module = ["tests.*"]
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def fixture_dummy_work_item_attachment():
TEST_DOCUMENT_RESPONSE = TEST_RESPONSES / "get_document.json"
TEST_DOCUMENT_POST_REQUEST = TEST_REQUESTS / "create_document.json"
TEST_DOCUMENT_PATCH_REQUEST = TEST_REQUESTS / "update_document.json"
TEST_DOCUMENT_PATCH_REQUEST2 = TEST_REQUESTS / "update_document_2.json"
TEST_ERROR_RESPONSE = TEST_RESPONSES / "error.json"
TEST_FAULTS_ERROR_RESPONSES = TEST_RESPONSES / "faulty_errors.json"
TEST_PROJECT_RESPONSE_JSON = TEST_RESPONSES / "project.json"
Expand Down
2 changes: 1 addition & 1 deletion tests/data/expected_requests/create_document.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"data": [{"type": "documents", "attributes": {"homePageContent": {"type": "text/html", "value": "super Value"}, "moduleName": "name", "title": "Fancy Title"}}]}
{"data": [{"type": "documents", "attributes": {"homePageContent": {"type": "text/html", "value": "<p>super Value</p>"}, "moduleName": "name", "outlineNumbering": {"prefix": "TEST"}, "renderingLayouts": [{"label": "My label", "layouter": "paragraph", "properties": [{"key": "fieldsAtEndAsTable", "value": "true"}, {"key": "fieldsAtStart", "value": "id"}, {"key": "fieldsAtEnd", "value": "custom"}, {"key": "sidebarWorkItemFields", "value": "id"}, {"key": "hidden", "value": "false"}], "type": "task"}, {"label": "My label", "layouter": "paragraph", "properties": [{"key": "fieldsAtEndAsTable", "value": "false"}, {"key": "fieldsAtStart", "value": "id"}, {"key": "hidden", "value": "false"}], "type": "task2"}], "title": "Fancy Title"}}]}
2 changes: 1 addition & 1 deletion tests/data/expected_requests/update_document.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"data": {"type": "documents", "id": "PROJ/folder/name", "attributes": {"homePageContent": {"type": "text/html", "value": "super Value"}, "title": "Fancy Title"}}}
{"data": {"type": "documents", "id": "PROJ/folder/name1", "attributes": {"homePageContent": {"type": "text/html", "value": "<p>super Value</p>"}, "title": "Fancy Title"}}}
1 change: 1 addition & 0 deletions tests/data/expected_requests/update_document_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"data": {"type": "documents", "id": "PROJ/folder/name", "attributes": {"homePageContent": {"type": "text/html", "value": "<p>super Value</p>"}, "renderingLayouts": [{"label": "My label", "layouter": "paragraph", "properties": [{"key": "fieldsAtEndAsTable", "value": "false"}, {"key": "fieldsAtStart", "value": "id"}, {"key": "fieldsAtEnd", "value": "custom"}, {"key": "sidebarWorkItemFields", "value": "id"}, {"key": "hidden", "value": "true"}], "type": "task"}, {"label": "My label", "layouter": "paragraph", "properties": [{"key": "fieldsAtEndAsTable", "value": "false"}, {"key": "fieldsAtStart", "value": "id"}, {"key": "hidden", "value": "false"}], "type": "task2"}], "title": "Fancy Title"}}}
2 changes: 2 additions & 0 deletions tests/data/expected_requests/update_document_2.json.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Copyright DB InfraGO AG and contributors
SPDX-License-Identifier: Apache-2.0
30 changes: 28 additions & 2 deletions tests/data/mock_api_responses/get_document.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,34 @@
},
"moduleFolder": "MySpaceId",
"moduleName": "MyDocumentName",
"outlineNumbering": {},
"renderingLayouts": [],
"outlineNumbering": {
"prefix": "PREFIX"
},
"renderingLayouts": [
{
"type": "task",
"label": "My label",
"layouter": "paragraph",
"properties": [
{
"key": "fieldsAtStart",
"value": "id"
},
{
"key": "fieldsAtEnd",
"value": "custom,bla"
},
{
"key": "sidebarWorkItemFields",
"value": "id"
},
{
"key": "fieldsAtEndAsTable",
"value": "true"
}
]
}
],
"status": "open",
"structureLinkRole": "parent",
"title": "MyDocumentName",
Expand Down
Loading

0 comments on commit 8084982

Please sign in to comment.