Skip to content

Commit 977aad3

Browse files
authored
feat: add String Corrections API support (#230)
1 parent cb20013 commit 977aad3

4 files changed

Lines changed: 344 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__pdoc__ = {'tests': False}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from enum import Enum
2+
3+
4+
class ListCorrectionsOrderBy(Enum):
5+
ID = "id"
6+
TEXT = "text"
7+
CREATED_AT = "createdAt"
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from typing import Optional
2+
3+
from crowdin_api.api_resources.abstract.resources import BaseResource
4+
from crowdin_api.api_resources.enums import DenormalizePlaceholders, PluralCategoryName
5+
from crowdin_api.sorting import Sorting
6+
from crowdin_api.utils import convert_enum_to_string_if_exists
7+
8+
9+
class StringCorrectionsResource(BaseResource):
10+
"""
11+
Resource for String Corrections.
12+
13+
Use API to add or remove strings translations, approvals, and votes.
14+
15+
Link to documentation:
16+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections
17+
"""
18+
19+
def get_string_corrections_path(self, project_id: int, correction_id: Optional[int] = None):
20+
if correction_id is not None:
21+
return f"projects/{project_id}/corrections/{correction_id}"
22+
23+
return f"projects/{project_id}/corrections"
24+
25+
def list_corrections(
26+
self,
27+
project_id: int,
28+
string_id: int,
29+
limit: Optional[int] = None,
30+
offset: Optional[int] = None,
31+
order_by: Optional[Sorting] = None,
32+
denormalize_placeholders: Optional[DenormalizePlaceholders] = None,
33+
):
34+
"""
35+
List Corrections
36+
37+
Link to documentation:
38+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.getMany
39+
"""
40+
41+
params = {
42+
"stringId": string_id,
43+
"limit": limit,
44+
"offset": offset,
45+
"orderBy": str(order_by) if order_by is not None else None,
46+
"denormalizePlaceholders": convert_enum_to_string_if_exists(denormalize_placeholders)
47+
}
48+
49+
return self.requester.request(
50+
method="get",
51+
path=self.get_string_corrections_path(project_id),
52+
params=params
53+
)
54+
55+
def add_correction(
56+
self,
57+
project_id: int,
58+
string_id: int,
59+
text: str,
60+
plural_category_name: Optional[PluralCategoryName] = None,
61+
):
62+
"""
63+
Add Correction
64+
65+
Link to documentation:
66+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.post
67+
"""
68+
69+
params = {
70+
"stringId": string_id,
71+
"text": text,
72+
"pluralCategoryName": convert_enum_to_string_if_exists(plural_category_name),
73+
}
74+
75+
return self.requester.request(
76+
method="post",
77+
path=self.get_string_corrections_path(project_id),
78+
request_data=params
79+
)
80+
81+
def delete_corrections(
82+
self,
83+
project_id: int,
84+
string_id: int
85+
):
86+
"""
87+
Delete Corrections
88+
89+
Link to documentation:
90+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.deleteMany
91+
"""
92+
93+
params = {
94+
"stringId": string_id,
95+
}
96+
97+
return self.requester.request(
98+
method="delete",
99+
path=self.get_string_corrections_path(project_id),
100+
params=params
101+
)
102+
103+
def get_correction(
104+
self,
105+
project_id: int,
106+
correction_id: int,
107+
denormalize_placeholders: Optional[DenormalizePlaceholders] = None,
108+
):
109+
"""
110+
Get Correction
111+
112+
Link to documentation:
113+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.get
114+
"""
115+
116+
return self.requester.request(
117+
method="get",
118+
path=self.get_string_corrections_path(project_id, correction_id),
119+
params={
120+
"denormalizePlaceholders": convert_enum_to_string_if_exists(denormalize_placeholders),
121+
}
122+
)
123+
124+
def restore_correction(
125+
self,
126+
project_id: int,
127+
correction_id: int,
128+
):
129+
"""
130+
Restore Correction
131+
132+
Link to documentation:
133+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.put
134+
"""
135+
136+
return self.requester.request(
137+
method="put",
138+
path=self.get_string_corrections_path(project_id, correction_id),
139+
)
140+
141+
def delete_correction(
142+
self,
143+
project_id: int,
144+
correction_id: int
145+
):
146+
"""
147+
Delete Correction
148+
149+
Link to documentation:
150+
https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Corrections/operation/api.projects.corrections.delete
151+
"""
152+
153+
return self.requester.request(
154+
method="delete",
155+
path=self.get_string_corrections_path(project_id, correction_id)
156+
)
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
from unittest import mock
2+
3+
import pytest
4+
5+
from crowdin_api.api_resources.enums import DenormalizePlaceholders, PluralCategoryName
6+
from crowdin_api.api_resources.string_corrections.enums import ListCorrectionsOrderBy
7+
from crowdin_api.api_resources.string_corrections.resource import StringCorrectionsResource
8+
from crowdin_api.requester import APIRequester
9+
from crowdin_api.sorting import SortingRule, Sorting, SortingOrder
10+
11+
12+
class TestStringCorrectionsResource:
13+
resource_class = StringCorrectionsResource
14+
15+
def get_resource(self, base_absolut_url):
16+
return self.resource_class(requester=APIRequester(base_url=base_absolut_url))
17+
18+
def test_resource_with_id(self, base_absolut_url):
19+
project_id = 1
20+
resource = self.resource_class(
21+
requester=APIRequester(base_url=base_absolut_url), project_id=project_id
22+
)
23+
assert resource.get_project_id() == project_id
24+
25+
@pytest.mark.parametrize(
26+
"in_params, request_params",
27+
(
28+
(
29+
{
30+
"string_id": 1
31+
},
32+
{
33+
"stringId": 1,
34+
"limit": None,
35+
"offset": None,
36+
"orderBy": None,
37+
"denormalizePlaceholders": None
38+
},
39+
),
40+
(
41+
{
42+
"string_id": 1,
43+
"limit": 25,
44+
"offset": 0,
45+
"order_by": Sorting(
46+
[
47+
SortingRule(ListCorrectionsOrderBy.CREATED_AT, SortingOrder.DESC),
48+
SortingRule(ListCorrectionsOrderBy.ID)
49+
]
50+
),
51+
"denormalize_placeholders": DenormalizePlaceholders.ENABLE
52+
},
53+
{
54+
"stringId": 1,
55+
"limit": 25,
56+
"offset": 0,
57+
"orderBy": "createdAt desc,id",
58+
"denormalizePlaceholders": 1
59+
}
60+
),
61+
),
62+
)
63+
@mock.patch("crowdin_api.requester.APIRequester.request")
64+
def test_list_corrections(self, m_request, in_params, request_params, base_absolut_url):
65+
m_request.return_value = "response"
66+
67+
project_id = 1
68+
69+
resource = self.get_resource(base_absolut_url)
70+
assert resource.list_corrections(project_id, **in_params) == "response"
71+
m_request.assert_called_with(
72+
method="get",
73+
path=f"projects/{project_id}/corrections",
74+
params=request_params
75+
)
76+
77+
@pytest.mark.parametrize(
78+
"in_params, request_params",
79+
(
80+
(
81+
{
82+
"string_id": 1,
83+
"text": "sample",
84+
"plural_category_name": PluralCategoryName.ZERO
85+
},
86+
{
87+
"stringId": 1,
88+
"text": "sample",
89+
"pluralCategoryName": "zero"
90+
},
91+
),
92+
),
93+
)
94+
@mock.patch("crowdin_api.requester.APIRequester.request")
95+
def test_add_correction(self, m_request, in_params, request_params, base_absolut_url):
96+
m_request.return_value = "response"
97+
98+
project_id = 1
99+
100+
resource = self.get_resource(base_absolut_url)
101+
assert resource.add_correction(project_id, **in_params) == "response"
102+
m_request.assert_called_with(
103+
method="post",
104+
path=f"projects/{project_id}/corrections",
105+
request_data=request_params
106+
)
107+
108+
@mock.patch("crowdin_api.requester.APIRequester.request")
109+
def test_delete_corrections(self, m_request, base_absolut_url):
110+
m_request.return_value = "response"
111+
112+
project_id = 1
113+
string_id = 2
114+
resource = self.get_resource(base_absolut_url)
115+
assert resource.delete_corrections(project_id, string_id) == "response"
116+
117+
m_request.assert_called_with(
118+
method="delete",
119+
path=f"projects/{project_id}/corrections",
120+
params={
121+
"stringId": string_id,
122+
}
123+
)
124+
125+
@pytest.mark.parametrize(
126+
"in_params, request_params",
127+
(
128+
(
129+
{
130+
"denormalize_placeholders": DenormalizePlaceholders.ENABLE,
131+
},
132+
{
133+
"denormalizePlaceholders": 1
134+
}
135+
),
136+
),
137+
)
138+
@mock.patch("crowdin_api.requester.APIRequester.request")
139+
def test_get_correction(self, m_request, in_params, request_params, base_absolut_url):
140+
m_request.return_value = "response"
141+
142+
project_id = 1
143+
correction_id = 2
144+
145+
resource = self.get_resource(base_absolut_url)
146+
assert resource.get_correction(project_id, correction_id, **in_params) == "response"
147+
m_request.assert_called_with(
148+
method="get",
149+
path=f"projects/{project_id}/corrections/{correction_id}",
150+
params=request_params
151+
)
152+
153+
@mock.patch("crowdin_api.requester.APIRequester.request")
154+
def test_restore_correction(self, m_request, base_absolut_url):
155+
m_request.return_value = "response"
156+
157+
project_id = 1
158+
correction_id = 2
159+
160+
resource = self.get_resource(base_absolut_url)
161+
assert resource.restore_correction(project_id, correction_id) == "response"
162+
m_request.assert_called_with(
163+
method="put",
164+
path=f"projects/{project_id}/corrections/{correction_id}",
165+
)
166+
167+
@mock.patch("crowdin_api.requester.APIRequester.request")
168+
def test_delete_correction(self, m_request, base_absolut_url):
169+
m_request.return_value = "response"
170+
171+
project_id = 1
172+
correction_id = 2
173+
174+
resource = self.get_resource(base_absolut_url)
175+
assert resource.delete_correction(project_id, correction_id) == "response"
176+
177+
m_request.assert_called_with(
178+
method="delete",
179+
path=f"projects/{project_id}/corrections/{correction_id}",
180+
)

0 commit comments

Comments
 (0)