Skip to content

Commit 9568413

Browse files
authored
feat(api): add new endpoints for batch operations (#321)
1 parent a654a1c commit 9568413

10 files changed

Lines changed: 294 additions & 8 deletions

File tree

src/main/java/com/crowdin/client/stringcomments/StringCommentsApi.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,19 @@ public ResponseObject<StringComment> editStringComment(Long projectId, Long stri
114114
StringCommentResponseObject response = this.httpClient.patch(builtUrl, request, new HttpRequestConfig(), StringCommentResponseObject.class);
115115
return ResponseObject.of(response.getData());
116116
}
117+
118+
/**
119+
* @param projectId project identifier
120+
* @param request request object
121+
* @return list of updated string comment objects
122+
* @see <ul>
123+
* <li><a href="https://support.crowdin.com/developer/api/v2/#tag/String-Comments/operation/api.projects.comments.batchPatch" target="_blank"><b>API Documentation</b></a></li>
124+
* <li><a href="https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Comments/operation/api.projects.comments.batchPatch" target="_blank"><b>Enterprise API Documentation</b></a></li>
125+
* </ul>
126+
*/
127+
public ResponseList<StringComment> stringCommentBatchOperations(Long projectId, List<PatchRequest> request) {
128+
String builtUrl = String.format("%s/projects/%d/comments", this.url, projectId);
129+
StringCommentResponseList response = this.httpClient.patch(builtUrl, request, new HttpRequestConfig(), StringCommentResponseList.class);
130+
return StringCommentResponseList.to(response);
131+
}
117132
}

src/main/java/com/crowdin/client/stringtranslations/StringTranslationsApi.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.crowdin.client.core.model.*;
88
import com.crowdin.client.stringtranslations.model.*;
99

10+
import java.util.List;
1011
import java.util.Map;
1112
import java.util.Optional;
1213

@@ -133,6 +134,32 @@ public void removeApproval(Long projectId, Long approvalId) throws HttpException
133134
this.httpClient.delete(this.url + "/projects/" + projectId + "/approvals/" + approvalId, new HttpRequestConfig(), Void.class);
134135
}
135136

137+
/**
138+
* @param projectId project identifier
139+
* @see <ul>
140+
* <li><a href="https://support.crowdin.com/developer/api/v2/#tag/String-Translations/operation/api.projects.approvals.patch" target="_blank"><b>API Documentation</b></a></li>
141+
* <li><a href="https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Translations/operation/api.projects.approvals.patch" target="_blank"><b>Enterprise API Documentation</b></a></li>
142+
* </ul>
143+
*/
144+
public ResponseList<Approval> approvalBatchOperations(Long projectId, List<PatchRequest> request) {
145+
String url = this.url + "/projects/" + projectId + "/approvals";
146+
ApprovalResponseList response = this.httpClient.patch(url, request, new HttpRequestConfig(), ApprovalResponseList.class);
147+
return ApprovalResponseList.to(response);
148+
}
149+
150+
/**
151+
* @param projectId project identifier
152+
* @see <ul>
153+
* <li><a href="https://support.crowdin.com/developer/api/v2/#tag/String-Translations/operation/api.projects.translations.patch" target="_blank"><b>API Documentation</b></a></li>
154+
* <li><a href="https://support.crowdin.com/developer/enterprise/api/v2/#tag/String-Translations/operation/api.projects.translations.patch" target="_blank"><b>Enterprise API Documentation</b></a></li>
155+
* </ul>
156+
*/
157+
public ResponseList<StringTranslation> translationBatchOperations(Long projectId, List<PatchRequest> request) {
158+
String url = this.url + "/projects/" + projectId + "/translations";
159+
StringTranslationResponseList response = this.httpClient.patch(url, request, new HttpRequestConfig(), StringTranslationResponseList.class);
160+
return StringTranslationResponseList.to(response);
161+
}
162+
136163
/**
137164
* @param projectId project identifier
138165
* @param languageId language identifier

src/test/java/com/crowdin/client/stringcomments/StringCommentsApiTest.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ public List<RequestMock> getMocks() {
4747
"api/stringcomments/stringCommentResponse.json"),
4848
RequestMock.build(String.format("%s/projects/%d/comments/%d", this.url, projectId, stringCommentId), HttpDelete.METHOD_NAME),
4949
RequestMock.build(String.format("%s/projects/%d/comments/%d", this.url, projectId, stringCommentId), HttpPatch.METHOD_NAME,
50-
"api/stringcomments/editStringCommentRequest.json", "api/stringcomments/stringCommentResponse.json")
50+
"api/stringcomments/editStringCommentRequest.json", "api/stringcomments/stringCommentResponse.json"),
51+
RequestMock.build(
52+
String.format("%s/projects/%d/comments", this.url, projectId),
53+
HttpPatch.METHOD_NAME,
54+
"api/stringcomments/stringCommentBatchOperationsRequest.json",
55+
"api/stringcomments/stringCommentBatchOperationsResponse.json"
56+
)
5157
);
5258
}
5359

@@ -99,4 +105,41 @@ public void editStringCommentTest() {
99105
assertNotNull(response.getData());
100106

101107
}
108+
109+
@Test
110+
public void stringCommentBatchOperationsTest(){
111+
List<PatchRequest> request = new ArrayList<PatchRequest>() {{
112+
add(new PatchRequest() {{
113+
setOp(PatchOperation.REPLACE);
114+
setPath("/2814/text");
115+
setValue("some issue edited");
116+
}});
117+
add(new PatchRequest() {{
118+
setOp(PatchOperation.REPLACE);
119+
setPath("/2814/issueStatus");
120+
setValue(IssueStatus.RESOLVED);
121+
}});
122+
add(new PatchRequest() {{
123+
setOp(PatchOperation.ADD);
124+
setPath("/-");
125+
setValue(new AddStringCommentRequest() {{
126+
setText("some issue");
127+
setStringId(1L);
128+
setType(Type.ISSUE);
129+
setTargetLanguageId("en");
130+
setIssueType("translation_mistake");
131+
}});
132+
}});
133+
add(new PatchRequest() {{
134+
setOp(PatchOperation.REMOVE);
135+
setPath("/2815");
136+
}});
137+
}};
138+
139+
ResponseList<StringComment> response = this.getStringCommentsApi().stringCommentBatchOperations(projectId, request);
140+
assertNotNull(response);
141+
assertNotNull(response.getData());
142+
143+
assertEquals(IssueStatus.UNRESOLVED, response.getData().get(0).getData().getIssueStatus());
144+
}
102145
}

src/test/java/com/crowdin/client/stringtranslations/StringTranslationsApiTest.java

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package com.crowdin.client.stringtranslations;
22

3+
import com.crowdin.client.core.model.PatchOperation;
4+
import com.crowdin.client.core.model.PatchRequest;
35
import com.crowdin.client.core.model.ResponseList;
46
import com.crowdin.client.core.model.ResponseObject;
57
import com.crowdin.client.framework.RequestMock;
68
import com.crowdin.client.framework.TestClient;
79
import com.crowdin.client.stringtranslations.model.*;
8-
import org.apache.http.client.methods.HttpDelete;
9-
import org.apache.http.client.methods.HttpGet;
10-
import org.apache.http.client.methods.HttpPost;
11-
import org.apache.http.client.methods.HttpPut;
10+
import org.apache.http.client.methods.*;
1211
import org.junit.jupiter.api.Test;
1312

13+
import java.util.ArrayList;
1414
import java.util.Arrays;
1515
import java.util.List;
1616
import java.util.Collections;
1717

18-
import static org.junit.jupiter.api.Assertions.assertEquals;
19-
import static org.junit.jupiter.api.Assertions.assertTrue;
18+
import static org.junit.jupiter.api.Assertions.*;
2019

2120
public class StringTranslationsApiTest extends TestClient {
2221

@@ -51,7 +50,20 @@ public List<RequestMock> getMocks() {
5150
RequestMock.build(this.url + "/projects/" + projectId + "/votes", HttpPost.METHOD_NAME, "api/stringtranslations/addVoteRequest.json", "api/stringtranslations/vote.json"),
5251
RequestMock.build(this.url + "/projects/" + projectId + "/votes/" + voteId, HttpGet.METHOD_NAME, "api/stringtranslations/vote.json"),
5352
RequestMock.build(this.url + "/projects/" + projectId + "/votes/" + voteId, HttpDelete.METHOD_NAME),
54-
RequestMock.build(String.format("%s/projects/%d/translations/alignment", this.url, projectId), HttpPost.METHOD_NAME, "api/stringtranslations/alignTranslationRequest.json", "api/stringtranslations/alignTranslationResponse.json")
53+
RequestMock.build(String.format("%s/projects/%d/translations/alignment", this.url, projectId), HttpPost.METHOD_NAME, "api/stringtranslations/alignTranslationRequest.json", "api/stringtranslations/alignTranslationResponse.json"),
54+
55+
RequestMock.build(
56+
this.url + "/projects/" + projectId + "/approvals",
57+
HttpPatch.METHOD_NAME,
58+
"api/stringtranslations/approvalBatchOperationsRequest.json",
59+
"api/stringtranslations/approvalBatchOperationsResponse.json"
60+
),
61+
RequestMock.build(
62+
this.url + "/projects/" + projectId + "/translations",
63+
HttpPatch.METHOD_NAME,
64+
"api/stringtranslations/translationBatchOperationsRequest.json",
65+
"api/stringtranslations/translationBatchOperationsResponse.json"
66+
)
5567
);
5668
}
5769

@@ -189,4 +201,55 @@ public void cancelVoteTest() {
189201
this.getStringTranslationsApi().cancelVote(projectId, voteId);
190202
}
191203

204+
@Test
205+
public void approvalBatchOperationsTest() {
206+
List<PatchRequest> request = new ArrayList<PatchRequest>() {{
207+
add(new PatchRequest() {{
208+
setOp(PatchOperation.ADD);
209+
setPath("/-");
210+
setValue(new AddApprovalRequest() {{
211+
setTranslationId(200L);
212+
}});
213+
}});
214+
add(new PatchRequest() {{
215+
setOp(PatchOperation.REMOVE);
216+
setPath("/2815");
217+
}});
218+
}};
219+
220+
ResponseList<Approval> response = this.getStringTranslationsApi().approvalBatchOperations(projectId, request);
221+
assertNotNull(response);
222+
assertNotNull(response.getData());
223+
224+
assertEquals("uk", response.getData().get(0).getData().getLanguageId());
225+
assertEquals(190695, response.getData().get(0).getData().getTranslationId());
226+
}
227+
228+
@Test
229+
public void translationBatchOperationsTest() {
230+
List<PatchRequest> request = new ArrayList<PatchRequest>() {{
231+
add(new PatchRequest() {{
232+
setOp(PatchOperation.ADD);
233+
setPath("/-");
234+
setValue(new AddStringTranslationRequest() {{
235+
setStringId(35434L);
236+
setLanguageId("fr");
237+
setText("Цю стрічку перекладено");
238+
setPluralCategoryName(PluralCategoryName.FEW);
239+
setAddToTm(false);
240+
}});
241+
}});
242+
add(new PatchRequest() {{
243+
setOp(PatchOperation.REMOVE);
244+
setPath("/2815");
245+
}});
246+
}};
247+
248+
ResponseList<StringTranslation> response = this.getStringTranslationsApi().translationBatchOperations(projectId, request);
249+
assertNotNull(response);
250+
assertNotNull(response.getData());
251+
252+
assertEquals(190695, response.getData().get(0).getData().getId());
253+
assertEquals("tm", response.getData().get(0).getData().getProvider());
254+
}
192255
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[
2+
{
3+
"op": "replace",
4+
"path": "/2814/text",
5+
"value": "some issue edited"
6+
},
7+
{
8+
"op": "replace",
9+
"path": "/2814/issueStatus",
10+
"value": "resolved"
11+
},
12+
{
13+
"op": "add",
14+
"path": "/-",
15+
"value": {
16+
"text": "some issue",
17+
"stringId": 1,
18+
"type": "issue",
19+
"targetLanguageId": "en",
20+
"issueType": "translation_mistake"
21+
}
22+
},
23+
{
24+
"op": "remove",
25+
"path": "/2815"
26+
}
27+
]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"data": [
3+
{
4+
"data": {
5+
"id": 2,
6+
"text": "@BeMyEyes Please provide more details on where the text will be used",
7+
"userId": 6,
8+
"stringId": 742,
9+
"user": {
10+
"id": 12,
11+
"username": "john_smith",
12+
"fullName": "John Smith",
13+
"avatarUrl": ""
14+
},
15+
"string": {
16+
"id": 742,
17+
"text": "HTML page example",
18+
"type": "text",
19+
"hasPlurals": false,
20+
"isIcu": false,
21+
"context": "Document Title\\r\\nXPath: /html/head/title",
22+
"fileId": 22
23+
},
24+
"projectId": 1,
25+
"languageId": "bg",
26+
"type": "issue",
27+
"issueType": "source_mistake",
28+
"issueStatus": "unresolved",
29+
"resolverId": 12,
30+
"resolver": {
31+
"id": 12,
32+
"username": "john_smith",
33+
"fullName": "John Smith",
34+
"avatarUrl": ""
35+
},
36+
"resolvedAt": "2019-09-20T11:05:24+00:00",
37+
"createdAt": "2019-09-20T11:05:24+00:00"
38+
}
39+
}
40+
]
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{
3+
"op": "add",
4+
"path": "/-",
5+
"value": {
6+
"translationId": 200
7+
}
8+
},
9+
{
10+
"op": "remove",
11+
"path": "/2815"
12+
}
13+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"data": [
3+
{
4+
"data": {
5+
"id": 190695,
6+
"user": {
7+
"id": 19,
8+
"username": "john_doe",
9+
"fullName": "John Smith",
10+
"avatarUrl": ""
11+
},
12+
"translationId": 190695,
13+
"stringId": 2345,
14+
"languageId": "uk",
15+
"createdAt": "2019-09-19T12:42:12+00:00"
16+
}
17+
}
18+
]
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"op": "add",
4+
"path": "/-",
5+
"value": {
6+
"stringId": 35434,
7+
"languageId": "fr",
8+
"text": "Цю стрічку перекладено",
9+
"pluralCategoryName": "few",
10+
"addToTm": false
11+
}
12+
},
13+
{
14+
"op": "remove",
15+
"path": "/2815"
16+
}
17+
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"data": [
3+
{
4+
"data": {
5+
"id": 190695,
6+
"text": "Цю стрічку перекладено",
7+
"pluralCategoryName": "few",
8+
"user": {
9+
"id": 19,
10+
"username": "john_doe",
11+
"fullName": "John Smith",
12+
"avatarUrl": ""
13+
},
14+
"rating": 10,
15+
"provider": "tm",
16+
"isPreTranslated": true,
17+
"createdAt": "2019-09-23T11:26:54+00:00"
18+
}
19+
}
20+
]
21+
}

0 commit comments

Comments
 (0)