Skip to content

Commit

Permalink
Merge pull request #62 from crowdin/update_task_settings_templates_api
Browse files Browse the repository at this point in the history
add task settings templates endpoints
  • Loading branch information
andrii-bodnar authored Jan 10, 2023
2 parents 3a7c4f9 + 6701fd7 commit 5b2426d
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 7 deletions.
3 changes: 2 additions & 1 deletion crowdin_api/api_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .storages.resource import StoragesResource
from .string_comments.resource import StringCommentsResource
from .string_translations.resource import StringTranslationsResource
from .tasks.resource import TasksResource
from .tasks.resource import TasksResource, EnterpriseTasksResource
from .teams.resource import TeamsResource
from .translation_memory.resource import TranslationMemoryResource
from .translation_status.resource import TranslationStatusResource
Expand Down Expand Up @@ -43,6 +43,7 @@
"StringCommentsResource",
"StringTranslationsResource",
"TasksResource",
"EnterpriseTasksResource",
"TeamsResource",
"TranslationMemoryResource",
"TranslationStatusResource",
Expand Down
5 changes: 5 additions & 0 deletions crowdin_api/api_resources/tasks/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class VendorTaskOperationPatchPath(Enum):
status = "/status"


class ConfigTaskOperationPatchPath(Enum):
NAME = "/name"
CONFIG = "/config"


class CrowdinTaskType(Enum):
TRANSLATE = 0
PROOFREAD = 1
Expand Down
148 changes: 148 additions & 0 deletions crowdin_api/api_resources/tasks/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
CrowdinTaskAssignee,
TaskPatchRequest,
VendorPatchRequest,
ConfigPatchRequest,
EnterpriseTaskSettingsTemplateLanguages,
TaskSettingsTemplateLanguages,
)


Expand All @@ -35,6 +38,117 @@ class TasksResource(BaseResource):
Link to documentation:
https://developer.crowdin.com/api/v2/#tag/Tasks
"""
def get_task_settings_templates_path(self, projectId: int, taskSettingsTemplateId: Optional[int] = None):
if taskSettingsTemplateId is not None:
return f"projects/{projectId}/tasks/settings-templates/{taskSettingsTemplateId}"

return f"projects/{projectId}/tasks/settings-templates"

def list_task_settings_templates(
self,
projectId: int,
page: Optional[int] = None,
offset: Optional[int] = None,
limit: Optional[int] = None,
):
"""
List Task Settings Templates.
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.projects.tasks.settings-templates.getMany
Link to documentation for enterprise:
https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.tasks.settings-templates.getMany
"""

params = self.get_page_params(page=page, offset=offset, limit=limit)

return self._get_entire_data(
method="get",
path=self.get_task_settings_templates_path(projectId=projectId),
params=params,
)

def add_task_settings_template(
self,
projectId: int,
name: str,
config: TaskSettingsTemplateLanguages
):
"""
Add Task Settings Template.
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.projects.tasks.settings-templates.post
"""

return self.requester.request(
method="post",
path=self.get_task_settings_templates_path(projectId=projectId),
request_data={"name": name, "config": config},
)

def get_task_settings_template(self, projectId: int, taskSettingsTemplateId: int):
"""
Get Task Settings Template.
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.projects.tasks.settings-templates.get
Link to documentation for enterprise:
https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.tasks.settings-templates.get
"""

return self.requester.request(
method="get", path=self.get_task_settings_templates_path(
projectId=projectId,
taskSettingsTemplateId=taskSettingsTemplateId
)
)

def delete_task_settings_template(self, projectId: int, taskSettingsTemplateId: int):
"""
Delete Task Settings Template.
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.projects.tasks.settings-templates.delete
Link to documentation for enterprise:
https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.tasks.settings-templates.delete
"""

return self.requester.request(
method="delete",
path=self.get_task_settings_templates_path(
projectId=projectId,
taskSettingsTemplateId=taskSettingsTemplateId
),
)

def edit_task_settings_template(
self,
projectId: int,
taskSettingsTemplateId: int,
data: Iterable[ConfigPatchRequest],
):
"""
Edit Task Settings Template.
Link to documentation:
https://developer.crowdin.com/api/v2/#operation/api.projects.tasks.settings-templates.patch
Link to documentation for enterprise:
https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.tasks.settings-templates.patch
"""

return self.requester.request(
method="patch",
path=self.get_task_settings_templates_path(
projectId=projectId,
taskSettingsTemplateId=taskSettingsTemplateId
),
request_data=data,
)

def get_tasks_path(self, projectId: int, taskId: Optional[int] = None):
if taskId is not None:
Expand Down Expand Up @@ -346,3 +460,37 @@ def edit_task_archived_status(self, taskId: int, projectId: int, isArchived: boo
params={"projectId": projectId},
request_data=[{"op": "replace", "path": "/isArchived", "value": isArchived}],
)


class EnterpriseTasksResource(TasksResource):
"""
Resource for Tasks.
Create and assign tasks to get files translated or proofread by specific people. You can set
the due dates, split words between people, and receive notifications about the changes and
updates on tasks. Tasks are project-specific, so you’ll have to create them within a project.
Use API to create, modify, and delete specific tasks.
Link to documentation:
https://developer.crowdin.com/enterprise/api/v2/#tag/Tasks
"""

def add_task_settings_template(
self,
projectId: int,
name: str,
config: EnterpriseTaskSettingsTemplateLanguages
):
"""
Add Task Settings Template.
Link to documentation for enterprise:
https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.tasks.settings-templates.post
"""

return self.requester.request(
method="post",
path=self.get_task_settings_templates_path(projectId=projectId),
request_data={"name": name, "config": config},
)
141 changes: 140 additions & 1 deletion crowdin_api/api_resources/tasks/tests/test_tasks_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
TranslatedCrowdinTaskExpertise,
TranslatedCrowdinTaskSubjects,
TranslatedCrowdinTaskType,
ConfigTaskOperationPatchPath,
)
from crowdin_api.api_resources.tasks.resource import TasksResource
from crowdin_api.api_resources.tasks.resource import TasksResource, EnterpriseTasksResource
from crowdin_api.requester import APIRequester


Expand All @@ -27,6 +28,113 @@ class TestTasksResource:
def get_resource(self, base_absolut_url):
return self.resource_class(requester=APIRequester(base_url=base_absolut_url))

@pytest.mark.parametrize(
"incoming_data, path",
(
({"projectId": 1}, "projects/1/tasks/settings-templates"),
(
{"projectId": 1, "taskSettingsTemplateId": 2},
"projects/1/tasks/settings-templates/2"
),
),
)
def test_get_task_settings_templates_path(self, incoming_data, path, base_absolut_url):
resource = self.get_resource(base_absolut_url)
assert resource.get_task_settings_templates_path(**incoming_data) == path

@pytest.mark.parametrize(
"incoming_data, request_params",
(
({}, {"offset": 0, "limit": 25}),
),
)
@mock.patch("crowdin_api.requester.APIRequester.request")
def test_list_task_settings_templates(
self, m_request, incoming_data, request_params, base_absolut_url
):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert resource.list_task_settings_templates(projectId=1, **incoming_data) == "response"
m_request.assert_called_once_with(
method="get",
params=request_params,
path=resource.get_task_settings_templates_path(projectId=1),
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_add_task_settings_template(self, m_request, base_absolut_url):
m_request.return_value = "response"
input_name = "test template"
input_config_data = {
"languages": [
{
"languageId": "uk",
"userIds": [1]
}
]
}

resource = self.get_resource(base_absolut_url)
assert resource.add_task_settings_template(
projectId=1, name=input_name, config=input_config_data
) == "response"
m_request.assert_called_once_with(
method="post",
path=resource.get_task_settings_templates_path(projectId=1),
request_data={"name": input_name, "config": input_config_data},
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_get_task_settings_template(self, m_request, base_absolut_url):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert resource.get_task_settings_template(
projectId=1, taskSettingsTemplateId=2
) == "response"
m_request.assert_called_once_with(
method="get", path=resource.get_task_settings_templates_path(
projectId=1, taskSettingsTemplateId=2
)
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_delete_task_settings_template(self, m_request, base_absolut_url):
m_request.return_value = "response"

resource = self.get_resource(base_absolut_url)
assert resource.delete_task_settings_template(
projectId=1, taskSettingsTemplateId=2
) == "response"
m_request.assert_called_once_with(
method="delete", path=resource.get_task_settings_templates_path(
projectId=1, taskSettingsTemplateId=2
)
)

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_edit_task_settings_template(self, m_request, base_absolut_url):
m_request.return_value = "response"

data = [
{
"value": "value",
"op": PatchOperation.REPLACE,
"path": ConfigTaskOperationPatchPath.NAME,
}
]

resource = self.get_resource(base_absolut_url)
assert resource.edit_task_settings_template(
projectId=1, taskSettingsTemplateId=2, data=data
) == "response"
m_request.assert_called_once_with(
method="patch",
request_data=data,
path=resource.get_task_settings_templates_path(projectId=1, taskSettingsTemplateId=2),
)

@pytest.mark.parametrize(
"incoming_data, path",
(
Expand Down Expand Up @@ -443,3 +551,34 @@ def test_edit_task_archived_status(self, m_request, base_absolut_url):
params={"projectId": 1},
request_data=[{"op": "replace", "path": "/isArchived", "value": False}],
)


class TestEnterpriseTasksResource:
resource_class = EnterpriseTasksResource

def get_resource(self, base_absolut_url):
return self.resource_class(requester=APIRequester(base_url=base_absolut_url))

@mock.patch("crowdin_api.requester.APIRequester.request")
def test_add_task_settings_template(self, m_request, base_absolut_url):
m_request.return_value = "response"
input_name = "test template"
input_config_data = {
"languages": [
{
"languageId": "uk",
"userIds": [1],
"teamIds": [1]
}
]
}

resource = self.get_resource(base_absolut_url)
assert resource.add_task_settings_template(
projectId=1, name=input_name, config=input_config_data
) == "response"
m_request.assert_called_once_with(
method="post",
path=resource.get_task_settings_templates_path(projectId=1),
request_data={"name": input_name, "config": input_config_data},
)
28 changes: 27 additions & 1 deletion crowdin_api/api_resources/tasks/types.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from typing import Any
from typing import Any, Iterable, Union, Optional

from crowdin_api.api_resources.enums import PatchOperation
from crowdin_api.api_resources.tasks.enums import (
TaskOperationPatchPath,
VendorTaskOperationPatchPath,
ConfigTaskOperationPatchPath,
)
from crowdin_api.typing import TypedDict

Expand All @@ -23,3 +24,28 @@ class VendorPatchRequest(TypedDict):
value: Any
op: PatchOperation
path: VendorTaskOperationPatchPath


class ConfigPatchRequest(TypedDict):
value: Union[str, int]
op: PatchOperation
path: ConfigTaskOperationPatchPath


class TaskSettingsTemplateConfigLanguage(TypedDict):
languageId: str
userIds: Optional[Iterable[int]]


class TaskSettingsTemplateLanguages(TypedDict):
languages: Iterable[TaskSettingsTemplateConfigLanguage]


class EnterpriseTaskSettingsTemplateConfigLanguage(TypedDict):
languageId: str
userIds: Optional[Iterable[int]]
teamIds: Optional[Iterable[int]]


class EnterpriseTaskSettingsTemplateLanguages(TypedDict):
languages: Iterable[EnterpriseTaskSettingsTemplateConfigLanguage]
Loading

0 comments on commit 5b2426d

Please sign in to comment.