diff --git a/src/main/java/com/crowdin/client/Client.java b/src/main/java/com/crowdin/client/Client.java
index 4b71fece5..6145770a8 100644
--- a/src/main/java/com/crowdin/client/Client.java
+++ b/src/main/java/com/crowdin/client/Client.java
@@ -25,6 +25,7 @@
import com.crowdin.client.sourcestrings.SourceStringsApi;
import com.crowdin.client.storage.StorageApi;
import com.crowdin.client.stringcomments.StringCommentsApi;
+import com.crowdin.client.stringcorrections.StringCorrectionsApi;
import com.crowdin.client.stringtranslations.StringTranslationsApi;
import com.crowdin.client.tasks.TasksApi;
import com.crowdin.client.teams.TeamsApi;
@@ -74,6 +75,7 @@ public class Client extends CrowdinApi {
private final ClientsApi clientsApi;
private final BranchesApi branchesApi;
private final AIApi aiApi;
+ private final StringCorrectionsApi stringCorrectionsApi;
public Client(Credentials credentials) {
super(credentials);
@@ -110,6 +112,7 @@ public Client(Credentials credentials) {
this.clientsApi = new ClientsApi(credentials);
this.branchesApi = new BranchesApi(credentials);
this.aiApi = new AIApi(credentials);
+ this.stringCorrectionsApi = new StringCorrectionsApi(credentials);
}
public Client(Credentials credentials, ClientConfig clientConfig) {
@@ -147,6 +150,7 @@ public Client(Credentials credentials, ClientConfig clientConfig) {
this.clientsApi = new ClientsApi(credentials, clientConfig);
this.branchesApi = new BranchesApi(credentials, clientConfig);
this.aiApi = new AIApi(credentials, clientConfig);
+ this.stringCorrectionsApi = new StringCorrectionsApi(credentials, clientConfig);
}
}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/StringCorrectionsApi.java b/src/main/java/com/crowdin/client/stringcorrections/StringCorrectionsApi.java
new file mode 100644
index 000000000..6ac3534f2
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/StringCorrectionsApi.java
@@ -0,0 +1,111 @@
+package com.crowdin.client.stringcorrections;
+
+import com.crowdin.client.core.CrowdinApi;
+import com.crowdin.client.core.http.HttpRequestConfig;
+import com.crowdin.client.core.http.exceptions.HttpBadRequestException;
+import com.crowdin.client.core.http.exceptions.HttpException;
+import com.crowdin.client.core.model.ClientConfig;
+import com.crowdin.client.core.model.Credentials;
+import com.crowdin.client.core.model.ResponseList;
+import com.crowdin.client.core.model.ResponseObject;
+import com.crowdin.client.stringcorrections.model.*;
+
+import java.util.Map;
+import java.util.Optional;
+
+public class StringCorrectionsApi extends CrowdinApi {
+
+
+ public StringCorrectionsApi(Credentials credentials) {
+ super(credentials);
+ }
+
+ public StringCorrectionsApi(Credentials credentials, ClientConfig clientConfig) {
+ super(credentials, clientConfig);
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param params query params
+ * @return list of corrections
+ * @see
+ */
+ public ResponseList listCorrections(Long projectId, ListCorrectionsQueryParams params) throws HttpException, HttpBadRequestException {
+ Map> queryParams = HttpRequestConfig.buildUrlParams(
+ "stringId", Optional.of(params.getStringId()),
+ "orderBy", Optional.ofNullable(params.getOrderBy()),
+ "denormalizePlaceholders", Optional.ofNullable(params.getDenormalizePlaceholders()),
+ "limit", Optional.ofNullable(params.getLimit()),
+ "offset", Optional.ofNullable(params.getOffset())
+ );
+ CorrectionResponseList response = this.httpClient.get(this.url + "/projects/" + projectId + "/corrections", new HttpRequestConfig(queryParams), CorrectionResponseList.class);
+ return CorrectionResponseList.to(response);
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param request request object
+ * @return newly created correction
+ * @see
+ */
+ public ResponseObject addCorrection(Long projectId, AddCorrectionRequest request) throws HttpException, HttpBadRequestException {
+ CorrectionResponseObject response = this.httpClient.post(this.url + "/projects/" + projectId + "/corrections", request, new HttpRequestConfig(), CorrectionResponseObject.class);
+ return ResponseObject.of(response.getData());
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param correctionId correction identifier
+ * @return correction object
+ * @see
+ */
+ public ResponseObject getCorrection(Long projectId, Long correctionId) throws HttpException, HttpBadRequestException {
+ CorrectionResponseObject response = this.httpClient.get(this.url + "/projects/" + projectId + "/corrections/" + correctionId, new HttpRequestConfig(), CorrectionResponseObject.class);
+ return ResponseObject.of(response.getData());
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param stringId string identifier
+ * @see
+ */
+ public void deleteCorrections(Long projectId, Long stringId) throws HttpException, HttpBadRequestException {
+ Map> queryParams = HttpRequestConfig.buildUrlParams(
+ "stringId", Optional.of(stringId)
+ );
+ this.httpClient.delete(this.url + "/projects/" + projectId + "/corrections", new HttpRequestConfig(queryParams), Void.class);
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param correctionId correction identifier
+ * @return newly created correction
+ * @see
+ */
+ public ResponseObject restoreCorrection(Long projectId, Long correctionId) throws HttpException, HttpBadRequestException {
+ CorrectionResponseObject response = this.httpClient.put(this.url + "/projects/" + projectId + "/corrections/" + correctionId, null, new HttpRequestConfig(), CorrectionResponseObject.class);
+ return ResponseObject.of(response.getData());
+ }
+
+ /**
+ * @param projectId project identifier
+ * @param correctionId correction identifier
+ * @see
+ */
+ public void deleteCorrection(Long projectId, Long correctionId) throws HttpException, HttpBadRequestException {
+ this.httpClient.delete(this.url + "/projects/" + projectId + "/corrections/" + correctionId, new HttpRequestConfig(), Void.class);
+ }
+
+}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/model/AddCorrectionRequest.java b/src/main/java/com/crowdin/client/stringcorrections/model/AddCorrectionRequest.java
new file mode 100644
index 000000000..77fb8f2c5
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/model/AddCorrectionRequest.java
@@ -0,0 +1,10 @@
+package com.crowdin.client.stringcorrections.model;
+
+import lombok.Data;
+
+@Data
+public class AddCorrectionRequest {
+ private Long stringId;
+ private String text;
+ private String pluralCategoryName;
+}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/model/Correction.java b/src/main/java/com/crowdin/client/stringcorrections/model/Correction.java
new file mode 100644
index 000000000..0eb0793cc
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/model/Correction.java
@@ -0,0 +1,23 @@
+package com.crowdin.client.stringcorrections.model;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class Correction {
+
+ private Long id;
+ private String text;
+ private String pluralCategoryName;
+ private User user;
+ private Date createdAt;
+
+ @Data
+ public static class User {
+ private Long id;
+ private String username;
+ private String fullName;
+ private String avatarUrl;
+ }
+}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseList.java b/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseList.java
new file mode 100644
index 000000000..a5553b4bb
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseList.java
@@ -0,0 +1,26 @@
+package com.crowdin.client.stringcorrections.model;
+
+import com.crowdin.client.core.model.Pagination;
+import com.crowdin.client.core.model.ResponseList;
+import com.crowdin.client.core.model.ResponseObject;
+import lombok.Data;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Data
+public class CorrectionResponseList {
+
+ private List data;
+ private Pagination pagination;
+
+ public static ResponseList to(CorrectionResponseList correctionResponseList) {
+ return ResponseList.of(
+ correctionResponseList.getData().stream()
+ .map(CorrectionResponseObject::getData)
+ .map(ResponseObject::of)
+ .collect(Collectors.toList()),
+ correctionResponseList.getPagination()
+ );
+ }
+}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseObject.java b/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseObject.java
new file mode 100644
index 000000000..cdcc9862c
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/model/CorrectionResponseObject.java
@@ -0,0 +1,9 @@
+package com.crowdin.client.stringcorrections.model;
+
+import lombok.Data;
+
+@Data
+public class CorrectionResponseObject {
+
+ private Correction data;
+}
diff --git a/src/main/java/com/crowdin/client/stringcorrections/model/ListCorrectionsQueryParams.java b/src/main/java/com/crowdin/client/stringcorrections/model/ListCorrectionsQueryParams.java
new file mode 100644
index 000000000..dd349fc8d
--- /dev/null
+++ b/src/main/java/com/crowdin/client/stringcorrections/model/ListCorrectionsQueryParams.java
@@ -0,0 +1,14 @@
+package com.crowdin.client.stringcorrections.model;
+
+import com.crowdin.client.core.model.BooleanInt;
+import com.crowdin.client.core.model.Pagination;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ListCorrectionsQueryParams extends Pagination {
+ private Long stringId;
+ private String orderBy;
+ private BooleanInt denormalizePlaceholders;
+}
diff --git a/src/test/java/com/crowdin/client/framework/RequestMock.java b/src/test/java/com/crowdin/client/framework/RequestMock.java
index 6384f0028..036e1f5ab 100644
--- a/src/test/java/com/crowdin/client/framework/RequestMock.java
+++ b/src/test/java/com/crowdin/client/framework/RequestMock.java
@@ -52,6 +52,17 @@ public static RequestMock build(String url, String httpMethod, String responseFi
);
}
+ public static RequestMock build(String url, String httpMethod, Map urlParams) {
+ return new RequestMock(
+ url,
+ null,
+ null,
+ httpMethod,
+ urlParams,
+ Collections.emptyMap()
+ );
+ }
+
public static RequestMock build(String url, String httpMethod) {
return new RequestMock(
url,
diff --git a/src/test/java/com/crowdin/client/stringcorrections/bundles/StringCorrectionsApiTest.java b/src/test/java/com/crowdin/client/stringcorrections/bundles/StringCorrectionsApiTest.java
new file mode 100644
index 000000000..55f505ecb
--- /dev/null
+++ b/src/test/java/com/crowdin/client/stringcorrections/bundles/StringCorrectionsApiTest.java
@@ -0,0 +1,97 @@
+package com.crowdin.client.stringcorrections.bundles;
+
+import com.crowdin.client.core.model.ResponseList;
+import com.crowdin.client.core.model.ResponseObject;
+import com.crowdin.client.framework.RequestMock;
+import com.crowdin.client.framework.TestClient;
+import com.crowdin.client.stringcorrections.model.AddCorrectionRequest;
+import com.crowdin.client.stringcorrections.model.Correction;
+import com.crowdin.client.stringcorrections.model.ListCorrectionsQueryParams;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class StringCorrectionsApiTest extends TestClient {
+
+ private final Long projectId = 1L;
+ private final Long stringId = 35434L;
+ private final Long correctionId = 190695L;
+ private final String text = "This string has been corrected";
+ private final String pluralCategoryName = "few";
+
+ @Override
+ public List getMocks() {
+ return Arrays.asList(
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections", HttpGet.METHOD_NAME, "api/stringcorrections/listCorrectionsResponse.json", new HashMap() {{
+ put("stringId", stringId);
+ }}),
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections", HttpPost.METHOD_NAME, "api/stringcorrections/addCorrectionRequest.json", "api/stringcorrections/correction.json"),
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections/" + correctionId, HttpGet.METHOD_NAME, "api/stringcorrections/correction.json"),
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections/" + correctionId, HttpDelete.METHOD_NAME),
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections", HttpDelete.METHOD_NAME, new HashMap() {{
+ put("stringId", stringId);
+ }}),
+ RequestMock.build(this.url + "/projects/" + projectId + "/corrections/" + correctionId, HttpPut.METHOD_NAME, "api/stringcorrections/correction.json")
+ );
+ }
+
+ @Test
+ public void listCorrectionsTest() {
+ ListCorrectionsQueryParams listCorrectionsQueryParams = new ListCorrectionsQueryParams();
+ listCorrectionsQueryParams.setStringId(stringId);
+ ResponseList response = this.getStringCorrectionsApi().listCorrections(projectId, listCorrectionsQueryParams);
+ assertNotNull(response);
+ assertEquals(1, response.getData().size());
+ assertEquals(response.getData().get(0).getData().getId(), correctionId);
+ assertEquals(response.getData().get(0).getData().getText(), text);
+ assertEquals(response.getData().get(0).getData().getPluralCategoryName(), pluralCategoryName);
+ }
+
+ @Test
+ public void addCorrectionTest() {
+ AddCorrectionRequest request = new AddCorrectionRequest();
+ request.setStringId(stringId);
+ request.setPluralCategoryName(pluralCategoryName);
+ request.setText(text);
+
+ ResponseObject response = this.getStringCorrectionsApi().addCorrection(projectId, request);
+ assertEquals(response.getData().getText(), text);
+ assertEquals(response.getData().getId(), correctionId);
+ assertEquals(response.getData().getPluralCategoryName(), pluralCategoryName);
+ }
+
+ @Test
+ public void getCorrectionTest() {
+ ResponseObject response = this.getStringCorrectionsApi().getCorrection(projectId, correctionId);
+ assertEquals(response.getData().getText(), text);
+ assertEquals(response.getData().getId(), correctionId);
+ assertEquals(response.getData().getPluralCategoryName(), pluralCategoryName);
+ }
+
+ @Test
+ public void deleteCorrectionTest() {
+ this.getStringCorrectionsApi().deleteCorrection(projectId, correctionId);
+ }
+
+ @Test
+ public void deleteCorrectionsTest() {
+ this.getStringCorrectionsApi().deleteCorrections(projectId, stringId);
+ }
+
+ @Test
+ public void restoreCorrectionsTest() {
+ ResponseObject response = this.getStringCorrectionsApi().restoreCorrection(projectId, correctionId);
+ assertEquals(response.getData().getText(), text);
+ assertEquals(response.getData().getId(), correctionId);
+ assertEquals(response.getData().getPluralCategoryName(), pluralCategoryName);
+ }
+}
diff --git a/src/test/resources/api/stringcorrections/addCorrectionRequest.json b/src/test/resources/api/stringcorrections/addCorrectionRequest.json
new file mode 100644
index 000000000..575bcdfa8
--- /dev/null
+++ b/src/test/resources/api/stringcorrections/addCorrectionRequest.json
@@ -0,0 +1,5 @@
+{
+ "stringId": 35434,
+ "text": "This string has been corrected",
+ "pluralCategoryName": "few"
+}
\ No newline at end of file
diff --git a/src/test/resources/api/stringcorrections/correction.json b/src/test/resources/api/stringcorrections/correction.json
new file mode 100644
index 000000000..c1777c1b1
--- /dev/null
+++ b/src/test/resources/api/stringcorrections/correction.json
@@ -0,0 +1,14 @@
+{
+ "data": {
+ "id": 190695,
+ "text": "This string has been corrected",
+ "pluralCategoryName": "few",
+ "user": {
+ "id": 19,
+ "username": "john_doe",
+ "fullName": "John Smith",
+ "avatarUrl": ""
+ },
+ "createdAt": "2019-09-23T11:26:54+00:00"
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/api/stringcorrections/listCorrectionsResponse.json b/src/test/resources/api/stringcorrections/listCorrectionsResponse.json
new file mode 100644
index 000000000..ed76d6e1f
--- /dev/null
+++ b/src/test/resources/api/stringcorrections/listCorrectionsResponse.json
@@ -0,0 +1,20 @@
+{
+ "offset": 0,
+ "limit": 25,
+ "data": [
+ {
+ "data": {
+ "id": 190695,
+ "text": "This string has been corrected",
+ "pluralCategoryName": "few",
+ "user": {
+ "id": 19,
+ "username": "john_doe",
+ "fullName": "John Smith",
+ "avatarUrl": ""
+ },
+ "createdAt": "2019-09-23T11:26:54+00:00"
+ }
+ }
+ ]
+}
\ No newline at end of file