Skip to content

Commit 1734824

Browse files
authored
feat: add new endpoints for batch operations (#208)
1 parent c730e34 commit 1734824

File tree

6 files changed

+267
-2
lines changed

6 files changed

+267
-2
lines changed

crowdin_api/api_resources/string_comments/resource.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
StringCommentIssueType,
77
StringCommentType,
88
)
9-
from crowdin_api.api_resources.string_comments.types import StringCommentPatchRequest
9+
from crowdin_api.api_resources.string_comments.types import StringCommentPatchRequest, StringCommentBatchOpPatchRequest
1010
from crowdin_api.sorting import Sorting
1111

1212

@@ -149,3 +149,24 @@ def edit_string_comment(
149149
projectId=projectId, stringCommentId=stringCommentId
150150
),
151151
)
152+
153+
def string_comment_batch_operations(
154+
self,
155+
project_id: int,
156+
data: Iterable[StringCommentBatchOpPatchRequest]
157+
):
158+
"""
159+
String Comment Batch Operations.
160+
161+
Link to documentation:
162+
https://support.crowdin.com/developer/api/v2/#tag/String-Comments/operation/api.projects.comments.batchPatch
163+
164+
Link to documentation for enterprise:
165+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Comments/operation/api.projects.comments.batchPatch
166+
"""
167+
168+
return self.requester.request(
169+
method="patch",
170+
path=f"projects/{project_id}/comments",
171+
request_data=data,
172+
)

crowdin_api/api_resources/string_comments/tests/test_string_comments_resources.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,78 @@ def test_edit_string_comment(self, m_request, base_absolut_url):
183183
request_data=data,
184184
path=resource.get_string_comments_path(projectId=1, stringCommentId=2),
185185
)
186+
187+
@pytest.mark.parametrize(
188+
"in_params, request_data",
189+
(
190+
(
191+
[
192+
{
193+
"op": PatchOperation.REPLACE.value,
194+
"path": "/2814/text",
195+
"value": "some issue edited"
196+
},
197+
{
198+
"op": PatchOperation.REPLACE.value,
199+
"path": "/2814/issueStatus",
200+
"value": "resolved"
201+
},
202+
{
203+
"op": PatchOperation.ADD.value,
204+
"path": "/-",
205+
"value": {
206+
"text": "some issue",
207+
"stringId": 1,
208+
"type": "issue",
209+
"targetLanguageId": "en",
210+
"issueType": "translation_mistake"
211+
}
212+
},
213+
{
214+
"op": PatchOperation.REMOVE.value,
215+
"path": "/2815"
216+
}
217+
],
218+
[
219+
{
220+
"op": "replace",
221+
"path": "/2814/text",
222+
"value": "some issue edited"
223+
},
224+
{
225+
"op": "replace",
226+
"path": "/2814/issueStatus",
227+
"value": "resolved"
228+
},
229+
{
230+
"op": "add",
231+
"path": "/-",
232+
"value": {
233+
"text": "some issue",
234+
"stringId": 1,
235+
"type": "issue",
236+
"targetLanguageId": "en",
237+
"issueType": "translation_mistake"
238+
}
239+
},
240+
{
241+
"op": "remove",
242+
"path": "/2815"
243+
}
244+
],
245+
),
246+
),
247+
)
248+
@mock.patch("crowdin_api.requester.APIRequester.request")
249+
def test_string_comment_batch_operations(self, m_request, in_params, request_data, base_absolut_url):
250+
m_request.return_value = "response"
251+
252+
project_id = 1
253+
254+
resource = self.get_resource(base_absolut_url)
255+
assert resource.string_comment_batch_operations(project_id, in_params) == "response"
256+
m_request.assert_called_once_with(
257+
method="patch",
258+
path=f"projects/{project_id}/comments",
259+
request_data=request_data,
260+
)

crowdin_api/api_resources/string_comments/types.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ class StringCommentPatchRequest(TypedDict):
99
value: Any
1010
op: PatchOperation
1111
path: StringCommentPatchPath
12+
13+
14+
class StringCommentBatchOpPatchRequest(TypedDict):
15+
op: PatchOperation
16+
path: str
17+
value: Any

crowdin_api/api_resources/string_translations/resource.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
from crowdin_api.api_resources.abstract.resources import BaseResource
44
from crowdin_api.api_resources.enums import DenormalizePlaceholders, PluralCategoryName
55
from crowdin_api.api_resources.string_translations.enums import VoteMark
6+
from crowdin_api.api_resources.string_translations.types import (
7+
ApprovalBatchOpPatchRequest,
8+
TranslationBatchOpPatchRequest
9+
)
610
from crowdin_api.sorting import Sorting
711

812

@@ -429,3 +433,45 @@ def cancel_vote(self, voteId: int, projectId: Optional[int] = None):
429433
method="delete",
430434
path=self.get_translation_votes_path(projectId=projectId, voteId=voteId),
431435
)
436+
437+
def approval_batch_operations(
438+
self,
439+
project_id: int,
440+
data: Iterable[ApprovalBatchOpPatchRequest]
441+
):
442+
"""
443+
Approval Batch Operations
444+
445+
Link to documentation:
446+
https://support.crowdin.com/developer/api/v2/#tag/String-Translations/operation/api.projects.approvals.patch
447+
448+
Link to documentation for enterprise:
449+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Translations/operation/api.projects.approvals.patch
450+
"""
451+
452+
return self.requester.request(
453+
method="patch",
454+
path=f"projects/{project_id}/approvals",
455+
request_data=data,
456+
)
457+
458+
def translation_batch_operations(
459+
self,
460+
project_id: int,
461+
data: Iterable[TranslationBatchOpPatchRequest]
462+
):
463+
"""
464+
Translation Batch Operations
465+
466+
Link to documentation:
467+
https://support.crowdin.com/developer/api/v2/#tag/String-Translations/operation/api.projects.translations.patch
468+
469+
Link to documentation for enterprise:
470+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Translations/operation/api.projects.translations.patch
471+
"""
472+
473+
return self.requester.request(
474+
method="patch",
475+
path=f"projects/{project_id}/translations",
476+
request_data=data,
477+
)

crowdin_api/api_resources/string_translations/tests/test_string_translations_resources.py

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from unittest import mock
22

33
import pytest
4-
from crowdin_api.api_resources.enums import DenormalizePlaceholders
4+
from crowdin_api.api_resources.enums import DenormalizePlaceholders, PatchOperation
55
from crowdin_api.api_resources.string_translations.enums import (
66
ListLanguageTranslationsOrderBy,
77
ListStringTranslationsOrderBy,
@@ -522,3 +522,105 @@ def test_cancel_vote(self, m_request, base_absolut_url):
522522
method="delete",
523523
path=resource.get_translation_votes_path(projectId=1, voteId=2),
524524
)
525+
526+
@pytest.mark.parametrize(
527+
"in_params, request_params",
528+
(
529+
(
530+
[
531+
{
532+
"op": PatchOperation.ADD.value,
533+
"path": "/-",
534+
"value": {
535+
"translationId": 200
536+
}
537+
},
538+
{
539+
"op": PatchOperation.REMOVE.value,
540+
"path": "/2815"
541+
}
542+
],
543+
[
544+
{
545+
"op": "add",
546+
"path": "/-",
547+
"value": {
548+
"translationId": 200
549+
}
550+
},
551+
{
552+
"op": "remove",
553+
"path": "/2815"
554+
}
555+
]
556+
),
557+
),
558+
)
559+
@mock.patch("crowdin_api.requester.APIRequester.request")
560+
def test_approvals_batch_operations(self, m_request, in_params, request_params, base_absolut_url):
561+
m_request.return_value = "response"
562+
563+
project_id = 1
564+
565+
resource = self.get_resource(base_absolut_url)
566+
assert resource.approval_batch_operations(project_id, in_params) == "response"
567+
m_request.assert_called_once_with(
568+
method="patch",
569+
path=f"projects/{project_id}/approvals",
570+
request_data=request_params,
571+
)
572+
573+
@pytest.mark.parametrize(
574+
"in_params, request_params",
575+
(
576+
(
577+
[
578+
{
579+
"op": PatchOperation.ADD.value,
580+
"path": "/-",
581+
"value": {
582+
"stringId": 35434,
583+
"languageId": "fr",
584+
"text": "Цю стрічку перекладено",
585+
"pluralCategoryName": "few",
586+
"addToTm": False
587+
}
588+
},
589+
{
590+
"op": PatchOperation.REMOVE.value,
591+
"path": "/2815"
592+
}
593+
],
594+
[
595+
{
596+
"op": "add",
597+
"path": "/-",
598+
"value": {
599+
"stringId": 35434,
600+
"languageId": "fr",
601+
"text": "Цю стрічку перекладено",
602+
"pluralCategoryName": "few",
603+
"addToTm": False
604+
}
605+
},
606+
{
607+
"op": "remove",
608+
"path": "/2815"
609+
}
610+
]
611+
),
612+
),
613+
)
614+
@mock.patch("crowdin_api.requester.APIRequester.request")
615+
def test_translation_batch_operations(self, m_request, in_params, request_params, base_absolut_url):
616+
m_request.return_value = "response"
617+
618+
project_id = 1
619+
620+
resource = self.get_resource(base_absolut_url)
621+
assert resource.translation_batch_operations(project_id, in_params) == "response"
622+
m_request.assert_called_once_with(
623+
method="patch",
624+
path=f"projects/{project_id}/translations",
625+
request_data=request_params,
626+
)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from typing import TypedDict, Any
2+
3+
from crowdin_api.api_resources.enums import PatchOperation
4+
5+
6+
class ApprovalBatchOpPatchRequest(TypedDict):
7+
op: PatchOperation
8+
path: str
9+
value: Any
10+
11+
12+
class TranslationBatchOpPatchRequest(TypedDict):
13+
op: PatchOperation
14+
path: str
15+
value: Any

0 commit comments

Comments
 (0)